diff options
210 files changed, 5850 insertions, 1416 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 5133d024ef1..84a2a1d625b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -320,6 +320,10 @@ IF(NOT WITHOUT_SERVER) ADD_SUBDIRECTORY(mysql-test) ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess) ADD_SUBDIRECTORY(sql-bench) + + IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt) + ADD_SUBDIRECTORY(internal) + ENDIF() ENDIF() IF(UNIX) diff --git a/client/mysql.cc b/client/mysql.cc index 9bc1d02bb64..5e844f82b42 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1,6 +1,6 @@ -/* Copyright (C) 2000-2009 MySQL AB - Copyright 2000, 2010-2011, Oracle and/or its affiliates. - Copyright 2000-2010 Monty Program Ab +/* + Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2012, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,10 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define COPYRIGHT_NOTICE "\ -This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL v2 license\n" - /* mysql command tool * Commands compatible with mSQL by David J. Hughes * @@ -111,6 +107,7 @@ extern "C" { #endif #include "completion_hash.h" +#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE #define PROMPT_CHAR '\\' #define DEFAULT_DELIMITER ";" @@ -1193,7 +1190,7 @@ int main(int argc,char *argv[]) mysql_thread_id(&mysql), server_version_string(&mysql)); put_info((char*) glob_buffer.ptr(),INFO_INFO); - put_info(COPYRIGHT_NOTICE, INFO_INFO); + put_info(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000"), INFO_INFO); #ifdef HAVE_READLINE initialize_readline((char*) my_progname); @@ -1624,7 +1621,7 @@ static void usage(int version) if (version) return; - printf("%s", COPYRIGHT_NOTICE); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); printf("Usage: %s [OPTIONS] [database]\n", my_progname); my_print_help(my_long_options); print_defaults("my", load_default_groups); @@ -2808,7 +2805,7 @@ static int com_server_help(String *buffer __attribute__((unused)), char *line __attribute__((unused)), char *help_arg) { MYSQL_ROW cur; - const char *server_cmd= buffer->ptr(); + const char *server_cmd; char cmd_buf[100 + 1]; MYSQL_RES *result; int error; @@ -2823,9 +2820,12 @@ static int com_server_help(String *buffer __attribute__((unused)), *++end_arg= '\0'; } (void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS); - server_cmd= cmd_buf; } - + else + (void) strxnmov(cmd_buf, sizeof(cmd_buf), "help ", help_arg, NullS); + + server_cmd= cmd_buf; + if (!status.batch) { old_buffer= *buffer; @@ -2893,6 +2893,11 @@ static int com_server_help(String *buffer __attribute__((unused)), else { put_info("\nNothing found", INFO_INFO); + if (strncasecmp(server_cmd, "help 'contents'", 15) == 0) + { + put_info("\nPlease check if 'help tables' are loaded.\n", INFO_INFO); + goto err; + } put_info("Please try to run 'help contents' for a list of all accessible topics\n", INFO_INFO); } } diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 5fe5445bc05..40cd9a7fe9c 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -1,7 +1,6 @@ /* - Copyright (C) 2000 MySQL AB - Copyright (c) 2006, 2011, Oracle and/or its affiliates. - Copyright (C) 2010-2011 Monty Program Ab + Copyright (c) 2006, 2012, Oracle and/or its affiliates. + Copyright (C) 2010, 2012, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -252,7 +251,7 @@ get_one_option(int optid, const struct my_option *opt, case '?': printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); - puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); puts("MariaDB utility for upgrading databases to new MariaDB versions.\n"); my_print_help(my_long_options); die(0); diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index bab566e045c..daa1115514e 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -1,5 +1,6 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2010, 2012, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,6 +23,7 @@ #include <sys/stat.h> #include <mysql.h> #include <sql_common.h> +#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ #define ADMIN_VERSION "9.1" #define MAX_MYSQL_VAR 512 @@ -708,9 +710,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) case ADMIN_VER: new_line=1; print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc,\n" - "2009 Monty Program Ab"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); printf("Server version\t\t%s\n", mysql_get_server_info(mysql)); printf("Protocol version\t%d\n", mysql_get_proto_info(mysql)); printf("Connection\t\t%s\n",mysql_get_host_info(mysql)); @@ -1223,9 +1223,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc,\n" - "2009 Monty Program Ab"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); puts("Administration program for the mysqld daemon."); printf("Usage: %s [OPTIONS] command command....\n", my_progname); my_print_help(my_long_options); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index f604b8bc84f..8f6baea4b9f 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -38,6 +38,9 @@ #include "sql_priv.h" #include "log_event.h" #include "sql_common.h" +#include "my_dir.h" +#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE + #include "sql_string.h" // needed for Rpl_filter #include "sql_list.h" // needed for Rpl_filter @@ -1501,10 +1504,7 @@ static void print_version() static void usage() { print_version(); - puts("By Monty and Sasha, for your professional use\n\ -This software comes with NO WARRANTY: This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license.\n"); - + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); printf("\ Dumps a MySQL binary log in a format usable for viewing or for piping to\n\ the mysql command line client.\n\n"); @@ -2087,6 +2087,7 @@ static Exit_status check_header(IO_CACHE* file, uchar header[BIN_LOG_HEADER_SIZE]; uchar buf[PROBE_HEADER_LEN]; my_off_t tmp_pos, pos; + MY_STAT my_file_stat; delete glob_description_event; if (!(glob_description_event= new Format_description_log_event(3))) @@ -2096,7 +2097,16 @@ static Exit_status check_header(IO_CACHE* file, } pos= my_b_tell(file); - my_b_seek(file, (my_off_t)0); + + /* fstat the file to check if the file is a regular file. */ + if (my_fstat(file->file, &my_file_stat, MYF(0)) == -1) + { + error("Unable to stat the file."); + return ERROR_STOP; + } + if ((my_file_stat.st_mode & S_IFMT) == S_IFREG) + my_b_seek(file, (my_off_t)0); + if (my_b_read(file, header, sizeof(header))) { error("Failed reading header; probably an empty file."); diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 1fa1ae2fef5..cd92793ef58 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,6 +1,6 @@ -/* Copyright (C) 2000 MySQL AB & Jani Tolonen - Copyright (c) 2001, 2011, Oracle and/or its affiliates. - Copyright (C) 2010-2011 Monty Program Ab +/* + Copyright (c) 2001, 2012, Oracle and/or its affiliates. + Copyright (c) 2010, 2011, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,6 +25,7 @@ #include <mysql_version.h> #include <mysqld_error.h> #include <sslopt-vars.h> +#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ /* Exit codes */ @@ -229,13 +230,7 @@ static void usage(void) { DBUG_ENTER("usage"); print_version(); - puts("By Jani Tolonen, 2001-04-20, MySQL Development Team.\n"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,"); - puts("and you are welcome to modify and redistribute it under the GPL license.\n"); - printf("Usage: %s [OPTIONS] database [tables]\n", my_progname); - printf("OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n", - my_progname); - printf("OR %s [OPTIONS] --all-databases\n\n", my_progname); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); puts("This program can be used to CHECK (-c, -m, -C), REPAIR (-r), ANALYZE (-a),"); puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be"); puts("used at the same time. Not all options are supported by all storage engines."); diff --git a/client/mysqldump.c b/client/mysqldump.c index 8decdb65582..755c6f8ea3c 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -617,8 +617,7 @@ static void short_usage_sub(void) static void usage(void) { print_version(); - puts("By Igor Romanenko, Monty, Jani & Sinisa and others."); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license.\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); puts("Dumping structure and contents of MySQL databases and tables."); short_usage_sub(); print_defaults("my",load_default_groups); diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 35fb7c2e0a4..15be9341ca3 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -208,7 +208,8 @@ static void usage(void) puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); puts("Copyright 2008-2011 Oracle and Monty Program Ab."); print_version(); - printf("\n\ + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); + printf("\ Loads tables from text files in various formats. The base name of the\n\ text file must be the name of the table that should be used.\n\ If one uses sockets to connect to the MySQL server, the server will open and\n\ diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 61dfd8e9bb8..9febcc118fa 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -27,6 +27,7 @@ #include <signal.h> #include <stdarg.h> #include <sslopt-vars.h> +#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ static char * host=0, *opt_password=0, *user=0; static my_bool opt_show_keys= 0, opt_compress= 0, opt_count=0, opt_status= 0; @@ -270,9 +271,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); - puts("Copyright 2008-2011 Oracle and Monty Program Ab."); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license.\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); puts("Shows the structure of a MySQL database (databases, tables, and columns).\n"); printf("Usage: %s [OPTIONS] [database [table [column]]]\n",my_progname); puts("\n\ diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 3c9b8566abd..afafe1de647 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, 2011, Oracle and/or its affiliates. + Copyright (c) 2005, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -726,7 +726,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2005, 2010")); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2005")); puts("Run a query multiple times against the server.\n"); printf("Usage: %s [OPTIONS]\n",my_progname); print_defaults("my",load_default_groups); diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 6ccb1063cd2..a34edf228da 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -54,6 +54,8 @@ #include <signal.h> #include <my_stacktrace.h> +#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE + #ifdef __WIN__ #include <crtdbg.h> #define SIGNAL_FMT "exception 0x%x" @@ -6987,8 +6989,7 @@ void print_version(void) void usage() { print_version(); - printf("MySQL AB, by Sasha, Matt, Monty & Jani and others\n"); - printf("This software comes with ABSOLUTELY NO WARRANTY\n\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); printf("Runs a test against the mysql server and compares output with a results file.\n\n"); printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname); my_print_help(my_long_options); diff --git a/client/sql_string.h.dontuse b/client/sql_string.h.dontuse index fc302110513..67155ebcee7 100644 --- a/client/sql_string.h.dontuse +++ b/client/sql_string.h.dontuse @@ -1,8 +1,7 @@ #ifndef SQL_STRING_INCLUDED #define SQL_STRING_INCLUDED -/* - Copyright (c) 2000, 2010, Oracle and/or its affiliates +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -194,8 +193,12 @@ public: } bool real_alloc(uint32 arg_length); // Empties old string bool realloc(uint32 arg_length); - inline void shrink(uint32 arg_length) // Shrink buffer + + // Shrink the buffer, but only if it is allocated on the heap. + inline void shrink(uint32 arg_length) { + if (!is_alloced()) + return; if (arg_length < Alloced_length) { char *new_ptr; @@ -211,7 +214,7 @@ public: } } } - bool is_alloced() { return alloced; } + bool is_alloced() const { return alloced; } inline String& operator = (const String &s) { if (&s != this) diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index fdbe489116d..f5017d6c984 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -64,8 +64,10 @@ SET(CPACK_RPM_SPEC_MORE_DEFINE "${CPACK_RPM_SPEC_MORE_DEFINE} SET(CPACK_RPM_PACKAGE_REQUIRES "MariaDB-common") -SET(CPACK_RPM_server_USER_FILELIST "%ignore /etc" "%ignore /etc/init.d") +SET(CPACK_RPM_server_USER_FILELIST "%ignore /etc" "%ignore /etc/init.d" "%config(noreplace) /etc/my.cnf.d/*") SET(CPACK_RPM_common_USER_FILELIST "%config(noreplace) /etc/my.cnf") +SET(CPACK_RPM_shared_USER_FILELIST "%config(noreplace) /etc/my.cnf.d/*") +SET(CPACK_RPM_client_USER_FILELIST "%config(noreplace) /etc/my.cnf.d/*") SET(CPACK_RPM_client_PACKAGE_OBSOLETES "mysql-client MySQL-client MySQL-OurDelta-client") SET(CPACK_RPM_client_PACKAGE_PROVIDES "MariaDB-client MySQL-client mysql-client") @@ -84,6 +86,7 @@ SET(CPACK_RPM_server_PACKAGE_PROVIDES "MariaDB MariaDB-server MySQL-server confi SET(CPACK_RPM_server_PRE_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-prein.sh) SET(CPACK_RPM_server_PRE_UNINSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-preun.sh) SET(CPACK_RPM_server_POST_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-postin.sh) +SET(CPACK_RPM_server_POST_UNINSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-postun.sh) SET(CPACK_RPM_shared_PACKAGE_OBSOLETES "mysql-shared MySQL-shared-standard MySQL-shared-pro MySQL-shared-pro-cert MySQL-shared-pro-gpl MySQL-shared-pro-gpl-cert MySQL-shared MySQL-OurDelta-shared") SET(CPACK_RPM_shared_PACKAGE_PROVIDES "MariaDB-shared MySQL-shared mysql-shared libmysqlclient.so.18 libmysqlclient.so.18(libmysqlclient_16) libmysqlclient.so.18(libmysqlclient_18) libmysqlclient_r.so.18 libmysqlclient_r.so.18(libmysqlclient_18)") diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index 1e7f83ec227..524f368c6d7 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -133,7 +133,6 @@ MACRO(MYSQL_ADD_PLUGIN) ENDIF() ADD_LIBRARY(${target} STATIC ${SOURCES}) - SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_DEFINITONS "MYSQL_SERVER") DTRACE_INSTRUMENT(${target}) ADD_DEPENDENCIES(${target} GenError ${ARG_DEPENDENCIES}) RESTRICT_SYMBOL_EXPORTS(${target}) @@ -146,7 +145,7 @@ MACRO(MYSQL_ADD_PLUGIN) DTRACE_INSTRUMENT(${target}_embedded) IF(ARG_RECOMPILE_FOR_EMBEDDED) SET_TARGET_PROPERTIES(${target}_embedded - PROPERTIES COMPILE_DEFINITIONS "MYSQL_SERVER;EMBEDDED_LIBRARY") + PROPERTIES COMPILE_DEFINITIONS "EMBEDDED_LIBRARY") ENDIF() ADD_DEPENDENCIES(${target}_embedded GenError) ENDIF() diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake index b5b94310d29..cabff530b47 100644 --- a/cmake/ssl.cmake +++ b/cmake/ssl.cmake @@ -25,7 +25,7 @@ MACRO (MYSQL_USE_BUNDLED_SSL) SET(SSL_LIBRARIES yassl taocrypt) SET(SSL_INCLUDE_DIRS ${INC_DIRS}) SET(SSL_INTERNAL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/mySTL) - SET(SSL_DEFINES "-DHAVE_YASSL -DYASSL_PURE_C -DYASSL_PREFIX -DHAVE_OPENSSL -DYASSL_THREAD_SAFE") + SET(SSL_DEFINES "-DHAVE_YASSL -DYASSL_PURE_C -DYASSL_PREFIX -DHAVE_OPENSSL -DMULTI_THREADED") CHANGE_SSL_SETTINGS("bundled") #Remove -fno-implicit-templates #(yassl sources cannot be compiled with it) diff --git a/debian/mariadb-client-10.0.files b/debian/mariadb-client-10.0.files index 2c6c38f853e..ac68079718e 100644 --- a/debian/mariadb-client-10.0.files +++ b/debian/mariadb-client-10.0.files @@ -11,7 +11,6 @@ usr/bin/mysqlimport usr/bin/mysqlreport usr/bin/mysqlshow usr/bin/mysqlslap -usr/bin/mytop usr/bin/mysql_waitpid usr/share/lintian/overrides/mariadb-client-10.0 usr/share/man/man1/innotop.1 diff --git a/debian/patches/41_scripts__mysql_install_db.sh__no_test.dpatch b/debian/patches/41_scripts__mysql_install_db.sh__no_test.dpatch index e79ac71cc7b..d4e67b321b0 100755 --- a/debian/patches/41_scripts__mysql_install_db.sh__no_test.dpatch +++ b/debian/patches/41_scripts__mysql_install_db.sh__no_test.dpatch @@ -13,8 +13,8 @@ fi # Create database directories --for dir in $ldata $ldata/mysql $ldata/test -+for dir in $ldata $ldata/mysql +-for dir in "$ldata" "$ldata/mysql" "$ldata/test" ++for dir in "$ldata" "$ldata/mysql" do if test ! -d $dir then diff --git a/extra/perror.c b/extra/perror.c index a3104b6ddf0..c7dd6f0c205 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -28,6 +28,7 @@ #include "../storage/ndb/src/kernel/error/ndbd_exit_codes.c" #include "../storage/ndb/include/mgmapi/mgmapi_error.h" #endif +#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ static my_bool verbose, print_all_codes; @@ -113,7 +114,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); printf("Print a description for a system error code or a MySQL error code.\n"); printf("If you want to get the error for a negative error code, you should use\n-- before the first error code to tell perror that there was no more options.\n\n"); printf("Usage: %s [OPTIONS] [ERRORCODE [ERRORCODE...]]\n",my_progname); diff --git a/extra/yassl/README b/extra/yassl/README index 7720a9453dd..24bdf32f989 100644 --- a/extra/yassl/README +++ b/extra/yassl/README @@ -12,7 +12,16 @@ before calling SSL_new(); *** end Note *** -yaSSL Release notes, version 2.1.2 (9/2/2011) +yaSSL Release notes, version 2.2.2 (7/5/2012) + + This release of yaSSL contains bug fixes and more security checks around + malicious certificates. + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + + +*****************yaSSL Release notes, version 2.1.2 (9/2/2011) This release of yaSSL contains bug fixes, better non-blocking support with SSL_write, and OpenSSL RSA public key format support. diff --git a/extra/yassl/include/lock.hpp b/extra/yassl/include/lock.hpp index ae875001633..487bedfcc70 100644 --- a/extra/yassl/include/lock.hpp +++ b/extra/yassl/include/lock.hpp @@ -27,7 +27,7 @@ Visual Studio Source Annotations header (sourceannotations.h) fails to compile if outside of the global namespace. */ -#ifdef YASSL_THREAD_SAFE +#ifdef MULTI_THREADED #ifdef _WIN32 #include <windows.h> #endif @@ -36,8 +36,9 @@ namespace yaSSL { -#ifdef YASSL_THREAD_SAFE +#ifdef MULTI_THREADED #ifdef _WIN32 + #include <windows.h> class Mutex { CRITICAL_SECTION cs_; @@ -77,7 +78,7 @@ namespace yaSSL { }; #endif // _WIN32 -#else // YASSL_THREAD_SAFE (WE'RE SINGLE) +#else // MULTI_THREADED (WE'RE SINGLE) class Mutex { public: @@ -87,7 +88,7 @@ namespace yaSSL { }; }; -#endif // YASSL_THREAD_SAFE +#endif // MULTI_THREADED diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index 9104a2f501c..eaf7b0cd1fb 100644 --- a/extra/yassl/include/openssl/ssl.h +++ b/extra/yassl/include/openssl/ssl.h @@ -34,7 +34,7 @@ #include "rsa.h" -#define YASSL_VERSION "2.2.0" +#define YASSL_VERSION "2.2.2" #if defined(__cplusplus) diff --git a/extra/yassl/include/yassl_error.hpp b/extra/yassl/include/yassl_error.hpp index 87bb4c55e96..8efc7f72e87 100644 --- a/extra/yassl/include/yassl_error.hpp +++ b/extra/yassl/include/yassl_error.hpp @@ -65,7 +65,7 @@ enum YasslError { enum Library { yaSSL_Lib = 0, CryptoLib, SocketLib }; enum { MAX_ERROR_SZ = 80 }; -void SetErrorString(unsigned long, char*); +void SetErrorString(YasslError, char*); /* remove for now, if go back to exceptions use this wrapper // Base class for all yaSSL exceptions diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp index e293b80ec04..a89490e9701 100644 --- a/extra/yassl/src/cert_wrapper.cpp +++ b/extra/yassl/src/cert_wrapper.cpp @@ -257,8 +257,7 @@ int CertManager::Validate() TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length()); TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_); - int err = cert.GetError().What(); - if ( err ) + if (int err = cert.GetError().What()) return err; const TaoCrypt::PublicKey& key = cert.GetPublicKey(); diff --git a/extra/yassl/src/lock.cpp b/extra/yassl/src/lock.cpp index 9eb41408ff7..d603440757f 100644 --- a/extra/yassl/src/lock.cpp +++ b/extra/yassl/src/lock.cpp @@ -26,7 +26,7 @@ namespace yaSSL { -#ifdef YASSL_THREAD_SAFE +#ifdef MULTI_THREADED #ifdef _WIN32 Mutex::Mutex() @@ -79,7 +79,7 @@ namespace yaSSL { #endif // _WIN32 -#endif // YASSL_THREAD_SAFE +#endif // MULTI_THREADED diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index 54cfdbba83c..5e4e8197ff2 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -26,7 +26,6 @@ - /* see man pages for function descriptions */ #include "runtime.hpp" @@ -747,7 +746,7 @@ void SSL_CTX_set_verify(SSL_CTX* ctx, int mode, VerifyCallback vc) int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file, const char* path) { - int ret = SSL_SUCCESS; + int ret = SSL_FAILURE; const int HALF_PATH = 128; if (file) ret = read_file(ctx, file, SSL_FILETYPE_PEM, CA); @@ -1014,7 +1013,7 @@ char* ERR_error_string(unsigned long errNumber, char* buffer) static char* msg = (char*)"Please supply a buffer for error string"; if (buffer) { - SetErrorString(errNumber, buffer); + SetErrorString(YasslError(errNumber), buffer); return buffer; } diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp index e55c10c68c0..f48fbdc925e 100644 --- a/extra/yassl/src/yassl_error.cpp +++ b/extra/yassl/src/yassl_error.cpp @@ -31,11 +31,6 @@ #pragma warning(disable: 4996) #endif -#ifdef _MSC_VER - // 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy - #pragma warning(disable: 4996) -#endif - namespace yaSSL { @@ -60,7 +55,7 @@ Library Error::get_lib() const */ -void SetErrorString(unsigned long error, char* buffer) +void SetErrorString(YasslError error, char* buffer) { using namespace TaoCrypt; const int max = MAX_ERROR_SZ; // shorthand diff --git a/extra/yassl/taocrypt/include/aes.hpp b/extra/yassl/taocrypt/include/aes.hpp index dc19c98a83a..e2041fc9350 100644 --- a/extra/yassl/taocrypt/include/aes.hpp +++ b/extra/yassl/taocrypt/include/aes.hpp @@ -92,7 +92,6 @@ typedef BlockCipher<ENCRYPTION, AES, CBC> AES_CBC_Encryption; typedef BlockCipher<DECRYPTION, AES, CBC> AES_CBC_Decryption; - } // naemspace #endif // TAO_CRYPT_AES_HPP diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp index 69be55ce257..afa49d5e8a0 100644 --- a/extra/yassl/taocrypt/include/misc.hpp +++ b/extra/yassl/taocrypt/include/misc.hpp @@ -140,9 +140,13 @@ void CleanUp(); // Turn on ia32 ASM for Big Integer // CodeWarrior defines _MSC_VER +// +// Do not use assembler with GCC, as the implementation for it is broken; +// it does not use proper GCC asm contraints and makes assumptions about +// frame pointers and so on, which breaks depending on GCC version and +// optimization level. #if !defined(TAOCRYPT_DISABLE_X86ASM) && ((defined(_MSC_VER) && \ - !defined(__MWERKS__) && defined(_M_IX86)) || \ - (defined(__GNUC__) && defined(__i386__))) + !defined(__MWERKS__) && defined(_M_IX86))) #define TAOCRYPT_X86ASM_AVAILABLE #endif diff --git a/extra/yassl/taocrypt/include/pwdbased.hpp b/extra/yassl/taocrypt/include/pwdbased.hpp index f40a336e2c3..d050fd8988b 100644 --- a/extra/yassl/taocrypt/include/pwdbased.hpp +++ b/extra/yassl/taocrypt/include/pwdbased.hpp @@ -48,9 +48,11 @@ word32 PBKDF2_HMAC<T>::DeriveKey(byte* derived, word32 dLen, const byte* pwd, word32 pLen, const byte* salt, word32 sLen, word32 iterations) const { - if (dLen > MaxDerivedKeyLength()) + if (dLen > MaxDerivedKeyLength()) return 0; + if (iterations < 0) + return 0; ByteBlock buffer(T::DIGEST_SIZE); HMAC<T> hmac; diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp index 04fdcd85bd8..d2377ea6fb3 100644 --- a/extra/yassl/taocrypt/src/asn.cpp +++ b/extra/yassl/taocrypt/src/asn.cpp @@ -162,6 +162,8 @@ word32 GetLength(Source& source) else length = b; + if (source.IsLeft(length) == false) return 0; + return length; } @@ -840,7 +842,7 @@ void CertDecoder::GetName(NameType nt) if (email) { if (!(ptr = AddTag(ptr, buf_end, "/emailAddress=", 14, length))) { source_.SetError(CONTENT_E); - return; + return; } } diff --git a/extra/yassl/taocrypt/src/coding.cpp b/extra/yassl/taocrypt/src/coding.cpp index 97c62ea12a7..0512ea9c889 100644 --- a/extra/yassl/taocrypt/src/coding.cpp +++ b/extra/yassl/taocrypt/src/coding.cpp @@ -103,6 +103,16 @@ void HexDecoder::Decode() byte b = coded_.next() - 0x30; // 0 starts at 0x30 byte b2 = coded_.next() - 0x30; + // sanity checks + if (b >= sizeof(hexDecode)/sizeof(hexDecode[0])) { + coded_.SetError(PEM_E); + return; + } + if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0])) { + coded_.SetError(PEM_E); + return; + } + b = hexDecode[b]; b2 = hexDecode[b2]; @@ -178,6 +188,7 @@ void Base64Decoder::Decode() { word32 bytes = coded_.size(); word32 plainSz = bytes - ((bytes + (pemLineSz - 1)) / pemLineSz); + const byte maxIdx = (byte)sizeof(base64Decode) + 0x2B - 1; plainSz = ((plainSz * 3) / 4) + 3; decoded_.New(plainSz); @@ -200,6 +211,16 @@ void Base64Decoder::Decode() if (e4 == pad) pad4 = true; + if (e1 < 0x2B || e2 < 0x2B || e3 < 0x2B || e4 < 0x2B) { + coded_.SetError(PEM_E); + return; + } + + if (e1 > maxIdx || e2 > maxIdx || e3 > maxIdx || e4 > maxIdx) { + coded_.SetError(PEM_E); + return; + } + e1 = base64Decode[e1 - 0x2B]; e2 = base64Decode[e2 - 0x2B]; e3 = (e3 == pad) ? 0 : base64Decode[e3 - 0x2B]; diff --git a/extra/yassl/taocrypt/src/crypto.cpp b/extra/yassl/taocrypt/src/crypto.cpp deleted file mode 100644 index 90d406bf0c2..00000000000 --- a/extra/yassl/taocrypt/src/crypto.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2000-2007 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA. -*/ - -/* put features that other apps expect from OpenSSL type crypto */ - - - -extern "C" { - - // for libcurl configure test, these are the signatures they use - // locking handled internally by library - char CRYPTO_lock() { return 0;} - char CRYPTO_add_lock() { return 0;} - - - // for openvpn, test are the signatures they use - char EVP_CIPHER_CTX_init() { return 0; } - char CRYPTO_mem_ctrl() { return 0; } -} // extern "C" - - - diff --git a/extra/yassl/taocrypt/taocrypt.dsw b/extra/yassl/taocrypt/taocrypt.dsw index d10d7534c3d..43115069160 100644 --- a/extra/yassl/taocrypt/taocrypt.dsw +++ b/extra/yassl/taocrypt/taocrypt.dsw @@ -3,6 +3,21 @@ Microsoft Developer Studio Workspace File, Format Version 6.00 ############################################################################### +Project: "benchmark"=.\benchmark\benchmark.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name taocrypt + End Project Dependency +}}} + +############################################################################### + Project: "taocrypt"=.\taocrypt.dsp - Package Owner=<4> Package=<5> @@ -15,7 +30,7 @@ Package=<4> ############################################################################### -Project: "test"=.\test.dsp - Package Owner=<4> +Project: "test"=.\test\test.dsp - Package Owner=<4> Package=<5> {{{ diff --git a/extra/yassl/taocrypt/test/memory.cpp b/extra/yassl/taocrypt/test/memory.cpp index ec398a64c45..a9b21f94902 100644 --- a/extra/yassl/taocrypt/test/memory.cpp +++ b/extra/yassl/taocrypt/test/memory.cpp @@ -31,7 +31,7 @@ To use MemoryTracker merely add this file to your project No need to instantiate anything -If your app is multi threaded define YASSL_THREAD_SAFE +If your app is multi threaded define MULTI_THREADED *********************************************************************/ diff --git a/extra/yassl/taocrypt/test.dsp b/extra/yassl/taocrypt/test/test.dsp index 1084f8e06e3..93b369de3d9 100644 --- a/extra/yassl/taocrypt/test.dsp +++ b/extra/yassl/taocrypt/test/test.dsp @@ -37,12 +37,12 @@ RSC=rc.exe # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 -# PROP Output_Dir "test\Release" -# PROP Intermediate_Dir "test\Release" +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /O2 /I "include" /I "mySTL" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c +# ADD CPP /nologo /MD /W3 /O2 /I "../include" /I "../mySTL" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -61,12 +61,12 @@ LINK32=link.exe # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 -# PROP Output_Dir "test\Debug" -# PROP Intermediate_Dir "test\Debug" +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "include" /I "mySTL" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "../include" /I "../mySTL" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -87,7 +87,7 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=.\test\test.cpp +SOURCE=.\test.cpp # End Source File # End Group # Begin Group "Header Files" diff --git a/extra/yassl/yassl.dsw b/extra/yassl/yassl.dsw index 288c88dfd5b..8da089fc1fa 100644 --- a/extra/yassl/yassl.dsw +++ b/extra/yassl/yassl.dsw @@ -90,7 +90,7 @@ Package=<4> ############################################################################### -Project: "test"=.\taocrypt\test.dsp - Package Owner=<4> +Project: "test"=.\taocrypt\test\test.dsp - Package Owner=<4> Package=<5> {{{ @@ -114,9 +114,6 @@ Package=<5> Package=<4> {{{ Begin Project Dependency - Project_Dep_Name taocrypt - End Project Dependency - Begin Project Dependency Project_Dep_Name yassl End Project Dependency }}} diff --git a/include/my_context.h b/include/my_context.h index 3438ce4c969..0abf49efd43 100644 --- a/include/my_context.h +++ b/include/my_context.h @@ -29,7 +29,7 @@ #define MY_CONTEXT_USE_WIN32_FIBERS 1 #elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__x86_64__) #define MY_CONTEXT_USE_X86_64_GCC_ASM -#elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__i386__) && !defined(SAFEMALLOC) +#elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__i386__) #define MY_CONTEXT_USE_I386_GCC_ASM #else #define MY_CONTEXT_USE_UCONTEXT diff --git a/include/thread_pool_priv.h b/include/thread_pool_priv.h index 4060cf51733..78526894e21 100644 --- a/include/thread_pool_priv.h +++ b/include/thread_pool_priv.h @@ -36,6 +36,7 @@ #include <debug_sync.h> #include <sql_profile.h> #include <table.h> +#include <sql_list.h> /* Needed to get access to scheduler variables */ void* thd_get_scheduler_data(THD *thd); @@ -56,9 +57,14 @@ void thd_unlock_data(THD *thd); bool thd_is_transaction_active(THD *thd); int thd_connection_has_data(THD *thd); void thd_set_net_read_write(THD *thd, uint val); +uint thd_get_net_read_write(THD *thd); void thd_set_mysys_var(THD *thd, st_my_thread_var *mysys_var); +ulong thd_get_net_wait_timeout(THD *thd); my_socket thd_get_fd(THD *thd); +THD *first_global_thread(); +THD *next_global_thread(THD *thd); + /* Print to the MySQL error log */ void sql_print_error(const char *format, ...); diff --git a/include/violite.h b/include/violite.h index 9d82bda67c3..b8757bebf55 100644 --- a/include/violite.h +++ b/include/violite.h @@ -199,6 +199,12 @@ void vio_end(void); #endif /* !defined(DONT_MAP_VIO) */ #ifdef _WIN32 + +/* shutdown(2) flags */ +#ifndef SHUT_RD +#define SHUT_RD SD_BOTH +#endif + /* Set thread id for io cancellation (required on Windows XP only, and should to be removed if XP is no more supported) diff --git a/include/welcome_copyright_notice.h b/include/welcome_copyright_notice.h index 739aeb4ede8..adb7b9f9c20 100644 --- a/include/welcome_copyright_notice.h +++ b/include/welcome_copyright_notice.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. +/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,11 +16,14 @@ #ifndef _welcome_copyright_notice_h_ #define _welcome_copyright_notice_h_ +#define COPYRIGHT_NOTICE_CURRENT_YEAR "2012" + /* This define specifies copyright notice which is displayed by every MySQL program on start, or on help screen. */ -#define ORACLE_WELCOME_COPYRIGHT_NOTICE(years) \ - "Copyright (c) " years ", Oracle, Monty Program Ab and others.\n" +#define ORACLE_WELCOME_COPYRIGHT_NOTICE(first_year) \ + "Copyright (c) " first_year ", " COPYRIGHT_NOTICE_CURRENT_YEAR \ + ", Oracle, Monty Program Ab and others.\n" #endif /* _welcome_copyright_notice_h_ */ diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql index c30cb7d1ff4..d957e33d41c 100644 --- a/mysql-test/include/mtr_warnings.sql +++ b/mysql-test/include/mtr_warnings.sql @@ -97,7 +97,6 @@ INSERT INTO global_suppressions VALUES ("Failed to open log"), ("Failed to open the existing master info file"), ("Forcing shutdown of [0-9]* plugins"), - ("Forcing close of thread"), /* Due to timing issues, it might be that this warning diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index 5446406924f..ba01db4a66f 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -1687,6 +1687,7 @@ SELECT t.b, t.c, t1.a FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t WHERE t.b AND t.c = t1.a; b c a +8 c c EXPLAIN EXTENDED SELECT t.b, t.c, t1.a FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t @@ -1701,6 +1702,7 @@ SELECT t.b, t.c, t1.a FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t WHERE t.b <> 0 AND t.c = t1.a; b c a +8 c c INSERT INTO t3 VALUES (100), (200); EXPLAIN EXTENDED SELECT t.b, t.c, t1.a @@ -1716,7 +1718,7 @@ SELECT t.b, t.c, t1.a FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t WHERE t.b AND t.c = t1.a; b c a -NULL NULL c +8 c c EXPLAIN EXTENDED SELECT t.b, t.c, t1.a FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t @@ -1731,7 +1733,7 @@ SELECT t.b, t.c, t1.a FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t WHERE t.b <> 0 AND t.c = t1.a; b c a -NULL NULL c +8 c c SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2,t3; # diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 205197bc7f6..80729545902 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -2867,3 +2867,16 @@ SET @@global.max_allowed_packet:= @tmp_max; # # End of 5.5 tests # +SELECT @tmp_max:= @@global.max_allowed_packet; +@tmp_max:= @@global.max_allowed_packet +1048576 +SET @@global.max_allowed_packet=1024*1024*1024; +SELECT @@global.max_allowed_packet; +@@global.max_allowed_packet +1073741824 +SELECT CHAR_LENGTH(EXPORT_SET(1,1,1,REPEAT(1,100000000))); +CHAR_LENGTH(EXPORT_SET(1,1,1,REPEAT(1,100000000))) +NULL +Warnings: +Warning 1301 Result of repeat() was larger than max_allowed_packet (1048576) - truncated +SET @@global.max_allowed_packet:= @tmp_max; diff --git a/mysql-test/r/information_schema_all_engines.result b/mysql-test/r/information_schema_all_engines.result index 7d47f0404bb..4dac9a3e53c 100644 --- a/mysql-test/r/information_schema_all_engines.result +++ b/mysql-test/r/information_schema_all_engines.result @@ -16,6 +16,7 @@ INDEX_STATISTICS INNODB_BUFFER_POOL_PAGES INNODB_BUFFER_POOL_PAGES_BLOB INNODB_BUFFER_POOL_PAGES_INDEX +INNODB_CHANGED_PAGES INNODB_CMP INNODB_CMPMEM INNODB_CMPMEM_RESET @@ -88,6 +89,7 @@ INDEX_STATISTICS TABLE_SCHEMA INNODB_BUFFER_POOL_PAGES page_type INNODB_BUFFER_POOL_PAGES_BLOB space_id INNODB_BUFFER_POOL_PAGES_INDEX index_id +INNODB_CHANGED_PAGES space_id INNODB_CMP page_size INNODB_CMPMEM page_size INNODB_CMPMEM_RESET page_size @@ -160,6 +162,7 @@ INDEX_STATISTICS TABLE_SCHEMA INNODB_BUFFER_POOL_PAGES page_type INNODB_BUFFER_POOL_PAGES_BLOB space_id INNODB_BUFFER_POOL_PAGES_INDEX index_id +INNODB_CHANGED_PAGES space_id INNODB_CMP page_size INNODB_CMPMEM page_size INNODB_CMPMEM_RESET page_size @@ -238,6 +241,7 @@ INDEX_STATISTICS information_schema.INDEX_STATISTICS 1 INNODB_BUFFER_POOL_PAGES information_schema.INNODB_BUFFER_POOL_PAGES 1 INNODB_BUFFER_POOL_PAGES_BLOB information_schema.INNODB_BUFFER_POOL_PAGES_BLOB 1 INNODB_BUFFER_POOL_PAGES_INDEX information_schema.INNODB_BUFFER_POOL_PAGES_INDEX 1 +INNODB_CHANGED_PAGES information_schema.INNODB_CHANGED_PAGES 1 INNODB_CMP information_schema.INNODB_CMP 1 INNODB_CMPMEM information_schema.INNODB_CMPMEM 1 INNODB_CMPMEM_RESET information_schema.INNODB_CMPMEM_RESET 1 @@ -299,6 +303,7 @@ Database: information_schema | INNODB_BUFFER_POOL_PAGES | | INNODB_BUFFER_POOL_PAGES_BLOB | | INNODB_BUFFER_POOL_PAGES_INDEX | +| INNODB_CHANGED_PAGES | | INNODB_CMP | | INNODB_CMPMEM | | INNODB_CMPMEM_RESET | @@ -361,6 +366,7 @@ Database: INFORMATION_SCHEMA | INNODB_BUFFER_POOL_PAGES | | INNODB_BUFFER_POOL_PAGES_BLOB | | INNODB_BUFFER_POOL_PAGES_INDEX | +| INNODB_CHANGED_PAGES | | INNODB_CMP | | INNODB_CMPMEM | | INNODB_CMPMEM_RESET | @@ -411,5 +417,5 @@ Wildcard: inf_rmation_schema | information_schema | SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA; table_schema count(*) -information_schema 57 +information_schema 58 mysql 23 diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 6471a2f8bbd..bb455f2b39a 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -5589,4 +5589,52 @@ set join_buffer_size=default; set join_cache_level=default; set optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3; +# +# Bug #1058071: LEFT JOIN using blobs +# (mdev-564) when join buffer size is small +# +CREATE TABLE t1 ( +col269 decimal(31,10) unsigned DEFAULT NULL, +col280 multipoint DEFAULT NULL, +col281 tinyint(1) DEFAULT NULL, +col282 time NOT NULL, +col284 datetime DEFAULT NULL, +col286 date DEFAULT NULL, +col287 datetime DEFAULT NULL, +col288 decimal(30,29) DEFAULT NULL, +col291 time DEFAULT NULL, +col292 time DEFAULT NULL +) ENGINE=Aria; +INSERT INTO t1 VALUES +(0.0,PointFromText('POINT(9 0)'),0,'11:24:05','2013-04-14 21:30:28',NULL,'2011-12-20 06:00:34',9.9,'13:04:39',NULL), +(0.0,NULL,127,'05:43:12','2012-09-05 06:15:27','2027-01-01','2011-10-29 10:48:29',0.0,'06:24:05','11:33:37'), +(0.0,NULL,127,'12:54:41','2013-01-12 11:32:58','2011-11-03','2013-01-03 02:00:34',00,'11:54:15','20:19:15'), +(0.0,PointFromText('POINT(9 0)'),0,'19:48:07','2012-07-16 15:45:25','2012-03-25','2013-09-07 17:21:52',0.5,'17:36:54','21:24:19'), +(0.0,PointFromText('POINT(9 0)'),0,'03:43:48','2012-09-28 00:00:00','2012-06-26','2011-11-16 05:01:09',00,'01:25:42','19:30:06'), +(0.0,LineStringFromText('LINESTRING(0 0,9 9,0 0,9 0,0 0)'),127,'11:33:21','2012-03-31 10:29:22','2012-10-10','2012-04-21 19:21:06',NULL,'05:13:22','09:48:34'), +(NULL,PointFromText('POINT(9 0)'),127,'00:00:00','0000-00-00','2012-04-04 21:26:12','2013-03-04',0.0,'12:54:30',NULL), +(NULL,PointFromText('POINT(9 0)'),1,'00:00:00','2013-05-01 22:37:49','2013-06-26','2012-09-22 17:31:03',0.0,'08:09:57','11:15:36'); +Warnings: +Note 1265 Data truncated for column 'col286' at row 7 +CREATE TABLE t2 (b int) ENGINE=Aria; +INSERT INTO t2 VALUES (NULL); +CREATE TABLE t3 (c int) ENGINE=Aria; +INSERT INTO t3 VALUES (NULL); +set @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch = 'outer_join_with_cache=on,join_cache_incremental=on'; +set join_buffer_size=128; +EXPLAIN +SELECT 1 AS c FROM t1 NATURAL LEFT JOIN t2 LEFT OUTER JOIN t3 ON 1 +GROUP BY elt(t1.col282,1,t1.col280); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join) +SELECT 1 AS c FROM t1 NATURAL LEFT JOIN t2 LEFT OUTER JOIN t3 ON 1 +GROUP BY elt(t1.col282,1,t1.col280); +c +1 +set join_buffer_size=default; +set optimizer_switch=@tmp_optimizer_switch; +DROP table t1,t2,t3; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/limit_rows_examined.result b/mysql-test/r/limit_rows_examined.result index f4242f17a14..a51798a5883 100644 --- a/mysql-test/r/limit_rows_examined.result +++ b/mysql-test/r/limit_rows_examined.result @@ -318,7 +318,7 @@ LIMIT ROWS EXAMINED 9; c1 bb Warnings: -Warning 1931 Query execution was interrupted. The query examined at least 10 rows, which exceeds LIMIT ROWS EXAMINED (9). The query result may be incomplete. +Warning 1931 Query execution was interrupted. The query examined at least 12 rows, which exceeds LIMIT ROWS EXAMINED (9). The query result may be incomplete. Same as above, without subquery cache set @@optimizer_switch='subquery_cache=off'; select * from t1 @@ -347,7 +347,7 @@ LIMIT ROWS EXAMINED 5; c1 bb Warnings: -Warning 1931 Query execution was interrupted. The query examined at least 6 rows, which exceeds LIMIT ROWS EXAMINED (5). The query result may be incomplete. +Warning 1931 Query execution was interrupted. The query examined at least 7 rows, which exceeds LIMIT ROWS EXAMINED (5). The query result may be incomplete. Subqueries with materialization set @@optimizer_switch='semijoin=off,in_to_exists=off,materialization=on,subquery_cache=on'; explain diff --git a/mysql-test/r/log_state.result b/mysql-test/r/log_state.result index 52f98494942..3ccd1451bc4 100644 --- a/mysql-test/r/log_state.result +++ b/mysql-test/r/log_state.result @@ -199,7 +199,7 @@ SELECT @@general_log, @@log; 1 1 SET GLOBAL log = 0; Warnings: -Warning 1287 The syntax '@@log' is deprecated and will be removed in MariaDB 10.1. Please use '@@general_log' instead +Warning 1287 '@@log' is deprecated and will be removed in a future release. Please use '@@general_log' instead SHOW VARIABLES LIKE 'general_log'; Variable_name Value general_log OFF @@ -230,7 +230,7 @@ SELECT @@slow_query_log, @@log_slow_queries; 0 0 SET GLOBAL log_slow_queries = 0; Warnings: -Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MariaDB 10.1. Please use '@@slow_query_log' instead +Warning 1287 '@@log_slow_queries' is deprecated and will be removed in a future release. Please use '@@slow_query_log' instead SHOW VARIABLES LIKE 'slow_query_log'; Variable_name Value slow_query_log OFF @@ -283,16 +283,16 @@ SET GLOBAL slow_query_log_file = @old_slow_query_log_file; deprecated: SET GLOBAL log = 0; Warnings: -Warning 1287 The syntax '@@log' is deprecated and will be removed in MariaDB 10.1. Please use '@@general_log' instead +Warning 1287 '@@log' is deprecated and will be removed in a future release. Please use '@@general_log' instead SET GLOBAL log_slow_queries = 0; Warnings: -Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MariaDB 10.1. Please use '@@slow_query_log' instead +Warning 1287 '@@log_slow_queries' is deprecated and will be removed in a future release. Please use '@@slow_query_log' instead SET GLOBAL log = DEFAULT; Warnings: -Warning 1287 The syntax '@@log' is deprecated and will be removed in MariaDB 10.1. Please use '@@general_log' instead +Warning 1287 '@@log' is deprecated and will be removed in a future release. Please use '@@general_log' instead SET GLOBAL log_slow_queries = DEFAULT; Warnings: -Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MariaDB 10.1. Please use '@@slow_query_log' instead +Warning 1287 '@@log_slow_queries' is deprecated and will be removed in a future release. Please use '@@slow_query_log' instead not deprecated: SELECT @@global.general_log_file INTO @my_glf; SELECT @@global.slow_query_log_file INTO @my_sqlf; diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index 5b8e6ea3348..c065f949802 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -204,6 +204,10 @@ The following options may be given as the first argument: -?, --help Display this help and exit. --ignore-builtin-innodb Disable initialization of builtin InnoDB plugin + --ignore-db-dirs=name + Specifies a directory to add to the ignore list when + collecting database names from the datadir. Put a blank + argument to reset the list accumulated so far. --init-connect=name Command(s) that are executed for each new connection (unless the user has SUPER privilege) --init-file=name Read SQL commands from this file at startup @@ -979,6 +983,7 @@ general-log FALSE group-concat-max-len 1024 help TRUE ignore-builtin-innodb FALSE +ignore-db-dirs init-connect init-file (No default value) init-rpl-role MASTER diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result index 439930b8fe4..b86925e0eb8 100644 --- a/mysql-test/r/openssl_1.result +++ b/mysql-test/r/openssl_1.result @@ -44,9 +44,9 @@ ERROR 42000: DELETE command denied to user 'ssl_user4'@'localhost' for table 't1 drop user ssl_user1@localhost, ssl_user2@localhost, ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost; drop table t1; -mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation -mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation -mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation +mysqltest: Could not open connection 'default': 2026 SSL connection error: xxxx +mysqltest: Could not open connection 'default': 2026 SSL connection error: xxxx +mysqltest: Could not open connection 'default': 2026 SSL connection error: xxxx SSL error: Unable to get private key from '' mysqltest: Could not open connection 'default': 2026 SSL connection error: Unable to get private key SSL error: Unable to get certificate from '' diff --git a/mysql-test/r/order_fill_sortbuf.result b/mysql-test/r/order_fill_sortbuf.result index 2226e842901..6a0bd9d966b 100644 --- a/mysql-test/r/order_fill_sortbuf.result +++ b/mysql-test/r/order_fill_sortbuf.result @@ -1,4 +1,5 @@ drop table if exists t1,t2; +set @@sort_buffer_size=32804; CREATE TABLE `t1` ( `id` int(11) NOT NULL default '0', `id2` int(11) NOT NULL default '0', diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index 045a62a1d5a..3ca0cf8554f 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -777,3 +777,14 @@ execute stmt1 ; prepare stmt1 from ' select * from t5 ' ; execute stmt1 ; drop table t1, t5, t9; +# +# testcase for bug#11765413 - Crash with dependent subquery and +# prepared statement +create table t1 (c1 int); +insert into t1 values (1); +prepare stmt1 from "select 1 from t1 where 1=(select 1 from t1 having c1)"; +execute stmt1; +1 +1 +drop prepare stmt1; +drop table t1; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 30d5ca00bc0..378b20829f3 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4887,7 +4887,7 @@ CREATE TABLE t5 (f1 int) ; INSERT INTO t5 VALUES (20),(5); CREATE TABLE t6(f1 int); INSERT INTO t6 VALUES (9),(7); -SET SESSION join_buffer_size = 2048; +SET SESSION join_buffer_size = 2176; EXPLAIN SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; id select_type table type possible_keys key key_len ref rows Extra @@ -4901,50 +4901,50 @@ SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; f1 f1 f1 f1 f2 f1 f1 3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 -3 9 NULL NULL NULL 20 7 -7 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 20 9 3 9 NULL NULL NULL 20 9 -18 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 7 -3 9 NULL NULL NULL 5 7 7 9 NULL NULL NULL 20 9 -18 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 20 7 7 9 NULL NULL NULL 20 7 18 9 NULL NULL NULL 20 7 -7 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 7 -18 9 NULL NULL NULL 5 7 -3 9 NULL NULL NULL 20 9 -7 9 NULL NULL NULL 20 9 3 9 NULL NULL NULL 20 7 7 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 20 9 3 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 18 9 NULL NULL NULL 20 7 3 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 18 9 NULL NULL NULL 5 9 3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 5 7 3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 18 9 NULL NULL NULL 20 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 7 9 NULL NULL NULL 20 7 18 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 9 7 9 NULL NULL NULL 5 9 18 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 7 7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 5 7 SET SESSION join_buffer_size = DEFAULT; diff --git a/mysql-test/r/select_jcl6.result b/mysql-test/r/select_jcl6.result index a9c74afdd9c..b5c6f89b87b 100644 --- a/mysql-test/r/select_jcl6.result +++ b/mysql-test/r/select_jcl6.result @@ -4898,7 +4898,7 @@ CREATE TABLE t5 (f1 int) ; INSERT INTO t5 VALUES (20),(5); CREATE TABLE t6(f1 int); INSERT INTO t6 VALUES (9),(7); -SET SESSION join_buffer_size = 2048; +SET SESSION join_buffer_size = 2176; EXPLAIN SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; id select_type table type possible_keys key key_len ref rows Extra @@ -4913,48 +4913,48 @@ f1 f1 f1 f1 f2 f1 f1 3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 18 9 NULL NULL NULL 20 9 -3 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 20 7 -7 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 -18 9 NULL NULL NULL 5 7 3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 18 9 NULL NULL NULL 20 9 -3 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 20 7 -7 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 -18 9 NULL NULL NULL 5 7 3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 18 9 NULL NULL NULL 20 9 -3 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 20 7 -7 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 -18 9 NULL NULL NULL 5 7 3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 18 9 NULL NULL NULL 20 9 3 9 NULL NULL NULL 5 9 7 9 NULL NULL NULL 5 9 18 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 3 9 NULL NULL NULL 20 7 7 9 NULL NULL NULL 20 7 18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 3 9 NULL NULL NULL 5 7 7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 5 7 diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result index 30d5ca00bc0..378b20829f3 100644 --- a/mysql-test/r/select_pkeycache.result +++ b/mysql-test/r/select_pkeycache.result @@ -4887,7 +4887,7 @@ CREATE TABLE t5 (f1 int) ; INSERT INTO t5 VALUES (20),(5); CREATE TABLE t6(f1 int); INSERT INTO t6 VALUES (9),(7); -SET SESSION join_buffer_size = 2048; +SET SESSION join_buffer_size = 2176; EXPLAIN SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; id select_type table type possible_keys key key_len ref rows Extra @@ -4901,50 +4901,50 @@ SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; f1 f1 f1 f1 f2 f1 f1 3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 -3 9 NULL NULL NULL 20 7 -7 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 20 9 3 9 NULL NULL NULL 20 9 -18 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 7 -3 9 NULL NULL NULL 5 7 7 9 NULL NULL NULL 20 9 -18 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 20 7 7 9 NULL NULL NULL 20 7 18 9 NULL NULL NULL 20 7 -7 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 7 -18 9 NULL NULL NULL 5 7 -3 9 NULL NULL NULL 20 9 -7 9 NULL NULL NULL 20 9 3 9 NULL NULL NULL 20 7 7 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 20 9 3 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 18 9 NULL NULL NULL 20 7 3 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 18 9 NULL NULL NULL 5 9 3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 5 7 3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 18 9 NULL NULL NULL 20 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 7 9 NULL NULL NULL 20 7 18 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 9 7 9 NULL NULL NULL 5 9 18 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 7 7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 5 7 SET SESSION join_buffer_size = DEFAULT; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index f775336299b..a4bad836d1f 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -6638,6 +6638,23 @@ a ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) set optimizer_switch=@mdev367_optimizer_switch; DROP TABLE t1; # +# MDEV-521 single value subselect transformation problem +# +CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('u1'),('u2'); +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +FLUSH TABLES; +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +DROP TABLE t1; +# return optimizer switch changed in the beginning of this test +set optimizer_switch=@subselect_tmp; +# # lp:944706 Query with impossible or constant subquery in WHERE or HAVING is not # precomputed and thus not part of optimization # @@ -6847,6 +6864,27 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index DROP TABLE t1,t2; # +# MDEV-435: Expensive subqueries may be evaluated during optimization in merge_key_fields +# +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (8),(0); +CREATE TABLE t2 (b INT, c VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (4,'j'),(6,'v'); +CREATE TABLE t3 (d VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t3 VALUES ('b'),('c'); +EXPLAIN +SELECT * FROM t1 +WHERE a = (SELECT MAX(b) FROM t2 WHERE c IN (SELECT MAX(d) FROM t3)) OR a = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index a a 5 NULL 2 Using where; Using index +2 SUBQUERY <subquery3> ALL distinct_key NULL NULL NULL 1 +2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 +SELECT * FROM t1 +WHERE a = (SELECT MAX(b) FROM t2 WHERE c IN (SELECT MAX(d) FROM t3)) OR a = 10; +a +drop table t1, t2, t3; +# # MDEV-405: Server crashes in test_if_skip_sort_order on EXPLAIN with GROUP BY and HAVING in EXISTS subquery # CREATE TABLE t1 (a INT, KEY(a)); diff --git a/mysql-test/r/subselect2.result b/mysql-test/r/subselect2.result index ed00e4ef684..7eff7f949a8 100644 --- a/mysql-test/r/subselect2.result +++ b/mysql-test/r/subselect2.result @@ -179,4 +179,23 @@ pk a b SET optimizer_switch=@tmp_optimizer_switch; DROP VIEW v1; DROP TABLE t1,t2,t3; +# +# MDEV-567: Wrong result from a query with correlated subquery if ICP is allowed +# +CREATE TABLE t1 (a int, b int, INDEX idx(a)); +INSERT INTO t1 VALUES (9,0), (7,1), (1,9), (7,3), (2,1); +CREATE TABLE t2 (a int, b int, INDEX idx(a)); +INSERT INTO t2 VALUES (2,1), (6,4), (7,6), (9,4); +CREATE TABLE t3 (a int, b int); +INSERT INTO t3 VALUES (1,0), (1,1), (1,3); +SELECT * FROM t3 +WHERE a = (SELECT COUNT(DISTINCT t2.b) FROM t1, t2 +WHERE t1.a = t2.a AND t2.a BETWEEN 7 AND 9 +AND t3.b = t1.b +GROUP BY t1.b); +a b +1 0 +1 1 +1 3 +DROP TABLE t1, t2, t3; set optimizer_switch=@subselect2_test_tmp; diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index b33e7e113f2..049c4d14b1a 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -126,7 +126,7 @@ Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 Handler_read_rnd_deleted 0 -Handler_read_rnd_next 50 +Handler_read_rnd_next 41 select 'No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.' Z; Z No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1. diff --git a/mysql-test/r/subselect3_jcl6.result b/mysql-test/r/subselect3_jcl6.result index 4660cd60603..815a8985d44 100644 --- a/mysql-test/r/subselect3_jcl6.result +++ b/mysql-test/r/subselect3_jcl6.result @@ -136,7 +136,7 @@ Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 Handler_read_rnd_deleted 0 -Handler_read_rnd_next 50 +Handler_read_rnd_next 41 select 'No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.' Z; Z No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1. diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index 7f290fb5b03..c35075d80a1 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -430,7 +430,7 @@ set @old_optimizer_switch = @@session.optimizer_switch, SET SESSION OPTIMIZER_SWITCH = 'materialization=off,semijoin=off,loosescan=off,firstmatch=off,mrr=on'; SET SESSION engine_condition_pushdown = 1; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT `time_nokey` G1 FROM t1 WHERE ( `varchar_nokey` , `varchar_key` ) IN ( SELECT `varchar_nokey` , `varchar_nokey` ) AND `varchar_key` >= 'c' HAVING G1 ORDER BY `pk` ; @@ -438,7 +438,7 @@ G1 set @@session.optimizer_switch = @old_optimizer_switch, @@session.engine_condition_pushdown = @old_engine_condition_pushdown; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead DROP TABLE t1; # # During work with BUG#45863 I had problems with a query that was @@ -625,7 +625,7 @@ SELECT @old_icp:=@@engine_condition_pushdown; # SET SESSION engine_condition_pushdown = 'ON'; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT pk FROM t2 @@ -640,7 +640,7 @@ pk # Restore old value for Index condition pushdown SET SESSION engine_condition_pushdown=@old_icp; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead DROP TABLE t1,t2; # # End of 5.3 tests. @@ -1351,7 +1351,7 @@ ON SUBQUERY2_t3.f2) GROUP BY t1.f4 ORDER BY t1.f1 LIMIT 10; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 system NULL NULL NULL NULL 1 Using temporary; Using filesort -1 PRIMARY t1 index NULL f4 5 NULL 11 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where 2 DEPENDENT SUBQUERY SUBQUERY2_t1 system NULL NULL NULL NULL 1 2 DEPENDENT SUBQUERY SUBQUERY2_t2 index NULL f4 5 NULL 11 Using index 2 DEPENDENT SUBQUERY SUBQUERY2_t3 ALL NULL NULL NULL NULL 11 Using where; Using join buffer (flat, BNL join) diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index e72d25fdafa..cb9847a0d99 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -6637,6 +6637,23 @@ a ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) set optimizer_switch=@mdev367_optimizer_switch; DROP TABLE t1; # +# MDEV-521 single value subselect transformation problem +# +CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('u1'),('u2'); +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +FLUSH TABLES; +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +DROP TABLE t1; +# return optimizer switch changed in the beginning of this test +set optimizer_switch=@subselect_tmp; +# # lp:944706 Query with impossible or constant subquery in WHERE or HAVING is not # precomputed and thus not part of optimization # @@ -6845,6 +6862,26 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index DROP TABLE t1,t2; # +# MDEV-435: Expensive subqueries may be evaluated during optimization in merge_key_fields +# +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (8),(0); +CREATE TABLE t2 (b INT, c VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (4,'j'),(6,'v'); +CREATE TABLE t3 (d VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t3 VALUES ('b'),('c'); +EXPLAIN +SELECT * FROM t1 +WHERE a = (SELECT MAX(b) FROM t2 WHERE c IN (SELECT MAX(d) FROM t3)) OR a = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index a a 5 NULL 2 Using where; Using index +2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where +3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 +SELECT * FROM t1 +WHERE a = (SELECT MAX(b) FROM t2 WHERE c IN (SELECT MAX(d) FROM t3)) OR a = 10; +a +drop table t1, t2, t3; +# # MDEV-405: Server crashes in test_if_skip_sort_order on EXPLAIN with GROUP BY and HAVING in EXISTS subquery # CREATE TABLE t1 (a INT, KEY(a)); diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index 9030265356b..63eeb816b38 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -6633,6 +6633,23 @@ a ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) set optimizer_switch=@mdev367_optimizer_switch; DROP TABLE t1; # +# MDEV-521 single value subselect transformation problem +# +CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('u1'),('u2'); +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +FLUSH TABLES; +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +DROP TABLE t1; +# return optimizer switch changed in the beginning of this test +set optimizer_switch=@subselect_tmp; +# # lp:944706 Query with impossible or constant subquery in WHERE or HAVING is not # precomputed and thus not part of optimization # @@ -6842,6 +6859,27 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index DROP TABLE t1,t2; # +# MDEV-435: Expensive subqueries may be evaluated during optimization in merge_key_fields +# +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (8),(0); +CREATE TABLE t2 (b INT, c VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (4,'j'),(6,'v'); +CREATE TABLE t3 (d VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t3 VALUES ('b'),('c'); +EXPLAIN +SELECT * FROM t1 +WHERE a = (SELECT MAX(b) FROM t2 WHERE c IN (SELECT MAX(d) FROM t3)) OR a = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index a a 5 NULL 2 Using where; Using index +2 SUBQUERY <subquery3> ALL distinct_key NULL NULL NULL 1 +2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 +SELECT * FROM t1 +WHERE a = (SELECT MAX(b) FROM t2 WHERE c IN (SELECT MAX(d) FROM t3)) OR a = 10; +a +drop table t1, t2, t3; +# # MDEV-405: Server crashes in test_if_skip_sort_order on EXPLAIN with GROUP BY and HAVING in EXISTS subquery # CREATE TABLE t1 (a INT, KEY(a)); diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index e68f5990c08..6fd21f8d0b0 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -6644,6 +6644,23 @@ a ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) set optimizer_switch=@mdev367_optimizer_switch; DROP TABLE t1; # +# MDEV-521 single value subselect transformation problem +# +CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('u1'),('u2'); +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +FLUSH TABLES; +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +DROP TABLE t1; +# return optimizer switch changed in the beginning of this test +set optimizer_switch=@subselect_tmp; +# # lp:944706 Query with impossible or constant subquery in WHERE or HAVING is not # precomputed and thus not part of optimization # @@ -6853,6 +6870,27 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index DROP TABLE t1,t2; # +# MDEV-435: Expensive subqueries may be evaluated during optimization in merge_key_fields +# +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (8),(0); +CREATE TABLE t2 (b INT, c VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (4,'j'),(6,'v'); +CREATE TABLE t3 (d VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t3 VALUES ('b'),('c'); +EXPLAIN +SELECT * FROM t1 +WHERE a = (SELECT MAX(b) FROM t2 WHERE c IN (SELECT MAX(d) FROM t3)) OR a = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index a a 5 NULL 2 Using where; Using index +2 SUBQUERY <subquery3> ALL distinct_key NULL NULL NULL 1 +2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 +SELECT * FROM t1 +WHERE a = (SELECT MAX(b) FROM t2 WHERE c IN (SELECT MAX(d) FROM t3)) OR a = 10; +a +drop table t1, t2, t3; +# # MDEV-405: Server crashes in test_if_skip_sort_order on EXPLAIN with GROUP BY and HAVING in EXISTS subquery # CREATE TABLE t1 (a INT, KEY(a)); diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index f0ce541294a..b924a18ca8f 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -6633,6 +6633,23 @@ a ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) set optimizer_switch=@mdev367_optimizer_switch; DROP TABLE t1; # +# MDEV-521 single value subselect transformation problem +# +CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('u1'),('u2'); +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +FLUSH TABLES; +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +DROP TABLE t1; +# return optimizer switch changed in the beginning of this test +set optimizer_switch=@subselect_tmp; +# # lp:944706 Query with impossible or constant subquery in WHERE or HAVING is not # precomputed and thus not part of optimization # @@ -6842,6 +6859,27 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY t2 ref b b 5 test.t1.a 2 Using index DROP TABLE t1,t2; # +# MDEV-435: Expensive subqueries may be evaluated during optimization in merge_key_fields +# +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (8),(0); +CREATE TABLE t2 (b INT, c VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (4,'j'),(6,'v'); +CREATE TABLE t3 (d VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t3 VALUES ('b'),('c'); +EXPLAIN +SELECT * FROM t1 +WHERE a = (SELECT MAX(b) FROM t2 WHERE c IN (SELECT MAX(d) FROM t3)) OR a = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index a a 5 NULL 2 Using where; Using index +2 SUBQUERY <subquery3> ALL distinct_key NULL NULL NULL 1 +2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 +SELECT * FROM t1 +WHERE a = (SELECT MAX(b) FROM t2 WHERE c IN (SELECT MAX(d) FROM t3)) OR a = 10; +a +drop table t1, t2, t3; +# # MDEV-405: Server crashes in test_if_skip_sort_order on EXPLAIN with GROUP BY and HAVING in EXISTS subquery # CREATE TABLE t1 (a INT, KEY(a)); diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index a193751048c..ad5e39a2851 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -538,7 +538,7 @@ Warning 1292 Truncated incorrect read_buffer_size value: '100' set read_rnd_buffer_size=100; set global rpl_recovery_rank=100; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. set global server_id=100; set global slow_launch_time=100; set sort_buffer_size=100; @@ -1064,7 +1064,7 @@ set global net_write_timeout =@my_net_write_timeout; set global net_read_timeout =@my_net_read_timeout; set global rpl_recovery_rank =@my_rpl_recovery_rank; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. set global server_id =@my_server_id; set global slow_launch_time =@my_slow_launch_time; set global default_storage_engine =@my_storage_engine; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 5af20fd0c3c..1bcc9fb727f 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -4530,6 +4530,55 @@ WHERE t4.a >= v1.a); a a DROP VIEW v1; DROP TABLE t1,t2,t3,t4; +# +# LP bug #823237: dependent subquery with LEFT JOIN +# referencing view in WHERE +# (duplicate of LP bug #823189) +# +CREATE TABLE t1 (a int); +CREATE TABLE t2 ( b int, d int, e int); +INSERT INTO t2 VALUES (7,8,0); +CREATE TABLE t3 ( c int); +INSERT INTO t3 VALUES (0); +CREATE TABLE t4 (a int, b int, c int); +INSERT INTO t4 VALUES (93,1,0), (95,NULL,0); +CREATE VIEW v4 AS SELECT * FROM t4; +EXPLAIN EXTENDED +SELECT * FROM t3 , t4 +WHERE t4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) +WHERE t2.b > t4.b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00 +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where +2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00 +2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found +Warnings: +Note 1276 Field or reference 'test.t4.b' of SELECT #2 was resolved in SELECT #1 +Note 1003 select 0 AS `c`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t4` where (`test`.`t4`.`c` <= <expr_cache><`test`.`t4`.`b`>((select 0 from dual where (7 > `test`.`t4`.`b`)))) +SELECT * FROM t3 , t4 +WHERE t4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) +WHERE t2.b > t4.b); +c a b c +0 93 1 0 +EXPLAIN EXTENDED +SELECT * FROM t3, v4 +WHERE v4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) +WHERE t2.b > v4.b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00 +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where +2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00 +2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found +Warnings: +Note 1276 Field or reference 'v4.b' of SELECT #2 was resolved in SELECT #1 +Note 1003 select 0 AS `c`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t4` where (`test`.`t4`.`c` <= <expr_cache><`test`.`t4`.`b`>((select 0 from dual where (7 > `test`.`t4`.`b`)))) +SELECT * FROM t3, v4 +WHERE v4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) +WHERE t2.b > v4.b); +c a b c +0 93 1 0 +DROP VIEW v4; +DROP TABLE t1,t2,t3,t4; drop table if exists t_9801; drop view if exists v_9801; create table t_9801 (s1 int); @@ -4730,6 +4779,49 @@ id id bbb iddqd val1 30631 NULL NULL NULL NULL drop view v2; drop table t1,t2; +# +# MDEV-589 (LP BUG#1007647) : +# Assertion `vcol_table == 0 || vcol_table == table' failed in +# fill_record(THD*, List<Item>&, List<Item>&, bool) +# +CREATE TABLE t1 (f1 INT, f2 INT); +CREATE TABLE t2 (f1 INT, f2 INT); +CREATE ALGORITHM=MERGE VIEW v1 AS SELECT a1.f1, a2.f2 FROM t1 AS a1, t1 AS a2; +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM v1; +CREATE ALGORITHM=MERGE VIEW v3 AS SELECT a1.f1, a2.f2 FROM t1 AS a1, t2 AS a2; +CREATE ALGORITHM=MERGE VIEW v4 AS SELECT * FROM v3; +INSERT INTO v3 (f1, f2) VALUES (1, 2); +ERROR HY000: Can not modify more than one base table through a join view 'test.v3' +INSERT INTO v1 (f1, f2) VALUES (1, 2); +ERROR HY000: Can not modify more than one base table through a join view 'test.v1' +INSERT INTO v4 (f1, f2) VALUES (1, 2); +ERROR HY000: Can not modify more than one base table through a join view 'test.v4' +INSERT INTO v2 (f1, f2) VALUES (1, 2); +ERROR HY000: Can not modify more than one base table through a join view 'test.v2' +drop view v4,v3,v2,v1; +drop table t1,t2; +# +# MDEV-3799 fix of above bugfix (MDEV-589) +# Wrong result (NULLs instead of real values) with RIGHT JOIN +# in a FROM subquery and derived_merge=on +# +CREATE TABLE t1 (f1 INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (4),(6); +CREATE TABLE t2 (f2 INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (7),(8); +SELECT * FROM ( +SELECT * FROM t1 RIGHT JOIN t2 ON f1 = f2 +) AS alias; +f1 f2 +NULL 7 +NULL 8 +SELECT * FROM ( +SELECT * FROM t2 LEFT JOIN t1 ON f1 = f2 +) AS alias; +f2 f1 +7 NULL +8 NULL +drop tables t1,t2; # ----------------------------------------------------------------- # -- End of 5.3 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/suite/binlog/t/binlog_xa_recover.test b/mysql-test/suite/binlog/t/binlog_xa_recover.test index 36b2ddecb4f..b4d44664f1a 100644 --- a/mysql-test/suite/binlog/t/binlog_xa_recover.test +++ b/mysql-test/suite/binlog/t/binlog_xa_recover.test @@ -95,6 +95,7 @@ PURGE BINARY LOGS TO "master-bin.000006"; --write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect wait-binlog_xa_recover.test EOF +--error 0,2006,2013 SET DEBUG_SYNC= "now SIGNAL con4_cont"; connection con4; --error 2006,2013 diff --git a/mysql-test/suite/federated/federated_archive.test b/mysql-test/suite/federated/federated_archive.test index 1bde23889be..b35b82c6fa6 100644 --- a/mysql-test/suite/federated/federated_archive.test +++ b/mysql-test/suite/federated/federated_archive.test @@ -1,5 +1,5 @@ source include/have_archive.inc; -source federated.inc; +source suite/federated/include/federated.inc; connection slave; @@ -54,5 +54,5 @@ connection slave; DROP TABLE federated.archive_table; -source federated_cleanup.inc; +source suite/federated/include/federated_cleanup.inc; diff --git a/mysql-test/suite/federated/federated_bug_13118.test b/mysql-test/suite/federated/federated_bug_13118.test index fad6be75dac..78115a7959f 100644 --- a/mysql-test/suite/federated/federated_bug_13118.test +++ b/mysql-test/suite/federated/federated_bug_13118.test @@ -1,4 +1,4 @@ -source federated.inc; +source suite/federated/include/federated.inc; connection slave; --disable_warnings @@ -37,5 +37,5 @@ connection slave; DROP TABLE federated.bug_13118_table; -source federated_cleanup.inc; +source suite/federated/include/federated_cleanup.inc; diff --git a/mysql-test/suite/federated/federated_bug_25714.test b/mysql-test/suite/federated/federated_bug_25714.test index 633e469f595..bb5dcfe5d85 100644 --- a/mysql-test/suite/federated/federated_bug_25714.test +++ b/mysql-test/suite/federated/federated_bug_25714.test @@ -4,7 +4,7 @@ if (!$MYSQL_BUG25714) skip Need bug25714 test program; } -source federated.inc; +source suite/federated/include/federated.inc; connection master; # Disable concurrent inserts to avoid test failures when reading @@ -59,4 +59,4 @@ SET @@GLOBAL.CONCURRENT_INSERT= @OLD_SLAVE_CONCURRENT_INSERT; -source federated_cleanup.inc; +source suite/federated/include/federated_cleanup.inc; diff --git a/mysql-test/suite/federated/federated_bug_32426.test b/mysql-test/suite/federated/federated_bug_32426.test index 254dfaa610a..2615adbc1bc 100644 --- a/mysql-test/suite/federated/federated_bug_32426.test +++ b/mysql-test/suite/federated/federated_bug_32426.test @@ -1,4 +1,4 @@ -source federated.inc; +source include/federated.inc; --echo # --echo # Bug #32426: FEDERATED query returns corrupt results for ORDER BY @@ -21,4 +21,4 @@ DROP TABLE federated.t1; connection default; -source federated_cleanup.inc; +source include/federated_cleanup.inc; diff --git a/mysql-test/suite/federated/federated_bug_35333.test b/mysql-test/suite/federated/federated_bug_35333.test index 8bce63c34e5..6487e10e018 100644 --- a/mysql-test/suite/federated/federated_bug_35333.test +++ b/mysql-test/suite/federated/federated_bug_35333.test @@ -9,7 +9,7 @@ --echo # to complete while still indicating a problem. This fix applies to any non-fatal system --echo # error that occurs during a query against I_S.TABLES.de ---source federated.inc +--source suite/federated/include/federated.inc --disable_warnings # Federated database exists @@ -74,4 +74,4 @@ DROP TABLE t1; --echo # Cleanup --echo # ---source federated_cleanup.inc +--source suite/federated/include/federated_cleanup.inc diff --git a/mysql-test/suite/federated/federated_bug_585688.test b/mysql-test/suite/federated/federated_bug_585688.test index 6566125c419..02fec2c985c 100644 --- a/mysql-test/suite/federated/federated_bug_585688.test +++ b/mysql-test/suite/federated/federated_bug_585688.test @@ -1,4 +1,4 @@ -source federated.inc; +source include/federated.inc; --echo # --echo # Bug #585688: maridb crashes in federatedx code @@ -49,5 +49,5 @@ DROP TABLE federated.t1; connection default; -source federated_cleanup.inc; +source include/federated_cleanup.inc; diff --git a/mysql-test/suite/federated/federated_debug.test b/mysql-test/suite/federated/federated_debug.test index 08bd13eefaf..a640987a127 100644 --- a/mysql-test/suite/federated/federated_debug.test +++ b/mysql-test/suite/federated/federated_debug.test @@ -1,6 +1,6 @@ --source include/have_debug.inc --source include/long_test.inc ---source federated.inc +--source include/federated.inc --echo # --echo # Bug#47525: MySQL crashed (Federated) @@ -37,4 +37,4 @@ DROP TABLE t1; connection default; --echo # Federated cleanup -source federated_cleanup.inc; +source suite/federated/include/federated_cleanup.inc; diff --git a/mysql-test/suite/federated/federated_innodb.test b/mysql-test/suite/federated/federated_innodb.test index 278c5b18661..9212ba12b81 100644 --- a/mysql-test/suite/federated/federated_innodb.test +++ b/mysql-test/suite/federated/federated_innodb.test @@ -4,7 +4,7 @@ # See Bug #40645 Test main.federated_innodb does not always clean up after itself source include/have_innodb.inc; -source federated.inc; +source suite/federated/include/federated.inc; # # Bug#25513 Federated transaction failures @@ -36,4 +36,4 @@ connection slave; drop table federated.t1; -source federated_cleanup.inc; +source suite/federated/include/federated_cleanup.inc; diff --git a/mysql-test/suite/federated/federated_partition.test b/mysql-test/suite/federated/federated_partition.test index 13f26ecd756..ef1e27ec505 100644 --- a/mysql-test/suite/federated/federated_partition.test +++ b/mysql-test/suite/federated/federated_partition.test @@ -4,7 +4,7 @@ source have_federatedx.inc; source include/have_partition.inc; source include/have_innodb.inc; -source federated.inc; +source include/federated.inc; disable_warnings; drop table if exists t1; @@ -50,4 +50,4 @@ drop table federated.t1_2; --echo End of 5.1 tests -source federated_cleanup.inc; +source include/federated_cleanup.inc; diff --git a/mysql-test/suite/federated/federated_server.test b/mysql-test/suite/federated/federated_server.test index 9f7f833a401..c47a1acf2a3 100644 --- a/mysql-test/suite/federated/federated_server.test +++ b/mysql-test/suite/federated/federated_server.test @@ -4,7 +4,7 @@ # Slow test, don't run during staging part -- source include/not_staging.inc -- source include/big_test.inc --- source federated.inc +-- source include/federated.inc connection slave; create database first_db; @@ -343,4 +343,4 @@ drop table t1; drop server if exists s; -source federated_cleanup.inc; +source suite/federated/include/federated_cleanup.inc; diff --git a/mysql-test/suite/federated/federated_transactions.test b/mysql-test/suite/federated/federated_transactions.test index 637df45a52a..480f9a6ba27 100644 --- a/mysql-test/suite/federated/federated_transactions.test +++ b/mysql-test/suite/federated/federated_transactions.test @@ -1,6 +1,6 @@ source have_federatedx.inc; source include/have_innodb.inc; -source federated.inc; +source suite/federated/include/federated.inc; connection slave; DROP TABLE IF EXISTS federated.t1; @@ -36,4 +36,4 @@ INSERT INTO federated.t1 (id, name) VALUES (6, 'fig'); SELECT * FROM federated.t1; DELETE FROM federated.t1; -source federated_cleanup.inc; +source suite/federated/include/federated_cleanup.inc; diff --git a/mysql-test/suite/federated/federatedx.test b/mysql-test/suite/federated/federatedx.test index 2c307587b4f..fd2f363ff90 100644 --- a/mysql-test/suite/federated/federatedx.test +++ b/mysql-test/suite/federated/federatedx.test @@ -4,7 +4,7 @@ # ---source federated.inc +--source include/federated.inc --source have_federatedx.inc connection default; @@ -1999,4 +1999,4 @@ connection slave; SET @@GLOBAL.CONCURRENT_INSERT= @OLD_SLAVE_CONCURRENT_INSERT; connection default; -source federated_cleanup.inc; +source suite/federated/include/federated_cleanup.inc; diff --git a/mysql-test/suite/federated/federated.inc b/mysql-test/suite/federated/include/federated.inc index 17410846604..17410846604 100644 --- a/mysql-test/suite/federated/federated.inc +++ b/mysql-test/suite/federated/include/federated.inc diff --git a/mysql-test/suite/federated/federated_cleanup.inc b/mysql-test/suite/federated/include/federated_cleanup.inc index 06fd7f6737a..06fd7f6737a 100644 --- a/mysql-test/suite/federated/federated_cleanup.inc +++ b/mysql-test/suite/federated/include/federated_cleanup.inc diff --git a/mysql-test/suite/innodb/r/innodb_information_schema_buffer.result b/mysql-test/suite/innodb/r/innodb_information_schema_buffer.result new file mode 100644 index 00000000000..b4a350e77a3 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_information_schema_buffer.result @@ -0,0 +1,130 @@ +SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS; +SELECT count(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS; +SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE; +SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE; +CREATE TABLE infoschema_buffer_test (col1 INT) ENGINE = INNODB; +INSERT INTO infoschema_buffer_test VALUES(9); +SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE +FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE +WHERE TABLE_NAME like "%infoschema_buffer_test" + and PAGE_STATE="file_page" and PAGE_TYPE="index"; +TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE PAGE_STATE PAGE_TYPE +test/infoschema_buffer_test GEN_CLUST_INDEX 1 29 FILE_PAGE INDEX +INSERT INTO infoschema_buffer_test VALUES(19); +SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE +FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE +WHERE TABLE_NAME like "%infoschema_buffer_test" +and PAGE_STATE="file_page" and PAGE_TYPE="index"; +TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE PAGE_STATE PAGE_TYPE +test/infoschema_buffer_test GEN_CLUST_INDEX 2 58 FILE_PAGE INDEX +CREATE INDEX idx ON infoschema_buffer_test(col1); +SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE +FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE +WHERE TABLE_NAME like "%infoschema_buffer_test" +and PAGE_STATE="file_page" and INDEX_NAME = "idx" and PAGE_TYPE="index"; +TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE PAGE_STATE PAGE_TYPE +test/infoschema_buffer_test idx 2 32 FILE_PAGE INDEX +DROP TABLE infoschema_buffer_test; +SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE +FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE +WHERE TABLE_NAME like "%infoschema_buffer_test"; +TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE PAGE_STATE PAGE_TYPE +CREATE TABLE infoschema_parent (id INT NOT NULL, PRIMARY KEY (id)) +ENGINE=INNODB; +CREATE TABLE infoschema_child (id INT, parent_id INT, INDEX par_ind (parent_id), +FOREIGN KEY (parent_id) +REFERENCES infoschema_parent(id) +ON DELETE CASCADE) +ENGINE=INNODB; +SELECT count(*) +FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE +WHERE TABLE_NAME like "%infoschema_child" and PAGE_STATE="file_page" +and PAGE_TYPE="index"; +count(*) +2 +DROP TABLE infoschema_child; +DROP TABLE infoschema_parent; +show create table information_schema.innodb_buffer_page; +Table Create Table +INNODB_BUFFER_PAGE CREATE TEMPORARY TABLE `INNODB_BUFFER_PAGE` ( + `POOL_ID` bigint(21) unsigned NOT NULL DEFAULT '0', + `BLOCK_ID` bigint(21) unsigned NOT NULL DEFAULT '0', + `SPACE` bigint(21) unsigned NOT NULL DEFAULT '0', + `PAGE_NUMBER` bigint(21) unsigned NOT NULL DEFAULT '0', + `PAGE_TYPE` varchar(64) DEFAULT NULL, + `FLUSH_TYPE` bigint(21) unsigned NOT NULL DEFAULT '0', + `FIX_COUNT` bigint(21) unsigned NOT NULL DEFAULT '0', + `IS_HASHED` varchar(3) DEFAULT NULL, + `NEWEST_MODIFICATION` bigint(21) unsigned NOT NULL DEFAULT '0', + `OLDEST_MODIFICATION` bigint(21) unsigned NOT NULL DEFAULT '0', + `ACCESS_TIME` bigint(21) unsigned NOT NULL DEFAULT '0', + `TABLE_NAME` varchar(1024) DEFAULT NULL, + `INDEX_NAME` varchar(1024) DEFAULT NULL, + `NUMBER_RECORDS` bigint(21) unsigned NOT NULL DEFAULT '0', + `DATA_SIZE` bigint(21) unsigned NOT NULL DEFAULT '0', + `COMPRESSED_SIZE` bigint(21) unsigned NOT NULL DEFAULT '0', + `PAGE_STATE` varchar(64) DEFAULT NULL, + `IO_FIX` varchar(64) DEFAULT NULL, + `IS_OLD` varchar(3) DEFAULT NULL, + `FREE_PAGE_CLOCK` bigint(21) unsigned NOT NULL DEFAULT '0' +) ENGINE=MEMORY DEFAULT CHARSET=utf8 +show create table information_schema.innodb_buffer_page_lru; +Table Create Table +INNODB_BUFFER_PAGE_LRU CREATE TEMPORARY TABLE `INNODB_BUFFER_PAGE_LRU` ( + `POOL_ID` bigint(21) unsigned NOT NULL DEFAULT '0', + `LRU_POSITION` bigint(21) unsigned NOT NULL DEFAULT '0', + `SPACE` bigint(21) unsigned NOT NULL DEFAULT '0', + `PAGE_NUMBER` bigint(21) unsigned NOT NULL DEFAULT '0', + `PAGE_TYPE` varchar(64) DEFAULT NULL, + `FLUSH_TYPE` bigint(21) unsigned NOT NULL DEFAULT '0', + `FIX_COUNT` bigint(21) unsigned NOT NULL DEFAULT '0', + `IS_HASHED` varchar(3) DEFAULT NULL, + `NEWEST_MODIFICATION` bigint(21) unsigned NOT NULL DEFAULT '0', + `OLDEST_MODIFICATION` bigint(21) unsigned NOT NULL DEFAULT '0', + `ACCESS_TIME` bigint(21) unsigned NOT NULL DEFAULT '0', + `TABLE_NAME` varchar(1024) DEFAULT NULL, + `INDEX_NAME` varchar(1024) DEFAULT NULL, + `NUMBER_RECORDS` bigint(21) unsigned NOT NULL DEFAULT '0', + `DATA_SIZE` bigint(21) unsigned NOT NULL DEFAULT '0', + `COMPRESSED_SIZE` bigint(21) unsigned NOT NULL DEFAULT '0', + `COMPRESSED` varchar(3) DEFAULT NULL, + `IO_FIX` varchar(64) DEFAULT NULL, + `IS_OLD` varchar(3) DEFAULT NULL, + `FREE_PAGE_CLOCK` bigint(21) unsigned NOT NULL DEFAULT '0' +) ENGINE=MEMORY DEFAULT CHARSET=utf8 +show create table information_schema.innodb_buffer_pool_stats; +Table Create Table +INNODB_BUFFER_POOL_STATS CREATE TEMPORARY TABLE `INNODB_BUFFER_POOL_STATS` ( + `POOL_ID` bigint(21) unsigned NOT NULL DEFAULT '0', + `POOL_SIZE` bigint(21) unsigned NOT NULL DEFAULT '0', + `FREE_BUFFERS` bigint(21) unsigned NOT NULL DEFAULT '0', + `DATABASE_PAGES` bigint(21) unsigned NOT NULL DEFAULT '0', + `OLD_DATABASE_PAGES` bigint(21) unsigned NOT NULL DEFAULT '0', + `MODIFIED_DATABASE_PAGES` bigint(21) unsigned NOT NULL DEFAULT '0', + `PENDING_DECOMPRESS` bigint(21) unsigned NOT NULL DEFAULT '0', + `PENDING_READS` bigint(21) unsigned NOT NULL DEFAULT '0', + `PENDING_FLUSH_LRU` bigint(21) unsigned NOT NULL DEFAULT '0', + `PENDING_FLUSH_LIST` bigint(21) unsigned NOT NULL DEFAULT '0', + `PAGES_MADE_YOUNG` bigint(21) unsigned NOT NULL DEFAULT '0', + `PAGES_NOT_MADE_YOUNG` bigint(21) unsigned NOT NULL DEFAULT '0', + `PAGES_MADE_YOUNG_RATE` double NOT NULL DEFAULT '0', + `PAGES_MADE_NOT_YOUNG_RATE` double NOT NULL DEFAULT '0', + `NUMBER_PAGES_READ` bigint(21) unsigned NOT NULL DEFAULT '0', + `NUMBER_PAGES_CREATED` bigint(21) unsigned NOT NULL DEFAULT '0', + `NUMBER_PAGES_WRITTEN` bigint(21) unsigned NOT NULL DEFAULT '0', + `PAGES_READ_RATE` double NOT NULL DEFAULT '0', + `PAGES_CREATE_RATE` double NOT NULL DEFAULT '0', + `PAGES_WRITTEN_RATE` double NOT NULL DEFAULT '0', + `NUMBER_PAGES_GET` bigint(21) unsigned NOT NULL DEFAULT '0', + `HIT_RATE` bigint(21) unsigned NOT NULL DEFAULT '0', + `YOUNG_MAKE_PER_THOUSAND_GETS` bigint(21) unsigned NOT NULL DEFAULT '0', + `NOT_YOUNG_MAKE_PER_THOUSAND_GETS` bigint(21) unsigned NOT NULL DEFAULT '0', + `NUMBER_PAGES_READ_AHEAD` bigint(21) unsigned NOT NULL DEFAULT '0', + `NUMBER_READ_AHEAD_EVICTED` bigint(21) unsigned NOT NULL DEFAULT '0', + `READ_AHEAD_RATE` double NOT NULL DEFAULT '0', + `READ_AHEAD_EVICTED_RATE` double NOT NULL DEFAULT '0', + `LRU_IO_TOTAL` bigint(21) unsigned NOT NULL DEFAULT '0', + `LRU_IO_CURRENT` bigint(21) unsigned NOT NULL DEFAULT '0', + `UNCOMPRESS_TOTAL` bigint(21) unsigned NOT NULL DEFAULT '0', + `UNCOMPRESS_CURRENT` bigint(21) unsigned NOT NULL DEFAULT '0' +) ENGINE=MEMORY DEFAULT CHARSET=utf8 diff --git a/mysql-test/suite/innodb/t/innodb_bug14007649.test b/mysql-test/suite/innodb/t/innodb_bug14007649.test index da413e0ce59..9326e1c53ef 100644 --- a/mysql-test/suite/innodb/t/innodb_bug14007649.test +++ b/mysql-test/suite/innodb/t/innodb_bug14007649.test @@ -1,11 +1,6 @@ --source include/have_innodb.inc --source include/have_debug.inc -if (`select plugin_auth_version <= "1.0.17-13.01" from information_schema.plugins where plugin_name='innodb'`) -{ - --skip Not fixed in XtraDB 1.0.17-13.01 or earlier -} - create table t1 ( rowid int, f1 int, diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_buffer.opt b/mysql-test/suite/innodb/t/innodb_information_schema_buffer.opt new file mode 100644 index 00000000000..9e43eb47f97 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_information_schema_buffer.opt @@ -0,0 +1,3 @@ +--loose-innodb-buffer-pool-stats +--loose-innodb-buffer-page +--loose-innodb-buffer-page-lru diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_buffer.test b/mysql-test/suite/innodb/t/innodb_information_schema_buffer.test new file mode 100644 index 00000000000..b9c6aecd177 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_information_schema_buffer.test @@ -0,0 +1,81 @@ +# Exercise the code path for INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS +# and INFORMATION_SCHEMA.INNODB_BUFFER_PAGE + +-- source include/have_innodb.inc + +if (`select plugin_auth_version <= "1.1.8-29.0" from information_schema.plugins where plugin_name='innodb'`) +{ + --skip Not fixed in XtraDB 1.1.8-29.0 or earlier +} + +-- disable_result_log +SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS; + +# How many buffer pools we have +SELECT count(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS; + +SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE; + +# This gives the over all buffer pool size +SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE; + +-- enable_result_log + +# Create a table and check its page info behave correctly in the pool +CREATE TABLE infoschema_buffer_test (col1 INT) ENGINE = INNODB; + +INSERT INTO infoschema_buffer_test VALUES(9); + +# We should be able to see this table in the buffer pool if we check +# right away +SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE +FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE +WHERE TABLE_NAME like "%infoschema_buffer_test" + and PAGE_STATE="file_page" and PAGE_TYPE="index"; + +# The NUMBER_RECORDS and DATA_SIZE should check with each insertion +INSERT INTO infoschema_buffer_test VALUES(19); + +SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE +FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE +WHERE TABLE_NAME like "%infoschema_buffer_test" +and PAGE_STATE="file_page" and PAGE_TYPE="index"; + +CREATE INDEX idx ON infoschema_buffer_test(col1); + +SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE +FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE +WHERE TABLE_NAME like "%infoschema_buffer_test" +and PAGE_STATE="file_page" and INDEX_NAME = "idx" and PAGE_TYPE="index"; + + +# Check the buffer after dropping the table +DROP TABLE infoschema_buffer_test; + +SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE +FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE +WHERE TABLE_NAME like "%infoschema_buffer_test"; + +# Do one more test +#--replace_regex /'*[0-9]*'/'NUM'/ +CREATE TABLE infoschema_parent (id INT NOT NULL, PRIMARY KEY (id)) +ENGINE=INNODB; + +CREATE TABLE infoschema_child (id INT, parent_id INT, INDEX par_ind (parent_id), + FOREIGN KEY (parent_id) + REFERENCES infoschema_parent(id) + ON DELETE CASCADE) +ENGINE=INNODB; + +SELECT count(*) +FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE +WHERE TABLE_NAME like "%infoschema_child" and PAGE_STATE="file_page" +and PAGE_TYPE="index"; + +DROP TABLE infoschema_child; +DROP TABLE infoschema_parent; + +show create table information_schema.innodb_buffer_page; +show create table information_schema.innodb_buffer_page_lru; +show create table information_schema.innodb_buffer_pool_stats; + diff --git a/mysql-test/suite/plugins/r/pam.result b/mysql-test/suite/plugins/r/pam.result index 432fb48eb5a..86303206b3b 100644 --- a/mysql-test/suite/plugins/r/pam.result +++ b/mysql-test/suite/plugins/r/pam.result @@ -4,7 +4,7 @@ create user pam_test; grant proxy on pam_test to test_pam; # # athentication is successful, challenge/pin are ok -# note that current_user() differts from user() +# note that current_user() differs from user() # Challenge input first. Enter: not very secret challenge diff --git a/mysql-test/suite/plugins/t/pam.test b/mysql-test/suite/plugins/t/pam.test index 587a2380f94..68fa349a444 100644 --- a/mysql-test/suite/plugins/t/pam.test +++ b/mysql-test/suite/plugins/t/pam.test @@ -26,7 +26,7 @@ EOF --echo # --echo # athentication is successful, challenge/pin are ok ---echo # note that current_user() differts from user() +--echo # note that current_user() differs from user() --echo # --exec $MYSQL_TEST -u test_pam --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/pam_good.txt diff --git a/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result b/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result index cc693bff752..0cc1e4b5057 100644 --- a/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result +++ b/mysql-test/suite/rpl/r/rpl_cant_read_event_incident.result @@ -16,4 +16,6 @@ reset master; stop slave; reset slave; drop table if exists t; +reset master; End of the tests +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test b/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test index 4825090d6cd..86ee64b5e73 100644 --- a/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test +++ b/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test @@ -65,12 +65,11 @@ reset master; --connection slave stop slave; reset slave; -# The table t may have been created on the slave from binlog. It does not exist -# on the master. -# "May", as it depends on whether the SQL thread had time do do the CREATE -# TABLE before we stopped. ---disable_warnings +# Table was created from binlog, it may not be created if SQL thread is running +# slowly and IO thread reaches incident before SQL thread applies it. drop table if exists t; ---enable_warnings +reset master; --echo End of the tests +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/sys_vars/r/debug_basic.result b/mysql-test/suite/sys_vars/r/debug_basic.result index 7104775fa08..a97ad65b40f 100644 --- a/mysql-test/suite/sys_vars/r/debug_basic.result +++ b/mysql-test/suite/sys_vars/r/debug_basic.result @@ -1,6 +1,6 @@ set session debug="L"; Warnings: -Warning 1287 The syntax '@@debug' is deprecated and will be removed in MariaDB 10.1. Please use '@@debug_dbug' instead +Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead select @@global.debug="1"; @@global.debug="1" 0 diff --git a/mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result b/mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result index 935e23f9c3c..55e6f747a19 100644 --- a/mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result +++ b/mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result @@ -13,26 +13,26 @@ index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_inters '#--------------------FN_DYNVARS_028_01------------------------#' SET @@session.engine_condition_pushdown = 0; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SET @@session.engine_condition_pushdown = DEFAULT; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@session.engine_condition_pushdown; @@session.engine_condition_pushdown 0 SET @@global.engine_condition_pushdown = 0; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SET @@global.engine_condition_pushdown = DEFAULT; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@global.engine_condition_pushdown; @@global.engine_condition_pushdown 1 '#---------------------FN_DYNVARS_028_02-------------------------#' SET engine_condition_pushdown = 1; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@engine_condition_pushdown; @@engine_condition_pushdown 1 @@ -44,38 +44,38 @@ SELECT global.engine_condition_pushdown; ERROR 42S02: Unknown table 'global' in field list SET session engine_condition_pushdown = 0; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@session.engine_condition_pushdown; @@session.engine_condition_pushdown 0 SET global engine_condition_pushdown = 0; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@global.engine_condition_pushdown; @@global.engine_condition_pushdown 0 '#--------------------FN_DYNVARS_028_03------------------------#' SET @@session.engine_condition_pushdown = 0; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@session.engine_condition_pushdown; @@session.engine_condition_pushdown 0 SET @@session.engine_condition_pushdown = 1; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@session.engine_condition_pushdown; @@session.engine_condition_pushdown 1 SET @@global.engine_condition_pushdown = 0; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@global.engine_condition_pushdown; @@global.engine_condition_pushdown 0 SET @@global.engine_condition_pushdown = 1; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@global.engine_condition_pushdown; @@global.engine_condition_pushdown 1 @@ -115,16 +115,16 @@ ERROR 42000: Variable 'engine_condition_pushdown' can't be set to the value of ' '#-------------------FN_DYNVARS_028_05----------------------------#' SET @@global.engine_condition_pushdown = 0; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SET @@session.engine_condition_pushdown = 1; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@global.engine_condition_pushdown AS res_is_0; res_is_0 0 SET @@global.engine_condition_pushdown = 0; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@session.engine_condition_pushdown AS res_is_1; res_is_1 1 @@ -159,50 +159,50 @@ ON '#---------------------FN_DYNVARS_028_08-------------------------#' SET @@session.engine_condition_pushdown = OFF; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@session.engine_condition_pushdown; @@session.engine_condition_pushdown 0 SET @@session.engine_condition_pushdown = ON; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@session.engine_condition_pushdown; @@session.engine_condition_pushdown 1 SET @@global.engine_condition_pushdown = OFF; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@global.engine_condition_pushdown; @@global.engine_condition_pushdown 0 SET @@global.engine_condition_pushdown = ON; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@global.engine_condition_pushdown; @@global.engine_condition_pushdown 1 '#---------------------FN_DYNVARS_028_09----------------------#' SET @@session.engine_condition_pushdown = TRUE; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@session.engine_condition_pushdown; @@session.engine_condition_pushdown 1 SET @@session.engine_condition_pushdown = FALSE; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@session.engine_condition_pushdown; @@session.engine_condition_pushdown 0 SET @@global.engine_condition_pushdown = TRUE; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@global.engine_condition_pushdown; @@global.engine_condition_pushdown 1 SET @@global.engine_condition_pushdown = FALSE; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@global.engine_condition_pushdown; @@global.engine_condition_pushdown 0 @@ -215,7 +215,7 @@ select @@session.engine_condition_pushdown, 0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=off index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=off set @@session.engine_condition_pushdown = TRUE; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead select @@session.engine_condition_pushdown, @@global.engine_condition_pushdown, @@session.optimizer_switch, @@global.optimizer_switch; @@ -223,7 +223,7 @@ select @@session.engine_condition_pushdown, 1 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=off index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=off set @@session.engine_condition_pushdown = FALSE; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead select @@session.engine_condition_pushdown, @@global.engine_condition_pushdown, @@session.optimizer_switch, @@global.optimizer_switch; @@ -231,7 +231,7 @@ select @@session.engine_condition_pushdown, 0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=off index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=off set @@global.engine_condition_pushdown = TRUE; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead select @@session.engine_condition_pushdown, @@global.engine_condition_pushdown, @@session.optimizer_switch, @@global.optimizer_switch; @@ -239,7 +239,7 @@ select @@session.engine_condition_pushdown, 0 1 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=off index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=off set @@global.engine_condition_pushdown = FALSE; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead select @@session.engine_condition_pushdown, @@global.engine_condition_pushdown, @@session.optimizer_switch, @@global.optimizer_switch; @@ -271,13 +271,13 @@ select @@session.engine_condition_pushdown, 0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=off index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=off SET @@session.engine_condition_pushdown = @session_start_value; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@session.engine_condition_pushdown; @@session.engine_condition_pushdown 0 SET @@global.engine_condition_pushdown = @global_start_value; Warnings: -Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 10.1. Please use '@@optimizer_switch' instead +Warning 1287 '@@engine_condition_pushdown' is deprecated and will be removed in a future release. Please use '@@optimizer_switch' instead SELECT @@global.engine_condition_pushdown; @@global.engine_condition_pushdown 0 diff --git a/mysql-test/suite/sys_vars/r/ignore_db_dirs_basic.result b/mysql-test/suite/sys_vars/r/ignore_db_dirs_basic.result new file mode 100644 index 00000000000..55d61800a39 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/ignore_db_dirs_basic.result @@ -0,0 +1,49 @@ +select @@ignore_db_dirs; +@@ignore_db_dirs +e,lost+found,.mysqlgui,ignored_db +# Check that SHOW DATABASES ignores all directories from +# @@ignore_db_dirs and all directories with names starting +# with '.' +SHOW DATABASES; +Database +information_schema +#mysql50#.otherdir +mtr +mysql +performance_schema +test +USE ignored_db; +ERROR 42000: Incorrect database name 'ignored_db' +SELECT * FROM ignored_db.t1; +ERROR 42000: Incorrect database name 'ignored_db' +CALL ignored_db.p1(); +ERROR 42000: Incorrect database name 'ignored_db' +SELECT COUNT(*) FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='ignored_db'; +COUNT(*) +1 +CREATE DATABASE ignored_db; +ERROR 42000: Incorrect database name 'ignored_db' +CREATE DATABASE `lost+found`; +USE `lost+found`; +CREATE TABLE t1(id INT); +INSERT INTO t1 VALUES (1), (2); +SELECT * FROM `lost+found`.t1; +id +1 +2 +SHOW DATABASES; +Database +information_schema +#mysql50#.otherdir +lost+found +mtr +mysql +performance_schema +test +DROP DATABASE `lost+found`; +SET @@global.ignore_db_dirs = 'aha'; +ERROR HY000: Variable 'ignore_db_dirs' is a read only variable +SET @@local.ignore_db_dirs = 'aha'; +ERROR HY000: Variable 'ignore_db_dirs' is a read only variable +SET @@ignore_db_dirs = 'aha'; +ERROR HY000: Variable 'ignore_db_dirs' is a read only variable diff --git a/mysql-test/suite/sys_vars/r/innodb_changed_pages_limit_basic.result b/mysql-test/suite/sys_vars/r/innodb_changed_pages_limit_basic.result new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_changed_pages_limit_basic.result diff --git a/mysql-test/suite/sys_vars/r/innodb_persistent_stats_root_page_basic.result b/mysql-test/suite/sys_vars/r/innodb_persistent_stats_root_page_basic.result new file mode 100644 index 00000000000..38347ef8c68 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_persistent_stats_root_page_basic.result @@ -0,0 +1,24 @@ +SELECT @@global.innodb_persistent_stats_root_page; +@@global.innodb_persistent_stats_root_page +0 +SELECT COUNT(@@global.innodb_persistent_stats_root_page); +COUNT(@@global.innodb_persistent_stats_root_page) +1 +SET @@global.innodb_persistent_stats_root_page=100; +ERROR HY000: Variable 'innodb_persistent_stats_root_page' is a read only variable +SELECT @@global.innodb_persistent_stats_root_page = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='innodb_persistent_stats_root_page'; +@@global.innodb_persistent_stats_root_page = VARIABLE_VALUE +1 +SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='innodb_persistent_stats_root_page'; +COUNT(*) +1 +SELECT @@innodb_persistent_stats_root_page = @@global.innodb_persistent_stats_root_page; +@@innodb_persistent_stats_root_page = @@global.innodb_persistent_stats_root_page +1 +SELECT COUNT(@@local.innodb_persistent_stats_root_page); +ERROR HY000: Variable 'innodb_persistent_stats_root_page' is a GLOBAL variable +SELECT COUNT(@@session.innodb_persistent_stats_root_page); +ERROR HY000: Variable 'innodb_persistent_stats_root_page' is a GLOBAL variable diff --git a/mysql-test/suite/sys_vars/r/innodb_track_changed_pages_basic.result b/mysql-test/suite/sys_vars/r/innodb_track_changed_pages_basic.result new file mode 100644 index 00000000000..60f62a661f1 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_track_changed_pages_basic.result @@ -0,0 +1,21 @@ +SELECT COUNT(@@GLOBAL.innodb_track_changed_pages); +COUNT(@@GLOBAL.innodb_track_changed_pages) +1 +SET @@GLOBAL.innodb_track_changed_pages=1; +ERROR HY000: Variable 'innodb_track_changed_pages' is a read only variable +SELECT @@GLOBAL.innodb_track_changed_pages = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='innodb_track_changed_pages'; +@@GLOBAL.innodb_track_changed_pages = VARIABLE_VALUE +1 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'OFF' +SELECT @@innodb_track_changed_pages = @@GLOBAL.innodb_track_changed_pages; +@@innodb_track_changed_pages = @@GLOBAL.innodb_track_changed_pages +1 +SELECT COUNT(@@SESSION.innodb_track_changed_pages); +ERROR HY000: Variable 'innodb_track_changed_pages' is a GLOBAL variable +SELECT COUNT(@@LOCAL.innodb_track_changed_pages); +ERROR HY000: Variable 'innodb_track_changed_pages' is a GLOBAL variable +SELECT innodb_track_changed_pages = @@SESSION.innodb_track_changed_pages; +ERROR 42S22: Unknown column 'innodb_track_changed_pages' in 'field list' diff --git a/mysql-test/suite/sys_vars/r/log_basic.result b/mysql-test/suite/sys_vars/r/log_basic.result index d55346aa392..381fa523133 100644 --- a/mysql-test/suite/sys_vars/r/log_basic.result +++ b/mysql-test/suite/sys_vars/r/log_basic.result @@ -8,10 +8,10 @@ INIT_VALUE 1 SET @@global.log = ON; Warnings: -Warning 1287 The syntax '@@log' is deprecated and will be removed in MariaDB 10.1. Please use '@@general_log' instead +Warning 1287 '@@log' is deprecated and will be removed in a future release. Please use '@@general_log' instead SET global log = 0; Warnings: -Warning 1287 The syntax '@@log' is deprecated and will be removed in MariaDB 10.1. Please use '@@general_log' instead +Warning 1287 '@@log' is deprecated and will be removed in a future release. Please use '@@general_log' instead '#--------------------FN_DYNVARS_062_02-------------------------#' SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES @@ -20,4 +20,4 @@ VARIABLE_VALUE OFF SET @@global.log= @start_log; Warnings: -Warning 1287 The syntax '@@log' is deprecated and will be removed in MariaDB 10.1. Please use '@@general_log' instead +Warning 1287 '@@log' is deprecated and will be removed in a future release. Please use '@@general_log' instead diff --git a/mysql-test/suite/sys_vars/r/log_slow_queries_basic.result b/mysql-test/suite/sys_vars/r/log_slow_queries_basic.result index 9dbe565d488..2c47106ecb3 100644 --- a/mysql-test/suite/sys_vars/r/log_slow_queries_basic.result +++ b/mysql-test/suite/sys_vars/r/log_slow_queries_basic.result @@ -5,20 +5,20 @@ SELECT @start_value; '#---------------------FN_DYNVARS_004_01-------------------------#' SET @@global.log_slow_queries = DEFAULT; Warnings: -Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MariaDB 10.1. Please use '@@slow_query_log' instead +Warning 1287 '@@log_slow_queries' is deprecated and will be removed in a future release. Please use '@@slow_query_log' instead SELECT @@global.log_slow_queries = 0; @@global.log_slow_queries = 0 1 '#--------------------FN_DYNVARS_004_02------------------------#' SET @@global.log_slow_queries = ON; Warnings: -Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MariaDB 10.1. Please use '@@slow_query_log' instead +Warning 1287 '@@log_slow_queries' is deprecated and will be removed in a future release. Please use '@@slow_query_log' instead SELECT @@global.log_slow_queries; @@global.log_slow_queries 1 SET @@global.log_slow_queries = OFF; Warnings: -Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MariaDB 10.1. Please use '@@slow_query_log' instead +Warning 1287 '@@log_slow_queries' is deprecated and will be removed in a future release. Please use '@@slow_query_log' instead SELECT @@global.log_slow_queries; @@global.log_slow_queries 0 @@ -61,7 +61,7 @@ IF(@@global.log_slow_queries, "ON", "OFF") = VARIABLE_VALUE '#---------------------FN_DYNVARS_004_06----------------------#' SET @@global.log_slow_queries = 0; Warnings: -Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MariaDB 10.1. Please use '@@slow_query_log' instead +Warning 1287 '@@log_slow_queries' is deprecated and will be removed in a future release. Please use '@@slow_query_log' instead SELECT @@global.log_slow_queries; @@global.log_slow_queries 0 @@ -72,7 +72,7 @@ IF(@@global.log_slow_queries, "ON", "OFF") = VARIABLE_VALUE 1 SET @@global.log_slow_queries = 1; Warnings: -Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MariaDB 10.1. Please use '@@slow_query_log' instead +Warning 1287 '@@log_slow_queries' is deprecated and will be removed in a future release. Please use '@@slow_query_log' instead SELECT @@global.log_slow_queries; @@global.log_slow_queries 1 @@ -84,7 +84,7 @@ IF(@@global.log_slow_queries, "ON", "OFF") = VARIABLE_VALUE '#---------------------FN_DYNVARS_004_07----------------------#' SET @@global.log_slow_queries = TRUE; Warnings: -Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MariaDB 10.1. Please use '@@slow_query_log' instead +Warning 1287 '@@log_slow_queries' is deprecated and will be removed in a future release. Please use '@@slow_query_log' instead SELECT @@global.log_slow_queries; @@global.log_slow_queries 1 @@ -95,7 +95,7 @@ IF(@@global.log_slow_queries, "ON", "OFF") = VARIABLE_VALUE 1 SET @@global.log_slow_queries = FALSE; Warnings: -Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MariaDB 10.1. Please use '@@slow_query_log' instead +Warning 1287 '@@log_slow_queries' is deprecated and will be removed in a future release. Please use '@@slow_query_log' instead SELECT @@global.log_slow_queries; @@global.log_slow_queries 0 @@ -107,7 +107,7 @@ IF(@@global.log_slow_queries, "ON", "OFF") = VARIABLE_VALUE '#---------------------FN_DYNVARS_004_08----------------------#' SET @@global.log_slow_queries = ON; Warnings: -Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MariaDB 10.1. Please use '@@slow_query_log' instead +Warning 1287 '@@log_slow_queries' is deprecated and will be removed in a future release. Please use '@@slow_query_log' instead SELECT @@log_slow_queries = @@global.log_slow_queries; @@log_slow_queries = @@global.log_slow_queries 1 @@ -126,7 +126,7 @@ SELECT log_slow_queries = @@session.log_slow_queries; ERROR 42S22: Unknown column 'log_slow_queries' in 'field list' SET @@global.log_slow_queries = @start_value; Warnings: -Warning 1287 The syntax '@@log_slow_queries' is deprecated and will be removed in MariaDB 10.1. Please use '@@slow_query_log' instead +Warning 1287 '@@log_slow_queries' is deprecated and will be removed in a future release. Please use '@@slow_query_log' instead SELECT @@global.log_slow_queries; @@global.log_slow_queries 1 diff --git a/mysql-test/suite/sys_vars/r/multi_range_count_basic.result b/mysql-test/suite/sys_vars/r/multi_range_count_basic.result index c50e947b967..67ea0f7d03a 100644 --- a/mysql-test/suite/sys_vars/r/multi_range_count_basic.result +++ b/mysql-test/suite/sys_vars/r/multi_range_count_basic.result @@ -9,101 +9,101 @@ SELECT @start_session_value; '#--------------------FN_DYNVARS_090_01-------------------------#' SET @@global.multi_range_count = 100; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SET @@global.multi_range_count = DEFAULT; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@global.multi_range_count; @@global.multi_range_count 256 SET @@session.multi_range_count = 200; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SET @@session.multi_range_count = DEFAULT; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@session.multi_range_count; @@session.multi_range_count 256 '#--------------------FN_DYNVARS_090_02-------------------------#' SET @@global.multi_range_count = DEFAULT; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@global.multi_range_count = 256; @@global.multi_range_count = 256 1 SET @@session.multi_range_count = DEFAULT; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@session.multi_range_count = 256; @@session.multi_range_count = 256 1 '#--------------------FN_DYNVARS_090_03-------------------------#' SET @@global.multi_range_count = 1; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@global.multi_range_count; @@global.multi_range_count 1 SET @@global.multi_range_count = 60020; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@global.multi_range_count; @@global.multi_range_count 60020 SET @@global.multi_range_count = 65535; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@global.multi_range_count; @@global.multi_range_count 65535 SET @@global.multi_range_count = 4294967295; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@global.multi_range_count; @@global.multi_range_count 4294967295 SET @@global.multi_range_count = 4294967294; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@global.multi_range_count; @@global.multi_range_count 4294967294 '#--------------------FN_DYNVARS_090_04-------------------------#' SET @@session.multi_range_count = 1; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@session.multi_range_count; @@session.multi_range_count 1 SET @@session.multi_range_count = 50050; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@session.multi_range_count; @@session.multi_range_count 50050 SET @@session.multi_range_count = 65535; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@session.multi_range_count; @@session.multi_range_count 65535 SET @@session.multi_range_count = 4294967295; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@session.multi_range_count; @@session.multi_range_count 4294967295 SET @@session.multi_range_count = 4294967294; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@session.multi_range_count; @@session.multi_range_count 4294967294 '#------------------FN_DYNVARS_090_05-----------------------#' SET @@global.multi_range_count = 0; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead Warning 1292 Truncated incorrect multi_range_count value: '0' SELECT @@global.multi_range_count; @@global.multi_range_count @@ -114,7 +114,7 @@ SELECT @@global.multi_range_count; 4294967295 SET @@global.multi_range_count = -1024; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead Warning 1292 Truncated incorrect multi_range_count value: '-1024' SELECT @@global.multi_range_count; @@global.multi_range_count @@ -135,7 +135,7 @@ SELECT @@global.multi_range_count; 4294967295 SET @@session.multi_range_count = 0; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead Warning 1292 Truncated incorrect multi_range_count value: '0' SELECT @@session.multi_range_count; @@session.multi_range_count @@ -146,7 +146,7 @@ SELECT @@session.multi_range_count; 4294967295 SET @@session.multi_range_count = -1; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead Warning 1292 Truncated incorrect multi_range_count value: '-1' SELECT @@session.multi_range_count; @@session.multi_range_count @@ -178,13 +178,13 @@ WHERE VARIABLE_NAME='multi_range_count'; '#------------------FN_DYNVARS_090_08-----------------------#' SET @@global.multi_range_count = TRUE; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@global.multi_range_count; @@global.multi_range_count 1 SET @@global.multi_range_count = FALSE; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead Warning 1292 Truncated incorrect multi_range_count value: '0' SELECT @@global.multi_range_count; @@global.multi_range_count @@ -192,14 +192,14 @@ SELECT @@global.multi_range_count; '#---------------------FN_DYNVARS_090_09----------------------#' SET @@global.multi_range_count = 10; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@multi_range_count = @@global.multi_range_count; @@multi_range_count = @@global.multi_range_count 0 '#---------------------FN_DYNVARS_090_10----------------------#' SET @@multi_range_count = 100; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@multi_range_count = @@local.multi_range_count; @@multi_range_count = @@local.multi_range_count 1 @@ -209,7 +209,7 @@ SELECT @@local.multi_range_count = @@session.multi_range_count; '#---------------------FN_DYNVARS_090_11----------------------#' SET multi_range_count = 1; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@multi_range_count; @@multi_range_count 1 @@ -221,13 +221,13 @@ SELECT multi_range_count = @@session.multi_range_count; ERROR 42S22: Unknown column 'multi_range_count' in 'field list' SET @@global.multi_range_count = @start_global_value; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@global.multi_range_count; @@global.multi_range_count 256 SET @@session.multi_range_count = @start_session_value; Warnings: -Warning 1287 The syntax '@@multi_range_count' is deprecated and will be removed in MariaDB 10.1. Please use '@@mrr_buffer_size' instead +Warning 1287 '@@multi_range_count' is deprecated and will be removed in a future release. Please use '@@mrr_buffer_size' instead SELECT @@session.multi_range_count; @@session.multi_range_count 256 diff --git a/mysql-test/suite/sys_vars/r/rpl_recovery_rank_basic.result b/mysql-test/suite/sys_vars/r/rpl_recovery_rank_basic.result index 1962cf86db1..251f428b449 100644 --- a/mysql-test/suite/sys_vars/r/rpl_recovery_rank_basic.result +++ b/mysql-test/suite/sys_vars/r/rpl_recovery_rank_basic.result @@ -5,29 +5,29 @@ SELECT @start_global_value; '#--------------------FN_DYNVARS_142_01-------------------------#' SET @@global.rpl_recovery_rank = 500000; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. SET @@global.rpl_recovery_rank = DEFAULT; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. SELECT @@global.rpl_recovery_rank; @@global.rpl_recovery_rank 0 '#--------------------FN_DYNVARS_142_02-------------------------#' SET @@global.rpl_recovery_rank = 0; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. SELECT @@global.rpl_recovery_rank; @@global.rpl_recovery_rank 0 SET @@global.rpl_recovery_rank = 1024; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. SELECT @@global.rpl_recovery_rank; @@global.rpl_recovery_rank 1024 SET @@global.rpl_recovery_rank = 123456789; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. SELECT @@global.rpl_recovery_rank; @@global.rpl_recovery_rank 123456789 @@ -53,21 +53,21 @@ ERROR HY000: Variable 'rpl_recovery_rank' is a GLOBAL variable and should be set '#------------------FN_DYNVARS_142_04-----------------------#' SET @@global.rpl_recovery_rank = -1; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. Warning 1292 Truncated incorrect rpl_recovery_rank value: '-1' SELECT @@global.rpl_recovery_rank; @@global.rpl_recovery_rank 0 SET @@global.rpl_recovery_rank = -2147483648; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. Warning 1292 Truncated incorrect rpl_recovery_rank value: '-2147483648' SELECT @@global.rpl_recovery_rank; @@global.rpl_recovery_rank 0 SET @@global.rpl_recovery_rank = -2147483649; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. Warning 1292 Truncated incorrect rpl_recovery_rank value: '-2147483649' SELECT @@global.rpl_recovery_rank; @@global.rpl_recovery_rank @@ -81,7 +81,7 @@ ERROR 42000: Incorrect argument type to variable 'rpl_recovery_rank' '#------------------FN_DYNVARS_142_05-----------------------#' SET @@global.rpl_recovery_rank = 3000; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. SELECT @@global.rpl_recovery_rank = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='rpl_recovery_rank'; @@ -96,20 +96,20 @@ count(VARIABLE_VALUE) '#------------------FN_DYNVARS_142_07-----------------------#' SET @@global.rpl_recovery_rank = TRUE; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. SELECT @@global.rpl_recovery_rank; @@global.rpl_recovery_rank 1 SET @@global.rpl_recovery_rank = FALSE; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. SELECT @@global.rpl_recovery_rank; @@global.rpl_recovery_rank 0 '#---------------------FN_DYNVARS_001_08----------------------#' SET @@global.rpl_recovery_rank = 512; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. SELECT @@rpl_recovery_rank = @@global.rpl_recovery_rank; @@rpl_recovery_rank = @@global.rpl_recovery_rank 1 @@ -123,10 +123,10 @@ SELECT @@rpl_recovery_rank; 512 SET global rpl_recovery_rank = 64; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. SET @@global.rpl_recovery_rank = @start_global_value; Warnings: -Warning 1287 The syntax '@@rpl_recovery_rank' is deprecated and will be removed in MariaDB 10.1. +Warning 1287 '@@rpl_recovery_rank' is deprecated and will be removed in a future release. SELECT @@global.rpl_recovery_rank; @@global.rpl_recovery_rank 0 diff --git a/mysql-test/suite/sys_vars/r/sql_big_selects_func.result b/mysql-test/suite/sys_vars/r/sql_big_selects_func.result index 9ee26c71fe6..f96e28379a3 100644 --- a/mysql-test/suite/sys_vars/r/sql_big_selects_func.result +++ b/mysql-test/suite/sys_vars/r/sql_big_selects_func.result @@ -5,7 +5,7 @@ SET @session_max_join_size = @@SESSION.max_join_size; SET @global_max_join_size = @@GLOBAL.max_join_size; SET SQL_MAX_JOIN_SIZE=9; Warnings: -Warning 1287 The syntax '@@sql_max_join_size' is deprecated and will be removed in MariaDB 10.1. Please use '@@max_join_size' instead +Warning 1287 '@@sql_max_join_size' is deprecated and will be removed in a future release. Please use '@@max_join_size' instead CREATE TEMPORARY TABLE t1(a varchar(20) not null, b varchar(20)); CREATE TEMPORARY TABLE t2(a varchar(20) null, b varchar(20)); INSERT INTO t1 VALUES('aa','bb'); diff --git a/mysql-test/suite/sys_vars/r/sql_max_join_size_basic.result b/mysql-test/suite/sys_vars/r/sql_max_join_size_basic.result index dc1efd1794e..ffd526aa5d9 100644 --- a/mysql-test/suite/sys_vars/r/sql_max_join_size_basic.result +++ b/mysql-test/suite/sys_vars/r/sql_max_join_size_basic.result @@ -22,10 +22,10 @@ VARIABLE_NAME VARIABLE_VALUE SQL_MAX_JOIN_SIZE 18446744073709551615 set global sql_max_join_size=10; Warnings: -Warning 1287 The syntax '@@sql_max_join_size' is deprecated and will be removed in MariaDB 10.1. Please use '@@max_join_size' instead +Warning 1287 '@@sql_max_join_size' is deprecated and will be removed in a future release. Please use '@@max_join_size' instead set session sql_max_join_size=20; Warnings: -Warning 1287 The syntax '@@sql_max_join_size' is deprecated and will be removed in MariaDB 10.1. Please use '@@max_join_size' instead +Warning 1287 '@@sql_max_join_size' is deprecated and will be removed in a future release. Please use '@@max_join_size' instead select @@global.sql_max_join_size; @@global.sql_max_join_size 10 @@ -55,20 +55,20 @@ select @@sql_big_selects; 0 set sql_max_join_size=cast(-1 as unsigned int); Warnings: -Warning 1287 The syntax '@@sql_max_join_size' is deprecated and will be removed in MariaDB 10.1. Please use '@@max_join_size' instead +Warning 1287 '@@sql_max_join_size' is deprecated and will be removed in a future release. Please use '@@max_join_size' instead Note 1105 Cast to unsigned converted negative integer to it's positive complement select @@sql_big_selects; @@sql_big_selects 1 set sql_max_join_size=100; Warnings: -Warning 1287 The syntax '@@sql_max_join_size' is deprecated and will be removed in MariaDB 10.1. Please use '@@max_join_size' instead +Warning 1287 '@@sql_max_join_size' is deprecated and will be removed in a future release. Please use '@@max_join_size' instead select @@sql_big_selects; @@sql_big_selects 0 SET @@global.sql_max_join_size = @start_global_value; Warnings: -Warning 1287 The syntax '@@sql_max_join_size' is deprecated and will be removed in MariaDB 10.1. Please use '@@max_join_size' instead +Warning 1287 '@@sql_max_join_size' is deprecated and will be removed in a future release. Please use '@@max_join_size' instead SELECT @@global.sql_max_join_size; @@global.sql_max_join_size 18446744073709551615 diff --git a/mysql-test/suite/sys_vars/r/sql_max_join_size_func.result b/mysql-test/suite/sys_vars/r/sql_max_join_size_func.result index ac6aaf087ab..9460adad1b7 100644 --- a/mysql-test/suite/sys_vars/r/sql_max_join_size_func.result +++ b/mysql-test/suite/sys_vars/r/sql_max_join_size_func.result @@ -17,7 +17,7 @@ INSERT INTO t2 VALUES('aa4','bb'); '#--------------------FN_DYNVARS_161_01-------------------------#' SET SESSION sql_max_join_size=9; Warnings: -Warning 1287 The syntax '@@sql_max_join_size' is deprecated and will be removed in MariaDB 10.1. Please use '@@max_join_size' instead +Warning 1287 '@@sql_max_join_size' is deprecated and will be removed in a future release. Please use '@@max_join_size' instead SELECT * FROM t1 INNER JOIN t2 ON t1.a = t2.a; ERROR 42000: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay Expected error The SELECT would examine more than MAX_JOIN_SIZE rows. @@ -33,7 +33,7 @@ aa4 bb aa4 bb This should work SET SESSION sql_max_join_size=DEFAULT; Warnings: -Warning 1287 The syntax '@@sql_max_join_size' is deprecated and will be removed in MariaDB 10.1. Please use '@@max_join_size' instead +Warning 1287 '@@sql_max_join_size' is deprecated and will be removed in a future release. Please use '@@max_join_size' instead DELETE FROM t2 WHERE a = 'aa4'; SELECT * FROM t1 INNER JOIN t2 ON t1.a = t2.a; a b a b @@ -45,7 +45,7 @@ This should work '#----------------------------FN_DYNVARS_136_05-------------------------#' SET GLOBAL sql_max_join_size = 4; Warnings: -Warning 1287 The syntax '@@sql_max_join_size' is deprecated and will be removed in MariaDB 10.1. Please use '@@max_join_size' instead +Warning 1287 '@@sql_max_join_size' is deprecated and will be removed in a future release. Please use '@@max_join_size' instead ** Connecting con_int1 using root ** ** Connection con_int1 ** SELECT @@SESSION.sql_max_join_size; @@ -54,7 +54,7 @@ SELECT @@SESSION.sql_max_join_size; 4 Expected SET SESSION sql_max_join_size = 2; Warnings: -Warning 1287 The syntax '@@sql_max_join_size' is deprecated and will be removed in MariaDB 10.1. Please use '@@max_join_size' instead +Warning 1287 '@@sql_max_join_size' is deprecated and will be removed in a future release. Please use '@@max_join_size' instead ** Connecting con_int2 using root ** ** Connection con_int2 ** SELECT @@SESSION.sql_max_join_size; @@ -63,7 +63,7 @@ SELECT @@SESSION.sql_max_join_size; 4 Expected SET SESSION sql_max_join_size = 10; Warnings: -Warning 1287 The syntax '@@sql_max_join_size' is deprecated and will be removed in MariaDB 10.1. Please use '@@max_join_size' instead +Warning 1287 '@@sql_max_join_size' is deprecated and will be removed in a future release. Please use '@@max_join_size' instead ** Connection con_int2 ** SELECT @@SESSION.sql_max_join_size; @@SESSION.sql_max_join_size @@ -82,10 +82,10 @@ SELECT @@GLOBAL.sql_max_join_size; Disconnecting Connections con_int1, con_int2 SET @@SESSION.sql_max_join_size = @session_max_join_size; Warnings: -Warning 1287 The syntax '@@sql_max_join_size' is deprecated and will be removed in MariaDB 10.1. Please use '@@max_join_size' instead +Warning 1287 '@@sql_max_join_size' is deprecated and will be removed in a future release. Please use '@@max_join_size' instead SET @@GLOBAL.sql_max_join_size = @global_max_join_size ; Warnings: -Warning 1287 The syntax '@@sql_max_join_size' is deprecated and will be removed in MariaDB 10.1. Please use '@@max_join_size' instead +Warning 1287 '@@sql_max_join_size' is deprecated and will be removed in a future release. Please use '@@max_join_size' instead SET @@SESSION.sql_big_selects = @session_sql_big_selects; DROP TABLE t1; DROP TABLE t2; diff --git a/mysql-test/suite/sys_vars/t/ignore_db_dirs_basic-master.opt b/mysql-test/suite/sys_vars/t/ignore_db_dirs_basic-master.opt new file mode 100644 index 00000000000..30ee4f67284 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/ignore_db_dirs_basic-master.opt @@ -0,0 +1,11 @@ +--ignore-db-dir=a +--ignore-db-dir=b +--ignore-db-dir=c +--ignore-db-dir= +--ignore-db-dir=d +--ignore-db-dir x +--ignore-db-dir= +--ignore-db-dir=e +--ignore-db-dir=lost+found +--ignore-db-dir=.mysqlgui +--ignore-db-dir=ignored_db diff --git a/mysql-test/suite/sys_vars/t/ignore_db_dirs_basic.test b/mysql-test/suite/sys_vars/t/ignore_db_dirs_basic.test new file mode 100644 index 00000000000..9544fc540f9 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/ignore_db_dirs_basic.test @@ -0,0 +1,38 @@ +select @@ignore_db_dirs; +let $MYSQLD_DATADIR= `select @@datadir`; + +mkdir $MYSQLD_DATADIR/.mysqlgui; +mkdir $MYSQLD_DATADIR/.otherdir; +mkdir $MYSQLD_DATADIR/lost+found; +mkdir $MYSQLD_DATADIR/ignored_db; +--echo # Check that SHOW DATABASES ignores all directories from +--echo # @@ignore_db_dirs and all directories with names starting +--echo # with '.' +SHOW DATABASES; +--error ER_WRONG_DB_NAME +USE ignored_db; +--error ER_WRONG_DB_NAME +SELECT * FROM ignored_db.t1; +--error ER_WRONG_DB_NAME +CALL ignored_db.p1(); +SELECT COUNT(*) FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='ignored_db'; +--error ER_WRONG_DB_NAME +CREATE DATABASE ignored_db; +CREATE DATABASE `lost+found`; +USE `lost+found`; +CREATE TABLE t1(id INT); +INSERT INTO t1 VALUES (1), (2); +SELECT * FROM `lost+found`.t1; +SHOW DATABASES; +DROP DATABASE `lost+found`; +rmdir $MYSQLD_DATADIR/.mysqlgui; +rmdir $MYSQLD_DATADIR/.otherdir; +rmdir $MYSQLD_DATADIR/lost+found; +rmdir $MYSQLD_DATADIR/ignored_db; + +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET @@global.ignore_db_dirs = 'aha'; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET @@local.ignore_db_dirs = 'aha'; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET @@ignore_db_dirs = 'aha'; diff --git a/mysql-test/suite/sys_vars/t/innodb_changed_pages_limit_basic.test b/mysql-test/suite/sys_vars/t/innodb_changed_pages_limit_basic.test new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_changed_pages_limit_basic.test diff --git a/mysql-test/suite/sys_vars/t/innodb_persistent_stats_root_page_basic.test b/mysql-test/suite/sys_vars/t/innodb_persistent_stats_root_page_basic.test new file mode 100644 index 00000000000..2e216e10521 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_persistent_stats_root_page_basic.test @@ -0,0 +1,26 @@ +--source include/have_debug.inc +--source include/have_xtradb.inc + +SELECT @@global.innodb_persistent_stats_root_page; +SELECT COUNT(@@global.innodb_persistent_stats_root_page); + +# Read-only variable +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET @@global.innodb_persistent_stats_root_page=100; + +# Check if INFORMATION_SCHEMA agrees with the var +SELECT @@global.innodb_persistent_stats_root_page = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='innodb_persistent_stats_root_page'; + +SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='innodb_persistent_stats_root_page'; + +# Check if accessing the var without GLOBAL points to the same +SELECT @@innodb_persistent_stats_root_page = @@global.innodb_persistent_stats_root_page; + +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT COUNT(@@local.innodb_persistent_stats_root_page); + +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT COUNT(@@session.innodb_persistent_stats_root_page); diff --git a/mysql-test/suite/sys_vars/t/innodb_track_changed_pages_basic.test b/mysql-test/suite/sys_vars/t/innodb_track_changed_pages_basic.test new file mode 100644 index 00000000000..09d92a6bc2d --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_track_changed_pages_basic.test @@ -0,0 +1,21 @@ +# Tests for innodb_track_changed_pages variable + +--source include/have_xtradb.inc + +SELECT COUNT(@@GLOBAL.innodb_track_changed_pages); + +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET @@GLOBAL.innodb_track_changed_pages=1; + +SELECT @@GLOBAL.innodb_track_changed_pages = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='innodb_track_changed_pages'; + +SELECT @@innodb_track_changed_pages = @@GLOBAL.innodb_track_changed_pages; + +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT COUNT(@@SESSION.innodb_track_changed_pages); +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT COUNT(@@LOCAL.innodb_track_changed_pages); +--error ER_BAD_FIELD_ERROR +SELECT innodb_track_changed_pages = @@SESSION.innodb_track_changed_pages; diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index bdb206be07b..d8d8f4538e1 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1506,3 +1506,14 @@ SET @@global.max_allowed_packet:= @tmp_max; --echo # --echo # End of 5.5 tests --echo # + +# +# Bug#11765562 58545: +# EXPORT_SET() CAN BE USED TO MAKE ENTIRE SERVER COMPLETELY UNRESPONSIVE +# +SELECT @tmp_max:= @@global.max_allowed_packet; +SET @@global.max_allowed_packet=1024*1024*1024; +SELECT @@global.max_allowed_packet; +SELECT CHAR_LENGTH(EXPORT_SET(1,1,1,REPEAT(1,100000000))); +SET @@global.max_allowed_packet:= @tmp_max; + diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 003ffc8ff19..9b04c264faf 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -3587,5 +3587,54 @@ set optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3; +--echo # +--echo # Bug #1058071: LEFT JOIN using blobs +--echo # (mdev-564) when join buffer size is small +--echo # + +CREATE TABLE t1 ( + col269 decimal(31,10) unsigned DEFAULT NULL, + col280 multipoint DEFAULT NULL, + col281 tinyint(1) DEFAULT NULL, + col282 time NOT NULL, + col284 datetime DEFAULT NULL, + col286 date DEFAULT NULL, + col287 datetime DEFAULT NULL, + col288 decimal(30,29) DEFAULT NULL, + col291 time DEFAULT NULL, + col292 time DEFAULT NULL +) ENGINE=Aria; + +INSERT INTO t1 VALUES +(0.0,PointFromText('POINT(9 0)'),0,'11:24:05','2013-04-14 21:30:28',NULL,'2011-12-20 06:00:34',9.9,'13:04:39',NULL), +(0.0,NULL,127,'05:43:12','2012-09-05 06:15:27','2027-01-01','2011-10-29 10:48:29',0.0,'06:24:05','11:33:37'), +(0.0,NULL,127,'12:54:41','2013-01-12 11:32:58','2011-11-03','2013-01-03 02:00:34',00,'11:54:15','20:19:15'), +(0.0,PointFromText('POINT(9 0)'),0,'19:48:07','2012-07-16 15:45:25','2012-03-25','2013-09-07 17:21:52',0.5,'17:36:54','21:24:19'), +(0.0,PointFromText('POINT(9 0)'),0,'03:43:48','2012-09-28 00:00:00','2012-06-26','2011-11-16 05:01:09',00,'01:25:42','19:30:06'), +(0.0,LineStringFromText('LINESTRING(0 0,9 9,0 0,9 0,0 0)'),127,'11:33:21','2012-03-31 10:29:22','2012-10-10','2012-04-21 19:21:06',NULL,'05:13:22','09:48:34'), +(NULL,PointFromText('POINT(9 0)'),127,'00:00:00','0000-00-00','2012-04-04 21:26:12','2013-03-04',0.0,'12:54:30',NULL), +(NULL,PointFromText('POINT(9 0)'),1,'00:00:00','2013-05-01 22:37:49','2013-06-26','2012-09-22 17:31:03',0.0,'08:09:57','11:15:36'); + +CREATE TABLE t2 (b int) ENGINE=Aria; +INSERT INTO t2 VALUES (NULL); +CREATE TABLE t3 (c int) ENGINE=Aria; +INSERT INTO t3 VALUES (NULL); + +set @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch = 'outer_join_with_cache=on,join_cache_incremental=on'; +set join_buffer_size=128; + +EXPLAIN +SELECT 1 AS c FROM t1 NATURAL LEFT JOIN t2 LEFT OUTER JOIN t3 ON 1 + GROUP BY elt(t1.col282,1,t1.col280); + +SELECT 1 AS c FROM t1 NATURAL LEFT JOIN t2 LEFT OUTER JOIN t3 ON 1 + GROUP BY elt(t1.col282,1,t1.col280); + +set join_buffer_size=default; +set optimizer_switch=@tmp_optimizer_switch; + +DROP table t1,t2,t3; + # this must be the last command in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/mysqlshow.test b/mysql-test/t/mysqlshow.test index 105e03c841b..045329fd2e0 100644 --- a/mysql-test/t/mysqlshow.test +++ b/mysql-test/t/mysqlshow.test @@ -1,7 +1,5 @@ # Can't run test of external client with embedded server -- source include/not_embedded.inc -# Test lists tables in Information_schema, and InnoDB adds some --- source include/have_innodb.inc # Don't test when thread_pool active --source include/not_threadpool.inc @@ -31,3 +29,14 @@ select "---- -v -v -t ------" as ""; DROP TABLE t1, t2; --echo End of 5.0 tests + +# because of lp:1066512 this test shows xtradb I_S plugins, even when +# xtradb is supposed to be disabled + +# +# Bug #19147: mysqlshow INFORMATION_SCHEMA does not work +# +# --exec $MYSQL_SHOW information_schema +# --exec $MYSQL_SHOW INFORMATION_SCHEMA +# --exec $MYSQL_SHOW inf_rmation_schema + diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test index 9ef68d4018d..61e0dcc7197 100644 --- a/mysql-test/t/openssl_1.test +++ b/mysql-test/t/openssl_1.test @@ -74,25 +74,31 @@ drop table t1; # --exec echo "this query should not execute;" > $MYSQLTEST_VARDIR/tmp/test.sql # Handle that openssl gives different error messages from YaSSL. ---replace_regex /error:0000000[15]:lib\(0\):func\(0\):(reason\(1\)|DH lib)/ASN: bad other signature confirmation/ +#--replace_regex /error:00000001:lib\(0\):func\(0\):reason\(1\)/ASN: bad other signature confirmation/ +--replace_regex /2026 SSL connection error.*/2026 SSL connection error: xxxx/ --error 1 --exec $MYSQL_TEST --ssl-ca=$MYSQL_TEST_DIR/std_data/untrusted-cacert.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 +--echo # # Test that we can't open connection to server if we are using # a blank ca # ---replace_regex /error:0000000[15]:lib\(0\):func\(0\):(reason\(1\)|DH lib)/ASN: bad other signature confirmation/ +#--replace_regex /error:00000001:lib\(0\):func\(0\):reason\(1\)/ASN: bad other signature confirmation/ +--replace_regex /2026 SSL connection error.*/2026 SSL connection error: xxxx/ --error 1 --exec $MYSQL_TEST --ssl-ca= --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 +--echo # # Test that we can't open connection to server if we are using # a nonexistent ca file # ---replace_regex /error:0000000[15]:lib\(0\):func\(0\):(reason\(1\)|DH lib)/ASN: bad other signature confirmation/ +#--replace_regex /error:00000001:lib\(0\):func\(0\):reason\(1\)/ASN: bad other signature confirmation/ +--replace_regex /2026 SSL connection error.*/2026 SSL connection error: xxxx/ --error 1 --exec $MYSQL_TEST --ssl-ca=nonexisting_file.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 +--echo # # Test that we can't open connection to server if we are using diff --git a/mysql-test/t/order_fill_sortbuf-master.opt b/mysql-test/t/order_fill_sortbuf-master.opt deleted file mode 100644 index 7b6ade99226..00000000000 --- a/mysql-test/t/order_fill_sortbuf-master.opt +++ /dev/null @@ -1 +0,0 @@ ---sort_buffer=32804 diff --git a/mysql-test/t/order_fill_sortbuf.test b/mysql-test/t/order_fill_sortbuf.test index 7a8779b6e55..33c09e34b91 100644 --- a/mysql-test/t/order_fill_sortbuf.test +++ b/mysql-test/t/order_fill_sortbuf.test @@ -7,6 +7,8 @@ drop table if exists t1,t2; --enable_warnings +set @@sort_buffer_size=32804; + CREATE TABLE `t1` ( `id` int(11) NOT NULL default '0', `id2` int(11) NOT NULL default '0', diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test index b9e84d8d7df..812b1b5ff94 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -827,6 +827,16 @@ execute stmt1 ; drop table t1, t5, t9; +--echo # +--echo # testcase for bug#11765413 - Crash with dependent subquery and +--echo # prepared statement +create table t1 (c1 int); +insert into t1 values (1); +prepare stmt1 from "select 1 from t1 where 1=(select 1 from t1 having c1)"; +execute stmt1; +drop prepare stmt1; +drop table t1; + ##### RULES OF THUMB TO PRESERVE THE SYSTEMATICS OF THE PS TEST CASES ##### # # 0. You don't have the time to diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 618d6eb3ed4..44eaf7130a7 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -4174,7 +4174,7 @@ INSERT INTO t5 VALUES (20),(5); CREATE TABLE t6(f1 int); INSERT INTO t6 VALUES (9),(7); -SET SESSION join_buffer_size = 2048; +SET SESSION join_buffer_size = 2176; EXPLAIN SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 9f35ecc43f1..07f0084e7ab 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -5597,6 +5597,22 @@ set optimizer_switch=@mdev367_optimizer_switch; DROP TABLE t1; --echo # +--echo # MDEV-521 single value subselect transformation problem +--echo # +CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('u1'),('u2'); + +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +FLUSH TABLES; +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); + +# Cleanup +DROP TABLE t1; + +--echo # return optimizer switch changed in the beginning of this test +set optimizer_switch=@subselect_tmp; + +--echo # --echo # lp:944706 Query with impossible or constant subquery in WHERE or HAVING is not --echo # precomputed and thus not part of optimization --echo # @@ -5757,6 +5773,29 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS ( SELECT a FROM t1, t2 WHERE b = a GROUP B DROP TABLE t1,t2; --echo # +--echo # MDEV-435: Expensive subqueries may be evaluated during optimization in merge_key_fields +--echo # + +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (8),(0); + +CREATE TABLE t2 (b INT, c VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (4,'j'),(6,'v'); + +CREATE TABLE t3 (d VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t3 VALUES ('b'),('c'); + +EXPLAIN +SELECT * FROM t1 +WHERE a = (SELECT MAX(b) FROM t2 WHERE c IN (SELECT MAX(d) FROM t3)) OR a = 10; + +SELECT * FROM t1 +WHERE a = (SELECT MAX(b) FROM t2 WHERE c IN (SELECT MAX(d) FROM t3)) OR a = 10; + +drop table t1, t2, t3; + + +--echo # --echo # MDEV-405: Server crashes in test_if_skip_sort_order on EXPLAIN with GROUP BY and HAVING in EXISTS subquery --echo # CREATE TABLE t1 (a INT, KEY(a)); diff --git a/mysql-test/t/subselect2.test b/mysql-test/t/subselect2.test index 8d2939bdb53..75cf842fbdb 100644 --- a/mysql-test/t/subselect2.test +++ b/mysql-test/t/subselect2.test @@ -203,5 +203,24 @@ SET optimizer_switch=@tmp_optimizer_switch; DROP VIEW v1; DROP TABLE t1,t2,t3; +--echo # +--echo # MDEV-567: Wrong result from a query with correlated subquery if ICP is allowed +--echo # +CREATE TABLE t1 (a int, b int, INDEX idx(a)); +INSERT INTO t1 VALUES (9,0), (7,1), (1,9), (7,3), (2,1); + +CREATE TABLE t2 (a int, b int, INDEX idx(a)); +INSERT INTO t2 VALUES (2,1), (6,4), (7,6), (9,4); + +CREATE TABLE t3 (a int, b int); +INSERT INTO t3 VALUES (1,0), (1,1), (1,3); + +SELECT * FROM t3 + WHERE a = (SELECT COUNT(DISTINCT t2.b) FROM t1, t2 + WHERE t1.a = t2.a AND t2.a BETWEEN 7 AND 9 + AND t3.b = t1.b + GROUP BY t1.b); +DROP TABLE t1, t2, t3; + set optimizer_switch=@subselect2_test_tmp; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index c4881f7df3f..817da816c48 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -4381,6 +4381,46 @@ SELECT * FROM v1, t2 DROP VIEW v1; DROP TABLE t1,t2,t3,t4; +--echo # +--echo # LP bug #823237: dependent subquery with LEFT JOIN +--echo # referencing view in WHERE +--echo # (duplicate of LP bug #823189) +--echo # + +CREATE TABLE t1 (a int); + +CREATE TABLE t2 ( b int, d int, e int); +INSERT INTO t2 VALUES (7,8,0); + +CREATE TABLE t3 ( c int); +INSERT INTO t3 VALUES (0); + +CREATE TABLE t4 (a int, b int, c int); +INSERT INTO t4 VALUES (93,1,0), (95,NULL,0); + +CREATE VIEW v4 AS SELECT * FROM t4; + +EXPLAIN EXTENDED +SELECT * FROM t3 , t4 + WHERE t4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) + WHERE t2.b > t4.b); +SELECT * FROM t3 , t4 + WHERE t4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) + WHERE t2.b > t4.b); + + +EXPLAIN EXTENDED +SELECT * FROM t3, v4 + WHERE v4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) + WHERE t2.b > v4.b); + +SELECT * FROM t3, v4 + WHERE v4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) + WHERE t2.b > v4.b); + +DROP VIEW v4; +DROP TABLE t1,t2,t3,t4; + # # Bug#9801 (Views: imperfect error message) # @@ -4661,6 +4701,52 @@ create algorithm=MERGE view v2 as select 2 as id, id is null as bbb, id as iddqd select t1.*, v2.* from t1 left join v2 on t1.id = v2.id; drop view v2; drop table t1,t2; + +--echo # +--echo # MDEV-589 (LP BUG#1007647) : +--echo # Assertion `vcol_table == 0 || vcol_table == table' failed in +--echo # fill_record(THD*, List<Item>&, List<Item>&, bool) +--echo # +CREATE TABLE t1 (f1 INT, f2 INT); +CREATE TABLE t2 (f1 INT, f2 INT); +CREATE ALGORITHM=MERGE VIEW v1 AS SELECT a1.f1, a2.f2 FROM t1 AS a1, t1 AS a2; +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM v1; +CREATE ALGORITHM=MERGE VIEW v3 AS SELECT a1.f1, a2.f2 FROM t1 AS a1, t2 AS a2; +CREATE ALGORITHM=MERGE VIEW v4 AS SELECT * FROM v3; +--error ER_VIEW_MULTIUPDATE +INSERT INTO v3 (f1, f2) VALUES (1, 2); +--error ER_VIEW_MULTIUPDATE +INSERT INTO v1 (f1, f2) VALUES (1, 2); +--error ER_VIEW_MULTIUPDATE +INSERT INTO v4 (f1, f2) VALUES (1, 2); +--error ER_VIEW_MULTIUPDATE +INSERT INTO v2 (f1, f2) VALUES (1, 2); +drop view v4,v3,v2,v1; +drop table t1,t2; + +--echo # +--echo # MDEV-3799 fix of above bugfix (MDEV-589) +--echo # Wrong result (NULLs instead of real values) with RIGHT JOIN +--echo # in a FROM subquery and derived_merge=on +--echo # + +CREATE TABLE t1 (f1 INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (4),(6); + +CREATE TABLE t2 (f2 INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (7),(8); + +SELECT * FROM ( + SELECT * FROM t1 RIGHT JOIN t2 ON f1 = f2 +) AS alias; + +SELECT * FROM ( + SELECT * FROM t2 LEFT JOIN t1 ON f1 = f2 +) AS alias; + +drop tables t1,t2; + + --echo # ----------------------------------------------------------------- --echo # -- End of 5.3 tests. --echo # ----------------------------------------------------------------- diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index f9e51e48189..02e5c5373ae 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -1527,8 +1527,13 @@ int _my_b_get(IO_CACHE *info) int _my_b_write(register IO_CACHE *info, const uchar *Buffer, size_t Count) { size_t rest_length,length; + my_off_t pos_in_file= info->pos_in_file; - if (info->pos_in_file+info->buffer_length > info->end_of_file) + DBUG_EXECUTE_IF("simulate_huge_load_data_file", + { + pos_in_file=(my_off_t)(5000000000ULL); + }); + if (pos_in_file+info->buffer_length > info->end_of_file) { my_errno=errno=EFBIG; return info->error = -1; diff --git a/mysys/my_context.c b/mysys/my_context.c index 1a147437c90..6b8761e554d 100644 --- a/mysys/my_context.c +++ b/mysys/my_context.c @@ -1,5 +1,5 @@ /* - Copyright 2011 Kristian Nielsen and Monty Program Ab + Copyright 2011, 2012 Kristian Nielsen and Monty Program Ab This file is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -454,6 +454,15 @@ my_context_spawn(struct my_context *c, void (*f)(void *), void *d) ( "movl %%esp, (%[save])\n\t" "movl %[stack], %%esp\n\t" +#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 + /* + This emits a DWARF DW_CFA_undefined directive to make the return address + undefined. This indicates that this is the top of the stack frame, and + helps tools that use DWARF stack unwinding to obtain stack traces. + (I use numeric constant to avoid a dependency on libdwarf includes). + */ + ".cfi_escape 0x07, 8\n\t" +#endif /* Push the parameter on the stack. */ "pushl %[d]\n\t" "movl %%ebp, 4(%[save])\n\t" @@ -483,12 +492,12 @@ my_context_spawn(struct my_context *c, void (*f)(void *), void *d) "3:\n\t" "movl $1, %[ret]\n" "4:\n" - : [ret] "=a" (ret) + : [ret] "=a" (ret), + [f] "+c" (f), + [d] "+d" (d) : [stack] "a" (c->stack_top), /* Need this in callee-save register to preserve across function call. */ - [save] "D" (&c->save[0]), - [f] "c" (f), - [d] "d" (d) + [save] "D" (&c->save[0]) : "memory", "cc" ); diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index c1b0a129a30..7905ad90877 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -720,6 +720,11 @@ static int setval(const struct my_option *opts, void *value, char *argument, } *(ulong*)value= arg; } + else if (type < 0) + { + res= EXIT_AMBIGUOUS_OPTION; + goto ret; + } else *(ulong*)value= type - 1; } diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index 846a90cc127..402520990b6 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -654,7 +654,6 @@ void my_print_stacktrace(uchar* unused1, ulong unused2) &(package.sym)); have_source= SymGetLineFromAddr64(hProcess, addr, &line_offset, &line); - my_safe_printf_stderr("%p ", (uintptr_t)addr); if(have_module) { const char *base_image_name= my_basename(module.ImageName); diff --git a/plugin/auth_pam/mapper/pam_user_map.c b/plugin/auth_pam/mapper/pam_user_map.c new file mode 100644 index 00000000000..e73ab6de544 --- /dev/null +++ b/plugin/auth_pam/mapper/pam_user_map.c @@ -0,0 +1,93 @@ +/* + Pam module to change user names arbitrarily in the pam stack. + + Compile as + + gcc pam_user_map.c -shared -lpam -fPIC -o pam_user_map.so + + Install as appropriate (for example, in /lib/security/). + Add to your /etc/pam.d/mysql (preferrably, at the end) this line: +========================================================= +auth required pam_user_map.so +========================================================= + + And create /etc/security/user_map.conf with the desired mapping + in the format: orig_user_name: mapped_user_name +========================================================= +#comments and emty lines are ignored +john: jack +bob: admin +top: accounting +========================================================= + +*/ + +#include <stdio.h> +#include <syslog.h> +#include <security/pam_modules.h> + +#define FILENAME "/etc/security/user_map.conf" +#define skip(what) while (*s && (what)) s++ + +int pam_sm_authenticate(pam_handle_t *pamh, int flags, + int argc, const char *argv[]) +{ + int pam_err, line= 0; + const char *username; + char buf[256]; + FILE *f; + + f= fopen(FILENAME, "r"); + if (f == NULL) + { + pam_syslog(pamh, LOG_ERR, "Cannot open '%s'\n", FILENAME); + return PAM_SYSTEM_ERR; + } + + pam_err = pam_get_item(pamh, PAM_USER, (const void**)&username); + if (pam_err != PAM_SUCCESS) + goto ret; + + while (fgets(buf, sizeof(buf), f) != NULL) + { + char *s= buf, *from, *to, *end_from, *end_to; + line++; + + skip(isspace(*s)); + if (*s == '#' || *s == 0) continue; + from= s; + skip(isalnum(*s) || (*s == '_')); + end_from= s; + skip(isspace(*s)); + if (end_from == from || *s++ != ':') goto syntax_error; + skip(isspace(*s)); + to= s; + skip(isalnum(*s) || (*s == '_')); + end_to= s; + if (end_to == to) goto syntax_error; + + *end_from= *end_to= 0; + if (strcmp(username, from) == 0) + { + pam_err= pam_set_item(pamh, PAM_USER, to); + goto ret; + } + } + pam_err= PAM_SUCCESS; + goto ret; + +syntax_error: + pam_syslog(pamh, LOG_ERR, "Syntax error at %s:%d", FILENAME, line); + pam_err= PAM_SYSTEM_ERR; +ret: + fclose(f); + return pam_err; +} + +int pam_sm_setcred(pam_handle_t *pamh, int flags, + int argc, const char *argv[]) +{ + + return PAM_SUCCESS; +} + diff --git a/plugin/auth_pam/testing/pam_mariadb_mtr.c b/plugin/auth_pam/testing/pam_mariadb_mtr.c index 8ad1e18e696..473ec246fe0 100644 --- a/plugin/auth_pam/testing/pam_mariadb_mtr.c +++ b/plugin/auth_pam/testing/pam_mariadb_mtr.c @@ -12,7 +12,7 @@ Create /etc/pam.d/mariadb_mtr with ========================================================= auth required pam_mariadb_mtr.so pam_test -account required pam_mariadb_mtr.so +account required pam_permit.so ========================================================= */ @@ -23,9 +23,8 @@ account required pam_mariadb_mtr.so #define N 3 -PAM_EXTERN int -pam_sm_authenticate(pam_handle_t *pamh, int flags, - int argc, const char *argv[]) +int pam_sm_authenticate(pam_handle_t *pamh, int flags, + int argc, const char *argv[]) { struct pam_conv *conv; struct pam_response *resp = 0; @@ -71,17 +70,8 @@ ret: return retval; } -PAM_EXTERN int -pam_sm_setcred(pam_handle_t *pamh, int flags, - int argc, const char *argv[]) -{ - - return PAM_SUCCESS; -} - -PAM_EXTERN int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, - int argc, const char *argv[]) +int pam_sm_setcred(pam_handle_t *pamh, int flags, + int argc, const char *argv[]) { return PAM_SUCCESS; diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index fca1febffb5..1a511524e84 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -257,7 +257,7 @@ fi # Now we can get arguments from the groups [mysqld] and [mysql_install_db] # in the my.cfg file, then re-run to merge with command line arguments. -parse_arguments `$print_defaults $defaults mysqld mariadb mysql_install_db client-server` +parse_arguments `"$print_defaults" $defaults mysqld mariadb mysql_install_db client-server` parse_arguments PICK-ARGS-FROM-ARGV "$@" # Configure paths to support files @@ -307,7 +307,7 @@ fill_help_tables="$pkgdatadir/fill_help_tables.sql" create_system_tables="$pkgdatadir/mysql_system_tables.sql" fill_system_tables="$pkgdatadir/mysql_system_tables_data.sql" -for f in $fill_help_tables $create_system_tables $fill_system_tables +for f in "$fill_help_tables" "$create_system_tables" "$fill_system_tables" do if test ! -f "$f" then @@ -330,22 +330,25 @@ then exit 1 fi mysqld_opt="--lc-messages-dir=$langdir/.." +else + mysqld_opt="--lc-messages=en_US" fi + # Try to determine the hostname hostname=`@HOSTNAME@` # Check if hostname is valid if test "$cross_bootstrap" -eq 0 -a "$in_rpm" -eq 0 -a "$force" -eq 0 then - resolved=`$extra_bindir/resolveip $hostname 2>&1` + resolved=`"$extra_bindir/resolveip" $hostname 2>&1` if test $? -ne 0 then - resolved=`$extra_bindir/resolveip localhost 2>&1` + resolved=`"$extra_bindir/resolveip" localhost 2>&1` if test $? -ne 0 then echo "Neither host '$hostname' nor 'localhost' could be looked up with" - echo "$extra_bindir/resolveip" + echo "'$extra_bindir/resolveip'" echo "Please configure the 'hostname' command to return a correct" echo "hostname." echo "If you want to solve this at a later stage, restart this script" @@ -368,21 +371,21 @@ then fi # Create database directories -for dir in $ldata $ldata/mysql $ldata/test +for dir in "$ldata" "$ldata/mysql" "$ldata/test" do - if test ! -d $dir + if test ! -d "$dir" then - if ! `mkdir -p $dir` + if ! `mkdir -p "$dir"` then echo "Fatal error Can't create database directory '$dir'" link_to_help exit 1 fi - chmod 700 $dir + chmod 700 "$dir" fi if test -n "$user" then - chown $user $dir + chown $user "$dir" if test $? -ne 0 then echo "Cannot change ownership of the database directories to the '$user'" @@ -409,15 +412,19 @@ fi # Configure mysqld command line mysqld_bootstrap="${MYSQLD_BOOTSTRAP-$mysqld}" -mysqld_install_cmd_line="$mysqld_bootstrap $defaults $mysqld_opt --bootstrap \ - --basedir=$basedir --datadir=$ldata --log-warnings=0 \ +mysqld_install_cmd_line() +{ + "$mysqld_bootstrap" $defaults "$mysqld_opt" --bootstrap \ + "--basedir=$basedir" "--datadir=$ldata" --log-warnings=0 \ --loose-skip-ndbcluster --loose-skip-pbxt $args --max_allowed_packet=8M \ --default-storage-engine=myisam \ - --net_buffer_length=16K" + --net_buffer_length=16K +} + # Create the system and help tables by passing them to "mysqld --bootstrap" s_echo "Installing MariaDB/MySQL system tables in '$ldata' ..." -if { echo "use mysql;"; cat $create_system_tables $fill_system_tables; } | eval "$filter_cmd_line" | $mysqld_install_cmd_line > /dev/null +if { echo "use mysql;"; cat "$create_system_tables" "$fill_system_tables"; } | eval "$filter_cmd_line" | mysqld_install_cmd_line > /dev/null then s_echo "OK" else @@ -452,7 +459,7 @@ else fi s_echo "Filling help tables..." -if { echo "use mysql;"; cat $fill_help_tables; } | $mysqld_install_cmd_line > /dev/null +if { echo "use mysql;"; cat "$fill_help_tables"; } | mysqld_install_cmd_line > /dev/null then s_echo "OK" else @@ -474,11 +481,11 @@ then echo "PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !" echo "To do so, start the server, then issue the following commands:" echo - echo "$bindir/mysqladmin -u root password 'new-password'" - echo "$bindir/mysqladmin -u root -h $hostname password 'new-password'" + echo "'$bindir/mysqladmin' -u root password 'new-password'" + echo "'$bindir/mysqladmin' -u root -h $hostname password 'new-password'" echo echo "Alternatively you can run:" - echo "$bindir/mysql_secure_installation" + echo "'$bindir/mysql_secure_installation'" echo echo "which will also give you the option of removing the test" echo "databases and anonymous user created by default. This is" @@ -491,14 +498,14 @@ then then echo echo "You can start the MariaDB daemon with:" - echo "cd $basedir ; $bindir/mysqld_safe --datadir=$ldata" + echo "cd '$basedir' ; $bindir/mysqld_safe --datadir='$ldata'" echo echo "You can test the MariaDB daemon with mysql-test-run.pl" - echo "cd $basedir/mysql-test ; perl mysql-test-run.pl" + echo "cd '$basedir/mysql-test' ; perl mysql-test-run.pl" fi echo - echo "Please report any problems with the $scriptdir/mysqlbug script!" + echo "Please report any problems with the '$scriptdir/mysqlbug' script!" echo echo "The latest information about MariaDB is available at http://mariadb.org/." echo "You can find additional information about the MySQL part at:" diff --git a/scripts/mysql_secure_installation.pl.in b/scripts/mysql_secure_installation.pl.in index ca39420952b..de549add904 100755 --- a/scripts/mysql_secure_installation.pl.in +++ b/scripts/mysql_secure_installation.pl.in @@ -1,7 +1,7 @@ #!/usr/bin/perl # -*- cperl -*- # -# Copyright (c) 2007, 2010, Oracle and/or its affiliates +# Copyright (c) 2007, 2012, Oracle and/or its affiliates # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,7 +28,7 @@ my $mysql; # How to call the mysql client my $rootpass = ""; -$SIG{QUIT} = $SIG{INT} = sub { +$SIG{QUIT} = $SIG{INT} = $SIG{TERM} = $SIG{ABRT} = $SIG{HUP} = sub { print "\nAborting!\n\n"; echo_on(); cleanup(); @@ -242,7 +242,11 @@ sub reload_privilege_tables { } sub cleanup { - unlink($config,$command); + print "Cleaning up...\n"; + + foreach my $file ($config, $command) { + unlink $file or warn "Warning: Could not unlink $file: $!\n"; + } } diff --git a/scripts/mysql_secure_installation.sh b/scripts/mysql_secure_installation.sh index 772a9d8b1d8..28c631a46d5 100644 --- a/scripts/mysql_secure_installation.sh +++ b/scripts/mysql_secure_installation.sh @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright (c) 2002, 2010, Oracle and/or its affiliates +# Copyright (c) 2002, 2012, Oracle and/or its affiliates # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -18,7 +18,7 @@ config=".my.cnf.$$" command=".mysql.$$" -trap "interrupt" 2 +trap "interrupt" 1 2 3 6 15 rootpass="" echo_n= @@ -286,13 +286,16 @@ set_root_password() { if [ $? -eq 0 ]; then echo "Password updated successfully!" echo "Reloading privilege tables.." - reload_privilege_tables || exit 1 + reload_privilege_tables + if [ $? -eq 1 ]; then + clean_and_exit + fi echo rootpass=$password1 make_config else echo "Password update failed!" - exit 1 + clean_and_exit fi return 0 @@ -304,7 +307,7 @@ remove_anonymous_users() { echo " ... Success!" else echo " ... Failed!" - exit 1 + clean_and_exit fi return 0 @@ -364,6 +367,11 @@ cleanup() { rm -f $config $command } +# Remove the files before exiting. +clean_and_exit() { + cleanup + exit 1 +} # The actual script starts here diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index 48aefbd8c49..1ef743725e5 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -272,23 +272,28 @@ if ( defined $opt{regexp} ) { } } -# --- get list of tables to hotcopy --- +# --- get list of tables and views to hotcopy --- my $hc_locks = ""; my $hc_tables = ""; +my $hc_base_tables = ""; +my $hc_views = ""; +my $num_base_tables = 0; +my $num_views = 0; my $num_tables = 0; my $num_files = 0; foreach my $rdb ( @db_desc ) { my $db = $rdb->{src}; - my @dbh_tables = get_list_of_tables( $db ); + my @dbh_base_tables = get_list_of_tables( $db ); + my @dbh_views = get_list_of_views( $db ); ## filter out certain system non-lockable tables. ## keep in sync with mysqldump. if ($db =~ m/^mysql$/i) { - @dbh_tables = grep - { !/^(apply_status|schema|general_log|slow_log)$/ } @dbh_tables + @dbh_base_tables = grep + { !/^(apply_status|schema|general_log|slow_log)$/ } @dbh_base_tables } ## generate regex for tables/files @@ -303,11 +308,20 @@ foreach my $rdb ( @db_desc ) { ## filter (out) tables specified in t_regex print "Filtering tables with '$t_regex'\n" if $opt{debug}; - @dbh_tables = ( $negated - ? grep { $_ !~ $t_regex } @dbh_tables - : grep { $_ =~ $t_regex } @dbh_tables ); + @dbh_base_tables = ( $negated + ? grep { $_ !~ $t_regex } @dbh_base_tables + : grep { $_ =~ $t_regex } @dbh_base_tables ); + + ## filter (out) views specified in t_regex + print "Filtering tables with '$t_regex'\n" if $opt{debug}; + @dbh_views = ( $negated + ? grep { $_ !~ $t_regex } @dbh_views + : grep { $_ =~ $t_regex } @dbh_views ); } + ## Now concatenate the base table and view arrays. + my @dbh_tables = (@dbh_base_tables, @dbh_views); + ## get list of files to copy my $db_dir = "$datadir/$db"; opendir(DBDIR, $db_dir ) @@ -347,15 +361,25 @@ foreach my $rdb ( @db_desc ) { $rdb->{files} = [ @db_files ]; $rdb->{index} = [ @index_files ]; - my @hc_tables = map { quote_names("$db.$_") } @dbh_tables; + my @hc_base_tables = map { quote_names("$db.$_") } @dbh_base_tables; + my @hc_views = map { quote_names("$db.$_") } @dbh_views; + + my @hc_tables = (@hc_base_tables, @hc_views); $rdb->{tables} = [ @hc_tables ]; $hc_locks .= ", " if ( length $hc_locks && @hc_tables ); $hc_locks .= join ", ", map { "$_ READ" } @hc_tables; - $hc_tables .= ", " if ( length $hc_tables && @hc_tables ); - $hc_tables .= join ", ", @hc_tables; - $num_tables += scalar @hc_tables; + $hc_base_tables .= ", " if ( length $hc_base_tables && @hc_base_tables ); + $hc_base_tables .= join ", ", @hc_base_tables; + $hc_views .= ", " if ( length $hc_views && @hc_views ); + $hc_views .= join " READ, ", @hc_views; + + @hc_tables = (@hc_base_tables, @hc_views); + + $num_base_tables += scalar @hc_base_tables; + $num_views += scalar @hc_views; + $num_tables += $num_base_tables + $num_views; $num_files += scalar @{$rdb->{files}}; } @@ -467,7 +491,10 @@ if ( $opt{dryrun} ) { print "FLUSH TABLES /*!32323 $hc_tables */\n"; } else { - print "FLUSH TABLES $hc_tables WITH READ LOCK\n"; + # Lock base tables and views separately. + print "FLUSH TABLES $hc_base_tables WITH READ LOCK\n" + if ( $hc_base_tables ); + print "LOCK TABLES $hc_views READ\n" if ( $hc_views ); } print "FLUSH LOGS\n" if ( $opt{flushlog} ); @@ -484,16 +511,24 @@ else { # flush tables to make on-disk copy up to date $start = time; $dbh->do("FLUSH TABLES /*!32323 $hc_tables */"); + printf "Flushed tables ($hc_tables) in %d seconds.\n", time-$start unless $opt{quiet}; } else { - $dbh->do("FLUSH TABLES $hc_tables WITH READ LOCK"); - printf "Locked $num_tables tables in %d seconds.\n", time-$start unless $opt{quiet}; - $hc_started = time; # count from time lock is granted + # Lock base tables and views separately, as 'FLUSH TABLES <tbl_name> + # ... WITH READ LOCK' (introduced in 5.5) would fail for views. + # Also, flush tables to make on-disk copy up to date + $dbh->do("FLUSH TABLES $hc_base_tables WITH READ LOCK") + if ( $hc_base_tables ); + printf "Flushed $num_base_tables tables with read lock ($hc_base_tables) in %d seconds.\n", + time-$start unless $opt{quiet}; - # flush tables to make on-disk copy up to date $start = time; + $dbh->do("LOCK TABLES $hc_views READ") if ( $hc_views ); + printf "Locked $num_views views ($hc_views) in %d seconds.\n", + time-$start unless $opt{quiet}; + + $hc_started = time; # count from time lock is granted } - printf "Flushed tables ($hc_tables) in %d seconds.\n", time-$start unless $opt{quiet}; $dbh->do( "FLUSH LOGS" ) if ( $opt{flushlog} ); $dbh->do( "RESET MASTER" ) if ( $opt{resetmaster} ); $dbh->do( "RESET SLAVE" ) if ( $opt{resetslave} ); @@ -802,14 +837,29 @@ sub get_list_of_tables { my $tables = eval { - $dbh->selectall_arrayref('SHOW TABLES FROM ' . - $dbh->quote_identifier($db)) + $dbh->selectall_arrayref('SHOW FULL TABLES FROM ' . + $dbh->quote_identifier($db) . + ' WHERE Table_type = \'BASE TABLE\'') } || []; warn "Unable to retrieve list of tables in $db: $@" if $@; return (map { $_->[0] } @$tables); } +sub get_list_of_views { + my ( $db ) = @_; + + my $views = + eval { + $dbh->selectall_arrayref('SHOW FULL TABLES FROM ' . + $dbh->quote_identifier($db) . + ' WHERE Table_type = \'VIEW\'') + } || []; + warn "Unable to retrieve list of views in $db: $@" if $@; + + return (map { $_->[0] } @$views); +} + sub quote_names { my ( $name ) = @_; # given a db.table name, add quotes diff --git a/sql/create_options.cc b/sql/create_options.cc index e4881388688..5cedfa03a63 100644 --- a/sql/create_options.cc +++ b/sql/create_options.cc @@ -137,11 +137,8 @@ static bool set_one_value(ha_create_table_option *opt, my_option optp= { opt->name, 1, 0, (uchar **)val, 0, 0, GET_ULL, - REQUIRED_ARG, - (longlong) opt->def_value, - (longlong) opt->min_value, - opt->max_value, - 0, (long) opt->block_size, 0}; + REQUIRED_ARG, (longlong)opt->def_value, (longlong)opt->min_value, + opt->max_value, 0, (long) opt->block_size, 0}; ulonglong orig_val= strtoull(value->str, NULL, 10); my_bool unused; diff --git a/sql/filesort.cc b/sql/filesort.cc index 103d3600559..ac67fb56395 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -1,5 +1,5 @@ -/* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2012, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 7b50b26c6ca..c37f4f145cf 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -85,6 +85,7 @@ So, we can read full search-structure as 32-bit word #include <stdio.h> #include <string.h> +#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ struct hash_lex_struct { @@ -376,25 +377,9 @@ int main(int argc,char **argv) /* Broken up to indicate that it's not advice to you, gentle reader. */ printf("/*\n\n Do " "not " "edit " "this " "file " "directly!\n\n*/\n"); - printf("\ -/* Copyright (C) 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.\n\ - Copyright (C) 2008-2011 Oracle\n\ -\n\ - This program is free software; you can redistribute it and/or modify\n\ - it under the terms of the GNU General Public License as published by\n\ - the Free Software Foundation; version 2 of the License.\n\ -\n\ - This program is distributed in the hope that it will be useful,\n\ - but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ - GNU General Public License for more details.\n\ -\n\ - You should have received a copy of the GNU General Public License\n\ - along with this program; see the file COPYING. If not, write to the\n\ - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston\n\ - MA 02110-1301 USA. */\n\ -\n\ -"); + puts("/*"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); + puts("*/"); /* Broken up to indicate that it's not advice to you, gentle reader. */ printf("/* Do " "not " "edit " "this " "file! This is generated by " diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 4bc2b2439b4..2804da8e7ae 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -324,8 +324,7 @@ ha_partition::~ha_partition() for (i= 0; i < m_tot_parts; i++) delete m_file[i]; } - my_free(m_ordered_rec_buffer); - m_ordered_rec_buffer= NULL; + destroy_record_priority_queue(); my_free(m_part_ids_sorted_by_num_of_records); clear_handler_file(); @@ -2826,7 +2825,6 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) { char *name_buffer_ptr; int error= HA_ERR_INITIALIZATION; - uint alloc_len; handler **file; char name_buff[FN_REFLEN]; bool is_not_tmp_table= (table_share->tmp_table == NO_TMP_TABLE); @@ -2844,32 +2842,6 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) m_start_key.length= 0; m_rec0= table->record[0]; m_rec_length= table_share->stored_rec_length; - alloc_len= m_tot_parts * (m_rec_length + PARTITION_BYTES_IN_POS); - alloc_len+= table_share->max_key_length; - if (!m_ordered_rec_buffer) - { - if (!(m_ordered_rec_buffer= (uchar*)my_malloc(alloc_len, MYF(MY_WME)))) - { - DBUG_RETURN(error); - } - { - /* - We set-up one record per partition and each record has 2 bytes in - front where the partition id is written. This is used by ordered - index_read. - We also set-up a reference to the first record for temporary use in - setting up the scan. - */ - char *ptr= (char*)m_ordered_rec_buffer; - uint i= 0; - do - { - int2store(ptr, i); - ptr+= m_rec_length + PARTITION_BYTES_IN_POS; - } while (++i < m_tot_parts); - m_start_key.key= (const uchar*)ptr; - } - } if (!m_part_ids_sorted_by_num_of_records) { if (!(m_part_ids_sorted_by_num_of_records= @@ -2899,7 +2871,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) if (m_is_clone_of) { - uint i; + uint i, alloc_len; DBUG_ASSERT(m_clone_mem_root); /* Allocate an array of handler pointers for the partitions handlers. */ alloc_len= (m_tot_parts + 1) * sizeof(handler*); @@ -2977,12 +2949,6 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) being opened once. */ clear_handler_file(); - /* - Initialize priority queue, initialized to reading forward. - */ - if ((error= init_queue(&m_queue, m_tot_parts, (uint) PARTITION_BYTES_IN_POS, - 0, key_rec_cmp, (void*)this, 0, 0))) - goto err_handler; /* Use table_share->ha_part_data to share auto_increment_value among @@ -3136,7 +3102,7 @@ int ha_partition::close(void) DBUG_ENTER("ha_partition::close"); DBUG_ASSERT(table->s == table_share); - delete_queue(&m_queue); + destroy_record_priority_queue(); bitmap_free(&m_bulk_insert_started); if (!m_is_clone_of) bitmap_free(&(m_part_info->used_partitions)); @@ -4436,6 +4402,78 @@ int ha_partition::rnd_pos_by_record(uchar *record) subset of the partitions are used, then only use those partitions. */ + +/** + Setup the ordered record buffer and the priority queue. +*/ + +bool ha_partition::init_record_priority_queue() +{ + DBUG_ENTER("ha_partition::init_record_priority_queue"); + DBUG_ASSERT(!m_ordered_rec_buffer); + /* + Initialize the ordered record buffer. + */ + if (!m_ordered_rec_buffer) + { + uint alloc_len; + uint used_parts= bitmap_bits_set(&m_part_info->used_partitions); + /* Allocate record buffer for each used partition. */ + alloc_len= used_parts * (m_rec_length + PARTITION_BYTES_IN_POS); + /* Allocate a key for temporary use when setting up the scan. */ + alloc_len+= table_share->max_key_length; + + if (!(m_ordered_rec_buffer= (uchar*)my_malloc(alloc_len, MYF(MY_WME)))) + DBUG_RETURN(true); + + /* + We set-up one record per partition and each record has 2 bytes in + front where the partition id is written. This is used by ordered + index_read. + We also set-up a reference to the first record for temporary use in + setting up the scan. + */ + char *ptr= (char*) m_ordered_rec_buffer; + uint16 i= 0; + do + { + if (bitmap_is_set(&m_part_info->used_partitions, i)) + { + int2store(ptr, i); + ptr+= m_rec_length + PARTITION_BYTES_IN_POS; + } + } while (++i < m_tot_parts); + m_start_key.key= (const uchar*)ptr; + /* Initialize priority queue, initialized to reading forward. */ + if (init_queue(&m_queue, used_parts, (uint) PARTITION_BYTES_IN_POS, + 0, key_rec_cmp, (void*)m_curr_key_info, 0, 0)) + { + my_free(m_ordered_rec_buffer); + m_ordered_rec_buffer= NULL; + DBUG_RETURN(true); + } + } + DBUG_RETURN(false); +} + + +/** + Destroy the ordered record buffer and the priority queue. +*/ + +void ha_partition::destroy_record_priority_queue() +{ + DBUG_ENTER("ha_partition::destroy_record_priority_queue"); + if (m_ordered_rec_buffer) + { + delete_queue(&m_queue); + my_free(m_ordered_rec_buffer); + m_ordered_rec_buffer= NULL; + } + DBUG_VOID_RETURN; +} + + /* Initialize handler before start of index scan @@ -4478,6 +4516,10 @@ int ha_partition::index_init(uint inx, bool sorted) } else m_curr_key_info[1]= NULL; + + if (init_record_priority_queue()) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + /* Some handlers only read fields as specified by the bitmap for the read set. For partitioned handlers we always require that the @@ -4552,11 +4594,11 @@ int ha_partition::index_end() do { int tmp; - /* TODO RONM: Change to index_end() when code is stable */ if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file))) if ((tmp= (*file)->ha_index_end())) error= tmp; } while (*(++file)); + destroy_record_priority_queue(); DBUG_RETURN(error); } @@ -5268,6 +5310,7 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) uint i; uint j= queue_first_element(&m_queue); bool found= FALSE; + uchar *part_rec_buf_ptr= m_ordered_rec_buffer; DBUG_ENTER("ha_partition::handle_ordered_index_scan"); m_top_entry= NO_CURRENT_PART_ID; @@ -5278,7 +5321,7 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) { if (!(bitmap_is_set(&(m_part_info->used_partitions), i))) continue; - uchar *rec_buf_ptr= rec_buf(i); + uchar *rec_buf_ptr= part_rec_buf_ptr + PARTITION_BYTES_IN_POS; int error; handler *file= m_file[i]; @@ -5325,12 +5368,13 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) /* Initialize queue without order first, simply insert */ - queue_element(&m_queue, j++)= (uchar*)queue_buf(i); + queue_element(&m_queue, j++)= part_rec_buf_ptr; } else if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) { DBUG_RETURN(error); } + part_rec_buf_ptr+= m_rec_length + PARTITION_BYTES_IN_POS; } if (found) { @@ -5393,18 +5437,19 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same) { int error; uint part_id= m_top_entry; + uchar *rec_buf= queue_top(&m_queue) + PARTITION_BYTES_IN_POS; handler *file= m_file[part_id]; DBUG_ENTER("ha_partition::handle_ordered_next"); if (m_index_scan_type == partition_read_range) { error= file->read_range_next(); - memcpy(rec_buf(part_id), table->record[0], m_rec_length); + memcpy(rec_buf, table->record[0], m_rec_length); } else if (!is_next_same) - error= file->ha_index_next(rec_buf(part_id)); + error= file->ha_index_next(rec_buf); else - error= file->ha_index_next_same(rec_buf(part_id), m_start_key.key, + error= file->ha_index_next_same(rec_buf, m_start_key.key, m_start_key.length); if (error) { @@ -5447,10 +5492,11 @@ int ha_partition::handle_ordered_prev(uchar *buf) { int error; uint part_id= m_top_entry; + uchar *rec_buf= queue_top(&m_queue) + PARTITION_BYTES_IN_POS; handler *file= m_file[part_id]; DBUG_ENTER("ha_partition::handle_ordered_prev"); - if ((error= file->ha_index_prev(rec_buf(part_id)))) + if ((error= file->ha_index_prev(rec_buf))) { if (error == HA_ERR_END_OF_FILE) { @@ -7570,23 +7616,6 @@ int ha_partition::indexes_are_disabled(void) struct st_mysql_storage_engine partition_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; -mysql_declare_plugin(partition) -{ - MYSQL_STORAGE_ENGINE_PLUGIN, - &partition_storage_engine, - "partition", - "Mikael Ronstrom, MySQL AB", - "Partition Storage Engine Helper", - PLUGIN_LICENSE_GPL, - partition_initialize, /* Plugin Init */ - NULL, /* Plugin Deinit */ - 0x0100, /* 1.0 */ - NULL, /* status variables */ - NULL, /* system variables */ - NULL, /* config options */ - 0, /* flags */ -} -mysql_declare_plugin_end; maria_declare_plugin(partition) { MYSQL_STORAGE_ENGINE_PLUGIN, diff --git a/sql/ha_partition.h b/sql/ha_partition.h index ee2bd0e39b9..3a0a35fdfc0 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -510,21 +510,13 @@ public: virtual int read_range_next(); private: + bool init_record_priority_queue(); + void destroy_record_priority_queue(); int common_index_read(uchar * buf, bool have_start_key); int common_first_last(uchar * buf); int partition_scan_set_up(uchar * buf, bool idx_read_flag); int handle_unordered_next(uchar * buf, bool next_same); int handle_unordered_scan_next_partition(uchar * buf); - uchar *queue_buf(uint part_id) - { - return (m_ordered_rec_buffer + - (part_id * (m_rec_length + PARTITION_BYTES_IN_POS))); - } - uchar *rec_buf(uint part_id) - { - return (queue_buf(part_id) + - PARTITION_BYTES_IN_POS); - } int handle_ordered_index_scan(uchar * buf, bool reverse_order); int handle_ordered_next(uchar * buf, bool next_same); int handle_ordered_prev(uchar * buf); diff --git a/sql/handler.cc b/sql/handler.cc index 8041e457d03..ed671a921bb 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4811,7 +4811,20 @@ int handler::read_range_first(const key_range *start_key, DBUG_RETURN((result == HA_ERR_KEY_NOT_FOUND) ? HA_ERR_END_OF_FILE : result); - DBUG_RETURN (compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE); + + if (compare_key(end_range) <= 0) + { + DBUG_RETURN(0); + } + else + { + /* + The last read row does not fall in the range. So request + storage engine to release row lock if possible. + */ + unlock_row(); + DBUG_RETURN(HA_ERR_END_OF_FILE); + } } @@ -4843,7 +4856,20 @@ int handler::read_range_next() result= ha_index_next(table->record[0]); if (result) DBUG_RETURN(result); - DBUG_RETURN(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE); + + if (compare_key(end_range) <= 0) + { + DBUG_RETURN(0); + } + else + { + /* + The last read row does not fall in the range. So request + storage engine to release row lock if possible. + */ + unlock_row(); + DBUG_RETURN(HA_ERR_END_OF_FILE); + } } diff --git a/sql/item.cc b/sql/item.cc index 13a4524f131..216ef628271 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -6837,7 +6837,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) if (from_field != not_found_field) { Item_field* fld; - if (!(fld= new Item_field(thd, last_checked_context, from_field))) + if (!(fld= new Item_field(from_field))) goto error; thd->change_item_tree(reference, fld); mark_as_dependent(thd, last_checked_context->select_lex, @@ -9607,7 +9607,7 @@ table_map Item_direct_view_ref::used_tables() const { return get_depended_from() ? OUTER_REF_TABLE_BIT : - ((view->merged || !view->table) ? + ((view->is_merged_derived() || view->merged || !view->table) ? (*ref)->used_tables() : view->table->map); } @@ -9616,7 +9616,7 @@ table_map Item_direct_view_ref::not_null_tables() const { return get_depended_from() ? 0 : - ((view->merged || !view->table) ? + ((view->is_merged_derived() || view->merged || !view->table) ? (*ref)->not_null_tables() : view->table->map); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 4c0c81aa8c6..c2a7edb735a 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3300,23 +3300,21 @@ err: String* Item_func_export_set::val_str(String* str) { DBUG_ASSERT(fixed == 1); - ulonglong the_set = (ulonglong) args[0]->val_int(); - String yes_buf, *yes; - yes = args[1]->val_str(&yes_buf); - String no_buf, *no; - no = args[2]->val_str(&no_buf); - String *sep = NULL, sep_buf ; + String yes_buf, no_buf, sep_buf; + const ulonglong the_set = (ulonglong) args[0]->val_int(); + const String *yes= args[1]->val_str(&yes_buf); + const String *no= args[2]->val_str(&no_buf); + const String *sep= NULL; uint num_set_values = 64; - ulonglong mask = 0x1; str->length(0); str->set_charset(collation.collation); /* Check if some argument is a NULL value */ if (args[0]->null_value || args[1]->null_value || args[2]->null_value) { - null_value=1; - return 0; + null_value= true; + return NULL; } /* Arg count can only be 3, 4 or 5 here. This is guaranteed from the @@ -3329,37 +3327,56 @@ String* Item_func_export_set::val_str(String* str) num_set_values=64; if (args[4]->null_value) { - null_value=1; - return 0; + null_value= true; + return NULL; } /* Fall through */ case 4: if (!(sep = args[3]->val_str(&sep_buf))) // Only true if NULL { - null_value=1; - return 0; + null_value= true; + return NULL; } break; case 3: { /* errors is not checked - assume "," can always be converted */ uint errors; - sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin, collation.collation, &errors); + sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin, + collation.collation, &errors); sep = &sep_buf; } break; default: DBUG_ASSERT(0); // cannot happen } - null_value=0; + null_value= false; + + const ulong max_allowed_packet= current_thd->variables.max_allowed_packet; + const uint num_separators= num_set_values > 0 ? num_set_values - 1 : 0; + const ulonglong max_total_length= + num_set_values * max(yes->length(), no->length()) + + num_separators * sep->length(); + + if (unlikely(max_total_length > max_allowed_packet)) + { + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_ALLOWED_PACKET_OVERFLOWED, + ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), + func_name(), max_allowed_packet); + null_value= true; + return NULL; + } - for (uint i = 0; i < num_set_values; i++, mask = (mask << 1)) + uint ix; + ulonglong mask; + for (ix= 0, mask=0x1; ix < num_set_values; ++ix, mask = (mask << 1)) { if (the_set & mask) str->append(*yes); else str->append(*no); - if (i != num_set_values - 1) + if (ix != num_separators) str->append(*sep); } return str; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 83c7e3e1529..ab77bb0e59c 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -49,7 +49,7 @@ Item_subselect::Item_subselect(): used_tables_cache(0), have_to_be_excluded(0), const_item_cache(1), inside_first_fix_fields(0), done_first_fix_fields(FALSE), expr_cache(0), forced_const(FALSE), substitution(0), engine(0), eliminated(FALSE), - engine_changed(0), changed(0), is_correlated(FALSE) + changed(0), is_correlated(FALSE) { DBUG_ENTER("Item_subselect::Item_subselect"); DBUG_PRINT("enter", ("this: 0x%lx", (ulong) this)); @@ -623,6 +623,8 @@ bool Item_subselect::walk(Item_processor processor, bool walk_subquery, bool Item_subselect::exec() { + subselect_engine *org_engine= engine; + DBUG_ENTER("Item_subselect::exec"); /* @@ -644,11 +646,14 @@ bool Item_subselect::exec() #ifndef DBUG_OFF ++exec_counter; #endif - if (engine_changed) + if (engine != org_engine) { - engine_changed= 0; - res= exec(); - DBUG_RETURN(res); + /* + If the subquery engine changed during execution due to lazy subquery + optimization, or because the original engine found a more efficient other + engine, re-execute the subquery with the new engine. + */ + DBUG_RETURN(exec()); } DBUG_RETURN(res); } @@ -1063,11 +1068,9 @@ Item_singlerow_subselect::select_transformer(JOIN *join) } substitution= select_lex->item_list.head(); /* - as far as we moved content to upper level, field which depend of - 'upper' select is not really dependent => we remove this dependence + as far as we moved content to upper level we have to fix dependences & Co */ - substitution->walk(&Item::remove_dependence_processor, 0, - (uchar *) select_lex->outer_select()); + substitution->fix_after_pullout(select_lex->outer_select(), &substitution); } DBUG_RETURN(false); } @@ -2003,7 +2006,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN * join, } else { - Item *item= (Item*) select_lex->item_list.head(); + Item *item= (Item*) select_lex->item_list.head()->real_item(); if (select_lex->table_list.elements) { @@ -3143,10 +3146,8 @@ int subselect_single_select_engine::exec() DBUG_RETURN(1); /* purecov: inspected */ } } - if (item->engine_changed) - { + if (item->engine_changed(this)) DBUG_RETURN(1); - } } if (select_lex->uncacheable && select_lex->uncacheable != UNCACHEABLE_EXPLAIN diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 2a64c63a1be..1da129380e7 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -122,8 +122,6 @@ public: */ bool eliminated; - /* changed engine indicator */ - bool engine_changed; /* subquery is transformed */ bool changed; @@ -200,9 +198,9 @@ public: { old_engine= engine; engine= eng; - engine_changed= 1; return eng == 0; } + bool engine_changed(subselect_engine *eng) { return engine != eng; } /* True if this subquery has been already evaluated. Implemented only for single select and union subqueries only. @@ -260,7 +258,6 @@ public: st_select_lex*, st_select_lex*, Field*, Item*, Item_ident*); friend bool convert_join_subqueries_to_semijoins(JOIN *join); - }; /* single value subselect */ diff --git a/sql/log.cc b/sql/log.cc index 5c21fa21f97..69ff68d335f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -305,7 +305,7 @@ public: before_stmt_pos= MY_OFF_T_UNDEF; } - void set_binlog_cache_info(ulong param_max_binlog_cache_size, + void set_binlog_cache_info(my_off_t param_max_binlog_cache_size, ulong *param_ptr_binlog_cache_use, ulong *param_ptr_binlog_cache_disk_use) { @@ -382,7 +382,7 @@ private: is configured. This corresponds to either . max_binlog_cache_size or max_binlog_stmt_cache_size. */ - ulong saved_max_binlog_cache_size; + my_off_t saved_max_binlog_cache_size; /* Stores a pointer to the status variable that keeps track of the in-memory @@ -420,8 +420,8 @@ private: class binlog_cache_mngr { public: - binlog_cache_mngr(ulong param_max_binlog_stmt_cache_size, - ulong param_max_binlog_cache_size, + binlog_cache_mngr(my_off_t param_max_binlog_stmt_cache_size, + my_off_t param_max_binlog_cache_size, ulong *param_ptr_binlog_stmt_cache_use, ulong *param_ptr_binlog_stmt_cache_disk_use, ulong *param_ptr_binlog_cache_use, diff --git a/sql/mdl.cc b/sql/mdl.cc index 0e30e44c19a..ce37f10128b 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -395,7 +395,8 @@ public: bool has_pending_conflicting_lock(enum_mdl_type type); - bool can_grant_lock(enum_mdl_type type, MDL_context *requstor_ctx) const; + bool can_grant_lock(enum_mdl_type type, MDL_context *requstor_ctx, + bool ignore_lock_priority) const; inline static MDL_lock *create(const MDL_key *key); @@ -409,14 +410,24 @@ public: virtual bool needs_notification(const MDL_ticket *ticket) const = 0; virtual void notify_conflicting_locks(MDL_context *ctx) = 0; + virtual bitmap_t hog_lock_types_bitmap() const = 0; + /** List of granted tickets for this lock. */ Ticket_list m_granted; /** Tickets for contexts waiting to acquire a lock. */ Ticket_list m_waiting; + + /** + Number of times high priority lock requests have been granted while + low priority lock requests were waiting. + */ + ulong m_hog_lock_count; + public: MDL_lock(const MDL_key *key_arg) : key(key_arg), + m_hog_lock_count(0), m_ref_usage(0), m_ref_release(0), m_is_destroyed(FALSE), @@ -501,6 +512,15 @@ public: } virtual void notify_conflicting_locks(MDL_context *ctx); + /* + In scoped locks, only IX lock request would starve because of X/S. But that + is practically very rare case. So just return 0 from this function. + */ + virtual bitmap_t hog_lock_types_bitmap() const + { + return 0; + } + private: static const bitmap_t m_granted_incompatible[MDL_TYPE_END]; static const bitmap_t m_waiting_incompatible[MDL_TYPE_END]; @@ -553,6 +573,18 @@ public: } virtual void notify_conflicting_locks(MDL_context *ctx); + /* + To prevent starvation, these lock types that are only granted + max_write_lock_count times in a row while other lock types are + waiting. + */ + virtual bitmap_t hog_lock_types_bitmap() const + { + return (MDL_BIT(MDL_SHARED_NO_WRITE) | + MDL_BIT(MDL_SHARED_NO_READ_WRITE) | + MDL_BIT(MDL_EXCLUSIVE)); + } + private: static const bitmap_t m_granted_incompatible[MDL_TYPE_END]; static const bitmap_t m_waiting_incompatible[MDL_TYPE_END]; @@ -1285,6 +1317,41 @@ void MDL_lock::reschedule_waiters() { MDL_lock::Ticket_iterator it(m_waiting); MDL_ticket *ticket; + bool skip_high_priority= false; + bitmap_t hog_lock_types= hog_lock_types_bitmap(); + + if (m_hog_lock_count >= max_write_lock_count) + { + /* + If number of successively granted high-prio, strong locks has exceeded + max_write_lock_count give a way to low-prio, weak locks to avoid their + starvation. + */ + + if ((m_waiting.bitmap() & ~hog_lock_types) != 0) + { + /* + Even though normally when m_hog_lock_count is non-0 there is + some pending low-prio lock, we still can encounter situation + when m_hog_lock_count is non-0 and there are no pending low-prio + locks. This, for example, can happen when a ticket for pending + low-prio lock was removed from waiters list due to timeout, + and reschedule_waiters() is called after that to update the + waiters queue. m_hog_lock_count will be reset to 0 at the + end of this call in such case. + + Note that it is not an issue if we fail to wake up any pending + waiters for weak locks in the loop below. This would mean that + all of them are either killed, timed out or chosen as a victim + by deadlock resolver, but have not managed to remove ticket + from the waiters list yet. After tickets will be removed from + the waiters queue there will be another call to + reschedule_waiters() with pending bitmap updated to reflect new + state of waiters queue. + */ + skip_high_priority= true; + } + } /* Find the first (and hence the oldest) waiting request which @@ -1306,7 +1373,16 @@ void MDL_lock::reschedule_waiters() */ while ((ticket= it++)) { - if (can_grant_lock(ticket->get_type(), ticket->get_ctx())) + /* + Skip high-prio, strong locks if earlier we have decided to give way to + low-prio, weaker locks. + */ + if (skip_high_priority && + ((MDL_BIT(ticket->get_type()) & hog_lock_types) != 0)) + continue; + + if (can_grant_lock(ticket->get_type(), ticket->get_ctx(), + skip_high_priority)) { if (! ticket->get_ctx()->m_wait.set_status(MDL_wait::GRANTED)) { @@ -1320,6 +1396,13 @@ void MDL_lock::reschedule_waiters() */ m_waiting.remove_ticket(ticket); m_granted.add_ticket(ticket); + + /* + Increase counter of successively granted high-priority strong locks, + if we have granted one. + */ + if ((MDL_BIT(ticket->get_type()) & hog_lock_types) != 0) + m_hog_lock_count++; } /* If we could not update the wait slot of the waiter, @@ -1331,6 +1414,24 @@ void MDL_lock::reschedule_waiters() */ } } + + if ((m_waiting.bitmap() & ~hog_lock_types) == 0) + { + /* + Reset number of successively granted high-prio, strong locks + if there are no pending low-prio, weak locks. + This ensures: + - That m_hog_lock_count is correctly reset after strong lock + is released and weak locks are granted (or there are no + other lock requests). + - That situation when SNW lock is granted along with some SR + locks, but SW locks are still blocked are handled correctly. + - That m_hog_lock_count is zero in most cases when there are no pending + weak locks (see comment at the start of this method for example of + exception). This allows to save on checks at the start of this method. + */ + m_hog_lock_count= 0; + } } @@ -1485,8 +1586,9 @@ MDL_object_lock::m_waiting_incompatible[MDL_TYPE_END] = Check if request for the metadata lock can be satisfied given its current state. - @param type_arg The requested lock type. - @param requestor_ctx The MDL context of the requestor. + @param type_arg The requested lock type. + @param requestor_ctx The MDL context of the requestor. + @param ignore_lock_priority Ignore lock priority. @retval TRUE Lock request can be satisfied @retval FALSE There is some conflicting lock. @@ -1498,19 +1600,21 @@ MDL_object_lock::m_waiting_incompatible[MDL_TYPE_END] = bool MDL_lock::can_grant_lock(enum_mdl_type type_arg, - MDL_context *requestor_ctx) const + MDL_context *requestor_ctx, + bool ignore_lock_priority) const { bool can_grant= FALSE; bitmap_t waiting_incompat_map= incompatible_waiting_types_bitmap()[type_arg]; bitmap_t granted_incompat_map= incompatible_granted_types_bitmap()[type_arg]; + /* New lock request can be satisfied iff: - There are no incompatible types of satisfied requests in other contexts - There are no waiting requests which have higher priority - than this request. + than this request when priority was not ignored. */ - if (! (m_waiting.bitmap() & waiting_incompat_map)) + if (ignore_lock_priority || !(m_waiting.bitmap() & waiting_incompat_map)) { if (! (m_granted.bitmap() & granted_incompat_map)) can_grant= TRUE; @@ -1806,7 +1910,7 @@ MDL_context::try_acquire_lock_impl(MDL_request *mdl_request, ticket->m_lock= lock; - if (lock->can_grant_lock(mdl_request->type, this)) + if (lock->can_grant_lock(mdl_request->type, this, false)) { lock->m_granted.add_ticket(ticket); diff --git a/sql/mdl.h b/sql/mdl.h index f816d160f7b..477f4df7807 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -876,4 +876,10 @@ extern mysql_mutex_t LOCK_open; extern ulong mdl_locks_cache_size; static const ulong MDL_LOCKS_CACHE_SIZE_DEFAULT = 1024; +/* + Metadata locking subsystem tries not to grant more than + max_write_lock_count high-prio, strong locks successively, + to avoid starving out weak, low-prio locks. +*/ +extern "C" ulong max_write_lock_count; #endif diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 28eb0b7d756..d02d9194f3f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -278,6 +278,8 @@ extern "C" sig_handler handle_fatal_signal(int sig); /* Constants */ +#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE + const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"}; static const char *tc_heuristic_recover_names[]= @@ -624,6 +626,21 @@ I_List<THD> threads; Rpl_filter* rpl_filter; Rpl_filter* binlog_filter; +THD *first_global_thread() +{ + if (threads.is_empty()) + return NULL; + return threads.head(); +} + +THD *next_global_thread(THD *thd) +{ + if (threads.is_last(thd)) + return NULL; + struct ilink *next= thd->next; + return static_cast<THD*>(next); +} + struct system_variables global_system_variables; struct system_variables max_system_variables; struct system_status_var global_status_var; @@ -1809,6 +1826,7 @@ void clean_up(bool print_message) my_tz_free(); my_dboptions_cache_free(); + ignore_db_dirs_free(); #ifndef NO_EMBEDDED_ACCESS_CHECKS servers_free(1); acl_free(1); @@ -3519,6 +3537,9 @@ static int init_common_variables() mysql_init_variables()) return 1; + if (ignore_db_dirs_init()) + return 1; + #ifdef HAVE_TZNAME struct tm tm_tmp; localtime_r(&server_start_time,&tm_tmp); @@ -3952,6 +3973,12 @@ You should consider changing lower_case_table_names to 1 or 2", files_charset_info : &my_charset_bin); + if (ignore_db_dirs_process_additions()) + { + sql_print_error("An error occurred while storing ignore_db_dirs to a hash."); + return 1; + } + return 0; } @@ -6420,7 +6447,7 @@ struct my_option my_long_options[]= #ifdef HAVE_MMAP {"log-tc-size", 0, "Size of transaction coordinator log.", &opt_tc_log_size, &opt_tc_log_size, 0, GET_ULONG, - REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, (longlong) ULONG_MAX, 0, + REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, (ulonglong) ULONG_MAX, 0, TC_LOG_PAGE_SIZE, 0}, #endif {"master-info-file", 0, @@ -7157,6 +7184,7 @@ SHOW_VAR status_vars[]= { {"Aborted_clients", (char*) &aborted_threads, SHOW_LONG}, {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG}, {"Access_denied_errors", (char*) offsetof(STATUS_VAR, access_denied_errors), SHOW_LONG_STATUS}, + {"Binlog_bytes_written", (char*) offsetof(STATUS_VAR, binlog_bytes_written), SHOW_LONGLONG_STATUS}, {"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG}, {"Binlog_cache_use", (char*) &binlog_cache_use, SHOW_LONG}, {"Binlog_stmt_cache_disk_use",(char*) &binlog_stmt_cache_disk_use, SHOW_LONG}, @@ -7164,7 +7192,6 @@ SHOW_VAR status_vars[]= { {"Busy_time", (char*) offsetof(STATUS_VAR, busy_time), SHOW_DOUBLE_STATUS}, {"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS}, {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS}, - {"Binlog_bytes_written", (char*) offsetof(STATUS_VAR, binlog_bytes_written), SHOW_LONGLONG_STATUS}, {"Com", (char*) com_status_vars, SHOW_ARRAY}, {"Compression", (char*) &show_net_compression, SHOW_SIMPLE_FUNC}, {"Connections", (char*) &thread_id, SHOW_LONG_NOFLUSH}, @@ -7193,11 +7220,9 @@ SHOW_VAR status_vars[]= { {"Handler_external_lock", (char*) offsetof(STATUS_VAR, ha_external_lock_count), SHOW_LONGLONG_STATUS}, {"Handler_icp_attempts", (char*) offsetof(STATUS_VAR, ha_icp_attempts), SHOW_LONG_STATUS}, {"Handler_icp_match", (char*) offsetof(STATUS_VAR, ha_icp_match), SHOW_LONG_STATUS}, - {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_mrr_init_count), SHOW_LONG_STATUS}, {"Handler_mrr_key_refills", (char*) offsetof(STATUS_VAR, ha_mrr_key_refills_count), SHOW_LONG_STATUS}, {"Handler_mrr_rowid_refills", (char*) offsetof(STATUS_VAR, ha_mrr_rowid_refills_count), SHOW_LONG_STATUS}, - {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS}, {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS}, {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS}, @@ -7227,8 +7252,8 @@ SHOW_VAR status_vars[]= { {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS}, {"Opened_views", (char*) offsetof(STATUS_VAR, opened_views), SHOW_LONG_STATUS}, {"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_SIMPLE_FUNC}, - {"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS}, {"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS}, + {"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS}, {"Rows_tmp_read", (char*) offsetof(STATUS_VAR, rows_tmp_read), SHOW_LONGLONG_STATUS}, #ifdef HAVE_QUERY_CACHE {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH}, @@ -7252,9 +7277,9 @@ SHOW_VAR status_vars[]= { {"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count_), SHOW_LONG_STATUS}, {"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG}, #ifdef HAVE_REPLICATION - {"Slave_retried_transactions",(char*)&slave_retried_transactions, SHOW_LONG}, {"Slave_heartbeat_period", (char*) &show_heartbeat_period, SHOW_SIMPLE_FUNC}, {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats, SHOW_SIMPLE_FUNC}, + {"Slave_retried_transactions",(char*)&slave_retried_transactions, SHOW_LONG}, {"Slave_running", (char*) &show_slave_running, SHOW_SIMPLE_FUNC}, #endif {"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG}, @@ -7389,14 +7414,8 @@ static void usage(void) if (!default_collation_name) default_collation_name= (char*) default_charset_info->name; print_version(); - puts("\ -Copyright (C) 2000-2008 MySQL AB, by Monty and others.\n\ -Copyright (C) 2000, 2011 Oracle.\n\ -Copyright (C) 2009-2011 Monty Program Ab.\n\ -This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license\n\n\ -Starts the MariaDB database server.\n"); - + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); + puts("Starts the MariaDB database server.\n"); printf("Usage: %s [OPTIONS]\n", my_progname); if (!opt_verbose) puts("\nFor more help options (several pages), use mysqld --verbose --help."); @@ -7956,6 +7975,20 @@ mysqld_get_one_option(int optid, if (argument == NULL) /* no argument */ log_error_file_ptr= const_cast<char*>(""); break; + case OPT_IGNORE_DB_DIRECTORY: + if (*argument == 0) + ignore_db_dirs_reset(); + else + { + if (push_ignored_db_dir(argument)) + { + sql_print_error("Can't start server: " + "cannot process --ignore-db-dir=%.*s", + FN_REFLEN, argument); + return 1; + } + } + break; case OPT_MAX_LONG_DATA_SIZE: max_long_data_size_used= true; break; @@ -8024,7 +8057,6 @@ mysqld_get_one_option(int optid, "'%s'", argument); return 0; } - #endif break; } diff --git a/sql/mysqld.h b/sql/mysqld.h index 67fa44fe7d9..eaf22954cc4 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -497,20 +497,25 @@ enum options_mysqld OPT_BINLOG_FORMAT, OPT_BINLOG_IGNORE_DB, OPT_BIN_LOG, - OPT_LOG_BASENAME, OPT_BOOTSTRAP, OPT_CONSOLE, OPT_DEBUG_SYNC_TIMEOUT, OPT_DELAY_KEY_WRITE_ALL, OPT_DEPRECATED_OPTION, + OPT_ENGINE_CONDITION_PUSHDOWN, + OPT_IGNORE_DB_DIRECTORY, OPT_ISAM_LOG, OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_AGE_THRESHOLD, OPT_KEY_CACHE_BLOCK_SIZE, OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_PARTITIONS, + OPT_LOG_BASENAME, + OPT_LOG_ERROR, OPT_LOWER_CASE_TABLE_NAMES, + OPT_MAX_LONG_DATA_SIZE, OPT_ONE_THREAD, + OPT_PFS_INSTRUMENT, OPT_POOL_OF_THREADS, OPT_REPLICATE_DO_DB, OPT_REPLICATE_DO_TABLE, @@ -532,15 +537,12 @@ enum options_mysqld OPT_SSL_CAPATH, OPT_SSL_CERT, OPT_SSL_CIPHER, + OPT_SSL_CRL, + OPT_SSL_CRLPATH, OPT_SSL_KEY, OPT_UPDATE_LOG, OPT_WANT_CORE, - OPT_ENGINE_CONDITION_PUSHDOWN, - OPT_LOG_ERROR, - OPT_MAX_LONG_DATA_SIZE, - OPT_SSL_CRL, - OPT_SSL_CRLPATH, - OPT_PFS_INSTRUMENT + OPT_which_is_always_the_last }; #endif diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 994b3f75989..5cf3a29a4b7 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3853,27 +3853,28 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree) ppar->cur_subpart_fields+= ppar->is_subpart_keypart[key_tree_part]; *(ppar->arg_stack_end++)= key_tree; + if (ignore_part_fields) + { + /* + We come here when a condition on the first partitioning + fields led to evaluating the partitioning condition + (due to finding a condition of the type a < const or + b > const). Thus we must ignore the rest of the + partitioning fields but we still want to analyse the + subpartitioning fields. + */ + if (key_tree->next_key_part) + res= find_used_partitions(ppar, key_tree->next_key_part); + else + res= -1; + goto pop_and_go_right; + } + if (key_tree->type == SEL_ARG::KEY_RANGE) { if (ppar->part_info->get_part_iter_for_interval && key_tree->part <= ppar->last_part_partno) { - if (ignore_part_fields) - { - /* - We come here when a condition on the first partitioning - fields led to evaluating the partitioning condition - (due to finding a condition of the type a < const or - b > const). Thus we must ignore the rest of the - partitioning fields but we still want to analyse the - subpartitioning fields. - */ - if (key_tree->next_key_part) - res= find_used_partitions(ppar, key_tree->next_key_part); - else - res= -1; - goto pop_and_go_right; - } /* Collect left and right bound, their lengths and flags */ uchar *min_key= ppar->cur_min_key; uchar *max_key= ppar->cur_max_key; @@ -4114,6 +4115,13 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree) res= -1; goto pop_and_go_right; } + /* + No meaning in continuing with rest of partitioning key parts. + Will try to continue with subpartitioning key parts. + */ + ppar->ignore_part_fields= true; + did_set_ignore_part_fields= true; + goto process_next_key_part; } } diff --git a/sql/scheduler.cc b/sql/scheduler.cc index 78a1a2a32bb..0ae4121ef4c 100644 --- a/sql/scheduler.cc +++ b/sql/scheduler.cc @@ -79,11 +79,34 @@ void scheduler_init() { scheduler_wait_sync_end); } + +/** + Kill notification callback, used by one-thread-per-connection + and threadpool scheduler. + + Wakes up a thread that is stuck in read/poll/epoll/event-poll + routines used by threadpool, such that subsequent attempt to + read from client connection will result in IO error. +*/ + +void post_kill_notification(THD *thd) +{ + DBUG_ENTER("post_kill_notification"); + if (current_thd == thd || thd->system_thread) + DBUG_VOID_RETURN; + + if (thd->net.vio) + vio_shutdown(thd->net.vio, SHUT_RD); + DBUG_VOID_RETURN; +} + /* Initialize scheduler for --thread-handling=one-thread-per-connection */ #ifndef EMBEDDED_LIBRARY + + void one_thread_per_connection_scheduler(scheduler_functions *func, ulong *arg_max_connections, uint *arg_connection_count) @@ -95,6 +118,7 @@ void one_thread_per_connection_scheduler(scheduler_functions *func, func->init_new_connection_thread= init_new_connection_handler_thread; func->add_connection= create_thread_to_handle_connection; func->end_thread= one_thread_per_connection_end; + func->post_kill_notification= post_kill_notification; } #endif diff --git a/sql/scheduler.h b/sql/scheduler.h index 82bba5abe65..4e200e86d74 100644 --- a/sql/scheduler.h +++ b/sql/scheduler.h @@ -78,7 +78,7 @@ void one_thread_per_connection_scheduler(scheduler_functions *func, void one_thread_scheduler(scheduler_functions *func); extern void scheduler_init(); - +extern void post_kill_notification(THD *); /* To be used for pool-of-threads (implemeneted differently on various OSs) */ diff --git a/sql/set_var.cc b/sql/set_var.cc index 1276dd28e22..bf18ca49b37 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -130,9 +130,9 @@ void sys_var_end() put your additional checks here @param on_update_func a function to be called at the end of sys_var::update, any post-update activity should happen here - @param deprecated_version if not 0 - when this variable will go away - @param substitute if not 0 - what one should use instead when this - deprecated variable + @param substitute If non-NULL, this variable is deprecated and the + string describes what one should use instead. If an empty string, + the variable is deprecated but no replacement is offered. */ sys_var::sys_var(sys_var_chain *chain, const char *name_arg, const char *comment, int flags_arg, ptrdiff_t off, @@ -141,11 +141,12 @@ sys_var::sys_var(sys_var_chain *chain, const char *name_arg, PolyLock *lock, enum binlog_status_enum binlog_status_arg, on_check_function on_check_func, on_update_function on_update_func, - uint deprecated_version, const char *substitute) : + const char *substitute) : next(0), binlog_status(binlog_status_arg), flags(flags_arg), show_val_type(show_val_type_arg), guard(lock), offset(off), on_check(on_check_func), on_update(on_update_func), + deprecation_substitute(substitute), is_os_charset(FALSE) { /* @@ -171,12 +172,6 @@ sys_var::sys_var(sys_var_chain *chain, const char *name_arg, option.value= (uchar **)global_var_ptr(); option.def_value= def_val; - deprecated.version= deprecated_version; - deprecated.substitute= substitute; - DBUG_ASSERT((deprecated_version != 0) || (substitute == 0)); - DBUG_ASSERT(deprecated_version % 100 == 0); - DBUG_ASSERT(!deprecated_version || MYSQL_VERSION_ID < deprecated_version); - if (chain->last) chain->last->next= this; else @@ -271,21 +266,24 @@ bool sys_var::set_default(THD *thd, enum_var_type type) void sys_var::do_deprecated_warning(THD *thd) { - if (deprecated.version) + if (deprecation_substitute != NULL) { - char buf1[NAME_CHAR_LEN + 3], buf2[10]; + char buf1[NAME_CHAR_LEN + 3]; strxnmov(buf1, sizeof(buf1)-1, "@@", name.str, 0); - my_snprintf(buf2, sizeof(buf2), "%d.%d", deprecated.version/100/100, - deprecated.version/100%100); - uint errmsg= deprecated.substitute - ? ER_WARN_DEPRECATED_SYNTAX_WITH_VER - : ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT; + + /* + if deprecation_substitute is an empty string, + there is no replacement for the syntax + */ + uint errmsg= deprecation_substitute[0] == '\0' + ? ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT + : ER_WARN_DEPRECATED_SYNTAX; if (thd) push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DEPRECATED_SYNTAX, ER(errmsg), - buf1, buf2, deprecated.substitute); + buf1, deprecation_substitute); else - sql_print_warning(ER_DEFAULT(errmsg), buf1, buf2, deprecated.substitute); + sql_print_warning(ER_DEFAULT(errmsg), buf1, deprecation_substitute); } } diff --git a/sql/set_var.h b/sql/set_var.h index dcb60ba0bdf..52c68a4031e 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -81,7 +81,7 @@ protected: ptrdiff_t offset; ///< offset to the value from global_system_variables on_check_function on_check; on_update_function on_update; - struct { uint version; const char *substitute; } deprecated; + const char *const deprecation_substitute; bool is_os_charset; ///< true if the value is in character_set_filesystem public: @@ -90,7 +90,7 @@ public: enum get_opt_arg_type getopt_arg_type, SHOW_TYPE show_val_type_arg, longlong def_val, PolyLock *lock, enum binlog_status_enum binlog_status_arg, on_check_function on_check_func, on_update_function on_update_func, - uint deprecated_version, const char *substitute); + const char *substitute); virtual ~sys_var() {} diff --git a/sql/share/charsets/Index.xml b/sql/share/charsets/Index.xml index 80b844e2f19..f32d8bf6127 100644 --- a/sql/share/charsets/Index.xml +++ b/sql/share/charsets/Index.xml @@ -3,7 +3,7 @@ <charsets max-id="99"> <copyright> - Copyright (C) 2003 MySQL AB + Copyright (c) 2003, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 5a298b4d25c..49f35719a77 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6343,8 +6343,8 @@ ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT ER_PATH_LENGTH eng "The path specified for %.64s is too long." ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT - eng "The syntax '%s' is deprecated and will be removed in MariaDB %s." - ger "Die Syntax '%s' ist veraltet und wird in MariaDB %s entfernt." + eng "'%s' is deprecated and will be removed in a future release." + ger "'%s' ist veraltet und wird in einer zukünftigen Version entfernt werden." ER_WRONG_NATIVE_TABLE_STRUCTURE eng "Native table '%-.64s'.'%-.64s' has the wrong structure" diff --git a/sql/spatial.cc b/sql/spatial.cc index e82eec26fdb..de0b563eaf4 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -601,7 +601,8 @@ uint Gis_line_string::init_from_wkb(const char *wkb, uint len, Gis_point p; if (len < 4 || - (n_points= wkb_get_uint(wkb, bo))<1) + (n_points= wkb_get_uint(wkb, bo)) < 1 || + n_points > max_n_points) return 0; proper_length= 4 + n_points * POINT_DATA_SIZE; @@ -1334,9 +1335,9 @@ uint Gis_multi_point::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, Gis_point p; const char *wkb_end; - if (len < 4) + if (len < 4 || + (n_points= wkb_get_uint(wkb, bo)) > max_n_points) return 0; - n_points= wkb_get_uint(wkb, bo); proper_size= 4 + n_points * (WKB_HEADER_SIZE + POINT_DATA_SIZE); if (len < proper_size || res->reserve(proper_size)) diff --git a/sql/spatial.h b/sql/spatial.h index 07675d59040..1277e7bc01c 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -391,6 +391,10 @@ public: class Gis_line_string: public Geometry { + // Maximum number of points in LineString that can fit into String + static const uint32 max_n_points= + (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / + POINT_DATA_SIZE; public: Gis_line_string() {} /* Remove gcc warning */ virtual ~Gis_line_string() {} /* Remove gcc warning */ @@ -451,6 +455,10 @@ public: class Gis_multi_point: public Geometry { + // Maximum number of points in MultiPoint that can fit into String + static const uint32 max_n_points= + (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) / + (WKB_HEADER_SIZE + POINT_DATA_SIZE); public: Gis_multi_point() {} /* Remove gcc warning */ virtual ~Gis_multi_point() {} /* Remove gcc warning */ diff --git a/sql/sql_base.cc b/sql/sql_base.cc index feb4e43eb51..db926061406 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5059,8 +5059,6 @@ restart: */ if (thd->locked_tables_mode <= LTM_LOCK_TABLES) { - bool need_prelocking= FALSE; - TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last; /* Process elements of the prelocking set which are present there since parsing stage or were added to it by invocations of @@ -5073,10 +5071,19 @@ restart: for (Sroutine_hash_entry *rt= *sroutine_to_open; rt; sroutine_to_open= &rt->next, rt= rt->next) { + bool need_prelocking= false; + TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last; + error= open_and_process_routine(thd, thd->lex, rt, prelocking_strategy, has_prelocking_list, &ot_ctx, &need_prelocking); + if (need_prelocking && ! thd->lex->requires_prelocking()) + thd->lex->mark_as_requiring_prelocking(save_query_tables_last); + + if (need_prelocking && ! *start) + *start= thd->lex->query_tables; + if (error) { if (ot_ctx.can_recover_from_failed_open()) @@ -5097,12 +5104,6 @@ restart: goto err; } } - - if (need_prelocking && ! thd->lex->requires_prelocking()) - thd->lex->mark_as_requiring_prelocking(save_query_tables_last); - - if (need_prelocking && ! *start) - *start= thd->lex->query_tables; } } @@ -5375,6 +5376,12 @@ static bool check_lock_and_start_stmt(THD *thd, DBUG_ENTER("check_lock_and_start_stmt"); /* + Prelocking placeholder is not set for TABLE_LIST that + are directly used by TOP level statement. + */ + DBUG_ASSERT(table_list->prelocking_placeholder == false); + + /* TL_WRITE_DEFAULT and TL_READ_DEFAULT are supposed to be parser only types of locks so they should be converted to appropriate other types to be passed to storage engine. The exact lock type passed to the diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ba1d46ec3cc..fc5653750f3 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -275,6 +275,64 @@ bool Foreign_key::validate(List<Create_field> &table_fields) /**************************************************************************** ** Thread specific functions ****************************************************************************/ +#ifdef ONLY_FOR_MYSQL_CLOSED_SOURCE_SCHEDULED +/** + Get reference to scheduler data object + + @param thd THD object + + @retval Scheduler data object on THD +*/ +void *thd_get_scheduler_data(THD *thd) +{ + return thd->scheduler.data; +} + +/** + Set reference to Scheduler data object for THD object + + @param thd THD object + @param psi Scheduler data object to set on THD +*/ +void thd_set_scheduler_data(THD *thd, void *data) +{ + thd->scheduler.data= data; +} + +/** + Get reference to Performance Schema object for THD object + + @param thd THD object + + @retval Performance schema object for thread on THD +*/ +PSI_thread *thd_get_psi(THD *thd) +{ + return thd->scheduler.m_psi; +} + +/** + Get net_wait_timeout for THD object + + @param thd THD object + + @retval net_wait_timeout value for thread on THD +*/ +ulong thd_get_net_wait_timeout(THD* thd) +{ + return thd->variables.net_wait_timeout; +} + +/** + Set reference to Performance Schema object for THD object + + @param thd THD object + @param psi Performance schema object for thread +*/ +void thd_set_psi(THD *thd, PSI_thread *psi) +{ + thd->scheduler.m_psi= psi; +} /** Set the state on connection to killed @@ -407,6 +465,17 @@ void thd_set_net_read_write(THD *thd, uint val) } /** + Get reading/writing on socket from THD object + @param thd THD object + + @retval net.reading_or_writing value for thread on THD. +*/ +uint thd_get_net_read_write(THD *thd) +{ + return thd->net.reading_or_writing; +} + +/** Set reference to mysys variable in THD object @param thd THD object @@ -428,6 +497,7 @@ my_socket thd_get_fd(THD *thd) { return mysql_socket_getfd(thd->net.vio->mysql_socket); } +#endif /** Get thread attributes for connection threads diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 4148842a826..1f375bf1a03 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -681,7 +681,23 @@ void JOIN_CACHE::set_constants() uint len= length + fields*sizeof(uint)+blobs*sizeof(uchar *) + (prev_cache ? prev_cache->get_size_of_rec_offset() : 0) + sizeof(ulong); - buff_size= max(join->thd->variables.join_buff_size, 2*len); + /* + The values of size_of_rec_ofs, size_of_rec_len, size_of_fld_ofs, + base_prefix_length, pack_length, pack_length_with_blob_ptrs + will be recalculated later in this function when we get the estimate + for the actual value of the join buffer size. + */ + size_of_rec_ofs= size_of_rec_len= size_of_fld_ofs= 4; + base_prefix_length= (with_length ? size_of_rec_len : 0) + + (prev_cache ? prev_cache->get_size_of_rec_offset() : 0); + pack_length= (with_length ? size_of_rec_len : 0) + + (prev_cache ? prev_cache->get_size_of_rec_offset() : 0) + + length + fields*sizeof(uint); + pack_length_with_blob_ptrs= pack_length + blobs*sizeof(uchar *); + min_buff_size= 0; + min_records= 1; + buff_size= max(join->thd->variables.join_buff_size, + get_min_join_buffer_size()); size_of_rec_ofs= offset_size(buff_size); size_of_rec_len= blobs ? size_of_rec_ofs : offset_size(len); size_of_fld_ofs= size_of_rec_len; @@ -754,19 +770,24 @@ ulong JOIN_CACHE::get_min_join_buffer_size() if (!min_buff_size) { size_t len= 0; + size_t len_last= 0; for (JOIN_TAB *tab= start_tab; tab != join_tab; tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS)) { len+= tab->get_max_used_fieldlength(); + len_last=+ tab->get_used_fieldlength(); } - len+= get_record_max_affix_length() + get_max_key_addon_space_per_record(); - size_t min_sz= len*min_records; + size_t len_addon= get_record_max_affix_length() + + get_max_key_addon_space_per_record(); + len+= len_addon; + len_last+= len_addon; + size_t min_sz= len*(min_records-1) + len_last; + min_sz+= pack_length_with_blob_ptrs; size_t add_sz= 0; for (uint i=0; i < min_records; i++) add_sz+= join_tab_scan->aux_buffer_incr(i+1); avg_aux_buffer_incr= add_sz/min_records; min_sz+= add_sz; - min_sz+= pack_length_with_blob_ptrs; set_if_bigger(min_sz, 1); min_buff_size= min_sz; } diff --git a/sql/sql_list.h b/sql/sql_list.h index e3a04c36071..2b2d9e59771 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -667,6 +667,9 @@ public: inline void empty() { first= &last; last.prev= &first; } base_ilist() { empty(); } inline bool is_empty() { return first == &last; } + // Returns true if p is the last "real" object in the list, + // i.e. p->next points to the sentinel. + inline bool is_last(ilink *p) { return p->next == NULL || p->next == &last; } inline void append(ilink *a) { first->prev= &a->next; @@ -742,6 +745,7 @@ class I_List :private base_ilist { public: I_List() :base_ilist() {} + inline bool is_last(T *p) { return base_ilist::is_last(p); } inline void empty() { base_ilist::empty(); } inline bool is_empty() { return base_ilist::is_empty(); } inline void append(T* a) { base_ilist::append(a); } diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index f19b8ca26ef..e15f6339847 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -274,7 +274,7 @@ public: (plugin_var_arg->flags & PLUGIN_VAR_THDLOCAL ? SESSION : GLOBAL) | (plugin_var_arg->flags & PLUGIN_VAR_READONLY ? READONLY : 0), 0, -1, NO_ARG, pluginvar_show_type(plugin_var_arg), 0, 0, - VARIABLE_NOT_IN_BINLOG, 0, 0, 0, 0), + VARIABLE_NOT_IN_BINLOG, NULL, NULL, NULL), plugin_var(plugin_var_arg), orig_pluginvar_name(plugin_var_arg->name) { plugin_var->name= name_arg; } sys_var_pluginvar *cast_pluginvar() { return this; } @@ -2159,7 +2159,8 @@ static bool do_uninstall(THD *thd, TABLE *table, const LEX_STRING *name) struct st_plugin_int *plugin; mysql_mutex_assert_owner(&LOCK_plugin); - if (!(plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN))) + if (!(plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN)) || + plugin->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_DYING)) { my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PLUGIN", name->str); return 1; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 75611a054f0..969e6ee4574 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -878,6 +878,14 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array, param->set_param_func(param, &read_pos, (uint) (data_end - read_pos)); if (param->state == Item_param::NO_VALUE) DBUG_RETURN(1); + + if (param->limit_clause_param && param->item_type != Item::INT_ITEM) + { + param->set_int(param->val_int(), MY_INT64_NUM_DECIMAL_DIGITS); + param->item_type= Item::INT_ITEM; + if (!param->unsigned_flag && param->value.integer < 0) + DBUG_RETURN(1); + } } } /* diff --git a/sql/sql_priv.h b/sql/sql_priv.h index a1c0b2d8729..762a7769acf 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -365,6 +365,8 @@ inline int hexchar_to_int(char c) #define IS_TABLESPACES_NODEGROUP_ID 7 #define IS_TABLESPACES_TABLESPACE_COMMENT 8 +bool db_name_is_in_ignore_db_dirs_list(const char *dbase); + #endif /* MYSQL_SERVER */ #endif /* MYSQL_CLIENT */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ba44aba33b9..89d6e993b1d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -764,8 +764,6 @@ JOIN::prepare(Item ***rref_pointer_array, if (having) { - Query_arena backup, *arena; - arena= thd->activate_stmt_arena_if_needed(&backup); nesting_map save_allow_sum_func= thd->lex->allow_sum_func; thd->where="having clause"; thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level; @@ -781,9 +779,6 @@ JOIN::prepare(Item ***rref_pointer_array, (having->fix_fields(thd, &having) || having->check_cols(1))); select_lex->having_fix_field= 0; - select_lex->having= having; - if (arena) - thd->restore_active_arena(arena, &backup); if (having_fix_rc || thd->is_error()) DBUG_RETURN(-1); /* purecov: inspected */ @@ -1738,12 +1733,19 @@ JOIN::optimize_inner() DBUG_RETURN(1); } } - + /* + Calculate a possible 'limit' of table rows for 'GROUP BY': 'need_tmp' + implies that there will be more postprocessing so the specified + 'limit' should not be enforced yet in the call to + 'test_if_skip_sort_order'. + */ + const ha_rows limit = need_tmp ? HA_POS_ERROR : unit->select_limit_cnt; + if (!(select_options & SELECT_BIG_RESULT) && ((group_list && (!simple_group || !test_if_skip_sort_order(&join_tab[const_tables], group_list, - unit->select_limit_cnt, 0, + limit, 0, &join_tab[const_tables].table-> keys_in_use_for_group_by))) || select_distinct) && @@ -4016,8 +4018,10 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, new_fields->null_rejecting); } else if (old->eq_func && new_fields->eq_func && - ((old->val->const_item() && old->val->is_null()) || - new_fields->val->is_null())) + ((old->val->const_item() && !old->val->is_expensive() && + old->val->is_null()) || + (!new_fields->val->is_expensive() && + new_fields->val->is_null()))) { /* field = expression OR field IS NULL */ old->level= and_level; @@ -4031,7 +4035,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, Remember the NOT NULL value unless the value does not depend on other tables. */ - if (!old->val->used_tables() && old->val->is_null()) + if (!old->val->used_tables() && !old->val->is_expensive() && + old->val->is_null()) old->val= new_fields->val; } else @@ -8163,6 +8168,7 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables, key_part->length, ((Item_field*) keyuse->val->real_item())->field, keyuse->val->real_item()->full_name()); + return new store_key_item(thd, key_part->field, key_buff + maybe_null, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2a82ae115a0..73d441a2d9d 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -414,6 +414,281 @@ bool mysqld_show_privileges(THD *thd) } +/** Hash of LEX_STRINGs used to search for ignored db directories. */ +static HASH ignore_db_dirs_hash; + +/** + An array of LEX_STRING pointers to collect the options at + option parsing time. +*/ +static DYNAMIC_ARRAY ignore_db_dirs_array; + +/** + A value for the read only system variable to show a list of + ignored directories. +*/ +char *opt_ignore_db_dirs= NULL; + +/** + This flag is ON if: + - the list of ignored directories is not empty + + - and some of the ignored directory names + need no tablename-to-filename conversion. + Otherwise, if the name of the directory contains + unconditional characters like '+' or '.', they + never can match the database directory name. So the + db_name_is_in_ignore_db_dirs_list() can just return at once. +*/ +static bool skip_ignored_dir_check= TRUE; + +/** + Sets up the data structures for collection of directories at option + processing time. + We need to collect the directories in an array first, because + we need the character sets initialized before setting up the hash. + + @return state + @retval TRUE failed + @retval FALSE success +*/ + +bool +ignore_db_dirs_init() +{ + return my_init_dynamic_array(&ignore_db_dirs_array, sizeof(LEX_STRING *), + 0, 0); +} + + +/** + Retrieves the key (the string itself) from the LEX_STRING hash members. + + Needed by hash_init(). + + @param data the data element from the hash + @param out len_ret Placeholder to return the length of the key + @param unused + @return a pointer to the key +*/ + +static uchar * +db_dirs_hash_get_key(const uchar *data, size_t *len_ret, + my_bool __attribute__((unused))) +{ + LEX_STRING *e= (LEX_STRING *) data; + + *len_ret= e->length; + return (uchar *) e->str; +} + + +/** + Wrap a directory name into a LEX_STRING and push it to the array. + + Called at option processing time for each --ignore-db-dir option. + + @param path the name of the directory to push + @return state + @retval TRUE failed + @retval FALSE success +*/ + +bool +push_ignored_db_dir(char *path) +{ + LEX_STRING *new_elt; + char *new_elt_buffer; + size_t path_len= strlen(path); + + if (!path_len || path_len >= FN_REFLEN) + return true; + + // No need to normalize, it's only a directory name, not a path. + if (!my_multi_malloc(0, + &new_elt, sizeof(LEX_STRING), + &new_elt_buffer, path_len + 1, + NullS)) + return true; + new_elt->str= new_elt_buffer; + memcpy(new_elt_buffer, path, path_len); + new_elt_buffer[path_len]= 0; + new_elt->length= path_len; + return insert_dynamic(&ignore_db_dirs_array, (uchar*) &new_elt); +} + + +/** + Clean up the directory ignore options accumulated so far. + + Called at option processing time for each --ignore-db-dir option + with an empty argument. +*/ + +void +ignore_db_dirs_reset() +{ + LEX_STRING **elt; + while (NULL!= (elt= (LEX_STRING **) pop_dynamic(&ignore_db_dirs_array))) + if (elt && *elt) + my_free(*elt); +} + + +/** + Free the directory ignore option variables. + + Called at server shutdown. +*/ + +void +ignore_db_dirs_free() +{ + if (opt_ignore_db_dirs) + { + my_free(opt_ignore_db_dirs); + opt_ignore_db_dirs= NULL; + } + ignore_db_dirs_reset(); + delete_dynamic(&ignore_db_dirs_array); + my_hash_free(&ignore_db_dirs_hash); +} + + +/** + Initialize the ignore db directories hash and status variable from + the options collected in the array. + + Called when option processing is over and the server's in-memory + structures are fully initialized. + + @return state + @retval TRUE failed + @retval FALSE success +*/ + +static void dispose_db_dir(void *ptr) +{ + my_free(ptr); +} + + +bool +ignore_db_dirs_process_additions() +{ + ulong i; + size_t len; + char *ptr; + LEX_STRING *dir; + + + skip_ignored_dir_check= TRUE; + + if (my_hash_init(&ignore_db_dirs_hash, + lower_case_table_names ? + character_set_filesystem : &my_charset_bin, + 0, 0, 0, db_dirs_hash_get_key, + dispose_db_dir, + HASH_UNIQUE)) + return true; + + /* len starts from 1 because of the terminating zero. */ + len= 1; + for (i= 0; i < ignore_db_dirs_array.elements; i++) + { + get_dynamic(&ignore_db_dirs_array, (uchar *) &dir, i); + len+= dir->length + 1; // +1 for the comma + if (skip_ignored_dir_check) + { + char buff[FN_REFLEN]; + (void) tablename_to_filename(dir->str, buff, sizeof(buff)); + skip_ignored_dir_check= strcmp(dir->str, buff) != 0; + } + } + + /* No delimiter for the last directory. */ + if (len > 1) + len--; + + /* +1 the terminating zero */ + ptr= opt_ignore_db_dirs= (char *) my_malloc(len + 1, MYF(0)); + if (!ptr) + return true; + + /* Make sure we have an empty string to start with. */ + *ptr= 0; + + for (i= 0; i < ignore_db_dirs_array.elements; i++) + { + get_dynamic(&ignore_db_dirs_array, (uchar *) &dir, i); + if (my_hash_insert(&ignore_db_dirs_hash, (uchar *) dir)) + return true; + ptr= strnmov(ptr, dir->str, dir->length); + if (i + 1 < ignore_db_dirs_array.elements) + ptr= strmov(ptr, ","); + + /* + Set the transferred array element to NULL to avoid double free + in case of error. + */ + dir= NULL; + set_dynamic(&ignore_db_dirs_array, (uchar *) &dir, i); + } + + /* make sure the string is terminated */ + DBUG_ASSERT(ptr - opt_ignore_db_dirs <= (ptrdiff_t) len); + *ptr= 0; + + /* + It's OK to empty the array here as the allocated elements are + referenced through the hash now. + */ + reset_dynamic(&ignore_db_dirs_array); + + return false; +} + + +/** + Check if a directory name is in the hash of ignored directories. + + @return search result + @retval TRUE found + @retval FALSE not found +*/ + +static inline bool +is_in_ignore_db_dirs_list(const char *directory) +{ + return ignore_db_dirs_hash.records && + NULL != my_hash_search(&ignore_db_dirs_hash, (const uchar *) directory, + strlen(directory)); +} + + +/** + Check if a database name is in the hash of ignored directories. + + @return search result + @retval TRUE found + @retval FALSE not found +*/ + +bool +db_name_is_in_ignore_db_dirs_list(const char *directory) +{ + char buff[FN_REFLEN]; + uint buff_len; + + if (skip_ignored_dir_check) + return 0; + + buff_len= tablename_to_filename(directory, buff, sizeof(buff)); + + return my_hash_search(&ignore_db_dirs_hash, (uchar *) buff, buff_len)!=NULL; +} + + /* find_files() - find files in a given directory. @@ -499,6 +774,9 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db, if (!MY_S_ISDIR(file->mystat->st_mode)) continue; + if (is_in_ignore_db_dirs_list(file->name)) + continue; + file_name_len= filename_to_tablename(file->name, uname, sizeof(uname)); if (wild) { diff --git a/sql/sql_show.h b/sql/sql_show.h index 7541ed58e48..03d8af3aabd 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -158,4 +158,12 @@ public: void call_in_target_thread(); }; +/* Handle the ignored database directories list for SHOW/I_S. */ +bool ignore_db_dirs_init(); +void ignore_db_dirs_free(); +void ignore_db_dirs_reset(); +bool ignore_db_dirs_process_additions(); +bool push_ignored_db_dir(char *path); +extern char *opt_ignore_db_dirs; + #endif /* SQL_SHOW_H */ diff --git a/sql/sql_string.h b/sql/sql_string.h index 2f0cd9103dc..8b09d449c2b 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -2,8 +2,8 @@ #define SQL_STRING_INCLUDED /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2008-2011 Monty Program Ab + Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2008, 2011, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -279,8 +279,11 @@ public: } return realloc_with_extra(arg_length); } - inline void shrink(uint32 arg_length) // Shrink buffer + // Shrink the buffer, but only if it is allocated on the heap. + inline void shrink(uint32 arg_length) { + if (!is_alloced()) + return; if (ALIGN_SIZE(arg_length+1) < Alloced_length) { char *new_ptr; @@ -296,7 +299,7 @@ public: } } } - bool is_alloced() { return alloced; } + bool is_alloced() const { return alloced; } inline String& operator = (const String &s) { if (&s != this) diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 02f7fc0601c..193447156c0 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -51,6 +51,7 @@ #include <myisam.h> #include "log_slow.h" #include "debug_sync.h" // DEBUG_SYNC +#include "sql_show.h" #include "log_event.h" #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE @@ -771,14 +772,14 @@ static Sys_var_ulong Sys_connect_timeout( static Sys_var_charptr Sys_datadir( "datadir", "Path to the database root directory", READ_ONLY GLOBAL_VAR(mysql_real_data_home_ptr), - CMD_LINE(REQUIRED_ARG, 'h'), IN_FS_CHARSET, DEFAULT(0)); + CMD_LINE(REQUIRED_ARG, 'h'), IN_FS_CHARSET, DEFAULT(mysql_real_data_home)); #ifndef DBUG_OFF static Sys_var_dbug Sys_dbug( "debug", "Built-in DBUG debugger", sys_var::SESSION, CMD_LINE(OPT_ARG, '#'), DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super), ON_UPDATE(0), - DEPRECATED(100100, "'@@debug_dbug'")); + DEPRECATED("'@@debug_dbug'")); static Sys_var_dbug Sys_debug_dbug( "debug_dbug", "Built-in DBUG debugger", sys_var::SESSION, @@ -1438,7 +1439,7 @@ static Sys_var_harows Sys_sql_max_join_size( SESSION_VAR(max_join_size), NO_CMD_LINE, VALID_RANGE(1, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), - ON_UPDATE(fix_max_join_size), DEPRECATED(100100, "'@@max_join_size'")); + ON_UPDATE(fix_max_join_size), DEPRECATED("'@@max_join_size'")); static Sys_var_ulong Sys_max_long_data_size( "max_long_data_size", @@ -1881,7 +1882,7 @@ static Sys_var_ulong Sys_rpl_recovery_rank( GLOBAL_VAR(rpl_recovery_rank), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0), - DEPRECATED(100100, 0)); + DEPRECATED("")); static Sys_var_ulong Sys_range_alloc_block_size( "range_alloc_block_size", @@ -1895,7 +1896,7 @@ static Sys_var_ulong Sys_multi_range_count( SESSION_VAR(multi_range_count), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, ULONG_MAX), DEFAULT(256), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0), - DEPRECATED(100100, "'@@mrr_buffer_size'")); + DEPRECATED("'@@mrr_buffer_size'")); static bool fix_thd_mem_root(sys_var *self, THD *thd, enum_var_type type) { @@ -2679,7 +2680,7 @@ static Sys_var_mybool Sys_engine_condition_pushdown( CMD_LINE(OPT_ARG, OPT_ENGINE_CONDITION_PUSHDOWN), DEFAULT(TRUE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL), ON_UPDATE(fix_engine_condition_pushdown), - DEPRECATED(100100, "'@@optimizer_switch'")); + DEPRECATED("'@@optimizer_switch'")); static Sys_var_plugin Sys_default_storage_engine( "default_storage_engine", "The default storage engine for new tables", @@ -3361,7 +3362,7 @@ static Sys_var_mybool Sys_log( "log", "Alias for --general-log. Deprecated", GLOBAL_VAR(opt_log), NO_CMD_LINE, DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), - ON_UPDATE(fix_log_state), DEPRECATED(100100, "'@@general_log'")); + ON_UPDATE(fix_log_state), DEPRECATED("'@@general_log'")); static Sys_var_mybool Sys_slow_query_log( "slow_query_log", @@ -3378,7 +3379,7 @@ static Sys_var_mybool Sys_log_slow( "Alias for --slow-query-log. Deprecated", GLOBAL_VAR(opt_slow_log), NO_CMD_LINE, DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), - ON_UPDATE(fix_log_state), DEPRECATED(100100, "'@@slow_query_log'")); + ON_UPDATE(fix_log_state), DEPRECATED("'@@slow_query_log'")); static bool fix_log_state(sys_var *self, THD *thd, enum_var_type type) { @@ -3816,6 +3817,15 @@ static Sys_var_tz Sys_time_zone( SESSION_VAR(time_zone), NO_CMD_LINE, DEFAULT(&default_tz), NO_MUTEX_GUARD, IN_BINLOG); +static Sys_var_charptr Sys_ignore_db_dirs( + "ignore_db_dirs", + "Specifies a directory to add to the ignore list when collecting " + "database names from the datadir. Put a blank argument to reset " + "the list accumulated so far.", + READ_ONLY GLOBAL_VAR(opt_ignore_db_dirs), + CMD_LINE(REQUIRED_ARG, OPT_IGNORE_DB_DIRECTORY), + IN_FS_CHARSET, DEFAULT(0)); + static Sys_var_ulong Sys_sp_cache_size( "stored_program_cache", "The soft upper limit for number of cached stored routines for " diff --git a/sql/sys_vars.h b/sql/sys_vars.h index 54ae4025a65..98a2b4c17fb 100644 --- a/sql/sys_vars.h +++ b/sql/sys_vars.h @@ -61,7 +61,7 @@ @@foreign_key_checks <-> OPTION_NO_FOREIGN_KEY_CHECKS */ #define REVERSE(X) ~(X) -#define DEPRECATED(X, Y) X, Y +#define DEPRECATED(X) X #define session_var(THD, TYPE) (*(TYPE*)session_var_ptr(THD)) #define global_var(TYPE) (*(TYPE*)global_var_ptr()) @@ -128,10 +128,10 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id, getopt.arg_type, SHOWT, def_val, lock, binlog_status_arg, - on_check_func, on_update_func, deprecated_version, substitute) + on_check_func, on_update_func, substitute) { option.var_type= ARGT; option.min_value= min_val; @@ -240,11 +240,11 @@ public: ulonglong def_val, PolyLock *lock, enum binlog_status_enum binlog_status_arg, on_check_function on_check_func, on_update_function on_update_func, - uint deprecated_version, const char *substitute) + const char *substitute) : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id, getopt.arg_type, show_val_type_arg, def_val, lock, binlog_status_arg, on_check_func, - on_update_func, deprecated_version, substitute) + on_update_func, substitute) { for (typelib.count= 0; values[typelib.count]; typelib.count++) /*no-op */; typelib.name=""; @@ -307,11 +307,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : Sys_var_typelib(name_arg, comment, flag_args, off, getopt, SHOW_CHAR, values, def_val, lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute) + substitute) { option.var_type= GET_ENUM; global_var(ulong)= def_val; @@ -354,11 +354,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : Sys_var_typelib(name_arg, comment, flag_args, off, getopt, SHOW_MY_BOOL, bool_values, def_val, lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute) + substitute) { option.var_type= GET_BOOL; global_var(my_bool)= def_val; @@ -409,11 +409,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id, getopt.arg_type, SHOW_CHAR_PTR, (intptr)def_val, lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute) + substitute) { is_os_charset= is_os_charset_arg == IN_FS_CHARSET; /* @@ -504,7 +504,7 @@ public: : sys_var(&all_sys_vars, name_arg, comment, sys_var::READONLY+sys_var::ONLY_SESSION, 0, -1, NO_ARG, SHOW_CHAR, 0, NULL, VARIABLE_NOT_IN_BINLOG, - NULL, NULL, 0, NULL) + NULL, NULL, NULL) { is_os_charset= is_os_charset_arg == IN_FS_CHARSET; option.var_type= GET_STR; @@ -563,7 +563,7 @@ public: Sys_var_rpl_filter(const char *name, int getopt_id, const char *comment) : sys_var(&all_sys_vars, name, comment, sys_var::GLOBAL, 0, -1, NO_ARG, SHOW_CHAR, 0, NULL, VARIABLE_NOT_IN_BINLOG, - NULL, NULL, 0, NULL), opt_id(getopt_id) + NULL, NULL, NULL), opt_id(getopt_id) { option.var_type= GET_STR; } @@ -617,10 +617,10 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : Sys_var_charptr(name_arg, comment, flag_args, off, sizeof(char*), getopt, is_os_charset_arg, def_val, lock, binlog_status_arg, - on_check_func, on_update_func, deprecated_version, substitute) + on_check_func, on_update_func, substitute) { global_var(LEX_STRING).length= strlen(def_val); SYSVAR_ASSERT(size == sizeof(LEX_STRING)); @@ -655,7 +655,7 @@ public: : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id, getopt.arg_type, SHOW_CHAR, (intptr)def_val, 0, VARIABLE_NOT_IN_BINLOG, on_check_func, on_update_func, - 0, 0),max_length(max_length_arg) + 0),max_length(max_length_arg) { option.var_type= GET_NO_ARG; SYSVAR_ASSERT(scope() == ONLY_SESSION) @@ -744,11 +744,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : sys_var(&all_sys_vars, name_arg, comment, flag_args, 0, getopt.id, getopt.arg_type, SHOW_CHAR, (intptr)def_val, lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute) + substitute) { option.var_type= GET_NO_ARG; } bool do_check(THD *thd, set_var *var) { @@ -828,11 +828,11 @@ public: enum binlog_status_enum binlog_status_arg, on_check_function on_check_func, keycache_update_function on_update_func, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : Sys_var_ulonglong(name_arg, comment, flag_args, off, size, getopt, min_val, max_val, def_val, block_size, lock, binlog_status_arg, on_check_func, 0, - deprecated_version, substitute), + substitute), keycache_update(on_update_func) { option.var_type|= GET_ASK_ADDR; @@ -989,11 +989,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id, getopt.arg_type, SHOW_DOUBLE, (longlong) double2ulonglong(def_val), lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute) + substitute) { option.var_type= GET_DOUBLE; option.min_value= (longlong) double2ulonglong(min_val); @@ -1053,11 +1053,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : Sys_var_int(name_arg, comment, SESSION, off, size, getopt, min_val, max_val, def_val, block_size, lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute) + substitute) { } uchar *session_value_ptr(THD *thd, LEX_STRING *base) { @@ -1094,11 +1094,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : Sys_var_typelib(name_arg, comment, flag_args, off, getopt, SHOW_CHAR, values, def_val, lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute) + substitute) { option.var_type= GET_FLAGSET; global_var(ulonglong)= def_val; @@ -1205,11 +1205,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : Sys_var_typelib(name_arg, comment, flag_args, off, getopt, SHOW_CHAR, values, def_val, lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute) + substitute) { option.var_type= GET_SET; global_var(ulonglong)= def_val; @@ -1311,11 +1311,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id, getopt.arg_type, SHOW_CHAR, (intptr)def_val, lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute), + substitute), plugin_type(plugin_type_arg) { option.var_type= GET_STR; @@ -1424,11 +1424,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : sys_var(&all_sys_vars, name_arg, comment, flag_args, 0, getopt.id, getopt.arg_type, SHOW_CHAR, (intptr)def_val, lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute) + substitute) { SYSVAR_ASSERT(scope() == ONLY_SESSION); option.var_type= GET_NO_ARG; @@ -1517,11 +1517,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : Sys_var_typelib(name_arg, comment, flag_args, off, getopt, SHOW_MY_BOOL, bool_values, def_val, lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute) + substitute) { option.var_type= GET_BOOL; reverse_semantics= my_count_bits(bitmask_arg) > 1; @@ -1590,11 +1590,11 @@ public: on_check_function on_check_func, session_special_update_function update_func_arg, session_special_read_function read_func_arg, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : Sys_var_ulonglong(name_arg, comment, flag_args, 0, sizeof(ulonglong), getopt, min_val, max_val, 0, block_size, lock, binlog_status_arg, on_check_func, 0, - deprecated_version, substitute), + substitute), read_func(read_func_arg), update_func(update_func_arg) { SYSVAR_ASSERT(scope() == ONLY_SESSION); @@ -1640,11 +1640,11 @@ public: on_check_function on_check_func, session_special_update_function update_func_arg, session_special_read_function read_func_arg, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : Sys_var_double(name_arg, comment, flag_args, 0, sizeof(double), getopt, min_val, max_val, 0, lock, binlog_status_arg, on_check_func, 0, - deprecated_version, substitute), + substitute), read_func(read_func_arg), update_func(update_func_arg) { SYSVAR_ASSERT(scope() == ONLY_SESSION); @@ -1694,11 +1694,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id, getopt.arg_type, SHOW_CHAR, 0, lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute) + substitute) { SYSVAR_ASSERT(scope() == GLOBAL); SYSVAR_ASSERT(getopt.id == -1); @@ -1762,11 +1762,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id, getopt.arg_type, SHOW_CHAR, (intptr)def_val, lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute), + substitute), name_offset(name_off) { option.var_type= GET_STR; @@ -1834,11 +1834,11 @@ public: enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG, on_check_function on_check_func=0, on_update_function on_update_func=0, - uint deprecated_version=0, const char *substitute=0) + const char *substitute=0) : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id, getopt.arg_type, SHOW_CHAR, (intptr)def_val, lock, binlog_status_arg, on_check_func, on_update_func, - deprecated_version, substitute) + substitute) { SYSVAR_ASSERT(getopt.id == -1); SYSVAR_ASSERT(size == sizeof(Time_zone *)); diff --git a/sql/table.cc b/sql/table.cc index f033c08553a..18aaed6d81f 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3444,6 +3444,9 @@ bool check_db_name(LEX_STRING *org_name) if (lower_case_table_names && name != any_db) my_casedn_str(files_charset_info, name); + if (db_name_is_in_ignore_db_dirs_list(name)) + return 1; + return check_table_name(name, name_length, check_for_path_chars); } @@ -4968,7 +4971,16 @@ TABLE *TABLE_LIST::get_real_join_table() tbl= (tbl->view != NULL ? tbl->view->select_lex.get_table_list() : tbl->derived->first_select()->get_table_list()); + + /* find left table in outer join on this level */ + while(tbl->outer_join & JOIN_TYPE_RIGHT) + { + DBUG_ASSERT(tbl->next_local); + tbl= tbl->next_local; + } + } + return tbl->table; } diff --git a/sql/table.h b/sql/table.h index 458d661ceb5..1f546693fb3 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1900,6 +1900,7 @@ struct TABLE_LIST /* TRUE <=> derived table should be filled right after optimization. */ bool fill_me; /* TRUE <=> view/DT is merged. */ + /* TODO: replace with derived_type */ bool merged; bool merged_for_insert; /* TRUE <=> don't prepare this derived table/view as it should be merged.*/ diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc index 7e5bbd11c69..6b956768287 100644 --- a/sql/threadpool_common.cc +++ b/sql/threadpool_common.cc @@ -257,7 +257,7 @@ static scheduler_functions tp_scheduler_functions= tp_add_connection, // add_connection tp_wait_begin, // thd_wait_begin tp_wait_end, // thd_wait_end - tp_post_kill_notification, // post_kill_notification + post_kill_notification, // post_kill_notification NULL, // end_thread tp_end // end }; diff --git a/sql/threadpool_unix.cc b/sql/threadpool_unix.cc index 60c3ad69c65..13deb167d9b 100644 --- a/sql/threadpool_unix.cc +++ b/sql/threadpool_unix.cc @@ -173,7 +173,6 @@ static int create_worker(thread_group_t *thread_group); static void *worker_main(void *param); static void check_stall(thread_group_t *thread_group); static void connection_abort(connection_t *connection); -void tp_post_kill_notification(THD *thd); static void set_wait_timeout(connection_t *connection); static void set_next_timeout_check(ulonglong abstime); static void print_pool_blocked_message(bool); @@ -444,7 +443,7 @@ static void timeout_check(pool_timer_t *timer) /* Wait timeout exceeded, kill connection. */ mysql_mutex_lock(&thd->LOCK_thd_data); thd->killed = KILL_CONNECTION; - tp_post_kill_notification(thd); + post_kill_notification(thd); mysql_mutex_unlock(&thd->LOCK_thd_data); } else @@ -1259,21 +1258,6 @@ static void connection_abort(connection_t *connection) /** - MySQL scheduler callback : kill connection -*/ - -void tp_post_kill_notification(THD *thd) -{ - DBUG_ENTER("tp_post_kill_notification"); - if (current_thd == thd || thd->system_thread) - DBUG_VOID_RETURN; - - if (thd->net.vio) - vio_shutdown(thd->net.vio, SHUT_RD); - DBUG_VOID_RETURN; -} - -/** MySQL scheduler callback: wait begin */ diff --git a/sql/threadpool_win.cc b/sql/threadpool_win.cc index 7bf4d98d16d..9cef1af272c 100644 --- a/sql/threadpool_win.cc +++ b/sql/threadpool_win.cc @@ -544,22 +544,6 @@ void tp_end(void) } } -/** - Notify pool about connection being killed. -*/ -void tp_post_kill_notification(THD *thd) -{ - if (current_thd == thd) - return; /* There is nothing to do.*/ - - if (thd->system_thread) - return; /* Will crash if we attempt to kill system thread. */ - - Vio *vio= thd->net.vio; - - vio_shutdown(vio, SD_BOTH); - -} /* Handle read completion/notification. diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 8376ebc9826..75026f2a443 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -275,7 +275,7 @@ int archive_discover(handlerton *hton, THD* thd, const char *db, build_table_filename(az_file, sizeof(az_file) - 1, db, name, ARZ, 0); - if (!(mysql_file_stat(arch_key_file_data, az_file, &file_stat, MYF(0)))) + if (!(mysql_file_stat(/* arch_key_file_data */ 0, az_file, &file_stat, MYF(0)))) goto err; if (!(azopen(&frm_stream, az_file, O_RDONLY|O_BINARY))) @@ -738,7 +738,7 @@ int ha_archive::create(const char *name, TABLE *table_arg, There is a chance that the file was "discovered". In this case just use whatever file is there. */ - if (!(mysql_file_stat(arch_key_file_data, name_buff, &file_stat, MYF(0)))) + if (!(mysql_file_stat(/* arch_key_file_data */ 0, name_buff, &file_stat, MYF(0)))) { my_errno= 0; if (!(azopen(&create_stream, name_buff, O_CREAT|O_RDWR|O_BINARY))) @@ -1625,7 +1625,7 @@ int ha_archive::info(uint flag) { MY_STAT file_stat; // Stat information for the data file - (void) mysql_file_stat(arch_key_file_data, share->data_file_name, &file_stat, MYF(MY_WME)); + (void) mysql_file_stat(/* arch_key_file_data */ 0, share->data_file_name, &file_stat, MYF(MY_WME)); if (flag & HA_STATUS_TIME) stats.update_time= (ulong) file_stat.st_mtime; diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index fcd8370f969..211a77e2891 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -1398,7 +1398,7 @@ bool ha_federated::create_where_from_key(String *to, break; } DBUG_PRINT("info", ("federated HA_READ_AFTER_KEY %d", i)); - if (store_length >= length) /* end key */ + if ((store_length >= length) || (i > 0)) /* for all parts of end key*/ { if (emit_key_part_name(&tmp, key_part)) goto err; diff --git a/storage/heap/CMakeLists.txt b/storage/heap/CMakeLists.txt index 0b9372bf224..3a0c2e7271c 100644 --- a/storage/heap/CMakeLists.txt +++ b/storage/heap/CMakeLists.txt @@ -21,8 +21,10 @@ SET(HEAP_SOURCES _check.c _rectest.c hp_block.c hp_clear.c hp_close.c hp_create MYSQL_ADD_PLUGIN(heap ${HEAP_SOURCES} STORAGE_ENGINE MANDATORY RECOMPILE_FOR_EMBEDDED) -ADD_EXECUTABLE(hp_test1 hp_test1.c) -TARGET_LINK_LIBRARIES(hp_test1 heap mysys dbug strings) +IF(WITH_UNIT_TESTS) + ADD_EXECUTABLE(hp_test1 hp_test1.c) + TARGET_LINK_LIBRARIES(hp_test1 heap mysys dbug strings) -ADD_EXECUTABLE(hp_test2 hp_test2.c) -TARGET_LINK_LIBRARIES(hp_test2 heap mysys dbug strings) + ADD_EXECUTABLE(hp_test2 hp_test2.c) + TARGET_LINK_LIBRARIES(hp_test2 heap mysys dbug strings) +ENDIF()
\ No newline at end of file diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 760bed8de8c..3f29f403622 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -1853,6 +1853,7 @@ btr_root_raise_and_insert( root = btr_cur_get_page(cursor); root_block = btr_cur_get_block(cursor); root_page_zip = buf_block_get_page_zip(root_block); + ut_ad(page_get_n_recs(root) > 0); #ifdef UNIV_ZIP_DEBUG ut_a(!root_page_zip || page_zip_validate(root_page_zip, root)); #endif /* UNIV_ZIP_DEBUG */ @@ -2331,12 +2332,20 @@ btr_insert_on_non_leaf_level_func( BTR_CONT_MODIFY_TREE, &cursor, 0, file, line, mtr); - err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG - | BTR_KEEP_SYS_FLAG - | BTR_NO_UNDO_LOG_FLAG, - &cursor, tuple, &rec, - &dummy_big_rec, 0, NULL, mtr); - ut_a(err == DB_SUCCESS); + ut_ad(cursor.flag == BTR_CUR_BINARY); + + err = btr_cur_optimistic_insert( + BTR_NO_LOCKING_FLAG | BTR_KEEP_SYS_FLAG + | BTR_NO_UNDO_LOG_FLAG, &cursor, tuple, &rec, + &dummy_big_rec, 0, NULL, mtr); + + if (err == DB_FAIL) { + err = btr_cur_pessimistic_insert( + BTR_NO_LOCKING_FLAG | BTR_KEEP_SYS_FLAG + | BTR_NO_UNDO_LOG_FLAG, + &cursor, tuple, &rec, &dummy_big_rec, 0, NULL, mtr); + ut_a(err == DB_SUCCESS); + } } /**************************************************************//** diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 5d1a19c3d30..95193546115 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -1326,7 +1326,12 @@ fail_err: if (UNIV_UNLIKELY(reorg)) { ut_a(zip_size); - ut_a(*rec); + /* It's possible for rec to be NULL if the + page is compressed. This is because a + reorganized page may become incompressible. */ + if (!*rec) { + goto fail; + } } } @@ -1462,20 +1467,9 @@ btr_cur_pessimistic_insert( ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor), MTR_MEMO_PAGE_X_FIX)); - /* Try first an optimistic insert; reset the cursor flag: we do not - assume anything of how it was positioned */ - cursor->flag = BTR_CUR_BINARY; - err = btr_cur_optimistic_insert(flags, cursor, entry, rec, - big_rec, n_ext, thr, mtr); - if (err != DB_FAIL) { - - return(err); - } - - /* Retry with a pessimistic insert. Check locks and write to undo log, - if specified */ + /* Check locks and write to undo log, if specified */ err = btr_cur_ins_lock_and_undo(flags, cursor, entry, thr, mtr, &dummy_inh); @@ -2079,8 +2073,12 @@ any_extern: goto err_exit; } - max_size = old_rec_size - + page_get_max_insert_size_after_reorganize(page, 1); + /* We do not attempt to reorganize if the page is compressed. + This is because the page may fail to compress after reorganization. */ + max_size = page_zip + ? page_get_max_insert_size(page, 1) + : (old_rec_size + + page_get_max_insert_size_after_reorganize(page, 1)); if (!(((max_size >= BTR_CUR_PAGE_REORGANIZE_LIMIT) && (max_size >= new_rec_size)) @@ -2434,7 +2432,12 @@ make_external: err = DB_SUCCESS; goto return_after_reservations; } else { - ut_a(optim_err != DB_UNDERFLOW); + /* If the page is compressed and it initially + compresses very well, and there is a subsequent insert + of a badly-compressing record, it is possible for + btr_cur_optimistic_update() to return DB_UNDERFLOW and + btr_cur_insert_if_possible() to return FALSE. */ + ut_a(page_zip || optim_err != DB_UNDERFLOW); /* Out of space: reset the free bits. */ if (!dict_index_is_clust(index) @@ -2463,7 +2466,9 @@ make_external: was_first = page_cur_is_before_first(page_cursor); /* Lock checks and undo logging were already performed by - btr_cur_upd_lock_and_undo(). */ + btr_cur_upd_lock_and_undo(). We do not try + btr_cur_optimistic_insert() because + btr_cur_insert_if_possible() already failed above. */ err = btr_cur_pessimistic_insert(BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 4f615da5809..1d0abbc2981 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -3483,11 +3483,18 @@ fail_exit: root = ibuf_tree_root_get(&mtr); - err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG - | BTR_NO_UNDO_LOG_FLAG, - cursor, - ibuf_entry, &ins_rec, - &dummy_big_rec, 0, thr, &mtr); + err = btr_cur_optimistic_insert( + BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG, + cursor, ibuf_entry, &ins_rec, + &dummy_big_rec, 0, thr, &mtr); + + if (err == DB_FAIL) { + err = btr_cur_pessimistic_insert( + BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG, + cursor, ibuf_entry, &ins_rec, + &dummy_big_rec, 0, thr, &mtr); + } + mutex_exit(&ibuf_pessimistic_insert_mutex); ibuf_size_update(root, &mtr); mutex_exit(&ibuf_mutex); diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index c9089255c39..fb3e21b8b26 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -778,12 +778,18 @@ page_copy_rec_list_start( if (new_page_zip) { mtr_set_log_mode(mtr, log_mode); + DBUG_EXECUTE_IF("page_copy_rec_list_start_compress_fail", + goto zip_reorganize;); + if (UNIV_UNLIKELY (!page_zip_compress(new_page_zip, new_page, index, mtr))) { + ulint ret_pos; +#ifndef DBUG_OFF +zip_reorganize: +#endif /* DBUG_OFF */ /* Before trying to reorganize the page, store the number of preceding records on the page. */ - ulint ret_pos - = page_rec_get_n_recs_before(ret); + ret_pos = page_rec_get_n_recs_before(ret); /* Before copying, "ret" was the predecessor of the predefined supremum record. If it was the predefined infimum record, then it would @@ -804,15 +810,10 @@ page_copy_rec_list_start( btr_blob_dbg_add(new_page, index, "copy_start_reorg_fail"); return(NULL); - } else { - /* The page was reorganized: - Seek to ret_pos. */ - ret = new_page + PAGE_NEW_INFIMUM; - - do { - ret = rec_get_next_ptr(ret, TRUE); - } while (--ret_pos); } + + /* The page was reorganized: Seek to ret_pos. */ + ret = page_rec_get_nth(new_page, ret_pos); } } diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index a99b6080e0a..e79518e24de 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -2302,9 +2302,16 @@ row_ins_index_entry_low( goto function_exit; } - err = btr_cur_pessimistic_insert( + + err = btr_cur_optimistic_insert( 0, &cursor, entry, &insert_rec, &big_rec, n_ext, thr, &mtr); + + if (err == DB_FAIL) { + err = btr_cur_pessimistic_insert( + 0, &cursor, entry, &insert_rec, + &big_rec, n_ext, thr, &mtr); + } } } diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 0acd7933c19..cf662cb1f88 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -1370,11 +1370,25 @@ row_merge_read_clustered_index( goto func_exit; } + /* Store the cursor position on the last user + record on the page. */ + btr_pcur_move_to_prev_on_page(&pcur); + /* Leaf pages must never be empty, unless + this is the only page in the index tree. */ + ut_ad(btr_pcur_is_on_user_rec(&pcur) + || buf_block_get_page_no( + btr_pcur_get_block(&pcur)) + == clust_index->page); + btr_pcur_store_position(&pcur, &mtr); mtr_commit(&mtr); mtr_start(&mtr); + /* Restore position on the record, or its + predecessor if the record was purged + meanwhile. */ btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr); + /* Move to the successor of the original record. */ has_next = btr_pcur_move_to_next_user_rec(&pcur, &mtr); } diff --git a/storage/maria/CMakeLists.txt b/storage/maria/CMakeLists.txt index 9ca198873d1..0f30f8f3156 100644 --- a/storage/maria/CMakeLists.txt +++ b/storage/maria/CMakeLists.txt @@ -50,6 +50,10 @@ MYSQL_ADD_PLUGIN(aria ${ARIA_SOURCES} STORAGE_ENGINE STATIC_ONLY DEFAULT RECOMPILE_FOR_EMBEDDED) +IF(NOT WITH_ARIA_STORAGE_ENGINE) + RETURN() +ENDIF() + TARGET_LINK_LIBRARIES(aria myisam) MYSQL_ADD_EXECUTABLE(aria_ftdump maria_ftdump.c COMPONENT Server) @@ -83,6 +87,7 @@ IF(WITH_UNIT_TESTS) ADD_EXECUTABLE(ma_sp_test ma_sp_test.c) TARGET_LINK_LIBRARIES(ma_sp_test aria) + ADD_SUBDIRECTORY(unittest) ENDIF() IF (MSVC) @@ -92,4 +97,3 @@ ENDIF() CMAKE_DEPENDENT_OPTION(USE_ARIA_FOR_TMP_TABLES "Use Aria for temporary tables" ON "WITH_ARIA_STORAGE_ENGINE" OFF) -ADD_SUBDIRECTORY(unittest) diff --git a/storage/maria/ma_ft_nlq_search.c b/storage/maria/ma_ft_nlq_search.c index 5c1ab85ef8a..c8b87c4f42c 100644 --- a/storage/maria/ma_ft_nlq_search.c +++ b/storage/maria/ma_ft_nlq_search.c @@ -82,6 +82,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) #error #endif DBUG_ENTER("walk_and_match"); + LINT_INIT(subkeys.i); LINT_INIT_STRUCT(subkeys); diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 6eaf77a5d2d..80353188f05 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -515,7 +515,8 @@ int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo, t1_keysegs[j].language != t2_keysegs[j].language) || t1_keysegs_j__type != t2_keysegs[j].type || t1_keysegs[j].null_bit != t2_keysegs[j].null_bit || - t1_keysegs[j].length != t2_keysegs[j].length) + t1_keysegs[j].length != t2_keysegs[j].length || + t1_keysegs[j].start != t2_keysegs[j].start) { DBUG_PRINT("error", ("Key segment %d (key %d) has different " "definition", j, i)); diff --git a/storage/perfschema/CMakeLists.txt b/storage/perfschema/CMakeLists.txt index 16087740da3..0c9713d45d4 100644 --- a/storage/perfschema/CMakeLists.txt +++ b/storage/perfschema/CMakeLists.txt @@ -192,6 +192,6 @@ table_users.cc ) MYSQL_ADD_PLUGIN(perfschema ${PERFSCHEMA_SOURCES} STORAGE_ENGINE DEFAULT STATIC_ONLY) -IF(WITH_PERFSCHEMA_STORAGE_ENGINE) +IF(WITH_PERFSCHEMA_STORAGE_ENGINE AND WITH_UNIT_TESTS) ADD_SUBDIRECTORY(unittest) ENDIF() diff --git a/storage/xtradb/CMakeLists.txt-disabled b/storage/xtradb/CMakeLists.txt-disabled index 1c75d5f829c..9fed5af5b00 100644 --- a/storage/xtradb/CMakeLists.txt-disabled +++ b/storage/xtradb/CMakeLists.txt-disabled @@ -95,12 +95,41 @@ IF(NOT CMAKE_CROSSCOMPILING) }" HAVE_IB_GCC_ATOMIC_BUILTINS ) + CHECK_C_SOURCE_RUNS( + " + #include <stdint.h> + int main() + { + int64_t x, y, res; + + x = 10; + y = 123; + res = __sync_bool_compare_and_swap(&x, x, y); + if (!res || x != y) { + return(1); + } + + x = 10; + y = 123; + res = __sync_add_and_fetch(&x, y); + if (res != 123 + 10 || x != 123 + 10) { + return(1); + } + + return(0); + }" + HAVE_IB_GCC_ATOMIC_BUILTINS_64 + ) ENDIF() IF(HAVE_IB_GCC_ATOMIC_BUILTINS) ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS=1) ENDIF() +IF(HAVE_IB_GCC_ATOMIC_BUILTINS_64) + ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS_64=1) +ENDIF() + # either define HAVE_IB_ATOMIC_PTHREAD_T_GCC or not IF(NOT CMAKE_CROSSCOMPILING) CHECK_C_SOURCE_RUNS( @@ -244,7 +273,7 @@ SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c ibuf/ibuf0ibuf.c pars/lexyy.c pars/pars0grm.c pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c lock/lock0lock.c lock/lock0iter.c - log/log0log.c log/log0recv.c + log/log0log.c log/log0recv.c log/log0online.c mach/mach0data.c mem/mem0mem.c mem/mem0pool.c mtr/mtr0log.c mtr/mtr0mtr.c diff --git a/storage/xtradb/btr/btr0sea.c b/storage/xtradb/btr/btr0sea.c index 855ab62c42f..7e9449a6474 100644 --- a/storage/xtradb/btr/btr0sea.c +++ b/storage/xtradb/btr/btr0sea.c @@ -183,6 +183,15 @@ btr_search_sys_create( //rw_lock_create(btr_search_latch_key, &btr_search_latch, // SYNC_SEARCH_SYS); + /* PS bug lp:1018264 - Multiple hash index partitions causes overly + large hash index: When multiple adaptive hash index partitions are + specified, _each_ partition was being created with hash_size which + should be 1/64 of the total size of all buffer pools which is + incorrect and can cause overly high memory usage. hash_size + should be representing the _total_ size of all partitions, not the + individual size of each partition. */ + hash_size /= btr_search_index_num; + btr_search_sys = mem_alloc(sizeof(btr_search_sys_t)); /* btr_search_index_num should be <= 32. (bits of trx->has_search_latch) */ diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c index a2ff171e0c5..6ce77372dac 100644 --- a/storage/xtradb/buf/buf0buf.c +++ b/storage/xtradb/buf/buf0buf.c @@ -2838,6 +2838,7 @@ wait_until_unfixed: && ibuf_debug) { /* Try to evict the block from the buffer pool, to use the insert buffer (change buffer) as much as possible. */ + ulint page_no = buf_block_get_page_no(block); if (buf_LRU_free_block(&block->page, TRUE, FALSE)) { mutex_exit(block_mutex); @@ -2864,6 +2865,18 @@ wait_until_unfixed: "innodb_change_buffering_debug evict %u %u\n", (unsigned) space, (unsigned) offset); return(NULL); + } else if (UNIV_UNLIKELY(buf_block_get_state(block) + != BUF_BLOCK_FILE_PAGE + || (buf_block_get_page_no(block) != page_no) + || (buf_block_get_space(block) != space))) { + + /* buf_LRU_free_block temporarily releases the + block mutex, and now block points to something + else. */ + mutex_exit(block_mutex); + block = NULL; + goto loop2; + } else if (buf_flush_page_try(buf_pool, block)) { fprintf(stderr, "innodb_change_buffering_debug flush %u %u\n", diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c index 16a91358080..e8300107f3d 100644 --- a/storage/xtradb/buf/buf0lru.c +++ b/storage/xtradb/buf/buf0lru.c @@ -2531,6 +2531,14 @@ func_exit: Dump the LRU page list to the specific file. */ #define LRU_DUMP_FILE "ib_lru_dump" #define LRU_DUMP_TEMP_FILE "ib_lru_dump.tmp" +#define LRU_OS_FILE_WRITE() \ + os_file_write(LRU_DUMP_FILE, dump_file, buffer, \ + (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL, \ + (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)), \ + buffer_size) +#define LRU_DUMP_PAGE_COUNT 1 /* Specifies how many dump pages + should be filled for each hold + of the LRU_list_mutex. */ UNIV_INTERN ibool @@ -2541,23 +2549,30 @@ buf_LRU_file_dump(void) ibool success; byte* buffer_base = NULL; byte* buffer = NULL; + const ulint buffer_size = LRU_DUMP_PAGE_COUNT * UNIV_PAGE_SIZE; buf_page_t* bpage; + buf_page_t* first_bpage; ulint buffers; ulint offset; - ibool ret = FALSE; + ulint pages_written; ulint i; + ulint total_pages; + + /* Sanity test to make sure page size is a multiple of + assumed dump record size */ + ut_a(UNIV_PAGE_SIZE % 8 == 0); for (i = 0; i < srv_n_data_files; i++) { if (strstr(srv_data_file_names[i], LRU_DUMP_FILE) != NULL) { fprintf(stderr, " InnoDB: The name '%s' seems to be used for" - " innodb_data_file_path. For safety, dumping of the LRU list" - " is not being done.\n", LRU_DUMP_FILE); + " innodb_data_file_path. Dumping LRU list is" + " not done for safeness.\n", LRU_DUMP_FILE); goto end; } } - buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE); + buffer_base = ut_malloc(UNIV_PAGE_SIZE + buffer_size); buffer = ut_align(buffer_base, UNIV_PAGE_SIZE); if (!buffer) { fprintf(stderr, @@ -2577,18 +2592,28 @@ buf_LRU_file_dump(void) } buffers = offset = 0; - for (i = 0; i < srv_buf_pool_instances; i++) { buf_pool_t* buf_pool; buf_pool = buf_pool_from_array(i); mutex_enter(&buf_pool->LRU_list_mutex); - bpage = UT_LIST_GET_LAST(buf_pool->LRU); + bpage = first_bpage = UT_LIST_GET_FIRST(buf_pool->LRU); + total_pages = UT_LIST_GET_LEN(buf_pool->LRU); - while (bpage != NULL) { - if (offset == 0) { - memset(buffer, 0, UNIV_PAGE_SIZE); + pages_written = 0; + while (bpage != NULL && (pages_written++ < total_pages)) { + + buf_page_t* next_bpage = UT_LIST_GET_NEXT(LRU, bpage); + + if (next_bpage == first_bpage) { + /* Do not release list mutex here, it will be + released just outside this while loop */ + fprintf(stderr, + "InnoDB: detected cycle in LRU for" + " buffer pool %lu, skipping to next" + " buffer pool.\n", i); + break; } mach_write_to_4(buffer + offset * 4, bpage->space); @@ -2596,52 +2621,71 @@ buf_LRU_file_dump(void) mach_write_to_4(buffer + offset * 4, bpage->offset); offset++; - if (offset == UNIV_PAGE_SIZE/4) { + ut_a(offset <= buffer_size); + if (offset == buffer_size/4) { + mutex_t *next_block_mutex = NULL; + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { - success = 0; + mutex_exit(&buf_pool->LRU_list_mutex); + success = FALSE; fprintf(stderr, " InnoDB: stopped dumping lru" " pages because of server" " shutdown.\n"); + goto end; + } + + /* While writing file, release buffer pool + mutex but keep the next page fixed so we + don't worry about our list iterator becoming + invalid */ + if (next_bpage) { + next_block_mutex = buf_page_get_mutex( + next_bpage); + + mutex_enter(next_block_mutex); + next_bpage->buf_fix_count++; + mutex_exit(next_block_mutex); + } + mutex_exit(&buf_pool->LRU_list_mutex); + + success = LRU_OS_FILE_WRITE(); + + /* Grab this here so that next_bpage can't + be purged when we drop the fix_count */ + mutex_enter(&buf_pool->LRU_list_mutex); + + if (next_bpage) { + mutex_enter(next_block_mutex); + next_bpage->buf_fix_count--; + mutex_exit(next_block_mutex); } - success = os_file_write(LRU_DUMP_FILE, dump_file, buffer, - (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL, - (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)), - UNIV_PAGE_SIZE); + if (!success) { mutex_exit(&buf_pool->LRU_list_mutex); fprintf(stderr, - " InnoDB: cannot write page %lu of %s\n", + " InnoDB: cannot write page" + " %lu of %s\n", buffers, LRU_DUMP_FILE); goto end; } buffers++; offset = 0; - } - bpage = UT_LIST_GET_PREV(LRU, bpage); - } + bpage = next_bpage; + } else { + bpage = UT_LIST_GET_NEXT(LRU, bpage); + } + } /* while(bpage ...) */ mutex_exit(&buf_pool->LRU_list_mutex); - } - - if (offset == 0) { - memset(buffer, 0, UNIV_PAGE_SIZE); - } + } /* for(srv_buf_pool_instances ...) */ mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL); offset++; mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL); offset++; - success = os_file_write(LRU_DUMP_FILE, dump_file, buffer, - (buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL, - (buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)), - UNIV_PAGE_SIZE); - if (!success) { - goto end; - } - - ret = TRUE; + success = LRU_OS_FILE_WRITE(); end: if (dump_file != (os_file_t) -1) { if (success) { @@ -2656,7 +2700,7 @@ end: if (buffer_base) ut_free(buffer_base); - return(ret); + return(success); } typedef struct { diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 39d6fb4bf11..36b7daaa682 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -358,7 +358,8 @@ static PSI_thread_info all_innodb_threads[] = { {&srv_error_monitor_thread_key, "srv_error_monitor_thread", 0}, {&srv_monitor_thread_key, "srv_monitor_thread", 0}, {&srv_master_thread_key, "srv_master_thread", 0}, - {&srv_purge_thread_key, "srv_purge_thread", 0} + {&srv_purge_thread_key, "srv_purge_thread", 0}, + {&srv_log_tracking_thread_key, "srv_redo_log_follow_thread", 0} }; # endif /* UNIV_PFS_THREAD */ @@ -368,7 +369,8 @@ performance schema instrumented if "UNIV_PFS_IO" is defined */ static PSI_file_info all_innodb_files[] = { {&innodb_file_data_key, "innodb_data_file", 0}, {&innodb_file_log_key, "innodb_log_file", 0}, - {&innodb_file_temp_key, "innodb_temp_file", 0} + {&innodb_file_temp_key, "innodb_temp_file", 0}, + {&innodb_file_bmp_key, "innodb_bmp_file", 0} }; # endif /* UNIV_PFS_IO */ #endif /* HAVE_PSI_INTERFACE */ @@ -12634,9 +12636,9 @@ static MYSQL_SYSVAR_BOOL(use_sys_stats_table, innobase_use_sys_stats_table, "So you should use ANALYZE TABLE command intentionally.", NULL, NULL, FALSE); -#ifdef UNIV_DEBUG_never -static MYSQL_SYSVAR_ULONG(sys_stats_root_page, innobase_sys_stats_root_page, - PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, +#ifdef UNIV_DEBUG +static MYSQL_SYSVAR_ULONG(persistent_stats_root_page, + innobase_sys_stats_root_page, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Override the SYS_STATS root page id, 0 = no override (for testing only)", NULL, NULL, 0, 0, ULONG_MAX, 0); #endif @@ -12839,6 +12841,18 @@ static MYSQL_SYSVAR_ENUM(stats_method, srv_innodb_stats_method, "NULLS_UNEQUAL and NULLS_IGNORED", NULL, NULL, SRV_STATS_NULLS_EQUAL, &innodb_stats_method_typelib); +static MYSQL_SYSVAR_BOOL(track_changed_pages, srv_track_changed_pages, + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, + "Track the redo log for changed pages and output a changed page bitmap", + NULL, NULL, FALSE); + +static MYSQL_SYSVAR_ULONGLONG(changed_pages_limit, srv_changed_pages_limit, + PLUGIN_VAR_RQCMDARG, + "The maximum number of rows for " + "INFORMATION_SCHEMA.INNODB_CHANGED_PAGES table, " + "0 - unlimited", + NULL, NULL, 1000000, 0, ~0ULL, 0); + #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug, PLUGIN_VAR_RQCMDARG, @@ -13003,7 +13017,7 @@ static MYSQL_SYSVAR_UINT(buffer_pool_restore_at_startup, srv_auto_lru_dump, static MYSQL_SYSVAR_BOOL(blocking_buffer_pool_restore, innobase_blocking_lru_restore, - PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, + PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, "Block XtraDB startup process until buffer pool is full restored from a " "dump file (if present). Disabled by default.", NULL, NULL, FALSE); @@ -13090,8 +13104,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(stats_auto_update), MYSQL_SYSVAR(stats_update_need_lock), MYSQL_SYSVAR(use_sys_stats_table), -#ifdef UNIV_DEBUG_never /* disable this flag. --innodb-sys-stats becomes ambiguous */ - MYSQL_SYSVAR(sys_stats_root_page), +#ifdef UNIV_DEBUG + MYSQL_SYSVAR(persistent_stats_root_page), #endif MYSQL_SYSVAR(stats_sample_pages), MYSQL_SYSVAR(adaptive_hash_index), @@ -13123,6 +13137,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(use_sys_malloc), MYSQL_SYSVAR(use_native_aio), MYSQL_SYSVAR(change_buffering), + MYSQL_SYSVAR(track_changed_pages), + MYSQL_SYSVAR(changed_pages_limit), #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG MYSQL_SYSVAR(change_buffering_debug), #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ @@ -13160,32 +13176,32 @@ maria_declare_plugin(xtradb) INNODB_VERSION_STR, /* string version */ MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ }, -i_s_innodb_rseg_maria, -i_s_innodb_undo_logs_maria, -i_s_innodb_trx_maria, -i_s_innodb_locks_maria, -i_s_innodb_lock_waits_maria, -i_s_innodb_cmp_maria, -i_s_innodb_cmp_reset_maria, -i_s_innodb_cmpmem_maria, -i_s_innodb_cmpmem_reset_maria, -i_s_innodb_sys_tables_maria, -i_s_innodb_sys_tablestats_maria, -i_s_innodb_sys_indexes_maria, -i_s_innodb_sys_columns_maria, -i_s_innodb_sys_fields_maria, -i_s_innodb_sys_foreign_maria, -i_s_innodb_sys_foreign_cols_maria, -i_s_innodb_sys_stats_maria, -i_s_innodb_table_stats_maria, -i_s_innodb_index_stats_maria, -i_s_innodb_buffer_pool_pages_maria, -i_s_innodb_buffer_pool_pages_index_maria, -i_s_innodb_buffer_pool_pages_blob_maria, -i_s_innodb_admin_command_maria +i_s_innodb_rseg, +i_s_innodb_undo_logs, +i_s_innodb_trx, +i_s_innodb_locks, +i_s_innodb_lock_waits, +i_s_innodb_cmp, +i_s_innodb_cmp_reset, +i_s_innodb_cmpmem, +i_s_innodb_cmpmem_reset, +i_s_innodb_sys_tables, +i_s_innodb_sys_tablestats, +i_s_innodb_sys_indexes, +i_s_innodb_sys_columns, +i_s_innodb_sys_fields, +i_s_innodb_sys_foreign, +i_s_innodb_sys_foreign_cols, +i_s_innodb_sys_stats, +i_s_innodb_table_stats, +i_s_innodb_index_stats, +i_s_innodb_buffer_pool_pages, +i_s_innodb_buffer_pool_pages_index, +i_s_innodb_buffer_pool_pages_blob, +i_s_innodb_admin_command, +i_s_innodb_changed_pages maria_declare_plugin_end; - /** @brief Initialize the default value of innodb_commit_concurrency. Once InnoDB is running, the innodb_commit_concurrency must not change diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index 5d86ea98d27..57a091ea80d 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -22,6 +22,14 @@ InnoDB INFORMATION SCHEMA tables interface to MySQL. Created July 18, 2007 Vasil Dimov *******************************************************/ +#ifndef MYSQL_SERVER +#define MYSQL_SERVER /* For Item_* classes */ +#include <item.h> +/* Prevent influence of this definition to other headers */ +#undef MYSQL_SERVER +#else +#include <mysql_priv.h> +#endif //MYSQL_SERVER #include <ctype.h> /*toupper*/ #include <mysqld_error.h> @@ -45,6 +53,7 @@ extern "C" { #include "dict0mem.h" #include "dict0types.h" #include "ha_prototypes.h" /* for innobase_convert_name() */ +#include "srv0srv.h" /* for srv_track_changed_pages */ #include "srv0start.h" /* for srv_was_started */ #include "trx0i_s.h" #include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */ @@ -54,6 +63,7 @@ extern "C" { #include "dict0dict.h" /* for dict_sys */ #include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */ #include "btr0btr.h" /* for btr_page_get_index_id */ +#include "log0online.h" } #define OK(expr) \ @@ -601,7 +611,52 @@ static struct st_mysql_information_schema i_s_info = MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION }; +UNIV_INTERN struct st_maria_plugin i_s_innodb_trx = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_TRX"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB transactions"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_trx_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */ static ST_FIELD_INFO innodb_locks_fields_info[] = @@ -820,6 +875,52 @@ innodb_locks_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_locks = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_LOCKS"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB conflicting locks"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_locks_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */ static ST_FIELD_INFO innodb_lock_waits_fields_info[] = @@ -955,6 +1056,52 @@ innodb_lock_waits_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_LOCK_WAITS"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB which lock is blocking which"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_lock_waits_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /*******************************************************************//** Common function to fill any of the dynamic tables: @@ -1240,7 +1387,100 @@ i_s_cmp_reset_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_CMP"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "Statistics for the InnoDB compression"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_cmp_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; +UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_CMP_RESET"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "Statistics for the InnoDB compression;" + " reset cumulated counts"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_cmp_reset_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /* Fields of the dynamic table information_schema.innodb_cmpmem. */ static ST_FIELD_INFO i_s_cmpmem_fields_info[] = @@ -1436,8 +1676,100 @@ i_s_cmpmem_reset_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_CMPMEM"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_cmpmem_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; + +UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_CMPMEM_RESET"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;" + " reset cumulated counts"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_cmpmem_reset_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /*******************************************************************//** Unbind a dynamic INFORMATION_SCHEMA table. @@ -1656,6 +1988,52 @@ innodb_sys_tables_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_tables = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_SYS_TABLES"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB SYS_TABLES"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_sys_tables_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /* Fields of the dynamic table INFORMATION_SCHEMA.SYS_TABLESTATS */ static ST_FIELD_INFO innodb_sys_tablestats_fields_info[] = @@ -1907,6 +2285,52 @@ innodb_sys_tablestats_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_tablestats = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_SYS_TABLESTATS"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB SYS_TABLESTATS"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_sys_tablestats_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /* Fields of the dynamic table INFORMATION_SCHEMA.SYS_INDEXES */ static ST_FIELD_INFO innodb_sysindex_fields_info[] = @@ -2107,6 +2531,52 @@ innodb_sys_indexes_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_indexes = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_SYS_INDEXES"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB SYS_INDEXES"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_sys_indexes_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /* Fields of the dynamic table INFORMATION_SCHEMA.SYS_COLUMNS */ static ST_FIELD_INFO innodb_sys_columns_fields_info[] = @@ -2297,6 +2767,52 @@ innodb_sys_columns_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_columns = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_SYS_COLUMNS"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB SYS_COLUMNS"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_sys_columns_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_sys_fields */ static ST_FIELD_INFO innodb_sys_fields_fields_info[] = { @@ -2458,6 +2974,52 @@ innodb_sys_fields_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_fields = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_SYS_FIELDS"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB SYS_FIELDS"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_sys_fields_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign */ static ST_FIELD_INFO innodb_sys_foreign_fields_info[] = @@ -2633,6 +3195,52 @@ innodb_sys_foreign_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_foreign = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_SYS_FOREIGN"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB SYS_FOREIGN"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_sys_foreign_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign_cols */ static ST_FIELD_INFO innodb_sys_foreign_cols_fields_info[] = { @@ -2801,6 +3409,52 @@ innodb_sys_foreign_cols_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_foreign_cols = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_SYS_FOREIGN_COLS"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB SYS_FOREIGN_COLS"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_sys_foreign_cols_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_sys_stats */ static ST_FIELD_INFO innodb_sys_stats_fields_info[] = @@ -2970,6 +3624,52 @@ innodb_sys_stats_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_stats = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_SYS_STATS"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "XtraDB SYS_STATS table"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, innodb_sys_stats_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, INNODB_VERSION_SHORT), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /*********************************************************************** */ @@ -3085,6 +3785,52 @@ i_s_innodb_rseg_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_rseg = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_RSEG"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB rollback segment information"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_innodb_rseg_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, 0x0100 /* 1.0 */), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /*********************************************************************** */ @@ -3402,7 +4148,37 @@ i_s_innodb_index_stats_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_table_stats = +{ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + STRUCT_FLD(info, &i_s_info), + STRUCT_FLD(name, "INNODB_TABLE_STATS"), + STRUCT_FLD(author, "Percona"), + STRUCT_FLD(descr, "InnoDB table statistics in memory"), + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + STRUCT_FLD(init, i_s_innodb_table_stats_init), + STRUCT_FLD(deinit, i_s_common_deinit), + STRUCT_FLD(version, 0x0100 /* 1.0 */), + STRUCT_FLD(status_vars, NULL), + STRUCT_FLD(system_vars, NULL), + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; +UNIV_INTERN struct st_maria_plugin i_s_innodb_index_stats = +{ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + STRUCT_FLD(info, &i_s_info), + STRUCT_FLD(name, "INNODB_INDEX_STATS"), + STRUCT_FLD(author, "Percona"), + STRUCT_FLD(descr, "InnoDB index statistics in memory"), + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + STRUCT_FLD(init, i_s_innodb_index_stats_init), + STRUCT_FLD(deinit, i_s_common_deinit), + STRUCT_FLD(version, 0x0100 /* 1.0 */), + STRUCT_FLD(status_vars, NULL), + STRUCT_FLD(system_vars, NULL), + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /*********************************************************************** */ @@ -3556,6 +4332,21 @@ i_s_innodb_admin_command_init( DBUG_RETURN(0); } +UNIV_INTERN struct st_maria_plugin i_s_innodb_admin_command = +{ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + STRUCT_FLD(info, &i_s_info), + STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"), + STRUCT_FLD(author, "Percona"), + STRUCT_FLD(descr, "XtraDB specific command acceptor"), + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + STRUCT_FLD(init, i_s_innodb_admin_command_init), + STRUCT_FLD(deinit, i_s_common_deinit), + STRUCT_FLD(version, 0x0100 /* 1.0 */), + STRUCT_FLD(status_vars, NULL), + STRUCT_FLD(system_vars, NULL), + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; /*********************************************************************** */ @@ -4106,337 +4897,146 @@ i_s_innodb_buffer_pool_pages_blob_init( DBUG_RETURN(0); } -/* MariaDB structures of I_S plugins above */ -UNIV_INTERN struct st_maria_plugin i_s_innodb_trx_maria = +UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages = { - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_TRX", - plugin_author, - "InnoDB transactions", - PLUGIN_LICENSE_GPL, - innodb_trx_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_locks_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_LOCKS", - plugin_author, - "InnoDB conflicting locks", - PLUGIN_LICENSE_GPL, - innodb_locks_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_LOCK_WAITS", - plugin_author, - "InnoDB which lock is blocking which", - PLUGIN_LICENSE_GPL, - innodb_lock_waits_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_CMP", - plugin_author, - "Statistics for the InnoDB compression", - PLUGIN_LICENSE_GPL, - i_s_cmp_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_CMP_RESET", - plugin_author, - "Statistics for the InnoDB compression; reset cumulated counts", - PLUGIN_LICENSE_GPL, - i_s_cmp_reset_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_CMPMEM", - plugin_author, - "Statistics for the InnoDB compressed buffer pool", - PLUGIN_LICENSE_GPL, - i_s_cmpmem_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_CMPMEM_RESET", - plugin_author, - "Statistics for the InnoDB compressed buffer pool; reset cumulated counts", - PLUGIN_LICENSE_GPL, - i_s_cmpmem_reset_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_tables_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_SYS_TABLES", - "Percona", - "InnoDB SYS_TABLES", - PLUGIN_LICENSE_GPL, - innodb_sys_tables_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_tablestats_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_SYS_TABLESTATS", - "Percona", - "InnoDB SYS_TABLESTATS", - PLUGIN_LICENSE_GPL, - innodb_sys_tablestats_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_indexes_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_SYS_INDEXES", - "Percona", - "InnoDB SYS_INDEXES", - PLUGIN_LICENSE_GPL, - innodb_sys_indexes_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_columns_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_SYS_COLUMNS", - "Percona", - "InnoDB SYS_COLUMNS", - PLUGIN_LICENSE_GPL, - innodb_sys_columns_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_fields_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_SYS_FIELDS", - "Percona", - "InnoDB SYS_FIELDS", - PLUGIN_LICENSE_GPL, - innodb_sys_fields_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_foreign_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_SYS_FOREIGN", - "Percona", - "InnoDB SYS_FOREIGN", - PLUGIN_LICENSE_GPL, - innodb_sys_foreign_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_foreign_cols_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_SYS_FOREIGN_COLS", - "Percona", - "InnoDB SYS_FOREIGN_COLS", - PLUGIN_LICENSE_GPL, - innodb_sys_foreign_cols_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_stats_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_SYS_STATS", - "Percona", - "XtraDB SYS_STATS table", - PLUGIN_LICENSE_GPL, - innodb_sys_stats_init, - i_s_common_deinit, - INNODB_VERSION_SHORT, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_rseg_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_RSEG", - "Percona", - "InnoDB rollback segment information", - PLUGIN_LICENSE_GPL, - i_s_innodb_rseg_init, - i_s_common_deinit, - 0x0100, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_table_stats_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_TABLE_STATS", - "Percona", - "InnoDB table statistics in memory", - PLUGIN_LICENSE_GPL, - i_s_innodb_table_stats_init, - i_s_common_deinit, - 0x0100, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_index_stats_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_INDEX_STATS", - "Percona", - "InnoDB index statistics in memory", - PLUGIN_LICENSE_GPL, - i_s_innodb_index_stats_init, - i_s_common_deinit, - 0x0100, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_admin_command_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "XTRADB_ADMIN_COMMAND", - "Percona", - "XtraDB specific command acceptor", - PLUGIN_LICENSE_GPL, - i_s_innodb_admin_command_init, - i_s_common_deinit, - 0x0100, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE -}; -UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria = -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_BUFFER_POOL_PAGES", - "Percona", - "InnoDB buffer pool pages", - PLUGIN_LICENSE_GPL, - i_s_innodb_buffer_pool_pages_init, - i_s_common_deinit, - 0x0100, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB buffer pool pages"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, 0x0100 /* 1.0 */), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE }; -UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria = + +UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_index = { - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_BUFFER_POOL_PAGES_INDEX", - "Percona", - "InnoDB buffer pool index pages", - PLUGIN_LICENSE_GPL, - i_s_innodb_buffer_pool_pages_index_init, - i_s_common_deinit, - 0x0100, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_INDEX"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB buffer pool index pages"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_index_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, 0x0100 /* 1.0 */), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE }; -UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria = + +UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob = { - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &i_s_info, - "INNODB_BUFFER_POOL_PAGES_BLOB", - "Percona", - "InnoDB buffer pool blob pages", - PLUGIN_LICENSE_GPL, - i_s_innodb_buffer_pool_pages_blob_init, - i_s_common_deinit, - 0x0100, - NULL, - NULL, - INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_BUFFER_POOL_PAGES_BLOB"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB buffer pool blob pages"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_innodb_buffer_pool_pages_blob_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ + STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + /* unsigned int */ + STRUCT_FLD(version, 0x0100 /* 1.0 */), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE }; @@ -4632,7 +5232,7 @@ i_s_innodb_undo_logs_init( DBUG_RETURN(0); } -UNIV_INTERN struct st_mysql_plugin i_s_innodb_undo_logs = +UNIV_INTERN struct st_maria_plugin i_s_innodb_undo_logs = { /* the plugin type (a MYSQL_XXX_PLUGIN value) */ /* int */ @@ -4674,56 +5274,290 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_undo_logs = /* struct st_mysql_sys_var** */ STRUCT_FLD(system_vars, NULL), - /* reserved for dependency checking */ - /* void* */ - STRUCT_FLD(__reserved1, NULL), + INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE +}; - /* Plugin flags */ - /* unsigned long */ - STRUCT_FLD(flags, 0UL), +static ST_FIELD_INFO i_s_innodb_changed_pages_info[] = +{ + {STRUCT_FLD(field_name, "space_id"), + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + + {STRUCT_FLD(field_name, "page_id"), + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + + {STRUCT_FLD(field_name, "start_lsn"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + + {STRUCT_FLD(field_name, "end_lsn"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + + END_OF_ST_FIELD_INFO }; -UNIV_INTERN struct st_maria_plugin i_s_innodb_undo_logs_maria = +/*********************************************************************** + This function parses condition and gets upper bounds for start and end LSN's + if condition corresponds to certain pattern. + + We can't know right position to avoid scanning bitmap files from the beginning + to the lower bound. But we can stop scanning bitmap files if we reach upper bound. + + It's expected the most used queries will be like the following: + + SELECT * FROM INNODB_CHANGED_PAGES WHERE START_LSN > num1 AND start_lsn < num2; + + That's why the pattern is: + + pattern: comp | and_comp; + comp: lsn < int_num | lsn <= int_num | int_num > lsn | int_num >= lsn; + lsn: start_lsn | end_lsn; + and_comp: some_expression AND some_expression | some_expression AND and_comp; + some_expression: comp | any_other_expression; + + Suppose the condition is start_lsn < 100, this means we have to read all + blocks with start_lsn < 100. Which is equivalent to reading all the blocks + with end_lsn <= 99, or just end_lsn < 100. That's why it's enough to find + maximum lsn value, doesn't matter if this is start or end lsn and compare + it with "start_lsn" field. + + Example: + + SELECT * FROM INNODB_CHANGED_PAGES + WHERE + start_lsn > 10 AND + end_lsn <= 1111 AND + 555 > end_lsn AND + page_id = 100; + + max_lsn will be set to 555. +*/ +static +void +limit_lsn_range_from_condition( +/*===========================*/ + TABLE* table, /*!<in: table */ + COND* cond, /*!<in: condition */ + ib_uint64_t* max_lsn) /*!<in/out: maximum LSN + (must be initialized with maximum + available value) */ { - /* the plugin type (a MYSQL_XXX_PLUGIN value) */ - /* int */ - STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + if (cond->type() != Item::COND_ITEM && + cond->type() != Item::FUNC_ITEM) + return; + + switch (((Item_func*) cond)->functype()) + { + case Item_func::COND_AND_FUNC: + { + List_iterator<Item> li(*((Item_cond*) cond)-> + argument_list()); + Item *item; + while ((item= li++)) + limit_lsn_range_from_condition(table, + item, + max_lsn); + break; + } + case Item_func::LT_FUNC: + case Item_func::LE_FUNC: + case Item_func::GT_FUNC: + case Item_func::GE_FUNC: + { + Item *left; + Item *right; + Item_field *item_field; + ib_uint64_t tmp_result; + + /* + a <= b equals to b >= a that's why we just exchange + "left" and "right" in the case of ">" or ">=" + function + */ + if (((Item_func*) cond)->functype() == + Item_func::LT_FUNC || + ((Item_func*) cond)->functype() == + Item_func::LE_FUNC) + { + left = ((Item_func*) cond)->arguments()[0]; + right = ((Item_func*) cond)->arguments()[1]; + } else { + left = ((Item_func*) cond)->arguments()[1]; + right = ((Item_func*) cond)->arguments()[0]; + } - /* pointer to type-specific plugin descriptor */ - /* void* */ - STRUCT_FLD(info, &i_s_info), + if (!left || !right) + return; + if (left->type() != Item::FIELD_ITEM) + return; + if (right->type() != Item::INT_ITEM) + return; - /* plugin name */ - /* const char* */ - STRUCT_FLD(name, "INNODB_UNDO_LOGS"), + item_field = (Item_field*)left; - /* plugin author (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(author, "Percona"), + if (/* START_LSN */ + table->field[2] != item_field->field && + /* END_LSN */ + table->field[3] != item_field->field) + { + return; + } - /* general descriptive text (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(descr, "InnoDB rollback undo segment information"), + /* Check if the current field belongs to our table */ + if (table != item_field->field->table) + return; - /* the plugin license (PLUGIN_LICENSE_XXX) */ - /* int */ - STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + tmp_result = right->val_int(); + if (tmp_result < *max_lsn) + *max_lsn = tmp_result; - /* the function to invoke when plugin is loaded */ - /* int (*)(void*); */ - STRUCT_FLD(init, i_s_innodb_undo_logs_init), + break; + } + default:; + } - /* the function to invoke when plugin is unloaded */ - /* int (*)(void*); */ STRUCT_FLD(deinit, i_s_common_deinit), +} - /* plugin version (for SHOW PLUGINS) */ - STRUCT_FLD(version, 0x0100 /* 1.0 */), +/*********************************************************************** +Fill the dynamic table information_schema.innodb_changed_pages. +@return 0 on success, 1 on failure */ +static +int +i_s_innodb_changed_pages_fill( +/*==========================*/ + THD* thd, /*!<in: thread */ + TABLE_LIST* tables, /*!<in/out: tables to fill */ + COND* cond) /*!<in: condition */ +{ + TABLE* table = (TABLE *) tables->table; + log_bitmap_iterator_t i; + ib_uint64_t output_rows_num = 0UL; + ib_uint64_t max_lsn = ~0ULL; + + if (!srv_track_changed_pages) + return 0; + + if (!log_online_bitmap_iterator_init(&i)) + return 1; + + if (cond) + limit_lsn_range_from_condition(table, cond, &max_lsn); + + while(log_online_bitmap_iterator_next(&i) && + (!srv_changed_pages_limit || + output_rows_num < srv_changed_pages_limit) && + /* + There is no need to compare both start LSN and end LSN fields + with maximum value. It's enough to compare only start LSN. + Example: + + max_lsn = 100 + \\\\\\\\\\\\\\\\\\\\\\\\\|\\\\\\\\ - Query 1 + I------I I-------I I-------------I I----I + ////////////////// | - Query 2 + 1 2 3 4 + + Query 1: + SELECT * FROM INNODB_CHANGED_PAGES WHERE start_lsn < 100 + will select 1,2,3 bitmaps + Query 2: + SELECT * FROM INNODB_CHANGED_PAGES WHERE end_lsn < 100 + will select 1,2 bitmaps + + The condition start_lsn <= 100 will be false after reading + 1,2,3 bitmaps which suits for both cases. + */ + LOG_BITMAP_ITERATOR_START_LSN(i) <= max_lsn) + { + if (!LOG_BITMAP_ITERATOR_PAGE_CHANGED(i)) + continue; - /* struct st_mysql_show_var* */ - STRUCT_FLD(status_vars, NULL), + /* SPACE_ID */ + table->field[0]->store( + LOG_BITMAP_ITERATOR_SPACE_ID(i)); + /* PAGE_ID */ + table->field[1]->store( + LOG_BITMAP_ITERATOR_PAGE_NUM(i)); + /* START_LSN */ + table->field[2]->store( + LOG_BITMAP_ITERATOR_START_LSN(i)); + /* END_LSN */ + table->field[3]->store( + LOG_BITMAP_ITERATOR_END_LSN(i)); + + /* + I_S tables are in-memory tables. If bitmap file is big enough + a lot of memory can be used to store the table. But the size + of used memory can be diminished if we store only data which + corresponds to some conditions (in WHERE sql clause). Here + conditions are checked for the field values stored above. + + Conditions are checked twice. The first is here (during table + generation) and the second during query execution. Maybe it + makes sense to use some flag in THD object to avoid double + checking. + */ + if (cond && !cond->val_int()) + continue; - /* struct st_mysql_sys_var** */ - STRUCT_FLD(system_vars, NULL), + if (schema_table_store_record(thd, table)) + { + log_online_bitmap_iterator_release(&i); + return 1; + } + + ++output_rows_num; + } + + log_online_bitmap_iterator_release(&i); + return 0; +} + +static +int +i_s_innodb_changed_pages_init( +/*==========================*/ + void* p) +{ + DBUG_ENTER("i_s_innodb_changed_pages_init"); + ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; + schema->fields_info = i_s_innodb_changed_pages_info; + schema->fill_table = i_s_innodb_changed_pages_fill; + + DBUG_RETURN(0); +} + +UNIV_INTERN struct st_maria_plugin i_s_innodb_changed_pages = +{ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + STRUCT_FLD(info, &i_s_info), + STRUCT_FLD(name, "INNODB_CHANGED_PAGES"), + STRUCT_FLD(author, "Percona"), + STRUCT_FLD(descr, "InnoDB CHANGED_PAGES table"), + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + STRUCT_FLD(init, i_s_innodb_changed_pages_init), + STRUCT_FLD(deinit, i_s_common_deinit), + STRUCT_FLD(version, 0x0100 /* 1.0 */), + STRUCT_FLD(status_vars, NULL), + STRUCT_FLD(system_vars, NULL), INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE }; diff --git a/storage/xtradb/handler/i_s.h b/storage/xtradb/handler/i_s.h index 329cc2f5f91..a8964356747 100644 --- a/storage/xtradb/handler/i_s.h +++ b/storage/xtradb/handler/i_s.h @@ -28,52 +28,29 @@ Created July 18, 2007 Vasil Dimov const char plugin_author[] = "Oracle Corporation"; -extern struct st_mysql_plugin i_s_innodb_trx; -extern struct st_mysql_plugin i_s_innodb_locks; -extern struct st_mysql_plugin i_s_innodb_lock_waits; -extern struct st_mysql_plugin i_s_innodb_cmp; -extern struct st_mysql_plugin i_s_innodb_cmp_reset; -extern struct st_mysql_plugin i_s_innodb_cmpmem; -extern struct st_mysql_plugin i_s_innodb_cmpmem_reset; -extern struct st_mysql_plugin i_s_innodb_sys_tables; -extern struct st_mysql_plugin i_s_innodb_sys_tablestats; -extern struct st_mysql_plugin i_s_innodb_sys_indexes; -extern struct st_mysql_plugin i_s_innodb_sys_columns; -extern struct st_mysql_plugin i_s_innodb_sys_fields; -extern struct st_mysql_plugin i_s_innodb_sys_foreign; -extern struct st_mysql_plugin i_s_innodb_sys_foreign_cols; -extern struct st_mysql_plugin i_s_innodb_rseg; -extern struct st_mysql_plugin i_s_innodb_undo_logs; -extern struct st_mysql_plugin i_s_innodb_sys_stats; -extern struct st_mysql_plugin i_s_innodb_table_stats; -extern struct st_mysql_plugin i_s_innodb_index_stats; -extern struct st_mysql_plugin i_s_innodb_admin_command; -extern struct st_mysql_plugin i_s_innodb_buffer_pool_pages; -extern struct st_mysql_plugin i_s_innodb_buffer_pool_pages_index; -extern struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob; - -extern struct st_maria_plugin i_s_innodb_trx_maria; -extern struct st_maria_plugin i_s_innodb_locks_maria; -extern struct st_maria_plugin i_s_innodb_lock_waits_maria; -extern struct st_maria_plugin i_s_innodb_cmp_maria; -extern struct st_maria_plugin i_s_innodb_cmp_reset_maria; -extern struct st_maria_plugin i_s_innodb_cmpmem_maria; -extern struct st_maria_plugin i_s_innodb_cmpmem_reset_maria; -extern struct st_maria_plugin i_s_innodb_sys_tables_maria; -extern struct st_maria_plugin i_s_innodb_sys_tablestats_maria; -extern struct st_maria_plugin i_s_innodb_sys_indexes_maria; -extern struct st_maria_plugin i_s_innodb_sys_columns_maria; -extern struct st_maria_plugin i_s_innodb_sys_fields_maria; -extern struct st_maria_plugin i_s_innodb_sys_foreign_maria; -extern struct st_maria_plugin i_s_innodb_sys_foreign_cols_maria; -extern struct st_maria_plugin i_s_innodb_sys_stats_maria; -extern struct st_maria_plugin i_s_innodb_rseg_maria; -extern struct st_maria_plugin i_s_innodb_undo_logs_maria; -extern struct st_maria_plugin i_s_innodb_table_stats_maria; -extern struct st_maria_plugin i_s_innodb_index_stats_maria; -extern struct st_maria_plugin i_s_innodb_admin_command_maria; -extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_maria; -extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_index_maria; -extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria; +extern struct st_maria_plugin i_s_innodb_trx; +extern struct st_maria_plugin i_s_innodb_locks; +extern struct st_maria_plugin i_s_innodb_lock_waits; +extern struct st_maria_plugin i_s_innodb_cmp; +extern struct st_maria_plugin i_s_innodb_cmp_reset; +extern struct st_maria_plugin i_s_innodb_cmpmem; +extern struct st_maria_plugin i_s_innodb_cmpmem_reset; +extern struct st_maria_plugin i_s_innodb_sys_tables; +extern struct st_maria_plugin i_s_innodb_sys_tablestats; +extern struct st_maria_plugin i_s_innodb_sys_indexes; +extern struct st_maria_plugin i_s_innodb_sys_columns; +extern struct st_maria_plugin i_s_innodb_sys_fields; +extern struct st_maria_plugin i_s_innodb_sys_foreign; +extern struct st_maria_plugin i_s_innodb_sys_foreign_cols; +extern struct st_maria_plugin i_s_innodb_rseg; +extern struct st_maria_plugin i_s_innodb_undo_logs; +extern struct st_maria_plugin i_s_innodb_sys_stats; +extern struct st_maria_plugin i_s_innodb_table_stats; +extern struct st_maria_plugin i_s_innodb_index_stats; +extern struct st_maria_plugin i_s_innodb_admin_command; +extern struct st_maria_plugin i_s_innodb_buffer_pool_pages; +extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_index; +extern struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob; +extern struct st_maria_plugin i_s_innodb_changed_pages; #endif /* i_s_h */ diff --git a/storage/xtradb/include/buf0lru.h b/storage/xtradb/include/buf0lru.h index c3672a65ed7..efaa758f27a 100644 --- a/storage/xtradb/include/buf0lru.h +++ b/storage/xtradb/include/buf0lru.h @@ -94,13 +94,12 @@ buf_LRU_insert_zip_clean( Try to free a block. If bpage is a descriptor of a compressed-only page, the descriptor object will be freed as well. -NOTE: If this function returns TRUE, it will temporarily -release buf_pool->mutex. Furthermore, the page frame will no longer be -accessible via bpage. +NOTE: This will temporarily release buf_pool_mutex. Furthermore, the +page frame will no longer be accessible via bpage. -The caller must hold buf_pool->mutex and buf_page_get_mutex(bpage) and -release these two mutexes after the call. No other -buf_page_get_mutex() may be held when calling this function. +The caller must hold buf_page_get_mutex(bpage) and release this mutex +after the call. No other buf_page_get_mutex() may be held when +calling this function. @return TRUE if freed, FALSE otherwise. */ UNIV_INTERN ibool diff --git a/storage/xtradb/include/log0log.h b/storage/xtradb/include/log0log.h index 857ec0946c2..96c4b81695a 100644 --- a/storage/xtradb/include/log0log.h +++ b/storage/xtradb/include/log0log.h @@ -977,6 +977,11 @@ struct log_struct{ become signaled */ /* @} */ #endif /* UNIV_LOG_ARCHIVE */ + ib_uint64_t tracked_lsn; /*!< log tracking has advanced to this + lsn. Field accessed atomically where + 64-bit atomic ops are supported, + protected by the log sys mutex + otherwise. */ }; /** Test if flush order mutex is owned. */ diff --git a/storage/xtradb/include/log0online.h b/storage/xtradb/include/log0online.h new file mode 100644 index 00000000000..0e0ca169f6f --- /dev/null +++ b/storage/xtradb/include/log0online.h @@ -0,0 +1,111 @@ +/***************************************************************************** + +Copyright (c) 2011-2012, Percona Inc. All Rights Reserved. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +/**************************************************//** +@file include/log0online.h +Online database log parsing for changed page tracking +*******************************************************/ + +#ifndef log0online_h +#define log0online_h + +#include "univ.i" +#include "os0file.h" + +/*********************************************************************//** +Initializes the online log following subsytem. */ +UNIV_INTERN +void +log_online_read_init(); +/*===================*/ + +/*********************************************************************//** +Shuts down the online log following subsystem. */ +UNIV_INTERN +void +log_online_read_shutdown(); +/*=======================*/ + +/*********************************************************************//** +Reads and parses the redo log up to last checkpoint LSN to build the changed +page bitmap which is then written to disk. */ +UNIV_INTERN +void +log_online_follow_redo_log(); +/*=========================*/ + +/** The iterator through all bits of changed pages bitmap blocks */ +struct log_bitmap_iterator_struct +{ + char in_name[FN_REFLEN]; /*!< the file name for bitmap + input */ + os_file_t in; /*!< the bitmap input file */ + ib_uint64_t in_offset; /*!< the next write position in the + bitmap output file */ + ib_uint32_t bit_offset; /*!< bit offset inside of bitmap + block*/ + ib_uint64_t start_lsn; /*!< Start lsn of the block */ + ib_uint64_t end_lsn; /*!< End lsn of the block */ + ib_uint32_t space_id; /*!< Block space id */ + ib_uint32_t first_page_id; /*!< First block page id */ + ibool changed; /*!< true if current page was changed */ + byte* page; /*!< Bitmap block */ +}; + +typedef struct log_bitmap_iterator_struct log_bitmap_iterator_t; + +#define LOG_BITMAP_ITERATOR_START_LSN(i) \ + ((i).start_lsn) +#define LOG_BITMAP_ITERATOR_END_LSN(i) \ + ((i).end_lsn) +#define LOG_BITMAP_ITERATOR_SPACE_ID(i) \ + ((i).space_id) +#define LOG_BITMAP_ITERATOR_PAGE_NUM(i) \ + ((i).first_page_id + (i).bit_offset) +#define LOG_BITMAP_ITERATOR_PAGE_CHANGED(i) \ + ((i).changed) + +/*********************************************************************//** +Initializes log bitmap iterator. +@return TRUE if the iterator is initialized OK, FALSE otherwise. */ +UNIV_INTERN +ibool +log_online_bitmap_iterator_init( +/*============================*/ + log_bitmap_iterator_t *i); /*!<in/out: iterator */ + +/*********************************************************************//** +Releases log bitmap iterator. */ +UNIV_INTERN +void +log_online_bitmap_iterator_release( +/*===============================*/ + log_bitmap_iterator_t *i); /*!<in/out: iterator */ + +/*********************************************************************//** +Iterates through bits of saved bitmap blocks. +Sequentially reads blocks from bitmap file(s) and interates through +their bits. Ignores blocks with wrong checksum. +@return TRUE if iteration is successful, FALSE if all bits are iterated. */ +UNIV_INTERN +ibool +log_online_bitmap_iterator_next( +/*============================*/ + log_bitmap_iterator_t *i); /*!<in/out: iterator */ + +#endif diff --git a/storage/xtradb/include/log0recv.h b/storage/xtradb/include/log0recv.h index 15065267250..fdffd86e4c4 100644 --- a/storage/xtradb/include/log0recv.h +++ b/storage/xtradb/include/log0recv.h @@ -32,6 +32,28 @@ Created 9/20/1997 Heikki Tuuri #include "hash0hash.h" #include "log0log.h" +/******************************************************//** +Checks the 4-byte checksum to the trailer checksum field of a log +block. We also accept a log block in the old format before +InnoDB-3.23.52 where the checksum field contains the log block number. +@return TRUE if ok, or if the log block may be in the format of InnoDB +version predating 3.23.52 */ +UNIV_INTERN +ibool +log_block_checksum_is_ok_or_old_format( +/*===================================*/ + const byte* block); /*!< in: pointer to a log block */ + +/*******************************************************//** +Calculates the new value for lsn when more data is added to the log. */ +UNIV_INTERN +ib_uint64_t +recv_calc_lsn_on_data_add( +/*======================*/ + ib_uint64_t lsn, /*!< in: old lsn */ + ib_uint64_t len); /*!< in: this many bytes of data is + added, log block headers not included */ + #ifdef UNIV_HOTBACKUP extern ibool recv_replay_file_ops; @@ -182,6 +204,21 @@ UNIV_INTERN void recv_recovery_rollback_active(void); /*===============================*/ + +/*******************************************************************//** +Tries to parse a single log record and returns its length. +@return length of the record, or 0 if the record was not complete */ +UNIV_INTERN +ulint +recv_parse_log_rec( +/*===============*/ + byte* ptr, /*!< in: pointer to a buffer */ + byte* end_ptr,/*!< in: pointer to the buffer end */ + byte* type, /*!< out: type */ + ulint* space, /*!< out: space id */ + ulint* page_no,/*!< out: page number */ + byte** body); /*!< out: log record body start */ + /*******************************************************//** Scans log from a buffer and stores new log data to the parsing buffer. Parses and hashes the log records if new data found. Unless diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h index 5b1f9339845..4c795d93141 100644 --- a/storage/xtradb/include/os0file.h +++ b/storage/xtradb/include/os0file.h @@ -197,6 +197,7 @@ extern ulint srv_log_block_size; extern mysql_pfs_key_t innodb_file_data_key; extern mysql_pfs_key_t innodb_file_log_key; extern mysql_pfs_key_t innodb_file_temp_key; +extern mysql_pfs_key_t innodb_file_bmp_key; /* Following four macros are instumentations to register various file I/O operations with performance schema. @@ -867,6 +868,14 @@ os_file_set_eof( /*============*/ FILE* file); /*!< in: file to be truncated */ /***********************************************************************//** +Truncates a file at the specified position. +@return TRUE if success */ +UNIV_INTERN +ibool +os_file_set_eof_at( + os_file_t file, /*!< in: handle to a file */ + ib_uint64_t new_len);/*!< in: new file length */ +/***********************************************************************//** NOTE! Use the corresponding macro os_file_flush(), not directly this function! Flushes the write buffers of a given file to the disk. @return TRUE if success */ diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h index 6a99c60226b..887a40c64ea 100644 --- a/storage/xtradb/include/os0sync.h +++ b/storage/xtradb/include/os0sync.h @@ -265,7 +265,11 @@ Atomic compare-and-swap and increment for InnoDB. */ #if defined(HAVE_IB_GCC_ATOMIC_BUILTINS) -#define HAVE_ATOMIC_BUILTINS +# define HAVE_ATOMIC_BUILTINS + +# ifdef HAVE_IB_GCC_ATOMIC_BUILTINS_64 +# define HAVE_ATOMIC_BUILTINS_64 +# endif /**********************************************************//** Returns true if swapped, ptr is pointer to target, old_val is value to @@ -304,6 +308,9 @@ amount of increment. */ # define os_atomic_increment_ulint(ptr, amount) \ os_atomic_increment(ptr, amount) +# define os_atomic_increment_uint64(ptr, amount) \ + os_atomic_increment(ptr, amount) + /**********************************************************//** Returns the old value of *ptr, atomically sets *ptr to new_val */ @@ -312,12 +319,13 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */ #elif defined(HAVE_IB_SOLARIS_ATOMICS) -#define HAVE_ATOMIC_BUILTINS +# define HAVE_ATOMIC_BUILTINS +# define HAVE_ATOMIC_BUILTINS_64 /* If not compiling with GCC or GCC doesn't support the atomic intrinsics and running on Solaris >= 10 use Solaris atomics */ -#include <atomic.h> +# include <atomic.h> /**********************************************************//** Returns true if swapped, ptr is pointer to target, old_val is value to @@ -357,6 +365,9 @@ amount of increment. */ # define os_atomic_increment_ulint(ptr, amount) \ atomic_add_long_nv(ptr, amount) +# define os_atomic_increment_uint64(ptr, amount) \ + atomic_add_64_nv(ptr, amount) + /**********************************************************//** Returns the old value of *ptr, atomically sets *ptr to new_val */ @@ -365,7 +376,11 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */ #elif defined(HAVE_WINDOWS_ATOMICS) -#define HAVE_ATOMIC_BUILTINS +# define HAVE_ATOMIC_BUILTINS + +# ifndef _WIN32 +# define HAVE_ATOMIC_BUILTINS_64 +# endif /* On Windows, use Windows atomics / interlocked */ # ifdef _WIN64 @@ -403,6 +418,11 @@ amount of increment. */ # define os_atomic_increment_ulint(ptr, amount) \ ((ulint) (win_xchg_and_add(ptr, amount) + amount)) +# define os_atomic_increment_uint64(ptr, amount) \ + ((ib_uint64_t) (InterlockedExchangeAdd64( \ + (ib_int64_t*) ptr, \ + (ib_int64_t) amount) + amount)) + /**********************************************************//** Returns the old value of *ptr, atomically sets *ptr to new_val. InterlockedExchange() operates on LONG, and the LONG will be diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h index a40683e00f1..b8820f1b7c9 100644 --- a/storage/xtradb/include/srv0srv.h +++ b/storage/xtradb/include/srv0srv.h @@ -69,6 +69,14 @@ extern os_event_t srv_error_event; /* This event is set at shutdown to wakeup threads from sleep */ extern os_event_t srv_shutdown_event; +/* This event is set on checkpoint completion to wake the redo log parser +thread */ +extern os_event_t srv_checkpoint_completed_event; + +/* This event is set on the online redo log following thread exit to signal +that the (slow) shutdown may proceed */ +extern os_event_t srv_redo_log_thread_finished_event; + /* If the last data file is auto-extended, we add this many pages to it at a time */ #define SRV_AUTO_EXTEND_INCREMENT \ @@ -136,6 +144,11 @@ extern char* srv_doublewrite_file; extern ibool srv_recovery_stats; +extern my_bool srv_track_changed_pages; + +extern +ulonglong srv_changed_pages_limit; + extern ibool srv_auto_extend_last_data_file; extern ulint srv_last_file_size_max; extern char** srv_log_group_home_dirs; @@ -402,6 +415,7 @@ extern mysql_pfs_key_t srv_error_monitor_thread_key; extern mysql_pfs_key_t srv_monitor_thread_key; extern mysql_pfs_key_t srv_master_thread_key; extern mysql_pfs_key_t srv_purge_thread_key; +extern mysql_pfs_key_t srv_log_tracking_thread_key; /* This macro register the current thread and its key with performance schema */ @@ -697,6 +711,15 @@ srv_LRU_dump_restore_thread( void* arg); /*!< in: a dummy parameter required by os_thread_create */ /******************************************************************//** +A thread which follows the redo log and outputs the changed page bitmap. +@return a dummy value */ +UNIV_INTERN +os_thread_ret_t +srv_redo_log_follow_thread( +/*=======================*/ + void* arg); /*!< in: a dummy parameter required by + os_thread_create */ +/******************************************************************//** Outputs to a file the output of the InnoDB Monitor. @return FALSE if not all information printed due to failure to obtain necessary mutex */ diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index ce59a3f2741..9aee2a0c7f9 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -54,7 +54,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_BUGFIX 8 #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 28.1 +#define PERCONA_INNODB_VERSION 29.0 #endif /* The following is the InnoDB version as shown in diff --git a/storage/xtradb/include/ut0rbt.h b/storage/xtradb/include/ut0rbt.h index e26b637ae13..cd9df1c1a3d 100644 --- a/storage/xtradb/include/ut0rbt.h +++ b/storage/xtradb/include/ut0rbt.h @@ -116,6 +116,10 @@ struct ib_rbt_bound_struct { /* Compare a key with the node value (t is tree, k is key, n is node)*/ #define rbt_compare(t, k, n) (t->compare(k, n->value)) +/* Node size. FIXME: name might clash, but currently it does not, so for easier + maintenance do not rename it for now. */ +#define SIZEOF_NODE(t) ((sizeof(ib_rbt_node_t) + t->sizeof_value) - 1) + /**********************************************************************//** Free an instance of a red black tree */ UNIV_INTERN @@ -187,6 +191,17 @@ rbt_add_node( ib_rbt_bound_t* parent, /*!< in: parent */ const void* value); /*!< in: this value is copied to the node */ +/****************************************************************//** +Add a new caller-provided node to tree at the specified position. +The node must have its key fields initialized correctly. +@return added node */ +UNIV_INTERN +const ib_rbt_node_t* +rbt_add_preallocated_node( +/*======================*/ + ib_rbt_t* tree, /*!< in: rb tree */ + ib_rbt_bound_t* parent, /*!< in: parent */ + ib_rbt_node_t* node); /*!< in: node */ /**********************************************************************//** Return the left most data node in the tree @return left most node */ @@ -273,6 +288,13 @@ void rbt_clear( /*======*/ ib_rbt_t* tree); /*!< in: rb tree */ +/****************************************************************//** +Clear the tree without deleting and freeing its nodes. */ +UNIV_INTERN +void +rbt_reset( +/*======*/ + ib_rbt_t* tree); /*!< in: rb tree */ /**********************************************************************//** Merge the node from dst into src. Return the number of nodes merged. @return no. of recs merged */ diff --git a/storage/xtradb/log/log0log.c b/storage/xtradb/log/log0log.c index dcaf951a0ed..e3e023c0c5a 100644 --- a/storage/xtradb/log/log0log.c +++ b/storage/xtradb/log/log0log.c @@ -216,6 +216,54 @@ log_buf_pool_get_oldest_modification(void) return(lsn); } +/****************************************************************//** +Safely reads the log_sys->tracked_lsn value. Uses atomic operations +if available, otherwise this field is protected with the log system +mutex. The writer counterpart function is log_set_tracked_lsn() in +log0online.c. + +@return log_sys->tracked_lsn value. */ +UNIV_INLINE +ib_uint64_t +log_get_tracked_lsn() +{ +#ifdef HAVE_ATOMIC_BUILTINS_64 + return os_atomic_increment_uint64(&log_sys->tracked_lsn, 0); +#else + ut_ad(mutex_own(&(log_sys->mutex))); + return log_sys->tracked_lsn; +#endif +} + +/****************************************************************//** +Checks if the log groups have a big enough margin of free space in +so that a new log entry can be written without overwriting log data +that is not read by the changed page bitmap thread. +@return TRUE if there is not enough free space. */ +static +ibool +log_check_tracking_margin( + ulint lsn_advance) /*!< in: an upper limit on how much log data we + plan to write. If zero, the margin will be + checked for the already-written log. */ +{ + ib_uint64_t tracked_lsn; + ulint tracked_lsn_age; + + if (!srv_track_changed_pages) { + return FALSE; + } + + ut_ad(mutex_own(&(log_sys->mutex))); + + tracked_lsn = log_get_tracked_lsn(); + tracked_lsn_age = log_sys->lsn - tracked_lsn; + + /* The overwrite would happen when log_sys->log_group_capacity is + exceeded, but we use max_checkpoint_age for an extra safety margin. */ + return tracked_lsn_age + lsn_advance > log_sys->max_checkpoint_age; +} + /************************************************************//** Opens the log for log_write_low. The log must be closed with log_close and released with log_release. @@ -232,9 +280,7 @@ log_reserve_and_open( ulint archived_lsn_age; ulint dummy; #endif /* UNIV_LOG_ARCHIVE */ -#ifdef UNIV_DEBUG ulint count = 0; -#endif /* UNIV_DEBUG */ ut_a(len < log->buf_size / 2); loop: @@ -262,6 +308,19 @@ loop: goto loop; } + if (log_check_tracking_margin(len_upper_limit) && (++count < 50)) { + + /* This log write would violate the untracked LSN free space + margin. Limit this to 50 retries as there might be situations + where we have no choice but to proceed anyway, i.e. if the log + is about to be overflown, log tracking or not. */ + mutex_exit(&(log->mutex)); + + os_thread_sleep(10000); + + goto loop; + } + #ifdef UNIV_LOG_ARCHIVE if (log->archiving_state != LOG_ARCH_OFF) { @@ -400,6 +459,8 @@ log_close(void) ulint first_rec_group; ib_uint64_t oldest_lsn; ib_uint64_t lsn; + ib_uint64_t tracked_lsn; + ulint tracked_lsn_age; log_t* log = log_sys; ib_uint64_t checkpoint_age; @@ -426,6 +487,19 @@ log_close(void) log->check_flush_or_checkpoint = TRUE; } + if (srv_track_changed_pages) { + + tracked_lsn = log_get_tracked_lsn(); + tracked_lsn_age = lsn - tracked_lsn; + + if (tracked_lsn_age >= log->log_group_capacity) { + + fprintf(stderr, " InnoDB: Error: the age of the " + "oldest untracked record exceeds the log " + "group capacity!\n"); + } + } + checkpoint_age = lsn - log->last_checkpoint_lsn; if (checkpoint_age >= log->log_group_capacity) { @@ -893,6 +967,8 @@ log_init(void) log_sys->archiving_on = os_event_create(NULL); #endif /* UNIV_LOG_ARCHIVE */ + log_sys->tracked_lsn = 0; + /*----------------------------*/ log_block_init(log_sys->buf, log_sys->lsn); @@ -1742,6 +1818,12 @@ log_io_complete_checkpoint(void) } mutex_exit(&(log_sys->mutex)); + + /* Wake the redo log watching thread to parse the log up to this + checkpoint. */ + if (srv_track_changed_pages) { + os_event_set(srv_checkpoint_completed_event); + } } /*******************************************************************//** @@ -3169,6 +3251,15 @@ loop: log_checkpoint_margin(); + mutex_enter(&(log_sys->mutex)); + if (log_check_tracking_margin(0)) { + + mutex_exit(&(log_sys->mutex)); + os_thread_sleep(10000); + goto loop; + } + mutex_exit(&(log_sys->mutex)); + #ifdef UNIV_LOG_ARCHIVE log_archive_margin(); #endif /* UNIV_LOG_ARCHIVE */ @@ -3197,6 +3288,7 @@ logs_empty_and_mark_files_at_shutdown(void) /*=======================================*/ { ib_uint64_t lsn; + ib_uint64_t tracked_lsn; ulint arch_log_no; ibool server_busy; ulint count = 0; @@ -3388,6 +3480,12 @@ loop: } srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE; + /* Wake the log tracking thread which will then immediatelly + quit because of srv_shutdown_state value */ + if (srv_track_changed_pages) { + os_event_set(srv_checkpoint_completed_event); + os_event_wait(srv_redo_log_thread_finished_event); + } fil_close_all_files(); ut_a(srv_get_active_thread_type() == ULINT_UNDEFINED); return; @@ -3397,9 +3495,12 @@ loop: mutex_enter(&log_sys->mutex); + tracked_lsn = log_get_tracked_lsn(); + lsn = log_sys->lsn; if (lsn != log_sys->last_checkpoint_lsn + || (srv_track_changed_pages && (tracked_lsn != log_sys->last_checkpoint_lsn)) #ifdef UNIV_LOG_ARCHIVE || (srv_log_archive_on && lsn != log_sys->archived_lsn + LOG_BLOCK_HDR_SIZE) @@ -3457,6 +3558,11 @@ loop: srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE; + /* Signal the log following thread to quit */ + if (srv_track_changed_pages) { + os_event_set(srv_checkpoint_completed_event); + } + /* Make some checks that the server really is quiet */ ut_a(srv_get_active_thread_type() == ULINT_UNDEFINED); @@ -3477,6 +3583,10 @@ loop: fil_flush_file_spaces(FIL_TABLESPACE); + if (srv_track_changed_pages) { + os_event_wait(srv_redo_log_thread_finished_event); + } + fil_close_all_files(); /* Make some checks that the server really is quiet */ @@ -3603,6 +3713,18 @@ log_print( ((log_sys->n_log_ios - log_sys->n_log_ios_old) / time_elapsed)); + if (srv_track_changed_pages) { + + /* The maximum tracked LSN age is equal to the maximum + checkpoint age */ + fprintf(file, + "Log tracking enabled\n" + "Log tracked up to %llu\n" + "Max tracked LSN age %lu\n", + log_get_tracked_lsn(), + log_sys->max_checkpoint_age); + } + log_sys->n_log_ios_old = log_sys->n_log_ios; log_sys->last_printout_time = current_time; diff --git a/storage/xtradb/log/log0online.c b/storage/xtradb/log/log0online.c new file mode 100644 index 00000000000..1d478c467e6 --- /dev/null +++ b/storage/xtradb/log/log0online.c @@ -0,0 +1,1085 @@ +/***************************************************************************** + +Copyright (c) 2011-2012 Percona Inc. All Rights Reserved. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +/**************************************************//** +@file log/log0online.c +Online database log parsing for changed page tracking + +*******************************************************/ + +#include "log0online.h" + +#include "my_dbug.h" + +#include "log0recv.h" +#include "mach0data.h" +#include "mtr0log.h" +#include "srv0srv.h" +#include "srv0start.h" +#include "trx0sys.h" +#include "ut0rbt.h" + +enum { FOLLOW_SCAN_SIZE = 4 * (UNIV_PAGE_SIZE_MAX) }; + +/** Log parsing and bitmap output data structure */ +struct log_bitmap_struct { + byte read_buf[FOLLOW_SCAN_SIZE]; + /*!< log read buffer */ + byte parse_buf[RECV_PARSING_BUF_SIZE]; + /*!< log parse buffer */ + byte* parse_buf_end; /*!< parse buffer position where the + next read log data should be copied to. + If the previous log records were fully + parsed, it points to the start, + otherwise points immediatelly past the + end of the incomplete log record. */ + char* out_name; /*!< the file name for bitmap output */ + os_file_t out; /*!< the bitmap output file */ + ib_uint64_t out_offset; /*!< the next write position in the + bitmap output file */ + ib_uint64_t start_lsn; /*!< the LSN of the next unparsed + record and the start of the next LSN + interval to be parsed. */ + ib_uint64_t end_lsn; /*!< the end of the LSN interval to be + parsed, equal to the next checkpoint + LSN at the time of parse */ + ib_uint64_t next_parse_lsn; /*!< the LSN of the next unparsed + record in the current parse */ + ib_rbt_t* modified_pages; /*!< the current modified page set, + organized as the RB-tree with the keys + of (space, 4KB-block-start-page-id) + pairs */ + ib_rbt_node_t* page_free_list; /*!< Singly-linked list of freed nodes + of modified_pages tree for later + reuse. Nodes are linked through + ib_rbt_node_t.left as this field has + both the correct type and the tree does + not mind its overwrite during + rbt_next() tree traversal. */ +}; + +/* The log parsing and bitmap output struct instance */ +static struct log_bitmap_struct* log_bmp_sys; + +/* File name stem for modified page bitmaps */ +static const char* modified_page_stem = "ib_modified_log."; + +/* On server startup with empty database srv_start_lsn == 0, in +which case the first LSN of actual log records will be this. */ +#define MIN_TRACKED_LSN ((LOG_START_LSN) + (LOG_BLOCK_HDR_SIZE)) + +/* Tests if num bit of bitmap is set */ +#define IS_BIT_SET(bitmap, num) \ + (*((bitmap) + ((num) >> 3)) & (1UL << ((num) & 7UL))) + +/** The bitmap file block size in bytes. All writes will be multiples of this. + */ +enum { + MODIFIED_PAGE_BLOCK_SIZE = 4096 +}; + + +/** Offsets in a file bitmap block */ +enum { + MODIFIED_PAGE_IS_LAST_BLOCK = 0,/* 1 if last block in the current + write, 0 otherwise. */ + MODIFIED_PAGE_START_LSN = 4, /* The starting tracked LSN of this and + other blocks in the same write */ + MODIFIED_PAGE_END_LSN = 12, /* The ending tracked LSN of this and + other blocks in the same write */ + MODIFIED_PAGE_SPACE_ID = 20, /* The space ID of tracked pages in + this block */ + MODIFIED_PAGE_1ST_PAGE_ID = 24, /* The page ID of the first tracked + page in this block */ + MODIFIED_PAGE_BLOCK_UNUSED_1 = 28,/* Unused in order to align the start + of bitmap at 8 byte boundary */ + MODIFIED_PAGE_BLOCK_BITMAP = 32,/* Start of the bitmap itself */ + MODIFIED_PAGE_BLOCK_UNUSED_2 = MODIFIED_PAGE_BLOCK_SIZE - 8, + /* Unused in order to align the end of + bitmap at 8 byte boundary */ + MODIFIED_PAGE_BLOCK_CHECKSUM = MODIFIED_PAGE_BLOCK_SIZE - 4 + /* The checksum of the current block */ +}; + +/** Length of the bitmap data in a block in bytes */ +enum { MODIFIED_PAGE_BLOCK_BITMAP_LEN + = MODIFIED_PAGE_BLOCK_UNUSED_2 - MODIFIED_PAGE_BLOCK_BITMAP }; + +/** Length of the bitmap data in a block in page ids */ +enum { MODIFIED_PAGE_BLOCK_ID_COUNT = MODIFIED_PAGE_BLOCK_BITMAP_LEN * 8 }; + +/****************************************************************//** +Provide a comparisson function for the RB-tree tree (space, +block_start_page) pairs. Actual implementation does not matter as +long as the ordering is full. +@return -1 if p1 < p2, 0 if p1 == p2, 1 if p1 > p2 +*/ +static +int +log_online_compare_bmp_keys( +/*========================*/ + const void* p1, /*!<in: 1st key to compare */ + const void* p2) /*!<in: 2nd key to compare */ +{ + const byte *k1 = (const byte *)p1; + const byte *k2 = (const byte *)p2; + + ulint k1_space = mach_read_from_4(k1 + MODIFIED_PAGE_SPACE_ID); + ulint k2_space = mach_read_from_4(k2 + MODIFIED_PAGE_SPACE_ID); + if (k1_space == k2_space) { + ulint k1_start_page + = mach_read_from_4(k1 + MODIFIED_PAGE_1ST_PAGE_ID); + ulint k2_start_page + = mach_read_from_4(k2 + MODIFIED_PAGE_1ST_PAGE_ID); + return k1_start_page < k2_start_page + ? -1 : k1_start_page > k2_start_page ? 1 : 0; + } + return k1_space < k2_space ? -1 : 1; +} + +/****************************************************************//** +Set a bit for tracked page in the bitmap. Expand the bitmap tree as +necessary. */ +static +void +log_online_set_page_bit( +/*====================*/ + ulint space, /*!<in: log record space id */ + ulint page_no)/*!<in: log record page id */ +{ + ulint block_start_page; + ulint block_pos; + uint bit_pos; + ib_rbt_bound_t tree_search_pos; + byte search_page[MODIFIED_PAGE_BLOCK_SIZE]; + byte *page_ptr; + + ut_a(space != ULINT_UNDEFINED); + ut_a(page_no != ULINT_UNDEFINED); + + block_start_page = page_no / MODIFIED_PAGE_BLOCK_ID_COUNT + * MODIFIED_PAGE_BLOCK_ID_COUNT; + block_pos = block_start_page ? (page_no % block_start_page / 8) + : (page_no / 8); + bit_pos = page_no % 8; + + mach_write_to_4(search_page + MODIFIED_PAGE_SPACE_ID, space); + mach_write_to_4(search_page + MODIFIED_PAGE_1ST_PAGE_ID, + block_start_page); + + if (!rbt_search(log_bmp_sys->modified_pages, &tree_search_pos, + search_page)) { + page_ptr = rbt_value(byte, tree_search_pos.last); + } + else { + ib_rbt_node_t *new_node; + + if (log_bmp_sys->page_free_list) { + new_node = log_bmp_sys->page_free_list; + log_bmp_sys->page_free_list = new_node->left; + } + else { + new_node = ut_malloc(SIZEOF_NODE( + log_bmp_sys->modified_pages)); + } + memset(new_node, 0, SIZEOF_NODE(log_bmp_sys->modified_pages)); + + page_ptr = rbt_value(byte, new_node); + mach_write_to_4(page_ptr + MODIFIED_PAGE_SPACE_ID, space); + mach_write_to_4(page_ptr + MODIFIED_PAGE_1ST_PAGE_ID, + block_start_page); + + rbt_add_preallocated_node(log_bmp_sys->modified_pages, + &tree_search_pos, new_node); + } + page_ptr[MODIFIED_PAGE_BLOCK_BITMAP + block_pos] |= (1U << bit_pos); +} + +/****************************************************************//** +Calculate a bitmap block checksum. Algorithm borrowed from +log_block_calc_checksum. +@return checksum */ +UNIV_INLINE +ulint +log_online_calc_checksum( +/*=====================*/ + const byte* block) /*!<in: bitmap block */ +{ + ulint sum; + ulint sh; + ulint i; + + sum = 1; + sh = 0; + + for (i = 0; i < MODIFIED_PAGE_BLOCK_CHECKSUM; i++) { + + ulint b = block[i]; + sum &= 0x7FFFFFFFUL; + sum += b; + sum += b << sh; + sh++; + if (sh > 24) { + sh = 0; + } + } + + return sum; +} + +/****************************************************************//** +Get the last tracked fully LSN from the bitmap file by reading +backwards untile a correct end page is found. Detects incomplete +writes and corrupted data. Sets the start output position for the +written bitmap data. +@return the last fully tracked LSN */ +static +ib_uint64_t +log_online_read_last_tracked_lsn() +/*==============================*/ +{ + byte page[MODIFIED_PAGE_BLOCK_SIZE]; + ib_uint64_t read_offset = log_bmp_sys->out_offset; + /* Initialize these to nonequal values so that file size == 0 case with + zero loop repetitions is handled correctly */ + ulint checksum = 0; + ulint actual_checksum = !checksum; + ibool is_last_page = FALSE; + ib_uint64_t result; + + ut_ad(log_bmp_sys->out_offset % MODIFIED_PAGE_BLOCK_SIZE == 0); + + while (checksum != actual_checksum && read_offset > 0 && !is_last_page) + { + + ulint offset_low, offset_high; + ibool success; + + read_offset -= MODIFIED_PAGE_BLOCK_SIZE; + offset_high = (ulint)(read_offset >> 32); + offset_low = (ulint)(read_offset & 0xFFFFFFFF); + + success = os_file_read(log_bmp_sys->out, page, offset_low, + offset_high, MODIFIED_PAGE_BLOCK_SIZE); + if (!success) { + + /* The following call prints an error message */ + os_file_get_last_error(TRUE); + /* Here and below assume that bitmap file names do not + contain apostrophes, thus no need for + ut_print_filename(). */ + fprintf(stderr, "InnoDB: Warning: failed reading " + "changed page bitmap file \'%s\'\n", + log_bmp_sys->out_name); + return MIN_TRACKED_LSN; + } + + is_last_page + = mach_read_from_4(page + MODIFIED_PAGE_IS_LAST_BLOCK); + checksum = mach_read_from_4(page + + MODIFIED_PAGE_BLOCK_CHECKSUM); + actual_checksum = log_online_calc_checksum(page); + if (checksum != actual_checksum) { + + fprintf(stderr, "InnoDB: Warning: corruption " + "detected in \'%s\' at offset %llu\n", + log_bmp_sys->out_name, read_offset); + } + + }; + + if (UNIV_LIKELY(checksum == actual_checksum && is_last_page)) { + + log_bmp_sys->out_offset = read_offset + + MODIFIED_PAGE_BLOCK_SIZE; + result = mach_read_from_8(page + MODIFIED_PAGE_END_LSN); + } + else { + log_bmp_sys->out_offset = read_offset; + result = 0; + } + + /* Truncate the output file to discard the corrupted bitmap data, if + any */ + if (!os_file_set_eof_at(log_bmp_sys->out, + log_bmp_sys->out_offset)) { + fprintf(stderr, "InnoDB: Warning: failed truncating " + "changed page bitmap file \'%s\' to %llu bytes\n", + log_bmp_sys->out_name, log_bmp_sys->out_offset); + result = 0; + } + return result; +} + +/****************************************************************//** +Safely write the log_sys->tracked_lsn value. Uses atomic operations +if available, otherwise this field is protected with the log system +mutex. The reader counterpart function is log_get_tracked_lsn() in +log0log.c. */ +UNIV_INLINE +void +log_set_tracked_lsn( +/*================*/ + ib_uint64_t tracked_lsn) /*!<in: new value */ +{ +#ifdef HAVE_ATOMIC_BUILTINS_64 + /* Single writer, no data race here */ + ib_uint64_t old_value + = os_atomic_increment_uint64(&log_sys->tracked_lsn, 0); + (void) os_atomic_increment_uint64(&log_sys->tracked_lsn, + tracked_lsn - old_value); +#else + mutex_enter(&log_sys->mutex); + log_sys->tracked_lsn = tracked_lsn; + mutex_exit(&log_sys->mutex); +#endif +} + +/****************************************************************//** +Diagnose a gap in tracked LSN range on server startup due to crash or +very fast shutdown and try to close it by tracking the data +immediatelly, if possible. */ +static +void +log_online_track_missing_on_startup( +/*================================*/ + ib_uint64_t last_tracked_lsn, /*!<in: last tracked LSN read + from the bitmap file */ + ib_uint64_t tracking_start_lsn) /*!<in: last checkpoint LSN of + the current server startup */ +{ + ut_ad(last_tracked_lsn != tracking_start_lsn); + + fprintf(stderr, "InnoDB: last tracked LSN in \'%s\' is %llu, but " + "last checkpoint LSN is %llu. This might be due to a server " + "crash or a very fast shutdown. ", log_bmp_sys->out_name, + last_tracked_lsn, tracking_start_lsn); + + /* last_tracked_lsn might be < MIN_TRACKED_LSN in the case of empty + bitmap file, handle this too. */ + last_tracked_lsn = ut_max(last_tracked_lsn, MIN_TRACKED_LSN); + + /* See if we can fully recover the missing interval */ + if (log_sys->lsn - last_tracked_lsn < log_sys->log_group_capacity) { + + fprintf(stderr, + "Reading the log to advance the last tracked LSN.\n"); + + log_bmp_sys->start_lsn = last_tracked_lsn; + log_set_tracked_lsn(log_bmp_sys->start_lsn); + log_online_follow_redo_log(); + ut_ad(log_bmp_sys->end_lsn >= tracking_start_lsn); + + fprintf(stderr, + "InnoDB: continuing tracking changed pages from LSN " + "%llu\n", log_bmp_sys->end_lsn); + } + else { + fprintf(stderr, + "The age of last tracked LSN exceeds log capacity, " + "tracking-based incremental backups will work only " + "from the higher LSN!\n"); + + log_bmp_sys->end_lsn = log_bmp_sys->start_lsn + = tracking_start_lsn; + log_set_tracked_lsn(log_bmp_sys->start_lsn); + + fprintf(stderr, + "InnoDB: starting tracking changed pages from LSN " + "%llu\n", log_bmp_sys->end_lsn); + } +} + +/*********************************************************************//** +Initialize the online log following subsytem. */ +UNIV_INTERN +void +log_online_read_init() +/*==================*/ +{ + char buf[FN_REFLEN]; + ibool success; + ib_uint64_t tracking_start_lsn + = ut_max(log_sys->last_checkpoint_lsn, MIN_TRACKED_LSN); + + /* Assert (could be compile-time assert) that bitmap data start and end + in a bitmap block is 8-byte aligned */ + ut_a(MODIFIED_PAGE_BLOCK_BITMAP % 8 == 0); + ut_a(MODIFIED_PAGE_BLOCK_BITMAP_LEN % 8 == 0); + + log_bmp_sys = ut_malloc(sizeof(*log_bmp_sys)); + + ut_snprintf(buf, FN_REFLEN, "%s%s%d", srv_data_home, + modified_page_stem, 1); + log_bmp_sys->out_name = ut_malloc(strlen(buf) + 1); + ut_strcpy(log_bmp_sys->out_name, buf); + + log_bmp_sys->modified_pages = rbt_create(MODIFIED_PAGE_BLOCK_SIZE, + log_online_compare_bmp_keys); + log_bmp_sys->page_free_list = NULL; + + log_bmp_sys->out + = os_file_create_simple_no_error_handling + (innodb_file_bmp_key, log_bmp_sys->out_name, OS_FILE_OPEN, + OS_FILE_READ_WRITE, &success); + + if (!success) { + + /* New file, tracking from scratch */ + log_bmp_sys->out + = os_file_create_simple_no_error_handling + (innodb_file_bmp_key, log_bmp_sys->out_name, + OS_FILE_CREATE, OS_FILE_READ_WRITE, &success); + if (!success) { + + /* The following call prints an error message */ + os_file_get_last_error(TRUE); + fprintf(stderr, + "InnoDB: Error: Cannot create \'%s\'\n", + log_bmp_sys->out_name); + exit(1); + } + + log_bmp_sys->out_offset = 0; + } + else { + + /* Old file, read last tracked LSN and continue from there */ + ulint size_low; + ulint size_high; + ib_uint64_t last_tracked_lsn; + + success = os_file_get_size(log_bmp_sys->out, &size_low, + &size_high); + ut_a(success); + + log_bmp_sys->out_offset + = ((ib_uint64_t)size_high << 32) | size_low; + + if (log_bmp_sys->out_offset % MODIFIED_PAGE_BLOCK_SIZE != 0) { + + fprintf(stderr, + "InnoDB: Warning: truncated block detected " + "in \'%s\' at offset %llu\n", + log_bmp_sys->out_name, + log_bmp_sys->out_offset); + log_bmp_sys->out_offset -= + log_bmp_sys->out_offset + % MODIFIED_PAGE_BLOCK_SIZE; + } + + last_tracked_lsn = log_online_read_last_tracked_lsn(); + + if (last_tracked_lsn < tracking_start_lsn) { + + log_online_track_missing_on_startup(last_tracked_lsn, + tracking_start_lsn); + return; + } + + if (last_tracked_lsn > tracking_start_lsn) { + + fprintf(stderr, "InnoDB: last tracked LSN in \'%s\' " + "is %llu, but last checkpoint LSN is %llu. " + "The tracking-based incremental backups will " + "work only from the latter LSN!\n", + log_bmp_sys->out_name, last_tracked_lsn, + tracking_start_lsn); + } + + } + + fprintf(stderr, "InnoDB: starting tracking changed pages from " + "LSN %llu\n", tracking_start_lsn); + log_bmp_sys->start_lsn = tracking_start_lsn; + log_set_tracked_lsn(tracking_start_lsn); +} + +/*********************************************************************//** +Shut down the online log following subsystem. */ +UNIV_INTERN +void +log_online_read_shutdown() +/*======================*/ +{ + ib_rbt_node_t *free_list_node = log_bmp_sys->page_free_list; + + os_file_close(log_bmp_sys->out); + + rbt_free(log_bmp_sys->modified_pages); + + while (free_list_node) { + ib_rbt_node_t *next = free_list_node->left; + ut_free(free_list_node); + free_list_node = next; + } + + ut_free(log_bmp_sys->out_name); + ut_free(log_bmp_sys); +} + +/*********************************************************************//** +For the given minilog record type determine if the record has (space; page) +associated with it. +@return TRUE if the record has (space; page) in it */ +static +ibool +log_online_rec_has_page( +/*====================*/ + byte type) /*!<in: the minilog record type */ +{ + return type != MLOG_MULTI_REC_END && type != MLOG_DUMMY_RECORD; +} + +/*********************************************************************//** +Check if a page field for a given log record type actually contains a page +id. It does not for file operations and MLOG_LSN. +@return TRUE if page field contains actual page id, FALSE otherwise */ +static +ibool +log_online_rec_page_means_page( +/*===========================*/ + byte type) /*!<in: log record type */ +{ + return log_online_rec_has_page(type) +#ifdef UNIV_LOG_LSN_DEBUG + && type != MLOG_LSN +#endif + && type != MLOG_FILE_CREATE + && type != MLOG_FILE_RENAME + && type != MLOG_FILE_DELETE + && type != MLOG_FILE_CREATE2; +} + +/*********************************************************************//** +Parse the log data in the parse buffer for the (space, page) pairs and add +them to the modified page set as necessary. Removes the fully-parsed records +from the buffer. If an incomplete record is found, moves it to the end of the +buffer. */ +static +void +log_online_parse_redo_log() +/*=======================*/ +{ + byte *ptr = log_bmp_sys->parse_buf; + byte *end = log_bmp_sys->parse_buf_end; + + ulint len = 0; + + while (ptr != end + && log_bmp_sys->next_parse_lsn < log_bmp_sys->end_lsn) { + + byte type; + ulint space; + ulint page_no; + byte* body; + + /* recv_sys is not initialized, so on corrupt log we will + SIGSEGV. But the log of a live database should not be + corrupt. */ + len = recv_parse_log_rec(ptr, end, &type, &space, &page_no, + &body); + if (len > 0) { + + if (log_online_rec_page_means_page(type) + && (space != TRX_DOUBLEWRITE_SPACE)) { + + ut_a(len >= 3); + log_online_set_page_bit(space, page_no); + } + + ptr += len; + ut_ad(ptr <= end); + log_bmp_sys->next_parse_lsn + = recv_calc_lsn_on_data_add + (log_bmp_sys->next_parse_lsn, len); + } + else { + + /* Incomplete log record. Shift it to the + beginning of the parse buffer and leave it to be + completed on the next read. */ + ut_memmove(log_bmp_sys->parse_buf, ptr, end - ptr); + log_bmp_sys->parse_buf_end + = log_bmp_sys->parse_buf + (end - ptr); + ptr = end; + } + } + + if (len > 0) { + + log_bmp_sys->parse_buf_end = log_bmp_sys->parse_buf; + } +} + +/*********************************************************************//** +Check the log block checksum. +@return TRUE if the log block checksum is OK, FALSE otherwise. */ +static +ibool +log_online_is_valid_log_seg( +/*========================*/ + const byte* log_block) /*!< in: read log data */ +{ + ibool checksum_is_ok + = log_block_checksum_is_ok_or_old_format(log_block); + + if (!checksum_is_ok) { + + fprintf(stderr, + "InnoDB Error: log block checksum mismatch" + "expected %lu, calculated checksum %lu\n", + (ulong) log_block_get_checksum(log_block), + (ulong) log_block_calc_checksum(log_block)); + } + + return checksum_is_ok; +} + +/*********************************************************************//** +Copy new log data to the parse buffer while skipping log block header, +trailer and already parsed data. */ +static +void +log_online_add_to_parse_buf( +/*========================*/ + const byte* log_block, /*!< in: read log data */ + ulint data_len, /*!< in: length of read log data */ + ulint skip_len) /*!< in: how much of log data to + skip */ +{ + ulint start_offset = skip_len ? skip_len : LOG_BLOCK_HDR_SIZE; + ulint end_offset + = (data_len == OS_FILE_LOG_BLOCK_SIZE) + ? data_len - LOG_BLOCK_TRL_SIZE + : data_len; + ulint actual_data_len = (end_offset >= start_offset) + ? end_offset - start_offset : 0; + + ut_memcpy(log_bmp_sys->parse_buf_end, log_block + start_offset, + actual_data_len); + + log_bmp_sys->parse_buf_end += actual_data_len; + + ut_a(log_bmp_sys->parse_buf_end - log_bmp_sys->parse_buf + <= RECV_PARSING_BUF_SIZE); +} + +/*********************************************************************//** +Parse the log block: first copies the read log data to the parse buffer while +skipping log block header, trailer and already parsed data. Then it actually +parses the log to add to the modified page bitmap. */ +static +void +log_online_parse_redo_log_block( +/*============================*/ + const byte* log_block, /*!< in: read log data */ + ulint skip_already_parsed_len) /*!< in: how many bytes of + log data should be skipped as + they were parsed before */ +{ + ulint block_data_len; + + block_data_len = log_block_get_data_len(log_block); + + ut_ad(block_data_len % OS_FILE_LOG_BLOCK_SIZE == 0 + || block_data_len < OS_FILE_LOG_BLOCK_SIZE); + + log_online_add_to_parse_buf(log_block, block_data_len, + skip_already_parsed_len); + log_online_parse_redo_log(); +} + +/*********************************************************************//** +Read and parse one redo log chunk and updates the modified page bitmap. */ +static +void +log_online_follow_log_seg( +/*======================*/ + log_group_t* group, /*!< in: the log group to use */ + ib_uint64_t block_start_lsn, /*!< in: the LSN to read from */ + ib_uint64_t block_end_lsn) /*!< in: the LSN to read to */ +{ + /* Pointer to the current OS_FILE_LOG_BLOCK-sized chunk of the read log + data to parse */ + byte* log_block = log_bmp_sys->read_buf; + byte* log_block_end = log_bmp_sys->read_buf + + (block_end_lsn - block_start_lsn); + + mutex_enter(&log_sys->mutex); + log_group_read_log_seg(LOG_RECOVER, log_bmp_sys->read_buf, + group, block_start_lsn, block_end_lsn); + mutex_exit(&log_sys->mutex); + + while (log_block < log_block_end + && log_bmp_sys->next_parse_lsn < log_bmp_sys->end_lsn) { + + /* How many bytes of log data should we skip in the current log + block. Skipping is necessary because we round down the next + parse LSN thus it is possible to read the already-processed log + data many times */ + ulint skip_already_parsed_len = 0; + + if (!log_online_is_valid_log_seg(log_block)) { + break; + } + + if ((block_start_lsn <= log_bmp_sys->next_parse_lsn) + && (block_start_lsn + OS_FILE_LOG_BLOCK_SIZE + > log_bmp_sys->next_parse_lsn)) { + + /* The next parse LSN is inside the current block, skip + data preceding it. */ + skip_already_parsed_len + = log_bmp_sys->next_parse_lsn + - block_start_lsn; + } + else { + + /* If the next parse LSN is not inside the current + block, then the only option is that we have processed + ahead already. */ + ut_a(block_start_lsn > log_bmp_sys->next_parse_lsn); + } + + /* TODO: merge the copying to the parse buf code with + skip_already_len calculations */ + log_online_parse_redo_log_block(log_block, + skip_already_parsed_len); + + log_block += OS_FILE_LOG_BLOCK_SIZE; + block_start_lsn += OS_FILE_LOG_BLOCK_SIZE; + } + + return; +} + +/*********************************************************************//** +Read and parse the redo log in a given group in FOLLOW_SCAN_SIZE-sized +chunks and updates the modified page bitmap. */ +static +void +log_online_follow_log_group( +/*========================*/ + log_group_t* group, /*!< in: the log group to use */ + ib_uint64_t contiguous_lsn) /*!< in: the LSN of log block start + containing the log_parse_start_lsn */ +{ + ib_uint64_t block_start_lsn = contiguous_lsn; + ib_uint64_t block_end_lsn; + + log_bmp_sys->next_parse_lsn = log_bmp_sys->start_lsn; + log_bmp_sys->parse_buf_end = log_bmp_sys->parse_buf; + + do { + block_end_lsn = block_start_lsn + FOLLOW_SCAN_SIZE; + + log_online_follow_log_seg(group, block_start_lsn, + block_end_lsn); + + /* Next parse LSN can become higher than the last read LSN + only in the case when the read LSN falls right on the block + boundary, in which case next parse lsn is bumped to the actual + data LSN on the next (not yet read) block. This assert is + slightly conservative. */ + ut_a(log_bmp_sys->next_parse_lsn + <= block_end_lsn + LOG_BLOCK_HDR_SIZE + + LOG_BLOCK_TRL_SIZE); + + block_start_lsn = block_end_lsn; + } while (block_end_lsn < log_bmp_sys->end_lsn); + + /* Assert that the last read log record is a full one */ + ut_a(log_bmp_sys->parse_buf_end == log_bmp_sys->parse_buf); +} + +/*********************************************************************//** +Write, flush one bitmap block to disk and advance the output position if +successful. */ +static +void +log_online_write_bitmap_page( +/*=========================*/ + const byte *block) /*!< in: block to write */ +{ + ibool success; + + success = os_file_write(log_bmp_sys->out_name,log_bmp_sys->out, + block, + (ulint)(log_bmp_sys->out_offset & 0xFFFFFFFF), + (ulint)(log_bmp_sys->out_offset << 32), + MODIFIED_PAGE_BLOCK_SIZE); + if (UNIV_UNLIKELY(!success)) { + + /* The following call prints an error message */ + os_file_get_last_error(TRUE); + fprintf(stderr, "InnoDB: Error: failed writing changed page " + "bitmap file \'%s\'\n", log_bmp_sys->out_name); + return; + } + + success = os_file_flush(log_bmp_sys->out, FALSE); + if (UNIV_UNLIKELY(!success)) { + + /* The following call prints an error message */ + os_file_get_last_error(TRUE); + fprintf(stderr, "InnoDB: Error: failed flushing " + "changed page bitmap file \'%s\'\n", + log_bmp_sys->out_name); + return; + } + + log_bmp_sys->out_offset += MODIFIED_PAGE_BLOCK_SIZE; +} + +/*********************************************************************//** +Append the current changed page bitmap to the bitmap file. Clears the +bitmap tree and recycles its nodes to the free list. */ +static +void +log_online_write_bitmap() +/*=====================*/ +{ + ib_rbt_node_t *bmp_tree_node; + const ib_rbt_node_t *last_bmp_tree_node; + + bmp_tree_node = (ib_rbt_node_t *) + rbt_first(log_bmp_sys->modified_pages); + last_bmp_tree_node = rbt_last(log_bmp_sys->modified_pages); + + while (bmp_tree_node) { + + byte *page = rbt_value(byte, bmp_tree_node); + + if (bmp_tree_node == last_bmp_tree_node) { + mach_write_to_4(page + MODIFIED_PAGE_IS_LAST_BLOCK, 1); + } + + mach_write_to_8(page + MODIFIED_PAGE_START_LSN, + log_bmp_sys->start_lsn); + mach_write_to_8(page + MODIFIED_PAGE_END_LSN, + log_bmp_sys->end_lsn); + mach_write_to_4(page + MODIFIED_PAGE_BLOCK_CHECKSUM, + log_online_calc_checksum(page)); + + log_online_write_bitmap_page(page); + + bmp_tree_node->left = log_bmp_sys->page_free_list; + log_bmp_sys->page_free_list = bmp_tree_node; + + bmp_tree_node = (ib_rbt_node_t*) + rbt_next(log_bmp_sys->modified_pages, bmp_tree_node); + } + + rbt_reset(log_bmp_sys->modified_pages); +} + +/*********************************************************************//** +Read and parse the redo log up to last checkpoint LSN to build the changed +page bitmap which is then written to disk. */ +UNIV_INTERN +void +log_online_follow_redo_log() +/*========================*/ +{ + ib_uint64_t contiguous_start_lsn; + log_group_t* group; + + /* Grab the LSN of the last checkpoint, we will parse up to it */ + mutex_enter(&(log_sys->mutex)); + log_bmp_sys->end_lsn = log_sys->last_checkpoint_lsn; + mutex_exit(&(log_sys->mutex)); + + if (log_bmp_sys->end_lsn == log_bmp_sys->start_lsn) { + return; + } + + group = UT_LIST_GET_FIRST(log_sys->log_groups); + ut_a(group); + + contiguous_start_lsn = ut_uint64_align_down(log_bmp_sys->start_lsn, + OS_FILE_LOG_BLOCK_SIZE); + + while (group) { + log_online_follow_log_group(group, contiguous_start_lsn); + group = UT_LIST_GET_NEXT(log_groups, group); + } + + /* A crash injection site that ensures last checkpoint LSN > last + tracked LSN, so that LSN tracking for this interval is tested. */ + DBUG_EXECUTE_IF("crash_before_bitmap_write", DBUG_SUICIDE();); + + log_online_write_bitmap(); + log_bmp_sys->start_lsn = log_bmp_sys->end_lsn; + log_set_tracked_lsn(log_bmp_sys->start_lsn); +} + +/*********************************************************************//** +Initializes log bitmap iterator. +@return TRUE if the iterator is initialized OK, FALSE otherwise. */ +UNIV_INTERN +ibool +log_online_bitmap_iterator_init( +/*============================*/ + log_bitmap_iterator_t *i) /*!<in/out: iterator */ +{ + ibool success; + + ut_a(i); + ut_snprintf(i->in_name, FN_REFLEN, "%s%s%d", srv_data_home, + modified_page_stem, 1); + i->in_offset = 0; + /* + Set up bit offset out of the reasonable limit + to intiate reading block from file in + log_online_bitmap_iterator_next() + */ + i->bit_offset = MODIFIED_PAGE_BLOCK_BITMAP_LEN; + i->in = + os_file_create_simple_no_error_handling(innodb_file_bmp_key, + i->in_name, + OS_FILE_OPEN, + OS_FILE_READ_ONLY, + &success); + + if (!success) { + /* The following call prints an error message */ + os_file_get_last_error(TRUE); + fprintf(stderr, + "InnoDB: Error: Cannot open \'%s\'\n", + i->in_name); + return FALSE; + } + + i->page = ut_malloc(MODIFIED_PAGE_BLOCK_SIZE); + + i->start_lsn = i->end_lsn = 0; + i->space_id = 0; + i->first_page_id = 0; + i->changed = FALSE; + + return TRUE; +} + +/*********************************************************************//** +Releases log bitmap iterator. */ +UNIV_INTERN +void +log_online_bitmap_iterator_release( +/*===============================*/ + log_bitmap_iterator_t *i) /*!<in/out: iterator */ +{ + ut_a(i); + os_file_close(i->in); + ut_free(i->page); +} + +/*********************************************************************//** +Iterates through bits of saved bitmap blocks. +Sequentially reads blocks from bitmap file(s) and interates through +their bits. Ignores blocks with wrong checksum. +@return TRUE if iteration is successful, FALSE if all bits are iterated. */ +UNIV_INTERN +ibool +log_online_bitmap_iterator_next( +/*============================*/ + log_bitmap_iterator_t *i) /*!<in/out: iterator */ +{ + ulint offset_low; + ulint offset_high; + ulint size_low; + ulint size_high; + ulint checksum = 0; + ulint actual_checksum = !checksum; + + ibool success; + + ut_a(i); + + if (i->bit_offset < MODIFIED_PAGE_BLOCK_BITMAP_LEN) + { + ++i->bit_offset; + i->changed = + IS_BIT_SET(i->page + MODIFIED_PAGE_BLOCK_BITMAP, + i->bit_offset); + return TRUE; + } + + while (checksum != actual_checksum) + { + success = os_file_get_size(i->in, + &size_low, + &size_high); + if (!success) { + os_file_get_last_error(TRUE); + fprintf(stderr, + "InnoDB: Warning: can't get size of " + "page bitmap file \'%s\'\n", + i->in_name); + return FALSE; + } + + if (i->in_offset >= + (ib_uint64_t)(size_low) + + ((ib_uint64_t)(size_high) << 32)) + return FALSE; + + offset_high = (ulint)(i->in_offset >> 32); + offset_low = (ulint)(i->in_offset & 0xFFFFFFFF); + + success = os_file_read( + i->in, + i->page, + offset_low, + offset_high, + MODIFIED_PAGE_BLOCK_SIZE); + + if (!success) { + os_file_get_last_error(TRUE); + fprintf(stderr, + "InnoDB: Warning: failed reading " + "changed page bitmap file \'%s\'\n", + i->in_name); + return FALSE; + } + + checksum = mach_read_from_4( + i->page + MODIFIED_PAGE_BLOCK_CHECKSUM); + + actual_checksum = log_online_calc_checksum(i->page); + + i->in_offset += MODIFIED_PAGE_BLOCK_SIZE; + } + + i->start_lsn = + mach_read_from_8(i->page + MODIFIED_PAGE_START_LSN); + i->end_lsn = + mach_read_from_8(i->page + MODIFIED_PAGE_END_LSN); + i->space_id = + mach_read_from_4(i->page + MODIFIED_PAGE_SPACE_ID); + i->first_page_id = + mach_read_from_4(i->page + MODIFIED_PAGE_1ST_PAGE_ID); + i->bit_offset = + 0; + i->changed = + IS_BIT_SET(i->page + MODIFIED_PAGE_BLOCK_BITMAP, + i->bit_offset); + + return TRUE; +} + diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c index a554c576b6d..5ab8c14ae2e 100644 --- a/storage/xtradb/log/log0recv.c +++ b/storage/xtradb/log/log0recv.c @@ -857,7 +857,7 @@ block. We also accept a log block in the old format before InnoDB-3.23.52 where the checksum field contains the log block number. @return TRUE if ok, or if the log block may be in the format of InnoDB version predating 3.23.52 */ -static +UNIV_INTERN ibool log_block_checksum_is_ok_or_old_format( /*===================================*/ @@ -2102,7 +2102,7 @@ skip_this_recv_addr: /*******************************************************************//** Tries to parse a single log record and returns its length. @return length of the record, or 0 if the record was not complete */ -static +UNIV_INTERN ulint recv_parse_log_rec( /*===============*/ @@ -2173,7 +2173,7 @@ recv_parse_log_rec( /*******************************************************//** Calculates the new value for lsn when more data is added to the log. */ -static +UNIV_INTERN ib_uint64_t recv_calc_lsn_on_data_add( /*======================*/ @@ -3570,6 +3570,8 @@ recv_reset_logs( log_sys->archived_lsn = log_sys->lsn; #endif /* UNIV_LOG_ARCHIVE */ + log_sys->tracked_lsn = log_sys->lsn; + log_block_init(log_sys->buf, log_sys->lsn); log_block_set_first_rec_group(log_sys->buf, LOG_BLOCK_HDR_SIZE); diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c index 061d556c6e7..2555c010027 100644 --- a/storage/xtradb/os/os0file.c +++ b/storage/xtradb/os/os0file.c @@ -158,6 +158,7 @@ UNIV_INTERN ibool os_aio_print_debug = FALSE; UNIV_INTERN mysql_pfs_key_t innodb_file_data_key; UNIV_INTERN mysql_pfs_key_t innodb_file_log_key; UNIV_INTERN mysql_pfs_key_t innodb_file_temp_key; +UNIV_INTERN mysql_pfs_key_t innodb_file_bmp_key; #endif /* UNIV_PFS_IO */ /** The asynchronous i/o array slot structure */ @@ -1869,7 +1870,7 @@ os_file_rename_func( #ifdef __WIN__ BOOL ret; - ret = MoveFile((LPCTSTR)oldpath, (LPCTSTR)newpath); + ret = MoveFileEx((LPCTSTR)oldpath, (LPCTSTR)newpath, MOVEFILE_REPLACE_EXISTING); if (ret) { return(TRUE); @@ -2147,6 +2148,25 @@ os_file_set_eof( #endif /* __WIN__ */ } +/***********************************************************************//** +Truncates a file at the specified position. +@return TRUE if success */ +UNIV_INTERN +ibool +os_file_set_eof_at( + os_file_t file, /*!< in: handle to a file */ + ib_uint64_t new_len)/*!< in: new file length */ +{ +#ifdef __WIN__ + /* TODO: untested! */ + return(!_chsize_s(file, new_len)); +#else + /* TODO: works only with -D_FILE_OFFSET_BITS=64 ? */ + return(!ftruncate(file, new_len)); +#endif +} + + #ifndef __WIN__ /***********************************************************************//** Wrapper to fsync(2) that retries the call on some errors. diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c index 0a545a8247a..dff9fc07a7f 100644 --- a/storage/xtradb/srv/srv0srv.c +++ b/storage/xtradb/srv/srv0srv.c @@ -67,6 +67,7 @@ Created 10/8/1995 Heikki Tuuri #include "mem0pool.h" #include "sync0sync.h" #include "que0que.h" +#include "log0online.h" #include "log0recv.h" #include "pars0pars.h" #include "usr0sess.h" @@ -176,6 +177,10 @@ UNIV_INTERN char* srv_doublewrite_file = NULL; UNIV_INTERN ibool srv_recovery_stats = FALSE; +UNIV_INTERN my_bool srv_track_changed_pages = TRUE; + +UNIV_INTERN ulonglong srv_changed_pages_limit = 0; + /* if TRUE, then we auto-extend the last data file */ UNIV_INTERN ibool srv_auto_extend_last_data_file = FALSE; /* if != 0, this tells the max size auto-extending may increase the @@ -771,6 +776,10 @@ UNIV_INTERN os_event_t srv_lock_timeout_thread_event; UNIV_INTERN os_event_t srv_shutdown_event; +UNIV_INTERN os_event_t srv_checkpoint_completed_event; + +UNIV_INTERN os_event_t srv_redo_log_thread_finished_event; + UNIV_INTERN srv_sys_t* srv_sys = NULL; /* padding to prevent other memory update hotspots from residing on @@ -1110,6 +1119,9 @@ srv_init(void) srv_lock_timeout_thread_event = os_event_create(NULL); srv_shutdown_event = os_event_create(NULL); + srv_checkpoint_completed_event = os_event_create(NULL); + srv_redo_log_thread_finished_event = os_event_create(NULL); + for (i = 0; i < SRV_MASTER + 1; i++) { srv_n_threads_active[i] = 0; srv_n_threads[i] = 0; @@ -3034,6 +3046,46 @@ srv_shutdown_print_master_pending( } } +/******************************************************************//** +A thread which follows the redo log and outputs the changed page bitmap. +@return a dummy value */ +os_thread_ret_t +srv_redo_log_follow_thread( +/*=======================*/ + void* arg __attribute__((unused))) /*!< in: a dummy parameter + required by + os_thread_create */ +{ +#ifdef UNIV_DEBUG_THREAD_CREATION + fprintf(stderr, "Redo log follower thread starts, id %lu\n", + os_thread_pf(os_thread_get_curr_id())); +#endif + +#ifdef UNIV_PFS_THREAD + pfs_register_thread(srv_log_tracking_thread_key); +#endif + + my_thread_init(); + + do { + os_event_wait(srv_checkpoint_completed_event); + os_event_reset(srv_checkpoint_completed_event); + + if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) { + log_online_follow_redo_log(); + } + + } while (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE); + + log_online_read_shutdown(); + os_event_set(srv_redo_log_thread_finished_event); + + my_thread_end(); + os_thread_exit(NULL); + + OS_THREAD_DUMMY_RETURN; +} + /*******************************************************************//** Tells the InnoDB server that there has been activity in the database and wakes up the master thread if it is suspended (not sleeping). Used diff --git a/storage/xtradb/srv/srv0start.c b/storage/xtradb/srv/srv0start.c index d1329f445aa..7c98f74909e 100644 --- a/storage/xtradb/srv/srv0start.c +++ b/storage/xtradb/srv/srv0start.c @@ -51,6 +51,7 @@ Created 2/16/1996 Heikki Tuuri #include "rem0rec.h" #include "mtr0mtr.h" #include "log0log.h" +#include "log0online.h" #include "log0recv.h" #include "page0page.h" #include "page0cur.h" @@ -121,9 +122,9 @@ UNIV_INTERN enum srv_shutdown_state srv_shutdown_state = SRV_SHUTDOWN_NONE; static os_file_t files[1000]; /** io_handler_thread parameters for thread identification */ -static ulint n[SRV_MAX_N_IO_THREADS + 7]; +static ulint n[SRV_MAX_N_IO_THREADS + 8]; /** io_handler_thread identifiers */ -static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 7]; +static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 8]; /** We use this mutex to test the return value of pthread_mutex_trylock on successful locking. HP-UX does NOT return 0, though Linux et al do. */ @@ -145,6 +146,7 @@ UNIV_INTERN mysql_pfs_key_t srv_error_monitor_thread_key; UNIV_INTERN mysql_pfs_key_t srv_monitor_thread_key; UNIV_INTERN mysql_pfs_key_t srv_master_thread_key; UNIV_INTERN mysql_pfs_key_t srv_purge_thread_key; +UNIV_INTERN mysql_pfs_key_t srv_log_tracking_thread_key; #endif /* UNIV_PFS_THREAD */ /*********************************************************************//** @@ -2037,6 +2039,19 @@ innobase_start_or_create_for_mysql(void) if (srv_auto_lru_dump && srv_blocking_lru_restore) buf_LRU_file_restore(); + if (srv_track_changed_pages) { + + /* Initialize the log tracking subsystem here to block + server startup until it's completed due to the potential + need to re-read previous server run's log. */ + log_online_read_init(); + + /* Create the thread that follows the redo log to output the + changed page bitmap */ + os_thread_create(&srv_redo_log_follow_thread, NULL, + thread_ids + 6 + SRV_MAX_N_IO_THREADS); + } + srv_is_being_started = FALSE; err = dict_create_or_check_foreign_constraint_tables(); diff --git a/storage/xtradb/ut/ut0rbt.c b/storage/xtradb/ut/ut0rbt.c index 3d7cfa7636f..a5e9081b951 100644 --- a/storage/xtradb/ut/ut0rbt.c +++ b/storage/xtradb/ut/ut0rbt.c @@ -55,7 +55,6 @@ red-black properties: #endif #define ROOT(t) (t->root->left) -#define SIZEOF_NODE(t) ((sizeof(ib_rbt_node_t) + t->sizeof_value) - 1) /**********************************************************************//** Print out the sub-tree recursively. */ @@ -834,6 +833,21 @@ rbt_add_node( node = (ib_rbt_node_t*) ut_malloc(SIZEOF_NODE(tree)); memcpy(node->value, value, tree->sizeof_value); + return(rbt_add_preallocated_node(tree, parent, node)); +} + +/****************************************************************//** +Add a new caller-provided node to tree at the specified position. +The node must have its key fields initialized correctly. +@return added node */ +UNIV_INTERN +const ib_rbt_node_t* +rbt_add_preallocated_node( +/*======================*/ + ib_rbt_t* tree, /*!< in: rb tree */ + ib_rbt_bound_t* parent, /*!< in: parent */ + ib_rbt_node_t* node) /*!< in: node */ +{ node->parent = node->left = node->right = tree->nil; /* If tree is empty */ @@ -842,7 +856,7 @@ rbt_add_node( } /* Append the node, the hope here is that the caller knows - what s/he is doing. */ + what s/he is doing. */ rbt_tree_add_child(tree, parent, node); rbt_balance_tree(tree, node); @@ -854,6 +868,7 @@ rbt_add_node( return(node); } + /**********************************************************************//** Find a matching node in the rb tree. @return NULL if not found else the node where key was found */ @@ -1142,7 +1157,17 @@ rbt_clear( ib_rbt_t* tree) /*!< in: rb tree */ { rbt_free_node(ROOT(tree), tree->nil); + rbt_reset(tree); +} +/****************************************************************//** +Clear the tree without deleting and freeing its nodes. */ +UNIV_INTERN +void +rbt_reset( +/*======*/ + ib_rbt_t* tree) /*!< in: rb tree */ +{ tree->n_nodes = 0; tree->root->left = tree->root->right = tree->nil; } diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 5b9a296d90a..0d673e5b339 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -252,6 +252,9 @@ Vendor: %{mysql_vendor} Provides: msqlormysql MySQL-server mysql BuildRequires: %{distro_buildreq} +# Regression tests may take a long time, override the default to skip them +%{!?runselftest:%global runselftest 1} + # Think about what you use here since the first step is to # run a rm -rf BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -403,6 +406,16 @@ For a description of MySQL see the base MySQL RPM or http://www.mysql.com/ ############################################################################## %build +# Fail quickly and obviously if user tries to build as root +%if %runselftest + if [ x"`id -u`" = x0 ]; then + echo "The MySQL regression tests may fail if run as root." + echo "If you really need to build the RPM as root, use" + echo "--define='runselftest 0' to skip the regression tests." + exit 1 + fi +%endif + # Be strict about variables, bail at earliest opportunity, etc. set -eu @@ -480,6 +493,13 @@ mkdir release make ${MAKE_JFLAG} VERBOSE=1 ) +%if %runselftest + MTR_BUILD_THREAD=auto + export MTR_BUILD_THREAD + + (cd release && make test-bt-fast || true) +%endif + ############################################################################## %install @@ -1146,6 +1166,14 @@ echo "=====" >> $STATUS_HISTORY # merging BK trees) ############################################################################## %changelog +* Tue Jul 24 2012 Joerg Bruehe <joerg.bruehe@oracle.com> + +- Add a macro "runselftest": + if set to 1 (default), the test suite will be run during the RPM build; + this can be oveeridden via the command line by adding + --define "runselftest 0" + Failures of the test suite will NOT make the RPM build fail! + * Wed Sep 28 2011 Joerg Bruehe <joerg.bruehe@oracle.com> - Fix duplicate mentioning of "mysql_plugin" and its manual page, diff --git a/support-files/rpm/server-postin.sh b/support-files/rpm/server-postin.sh index 88ff059ff22..156865b61ad 100644 --- a/support-files/rpm/server-postin.sh +++ b/support-files/rpm/server-postin.sh @@ -1,37 +1,46 @@ -mysql_datadir=%{mysqldatadir} - -# Create data directory -mkdir -p $mysql_datadir/{mysql,test} # Make MySQL start/shutdown automatically when the machine does it. if [ $1 = 1 ] ; then if [ -x /sbin/chkconfig ] ; then /sbin/chkconfig --add mysql fi -fi -# Create a MySQL user and group. Do not report any problems if it already -# exists. -groupadd -r %{mysqld_group} 2> /dev/null || true -useradd -M -r -d $mysql_datadir -s /bin/bash -c "MySQL server" -g %{mysqld_group} %{mysqld_user} 2> /dev/null || true -# The user may already exist, make sure it has the proper group nevertheless (BUG#12823) -usermod -g %{mysqld_group} %{mysqld_user} 2> /dev/null || true + mysql_dirs=(`%{_sbindir}/mysqld --verbose --help 2>/dev/null|sed -ne 's/^\(basedir\|datadir\)[[:space:]]*\(.*\)$/\2/p'`) + basedir="${mysql_dirs[0]}" + datadir="${mysql_dirs[1]}" + # datadir may be relative to a basedir! + if expr $datadir : / > /dev/null; then + mysql_datadir=$datadir + else + mysql_datadir=$basedir/$datadir + fi + + # Create a MySQL user and group. Do not report any problems if it already + # exists. + groupadd -r %{mysqld_group} 2> /dev/null || true + useradd -M -r -d $mysql_datadir -s /bin/bash -c "MySQL server" -g %{mysqld_group} %{mysqld_user} 2> /dev/null || true + # The user may already exist, make sure it has the proper group nevertheless (BUG#12823) + usermod -g %{mysqld_group} %{mysqld_user} 2> /dev/null || true -# Change permissions so that the user that will run the MySQL daemon -# owns all database files. -chown -R %{mysqld_user}:%{mysqld_group} $mysql_datadir + # Change permissions so that the user that will run the MySQL daemon + # owns all database files. + chown -R %{mysqld_user}:%{mysqld_group} $mysql_datadir -# Initiate databases -%{_bindir}/mysql_install_db --rpm --user=%{mysqld_user} + if [ ! -e $mysql_datadir ]; then + # Create data directory + mkdir -p $mysql_datadir/{mysql,test} -# Upgrade databases if needed would go here - but it cannot be automated yet + # Initiate databases + %{_bindir}/mysql_install_db --rpm --user=%{mysqld_user} + fi -# Change permissions again to fix any new files. -chown -R %{mysqld_user}:%{mysqld_group} $mysql_datadir + # Change permissions again to fix any new files. + chown -R %{mysqld_user}:%{mysqld_group} $mysql_datadir -# Fix permissions for the permission database so that only the user -# can read them. -chmod -R og-rw $mysql_datadir/mysql + # Fix permissions for the permission database so that only the user + # can read them. + chmod -R og-rw $mysql_datadir/mysql +fi # install SELinux files - but don't override existing ones SETARGETDIR=/etc/selinux/targeted/src/policy diff --git a/tests/mysql_client_fw.c b/tests/mysql_client_fw.c index 979d47cb0b8..207eaead135 100644 --- a/tests/mysql_client_fw.c +++ b/tests/mysql_client_fw.c @@ -61,6 +61,7 @@ static unsigned int opt_count= 0; static unsigned int iter_count= 0; static my_bool have_innodb= FALSE; static char *opt_plugin_dir= 0, *opt_default_auth= 0; +static unsigned int opt_drop_db= 1; static const char *opt_basedir= "./"; static const char *opt_vardir= "mysql-test/var"; @@ -109,7 +110,7 @@ DBUG_PRINT("test", ("name: %s", str)); \ static void print_error(const char *msg); static void print_st_error(MYSQL_STMT *stmt, const char *msg); -static void client_disconnect(MYSQL* mysql, my_bool drop_db); +static void client_disconnect(MYSQL* mysql); /* @@ -134,6 +135,7 @@ static void die(const char *file, int line, const char *expr) { fflush(stdout); fprintf(stderr, "%s:%d: check failed: '%s'\n", file, line, expr); + fprintf(stderr, "MySQL error %d: %s\n", mysql_errno(0), mysql_error(0)); fflush(stderr); exit(1); } @@ -385,31 +387,31 @@ static MYSQL* client_connect(ulong flag, uint protocol, my_bool auto_reconnect) /* Close the connection */ -static void client_disconnect(MYSQL* mysql, my_bool drop_db) +static void client_disconnect(MYSQL* mysql) { - static char query[MAX_TEST_QUERY_LENGTH]; + static char query[MAX_TEST_QUERY_LENGTH]; - myheader_r("client_disconnect"); + myheader_r("client_disconnect"); - if (mysql) - { - if (drop_db) - { - if (!opt_silent) - fprintf(stdout, "\n dropping the test database '%s' ...", current_db); - strxmov(query, "DROP DATABASE IF EXISTS ", current_db, NullS); + if (mysql) + { + if (opt_drop_db) + { + if (!opt_silent) + fprintf(stdout, "\n dropping the test database '%s' ...", current_db); + strxmov(query, "DROP DATABASE IF EXISTS ", current_db, NullS); - mysql_query(mysql, query); - if (!opt_silent) - fprintf(stdout, "OK"); - } + mysql_query(mysql, query); + if (!opt_silent) + fprintf(stdout, "OK"); + } - if (!opt_silent) - fprintf(stdout, "\n closing the connection ..."); - mysql_close(mysql); - if (!opt_silent) - fprintf(stdout, "OK\n"); - } + if (!opt_silent) + fprintf(stdout, "\n closing the connection ..."); + mysql_close(mysql); + if (!opt_silent) + fprintf(stdout, "OK\n"); + } } @@ -1174,14 +1176,16 @@ static char **defaults_argv; static struct my_option client_test_long_options[] = { - {"basedir", 'b', "Basedir for tests.", (char**) &opt_basedir, - (char**) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"basedir", 'b', "Basedir for tests.", &opt_basedir, + &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"count", 't', "Number of times test to be executed", &opt_count, &opt_count, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0}, {"database", 'D', "Database to use", &opt_db, &opt_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"debug", '#', "Output debug log", (char**) &default_dbug_option, - (char**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"do-not-drop-database", 'd', "Do not drop database while disconnecting", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug", '#', "Output debug log", &default_dbug_option, + &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host", &opt_host, &opt_host, @@ -1217,8 +1221,8 @@ static struct my_option client_test_long_options[] = {"user", 'u', "User for login if not current user", &opt_user, &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"vardir", 'v', "Data dir for tests.", (char**) &opt_vardir, - (char**) &opt_vardir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"vardir", 'v', "Data dir for tests.", &opt_vardir, + &opt_vardir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"non-blocking-api", 'n', "Use the non-blocking client API for communication.", &non_blocking_api_enabled, &non_blocking_api_enabled, 0, @@ -1287,6 +1291,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), else opt_silent++; break; + case 'd': + opt_drop_db= 0; + break; case 'A': /* When the embedded server is being tested, the test suite needs to be @@ -1411,7 +1418,7 @@ int main(int argc, char **argv) fprintf(stderr, "\n\nGiven test not found: '%s'\n", *argv); fprintf(stderr, "See legal test names with %s -T\n\nAborting!\n", my_progname); - client_disconnect(mysql, 1); + client_disconnect(mysql); free_defaults(defaults_argv); exit(1); } @@ -1424,7 +1431,7 @@ int main(int argc, char **argv) /* End of tests */ } - client_disconnect(mysql, 1); /* disconnect from server */ + client_disconnect(mysql); /* disconnect from server */ free_defaults(defaults_argv); print_test_output(); diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 753df62abde..10db62781ee 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -17691,7 +17691,8 @@ static void test_bug43560(void) const char* values[] = {"eins", "zwei", "drei", "viele", NULL}; const char insert_str[] = "INSERT INTO t1 (c2) VALUES (?)"; unsigned long length; - + const unsigned int drop_db= opt_drop_db; + DBUG_ENTER("test_bug43560"); myheader("test_bug43560"); @@ -17756,9 +17757,11 @@ static void test_bug43560(void) rc= mysql_stmt_execute(stmt); DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST); - client_disconnect(conn, 0); + opt_drop_db= 0; + client_disconnect(conn); rc= mysql_query(mysql, "DROP TABLE t1"); myquery(rc); + opt_drop_db= drop_db; DBUG_VOID_RETURN; } @@ -18548,7 +18551,7 @@ static void test_progress_reporting() myquery(rc); rc= mysql_query(conn, "set @@global.progress_report_time=@save"); myquery(rc); - client_disconnect(conn, 0); + mysql_close(conn); } diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index b0e64468a55..0ed315c7d97 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -98,47 +98,51 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file, DBUG_ENTER("vio_set_cert_stuff"); DBUG_PRINT("enter", ("ctx: 0x%lx cert_file: %s key_file: %s", (long) ctx, cert_file, key_file)); - if (cert_file) - { - if (SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) - { - *error= SSL_INITERR_CERT; - DBUG_PRINT("error",("%s from file '%s'", sslGetErrString(*error), cert_file)); - DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); - fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error), - cert_file); - fflush(stderr); - DBUG_RETURN(1); - } - if (!key_file) - key_file= cert_file; + if (!cert_file && key_file) + cert_file= key_file; + + if (!key_file && cert_file) + key_file= cert_file; - if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) - { - *error= SSL_INITERR_KEY; - DBUG_PRINT("error", ("%s from file '%s'", sslGetErrString(*error), key_file)); - DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); - fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error), - key_file); - fflush(stderr); - DBUG_RETURN(1); - } + if (cert_file && + SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) + { + *error= SSL_INITERR_CERT; + DBUG_PRINT("error",("%s from file '%s'", sslGetErrString(*error), cert_file)); + DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); + fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error), + cert_file); + fflush(stderr); + DBUG_RETURN(1); + } - /* - If we are using DSA, we can copy the parameters from the private key - Now we know that a key and cert have been set against the SSL context - */ - if (!SSL_CTX_check_private_key(ctx)) - { - *error= SSL_INITERR_NOMATCH; - DBUG_PRINT("error", ("%s",sslGetErrString(*error))); - DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); - fprintf(stderr, "SSL error: %s\n", sslGetErrString(*error)); - fflush(stderr); - DBUG_RETURN(1); - } + if (key_file && + SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) + { + *error= SSL_INITERR_KEY; + DBUG_PRINT("error", ("%s from file '%s'", sslGetErrString(*error), key_file)); + DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); + fprintf(stderr, "SSL error: %s from '%s'\n", sslGetErrString(*error), + key_file); + fflush(stderr); + DBUG_RETURN(1); + } + + /* + If we are using DSA, we can copy the parameters from the private key + Now we know that a key and cert have been set against the SSL context + */ + if (cert_file && !SSL_CTX_check_private_key(ctx)) + { + *error= SSL_INITERR_NOMATCH; + DBUG_PRINT("error", ("%s",sslGetErrString(*error))); + DBUG_EXECUTE("error", ERR_print_errors_fp(DBUG_FILE);); + fprintf(stderr, "SSL error: %s\n", sslGetErrString(*error)); + fflush(stderr); + DBUG_RETURN(1); } + DBUG_RETURN(0); } @@ -219,6 +223,20 @@ new_VioSSLFd(const char *key_file, const char *cert_file, if (SSL_CTX_load_verify_locations(ssl_fd->ssl_context, ca_file, ca_path) == 0) { DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed")); + if (ca_file || ca_path) + { + /* fail only if ca file or ca path were supplied and looking into + them fails. */ + *error= SSL_INITERR_BAD_PATHS; + DBUG_PRINT("error", ("SSL_CTX_load_verify_locations failed : %s", + sslGetErrString(*error))); + report_errors(); + SSL_CTX_free(ssl_fd->ssl_context); + my_free(ssl_fd); + DBUG_RETURN(0); + } + + /* otherwise go use the defaults */ if (SSL_CTX_set_default_verify_paths(ssl_fd->ssl_context) == 0) { *error= SSL_INITERR_BAD_PATHS; |