diff options
277 files changed, 9604 insertions, 1902 deletions
diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh index 1bbc47341c9..7f8859dde54 100644 --- a/BUILD/FINISH.sh +++ b/BUILD/FINISH.sh @@ -21,6 +21,12 @@ extra_configs="$extra_configs $local_infile_configs $EXTRA_CONFIGS" configure="./configure $base_configs $extra_configs" +if test "$just_print" = "1" -a "$just_configure" = "1" +then + just_print="" + configure="$configure --print" +fi + commands="\ /bin/rm -rf configure; /bin/rm -rf CMakeCache.txt CMakeFiles/ diff --git a/CMakeLists.txt b/CMakeLists.txt index ab7729f3c52..2f8ac5a2fe0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -327,6 +327,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) @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=27 +MYSQL_VERSION_PATCH=28 MYSQL_VERSION_EXTRA= diff --git a/client/mysql.cc b/client/mysql.cc index 5aab3e1098f..67878b36227 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 d7f311fcb69..71bc936cfe6 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 c36c8a16881..e2ebb883f77 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.0" #define MAX_MYSQL_VAR 512 @@ -702,9 +704,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)); @@ -1176,9 +1176,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 2c1687c6c90..777e68902dd 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"); @@ -2073,6 +2073,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))) @@ -2082,7 +2083,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 39ceb423968..4218f2da62c 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 e9a7a66298e..284ea1e760a 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1,5 +1,6 @@ /* 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 @@ -616,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 e4e34f786d7..77d0cd0a7d3 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 d0db2020998..5cf2be1160c 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; @@ -266,9 +267,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 e3da44e2fc5..8e70a2609c3 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 @@ -722,7 +722,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 bb89db4b231..5415b653615 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" @@ -6961,8 +6963,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/configure.pl b/cmake/configure.pl index e8cfa0b1261..a542092c417 100644 --- a/cmake/configure.pl +++ b/cmake/configure.pl @@ -25,6 +25,7 @@ my $cmakeargs = ""; # Assume this script is in <srcroot>/cmake my $srcdir = dirname(dirname(abs_path($0))); my $cmake_install_prefix=""; +my $just_print= 0; # Sets installation directory, bindir, libdir, libexecdir etc # the equivalent CMake variables are given without prefix @@ -113,6 +114,11 @@ foreach my $option (@ARGV) system("cmake ${srcdir} -LH"); exit(0); } + if ($option =~ /print/) + { + $just_print=1; + next; + } if($option =~ /with-plugins=/) { my @plugins= split(/,/, substr($option,13)); @@ -233,6 +239,7 @@ foreach my $option (@ARGV) } print("configure.pl : calling cmake $srcdir $cmakeargs\n"); +exit(0) if ($just_print); unlink("CMakeCache.txt"); my $rc = system("cmake $srcdir $cmakeargs"); exit($rc); diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index 7bb5c64f337..da48afad00c 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -62,8 +62,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") @@ -83,9 +85,10 @@ SET(CPACK_RPM_server_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES} galera") 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.${SHARED_LIB_MAJOR_VERSION} libmysqlclient.so.${SHARED_LIB_MAJOR_VERSION}(libmysqlclient_${SHARED_LIB_MAJOR_VERSION}) libmysqlclient_r.so.${SHARED_LIB_MAJOR_VERSION} libmysqlclient_r.so.${SHARED_LIB_MAJOR_VERSION}(libmysqlclient_${SHARED_LIB_MAJOR_VERSION})") +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)") SET(CPACK_RPM_shared_POST_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/shared-post.sh) SET(CPACK_RPM_shared_POST_UNINSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/shared-post.sh) 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/dist/Debian/mariadb-server-5.5.postinst b/debian/dist/Debian/mariadb-server-5.5.postinst index 2e15b121db9..4da8979fd03 100644 --- a/debian/dist/Debian/mariadb-server-5.5.postinst +++ b/debian/dist/Debian/mariadb-server-5.5.postinst @@ -212,7 +212,7 @@ EOF # admin might already have chosen to remove one or more plugins. Newlines are necessary. install_plugins=`/bin/echo -e \ "USE mysql;\n" \ - "CREATE TABLE plugin (name char(64) COLLATE utf8_bin NOT NULL DEFAULT '', " \ + "CREATE TABLE IF NOT EXISTS plugin (name char(64) COLLATE utf8_bin NOT NULL DEFAULT '', " \ " dl char(128) COLLATE utf8_bin NOT NULL DEFAULT '', " \ " PRIMARY KEY (name)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='MySQL plugins';" ` diff --git a/debian/mariadb-client-5.5.files b/debian/mariadb-client-5.5.files index 335f736d680..9cb949ea53e 100644 --- a/debian/mariadb-client-5.5.files +++ b/debian/mariadb-client-5.5.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-5.5 usr/share/man/man1/innotop.1 diff --git a/debian/mariadb-server-5.5.mysql.init b/debian/mariadb-server-5.5.mysql.init index b83316aedea..01e1288525e 100644 --- a/debian/mariadb-server-5.5.mysql.init +++ b/debian/mariadb-server-5.5.mysql.init @@ -109,7 +109,7 @@ case "${1:-''}" in /usr/bin/mysqld_safe > /dev/null 2>&1 & # 6s was reported in #352070 to be too few when using ndbcluster - for i in $(seq 1 "${MYSQLD_STARTUP_TIMEOUT:-14}"); do + for i in $(seq 1 "${MYSQLD_STARTUP_TIMEOUT:-30}"); do sleep 1 if mysqld_status check_alive nowarn ; then break; fi log_progress_msg "." @@ -142,7 +142,7 @@ case "${1:-''}" in log_daemon_msg "Killing MariaDB database server by signal" "mysqld" killall -15 mysqld server_down= - for i in 1 2 3 4 5 6 7 8 9 10; do + for i in 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10; do sleep 1 if mysqld_status check_dead nowarn; then server_down=1; break; fi done 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 c8ea85c5504..fbea21f9091 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; @@ -114,7 +115,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 0d99888da88..2fcba67cfdd 100644 --- a/extra/yassl/include/openssl/ssl.h +++ b/extra/yassl/include/openssl/ssl.h @@ -35,7 +35,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 7e73464001a..917cfa1a8fb 100644 --- a/extra/yassl/src/cert_wrapper.cpp +++ b/extra/yassl/src/cert_wrapper.cpp @@ -250,8 +250,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 8401798534b..6c839bc2f79 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -27,7 +27,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 b6925f916f8..c58713855dd 100644 --- a/extra/yassl/taocrypt/include/misc.hpp +++ b/extra/yassl/taocrypt/include/misc.hpp @@ -136,9 +136,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 5ec4cac1c44..ad054809879 100644 --- a/extra/yassl/taocrypt/src/asn.cpp +++ b/extra/yassl/taocrypt/src/asn.cpp @@ -154,6 +154,8 @@ word32 GetLength(Source& source) else length = b; + if (source.IsLeft(length) == false) return 0; + return length; } @@ -832,7 +834,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/CMakeLists.txt b/include/CMakeLists.txt index a90238dbd42..95850da382b 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -51,6 +51,7 @@ SET(HEADERS m_ctype.h my_attribute.h my_compiler.h + handler_state.h ) INSTALL(FILES ${HEADERS} DESTINATION ${INSTALL_INCLUDEDIR} COMPONENT Development) diff --git a/include/handler_state.h b/include/handler_state.h new file mode 100644 index 00000000000..65604a672fb --- /dev/null +++ b/include/handler_state.h @@ -0,0 +1,21 @@ +/* + Map handler error message to sql states. Note that this list MUST be in + increasing order! + See sql_state.c for usage +*/ + +{ HA_ERR_KEY_NOT_FOUND, "02000", "" }, +{ HA_ERR_FOUND_DUPP_KEY, "23000", "" }, +{ HA_ERR_WRONG_COMMAND, "0A000", "" }, +{ HA_ERR_UNSUPPORTED, "0A000", "" }, +{ HA_WRONG_CREATE_OPTION, "0A000", "" }, +{ HA_ERR_FOUND_DUPP_UNIQUE, "23000", "" }, +{ HA_ERR_UNKNOWN_CHARSET, "0A000", "" }, +{ HA_ERR_READ_ONLY_TRANSACTION, "25000", "" }, +{ HA_ERR_LOCK_DEADLOCK, "40001", "" }, +{ HA_ERR_NO_REFERENCED_ROW, "23000", "" }, +{ HA_ERR_ROW_IS_REFERENCED, "23000", "" }, +{ HA_ERR_TABLE_EXIST, "42S01", "" }, +{ HA_ERR_FOREIGN_DUPLICATE_KEY, "23000", "" }, +{ HA_ERR_TABLE_READONLY, "25000", "" }, +{ HA_ERR_AUTOINC_ERANGE, "22003", "" }, diff --git a/include/mysql.h b/include/mysql.h index d71d049f69d..1fc164f62b2 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -848,6 +848,7 @@ int STDCALL mysql_close_start(MYSQL *sock); int STDCALL mysql_close_cont(MYSQL *sock, int status); my_socket STDCALL mysql_get_socket(const MYSQL *mysql); unsigned int STDCALL mysql_get_timeout_value(const MYSQL *mysql); +unsigned int STDCALL mysql_get_timeout_value_ms(const MYSQL *mysql); /* status return codes */ #define MYSQL_NO_DATA 100 diff --git a/include/mysql.h.pp b/include/mysql.h.pp index ce577146581..48ce79046ff 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -729,3 +729,4 @@ int mysql_close_start(MYSQL *sock); int mysql_close_cont(MYSQL *sock, int status); my_socket mysql_get_socket(const MYSQL *mysql); unsigned int mysql_get_timeout_value(const MYSQL *mysql); +unsigned int mysql_get_timeout_value_ms(const MYSQL *mysql); 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/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/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 182c8748934..f67b3962c1a 100644 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -17,7 +17,6 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/libmysql ${CMAKE_SOURCE_DIR}/regex - ${CMAKE_SOURCE_DIR}/sql ${CMAKE_SOURCE_DIR}/strings ${SSL_INCLUDE_DIRS} ${SSL_INTERNAL_INCLUDE_DIRS} diff --git a/mysql-test/extra/binlog_tests/binlog.test b/mysql-test/extra/binlog_tests/binlog.test index 3bbc693ceda..5b57eab1005 100644 --- a/mysql-test/extra/binlog_tests/binlog.test +++ b/mysql-test/extra/binlog_tests/binlog.test @@ -205,16 +205,55 @@ DROP PROCEDURE p4; --echo End of 5.0 tests -# Test of a too big SET INSERT_ID: see if the truncated value goes -# into binlog (right), or the too big value (wrong); we look at the -# binlog further down with SHOW BINLOG EVENTS. +# Test of a too big SET INSERT_ID. +# This should generate an error and should not be put in binlog +# We look at the binlog further down with SHOW BINLOG EVENTS. + reset master; create table t1 (id tinyint auto_increment primary key); +insert into t1 values(5); +set insert_id=128; +--error 167 +insert into t1 values(null) /* Not binlogged */; + +# The followin insert ignore will be put in binlog set insert_id=128; -insert into t1 values(null); +insert ignore into t1 values(null) /* Insert 128 */; + +# Insert with duplicate key error should not go into binglo +set insert_id=5; +--error ER_DUP_ENTRY +insert into t1 values(null) /* Not binlogged */; + +# Insert with autogenerated key + duplicate key error should go into binlog +set insert_id=5; +insert ignore into t1 values(null) /* Insert 5 */; select * from t1; drop table t1; +# Same tests but with 2 rows inserted at a time + +create table t1 (id tinyint auto_increment primary key) engine=myisam; +set insert_id=128; +--error 167 +insert into t1 values(5),(null) /* Insert_id 128 */; + +# The followin insert ignore will be put in binlog +set insert_id=128; +insert ignore into t1 values (4),(null) /* Insert_id 128 */; + +# Insert with duplicate key error should not go into binglo +set insert_id=5; +--error ER_DUP_ENTRY +insert into t1 values(3),(null) /* Insert_id 5 */; + +# Insert with autogenerated key + duplicate key error should go into binlog +set insert_id=5; +insert ignore into t1 values(2),(null) /* Insert_id 5 */; +select * from t1 order by id; +drop table t1; + + # bug#22027 create table t1 (a int); create table if not exists t2 select * from t1; diff --git a/mysql-test/extra/binlog_tests/binlog_insert_delayed.test b/mysql-test/extra/binlog_tests/binlog_insert_delayed.test index 7b31a3ebf17..8f669fc1152 100644 --- a/mysql-test/extra/binlog_tests/binlog_insert_delayed.test +++ b/mysql-test/extra/binlog_tests/binlog_insert_delayed.test @@ -28,6 +28,7 @@ # BUG#20627: INSERT DELAYED does not honour auto_increment_* variables # Bug in this test: BUG#38068: binlog_stm_binlog fails sporadically in pushbuild +reset master; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; diff --git a/mysql-test/extra/rpl_tests/rpl_auto_increment.test b/mysql-test/extra/rpl_tests/rpl_auto_increment.test index bd5943d46ea..8cd86de8040 100644 --- a/mysql-test/extra/rpl_tests/rpl_auto_increment.test +++ b/mysql-test/extra/rpl_tests/rpl_auto_increment.test @@ -111,7 +111,7 @@ set auto_increment_increment=11; set auto_increment_offset=4; insert into t1 values(null); insert into t1 values(null); ---error ER_DUP_ENTRY +--error 167 insert into t1 values(null); select a, mod(a-@@auto_increment_offset,@@auto_increment_increment) from t1 order by a; @@ -120,6 +120,8 @@ create table t2 (a tinyint unsigned not null auto_increment primary key) engine= set auto_increment_increment=10; set auto_increment_offset=1; set insert_id=1000; +insert into t2 values(10); +--error 167 insert into t2 values(null); select a, mod(a-@@auto_increment_offset,@@auto_increment_increment) from t2 order by a; @@ -127,6 +129,7 @@ select a, mod(a-@@auto_increment_offset,@@auto_increment_increment) from t2 orde create table t3 like t1; set auto_increment_increment=1000; set auto_increment_offset=700; +--error 167 insert into t3 values(null); select * from t3 order by a; sync_slave_with_master; diff --git a/mysql-test/extra/rpl_tests/rpl_insert_delayed.test b/mysql-test/extra/rpl_tests/rpl_insert_delayed.test index df08622b0bd..62e90b629ba 100644 --- a/mysql-test/extra/rpl_tests/rpl_insert_delayed.test +++ b/mysql-test/extra/rpl_tests/rpl_insert_delayed.test @@ -102,7 +102,9 @@ CREATE TABLE t1(a int, UNIQUE(a)); --let $_start= query_get_value(SHOW MASTER STATUS, Position, 1) INSERT DELAYED IGNORE INTO t1 VALUES(1); +--disable_warnings INSERT DELAYED IGNORE INTO t1 VALUES(1); +--enable_warnings flush table t1; # to wait for INSERT DELAYED to be done if (`SELECT @@global.binlog_format = 'STATEMENT'`) { diff --git a/mysql-test/include/strict_autoinc.inc b/mysql-test/include/strict_autoinc.inc index 823efcc2040..3298008b66f 100644 --- a/mysql-test/include/strict_autoinc.inc +++ b/mysql-test/include/strict_autoinc.inc @@ -19,11 +19,12 @@ select count(*) from t1; set auto_increment_increment=1000; set auto_increment_offset=700; ---error ER_WARN_DATA_OUT_OF_RANGE +--error 167 insert into t1 values(null); select count(*) from t1; set @@sql_mode=@org_mode; +--error 167 insert into t1 values(null); select * from t1; diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index 30b4ff11227..12cbf294b69 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -150,7 +150,7 @@ select last_insert_id(); last_insert_id() 255 insert into t1 set i = null; -ERROR 23000: Duplicate entry '255' for key 'PRIMARY' +ERROR 22003: Out of range value for column 'i' at row 1 select last_insert_id(); last_insert_id() 255 @@ -162,8 +162,7 @@ select last_insert_id(); last_insert_id() 255 insert into t1 set i = null; -Warnings: -Warning 1264 Out of range value for column 'i' at row 1 +ERROR 22003: Out of range value for column 'i' at row 1 select last_insert_id(); last_insert_id() 255 @@ -487,7 +486,7 @@ SELECT @@SESSION.AUTO_INCREMENT_OFFSET; @@SESSION.AUTO_INCREMENT_OFFSET 1 INSERT INTO t1 VALUES (NULL), (NULL), (NULL); -ERROR 22003: Out of range value for column 't1' at row 167 +ERROR 22003: Out of range value for column 'c1' at row 2 SELECT * FROM t1; c1 1 diff --git a/mysql-test/r/auto_increment_ranges_innodb.result b/mysql-test/r/auto_increment_ranges_innodb.result new file mode 100644 index 00000000000..fb936ddfd2b --- /dev/null +++ b/mysql-test/r/auto_increment_ranges_innodb.result @@ -0,0 +1,266 @@ +set default_storage_engine=innodb; +drop table if exists t1; +# +# Testing ranges with smallint +# +create table t1 (a smallint primary key auto_increment); +insert into t1 values(32767); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +truncate table t1; +insert into t1 values(32767-1); +insert into t1 values(NULL); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +select * from t1; +a +32766 +32767 +truncate table t1; +insert into t1 values(32767),(NULL); +ERROR 22003: Out of range value for column 'a' at row 2 +select * from t1; +a +truncate table t1; +insert into t1 values(32767-1),(NULL),(NULL); +ERROR 22003: Out of range value for column 'a' at row 3 +truncate table t1; +insert into t1 values(32767+1); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +select * from t1; +a +32767 +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +drop table t1; +# +# Testing ranges with unsigned smallint +# +create table t1 (a smallint unsigned primary key auto_increment); +insert into t1 values(65535); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +truncate table t1; +insert into t1 values(65535-1); +insert into t1 values(NULL); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +select * from t1; +a +65534 +65535 +truncate table t1; +insert into t1 values(65535),(NULL); +ERROR 22003: Out of range value for column 'a' at row 2 +select * from t1; +a +truncate table t1; +insert into t1 values(65535-1),(NULL),(NULL); +ERROR 22003: Out of range value for column 'a' at row 3 +truncate table t1; +insert into t1 values(65535+1); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +select * from t1; +a +65535 +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +drop table t1; +# +# Testing ranges with integer +# +create table t1 (a int primary key auto_increment); +insert into t1 values(2147483647); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +truncate table t1; +insert into t1 values(2147483647-1); +insert into t1 values(NULL); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +select * from t1; +a +2147483646 +2147483647 +truncate table t1; +insert into t1 values(2147483647),(NULL); +ERROR 22003: Out of range value for column 'a' at row 2 +select * from t1; +a +truncate table t1; +insert into t1 values(2147483647-1),(NULL),(NULL); +ERROR 22003: Out of range value for column 'a' at row 3 +truncate table t1; +insert into t1 values(2147483647+1); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +select * from t1; +a +2147483647 +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +drop table t1; +# +# Testing ranges with unsigned integer +# +create table t1 (a int unsigned primary key auto_increment); +insert into t1 values(4294967295); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +truncate table t1; +insert into t1 values(4294967295-1); +insert into t1 values(NULL); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +select * from t1; +a +4294967294 +4294967295 +truncate table t1; +insert into t1 values(4294967295),(NULL); +ERROR 22003: Out of range value for column 'a' at row 2 +select * from t1; +a +truncate table t1; +insert into t1 values(4294967295-1),(NULL),(NULL); +ERROR 22003: Out of range value for column 'a' at row 3 +truncate table t1; +insert into t1 values(4294967295+1); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +select * from t1; +a +4294967295 +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +drop table t1; +# +# Testing ranges with bigint +# +create table t1 (a bigint primary key auto_increment); +insert into t1 values(cast(9223372036854775807 as unsigned)); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +truncate table t1; +insert into t1 values(cast(9223372036854775807 as unsigned)-1); +insert into t1 values(NULL); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +select * from t1; +a +9223372036854775806 +9223372036854775807 +truncate table t1; +insert into t1 values(cast(9223372036854775807 as unsigned)),(NULL); +ERROR 22003: Out of range value for column 'a' at row 2 +select * from t1; +a +truncate table t1; +insert into t1 values(cast(9223372036854775807 as unsigned)-1),(NULL),(NULL); +ERROR 22003: Out of range value for column 'a' at row 3 +truncate table t1; +insert into t1 values(cast(9223372036854775807 as unsigned)+1); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +select * from t1; +a +9223372036854775807 +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +drop table t1; +# +# Testing ranges with unsigned bigint +# +create table t1 (a bigint unsigned primary key auto_increment); +insert into t1 values(18446744073709551615-1); +insert into t1 values(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +insert into t1 values(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +truncate table t1; +insert into t1 values(18446744073709551615-1); +insert into t1 values(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +insert into t1 values(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +select * from t1; +a +18446744073709551614 +truncate table t1; +insert into t1 values(18446744073709551615),(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +select * from t1; +a +truncate table t1; +insert into t1 values(18446744073709551615-1),(NULL),(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +drop table t1; +# +# Test IGNORE and strict mode +# +create table t1 (a smallint primary key auto_increment); +insert ignore into t1 values(32766),(NULL),(NULL),(1); +Warnings: +Warning 167 Out of range value for column 'a' at row 3 +select * from t1; +a +1 +32766 +32767 +truncate table t1; +set @org_mode=@@sql_mode; +set @@sql_mode='ansi,traditional'; +insert ignore into t1 values(32766),(NULL),(NULL); +Warnings: +Warning 167 Out of range value for column 'a' at row 3 +truncate table t1; +insert into t1 values(32766),(NULL),(NULL); +ERROR 22003: Out of range value for column 'a' at row 3 +set @@sql_mode=@org_mode; +drop table t1; +# +# Test auto increment with negative numbers +# +CREATE TABLE t1 (a INTEGER AUTO_INCREMENT, PRIMARY KEY (a)); +INSERT INTO t1 VALUES (NULL), (2), (-5), (NULL); +INSERT INTO t1 VALUES (NULL); +SELECT * FROM t1; +a +-5 +1 +2 +3 +5 +TRUNCATE TABLE t1; +INSERT INTO t1 VALUES (-5), (NULL); +SELECT * FROM t1; +a +-5 +1 +DROP TABLE t1; +# +# Test inserting a value out-of-range into an auto increment column +# +CREATE TABLE t1 (a smallint AUTO_INCREMENT, PRIMARY KEY (a)); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (32768); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +INSERT INTO t1 VALUES (NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +SELECT * FROM t1; +a +2 +32767 +DROP TABLE t1; +# +# Test old behaviour +# +create table t1 (a smallint primary key auto_increment); +insert into t1 values(32766),(NULL); +delete from t1 where a=32767; +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +drop table t1; diff --git a/mysql-test/r/auto_increment_ranges_myisam.result b/mysql-test/r/auto_increment_ranges_myisam.result new file mode 100644 index 00000000000..5101321c864 --- /dev/null +++ b/mysql-test/r/auto_increment_ranges_myisam.result @@ -0,0 +1,272 @@ +set default_storage_engine=MYISAM; +drop table if exists t1; +# +# Testing ranges with smallint +# +create table t1 (a smallint primary key auto_increment); +insert into t1 values(32767); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +truncate table t1; +insert into t1 values(32767-1); +insert into t1 values(NULL); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +select * from t1; +a +32766 +32767 +truncate table t1; +insert into t1 values(32767),(NULL); +ERROR 22003: Out of range value for column 'a' at row 2 +select * from t1; +a +32767 +truncate table t1; +insert into t1 values(32767-1),(NULL),(NULL); +ERROR 22003: Out of range value for column 'a' at row 3 +truncate table t1; +insert into t1 values(32767+1); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +select * from t1; +a +32767 +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +drop table t1; +# +# Testing ranges with unsigned smallint +# +create table t1 (a smallint unsigned primary key auto_increment); +insert into t1 values(65535); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +truncate table t1; +insert into t1 values(65535-1); +insert into t1 values(NULL); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +select * from t1; +a +65534 +65535 +truncate table t1; +insert into t1 values(65535),(NULL); +ERROR 22003: Out of range value for column 'a' at row 2 +select * from t1; +a +65535 +truncate table t1; +insert into t1 values(65535-1),(NULL),(NULL); +ERROR 22003: Out of range value for column 'a' at row 3 +truncate table t1; +insert into t1 values(65535+1); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +select * from t1; +a +65535 +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +drop table t1; +# +# Testing ranges with integer +# +create table t1 (a int primary key auto_increment); +insert into t1 values(2147483647); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +truncate table t1; +insert into t1 values(2147483647-1); +insert into t1 values(NULL); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +select * from t1; +a +2147483646 +2147483647 +truncate table t1; +insert into t1 values(2147483647),(NULL); +ERROR 22003: Out of range value for column 'a' at row 2 +select * from t1; +a +2147483647 +truncate table t1; +insert into t1 values(2147483647-1),(NULL),(NULL); +ERROR 22003: Out of range value for column 'a' at row 3 +truncate table t1; +insert into t1 values(2147483647+1); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +select * from t1; +a +2147483647 +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +drop table t1; +# +# Testing ranges with unsigned integer +# +create table t1 (a int unsigned primary key auto_increment); +insert into t1 values(4294967295); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +truncate table t1; +insert into t1 values(4294967295-1); +insert into t1 values(NULL); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +select * from t1; +a +4294967294 +4294967295 +truncate table t1; +insert into t1 values(4294967295),(NULL); +ERROR 22003: Out of range value for column 'a' at row 2 +select * from t1; +a +4294967295 +truncate table t1; +insert into t1 values(4294967295-1),(NULL),(NULL); +ERROR 22003: Out of range value for column 'a' at row 3 +truncate table t1; +insert into t1 values(4294967295+1); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +select * from t1; +a +4294967295 +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +drop table t1; +# +# Testing ranges with bigint +# +create table t1 (a bigint primary key auto_increment); +insert into t1 values(cast(9223372036854775807 as unsigned)); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +truncate table t1; +insert into t1 values(cast(9223372036854775807 as unsigned)-1); +insert into t1 values(NULL); +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +select * from t1; +a +9223372036854775806 +9223372036854775807 +truncate table t1; +insert into t1 values(cast(9223372036854775807 as unsigned)),(NULL); +ERROR 22003: Out of range value for column 'a' at row 2 +select * from t1; +a +9223372036854775807 +truncate table t1; +insert into t1 values(cast(9223372036854775807 as unsigned)-1),(NULL),(NULL); +ERROR 22003: Out of range value for column 'a' at row 3 +truncate table t1; +insert into t1 values(cast(9223372036854775807 as unsigned)+1); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +select * from t1; +a +9223372036854775807 +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +drop table t1; +# +# Testing ranges with unsigned bigint +# +create table t1 (a bigint unsigned primary key auto_increment); +insert into t1 values(18446744073709551615-1); +insert into t1 values(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +insert into t1 values(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +truncate table t1; +insert into t1 values(18446744073709551615-1); +insert into t1 values(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +insert into t1 values(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +select * from t1; +a +18446744073709551614 +truncate table t1; +insert into t1 values(18446744073709551615),(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +select * from t1; +a +18446744073709551615 +truncate table t1; +insert into t1 values(18446744073709551615-1),(NULL),(NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +drop table t1; +# +# Test IGNORE and strict mode +# +create table t1 (a smallint primary key auto_increment); +insert ignore into t1 values(32766),(NULL),(NULL),(1); +Warnings: +Warning 167 Out of range value for column 'a' at row 3 +select * from t1; +a +1 +32766 +32767 +truncate table t1; +set @org_mode=@@sql_mode; +set @@sql_mode='ansi,traditional'; +insert ignore into t1 values(32766),(NULL),(NULL); +Warnings: +Warning 167 Out of range value for column 'a' at row 3 +truncate table t1; +insert into t1 values(32766),(NULL),(NULL); +ERROR 22003: Out of range value for column 'a' at row 3 +set @@sql_mode=@org_mode; +drop table t1; +# +# Test auto increment with negative numbers +# +CREATE TABLE t1 (a INTEGER AUTO_INCREMENT, PRIMARY KEY (a)); +INSERT INTO t1 VALUES (NULL), (2), (-5), (NULL); +INSERT INTO t1 VALUES (NULL); +SELECT * FROM t1; +a +-5 +1 +2 +3 +4 +TRUNCATE TABLE t1; +INSERT INTO t1 VALUES (-5), (NULL); +SELECT * FROM t1; +a +-5 +1 +DROP TABLE t1; +# +# Test inserting a value out-of-range into an auto increment column +# +CREATE TABLE t1 (a smallint AUTO_INCREMENT, PRIMARY KEY (a)); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (32768); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +INSERT INTO t1 VALUES (NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +SELECT * FROM t1; +a +2 +32767 +DROP TABLE t1; +# +# Test old behaviour +# +create table t1 (a smallint primary key auto_increment); +insert into t1 values(32766),(NULL); +delete from t1 where a=32767; +insert into t1 values(NULL); +ERROR 22003: Out of range value for column 'a' at row 1 +drop table t1; diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result index 3e3d75f66e4..af198edc4ca 100644 --- a/mysql-test/r/commit_1innodb.result +++ b/mysql-test/r/commit_1innodb.result @@ -529,6 +529,8 @@ SUCCESS # 13. Read-write statement: INSERT IGNORE, change 0 rows. # insert ignore t1 set a=2; +Warnings: +Warning 1062 Duplicate entry '2' for key 'a' call p_verify_status_increment(2, 2, 1, 0); SUCCESS diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 0a6dff6d9a3..ba52959be84 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -2396,6 +2396,8 @@ a b drop table t1; create table if not exists t1 (a int unique, b int) ignore select 1 as a, 1 as b union select 1 as a, 2 as b; +Warnings: +Warning 1062 Duplicate entry '1' for key 'a' select * from t1; a b 1 1 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/insert.result b/mysql-test/r/insert.result index 655303be7f4..7110f541fb7 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -327,9 +327,11 @@ select row_count(); row_count() 3 insert ignore into t1 values (1, 1); +Warnings: +Warning 1062 Duplicate entry '1' for key 'PRIMARY' select row_count(); row_count() -0 +-1 replace into t1 values (1, 11); select row_count(); row_count() @@ -371,7 +373,15 @@ drop table t1,t2; create table t1 (id int primary key auto_increment, data int, unique(data)); insert ignore into t1 values(NULL,100),(NULL,110),(NULL,120); insert ignore into t1 values(NULL,10),(NULL,20),(NULL,110),(NULL,120),(NULL,100),(NULL,90); +Warnings: +Warning 1062 Duplicate entry '110' for key 'data' +Warning 1062 Duplicate entry '120' for key 'data' +Warning 1062 Duplicate entry '100' for key 'data' insert ignore into t1 values(NULL,130),(NULL,140),(500,110),(550,120),(450,100),(NULL,150); +Warnings: +Warning 1062 Duplicate entry '110' for key 'data' +Warning 1062 Duplicate entry '120' for key 'data' +Warning 1062 Duplicate entry '100' for key 'data' select * from t1 order by id; id data 1 100 diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index c952b914167..8bfc4e9215e 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -6,6 +6,10 @@ insert into t2 (payoutID) SELECT DISTINCT payoutID FROM t1; insert into t2 (payoutID) SELECT payoutID+10 FROM t1; ERROR 23000: Duplicate entry '16' for key 'PRIMARY' insert ignore into t2 (payoutID) SELECT payoutID+10 FROM t1; +Warnings: +Warning 1062 Duplicate entry '16' for key 'PRIMARY' +Warning 1062 Duplicate entry '16' for key 'PRIMARY' +Warning 1062 Duplicate entry '22' for key 'PRIMARY' select * from t2; payoutID 1 diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result index c3acea5d11f..1987c5c0559 100644 --- a/mysql-test/r/insert_update.result +++ b/mysql-test/r/insert_update.result @@ -172,11 +172,15 @@ DROP TABLE t2; create table t1 (a int not null unique) engine=myisam; insert into t1 values (1),(2); insert ignore into t1 select 1 on duplicate key update a=2; +Warnings: +Warning 1062 Duplicate entry '2' for key 'a' select * from t1; a 1 2 insert ignore into t1 select a from t1 as t2 on duplicate key update a=t1.a+1 ; +Warnings: +Warning 1062 Duplicate entry '2' for key 'a' select * from t1; a 1 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/log_state.result b/mysql-test/r/log_state.result index 1a6f8534cc2..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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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/mix2_myisam.result b/mysql-test/r/mix2_myisam.result index e5f5857d2c9..6f90555325b 100644 --- a/mysql-test/r/mix2_myisam.result +++ b/mysql-test/r/mix2_myisam.result @@ -702,6 +702,8 @@ id 2 99 insert ignore into t1 values (100,1,2,'D'),(1,1,99,'D'); +Warnings: +Warning 1062 Duplicate entry '1-1' for key 'PRIMARY' commit; select id,id3 from t1; id id3 diff --git a/mysql-test/r/myisam_mrr.result b/mysql-test/r/myisam_mrr.result index 03d212dbc04..bd50df7c40e 100644 --- a/mysql-test/r/myisam_mrr.result +++ b/mysql-test/r/myisam_mrr.result @@ -278,6 +278,8 @@ bb-1 NULL cc-2 NULL-1 drop table t1, t2, t3, t4; create table t1 (a int, b int not null,unique key (a,b),index(b)); insert ignore into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(null,7),(9,9),(8,8),(7,7),(null,9),(null,9),(6,6); +Warnings: +Warning 1062 Duplicate entry '6-6' for key 'a' create table t2 like t1; insert into t2 select * from t1; alter table t1 modify b blob not null, add c int not null, drop key a, add unique key (a,b(20),c), drop key b, add key (b(10)); diff --git a/mysql-test/r/mysqld--help,win.rdiff b/mysql-test/r/mysqld--help,win.rdiff index 957292b265f..cd39445f3e6 100644 --- a/mysql-test/r/mysqld--help,win.rdiff +++ b/mysql-test/r/mysqld--help,win.rdiff @@ -1,6 +1,6 @@ ---- r/mysqld--help.result 2012-01-13 16:50:49.000000000 +0100 -+++ r/mysqld--help-win.result 2012-01-19 14:12:00.000000000 +0100 -@@ -240,7 +240,6 @@ +--- mysql-test/r/mysqld--help.result 2012-09-08 22:22:06 +0000 ++++ mysql-test/r/mysqld--help.result 2012-10-01 14:03:59 +0000 +@@ -244,7 +244,6 @@ The number of segments in a key cache -L, --language=name Client error messages in given language. May be given as a full path. Deprecated. Use --lc-messages-dir instead. @@ -8,7 +8,7 @@ --lc-messages=name Set the language used for the error messages. -L, --lc-messages-dir=name Directory where error messages are -@@ -436,6 +435,7 @@ +@@ -440,6 +439,7 @@ NULLS_UNEQUAL (default behavior for 4.1 and later), NULLS_EQUAL (emulate 4.0 behavior), and NULLS_IGNORED --myisam-use-mmap Use memory mapping for reading and writing MyISAM tables @@ -16,7 +16,7 @@ --net-buffer-length=# Buffer length for TCP/IP and socket communication --net-read-timeout=# -@@ -695,6 +695,9 @@ +@@ -707,6 +707,9 @@ files within specified directory --server-id=# Uniquely identifies the server instance in the community of replication partners @@ -26,7 +26,7 @@ --show-slave-auth-info Show user and password in SHOW SLAVE HOSTS on this master. -@@ -759,6 +762,10 @@ +@@ -774,6 +777,10 @@ Log slow queries to given log file. Defaults logging to 'hostname'-slow.log. Must be enabled to activate other slow log options @@ -37,7 +37,7 @@ --socket=name Socket file to use for connection --sort-buffer-size=# Each thread that needs to do a sort allocates a buffer of -@@ -767,6 +774,7 @@ +@@ -782,6 +789,7 @@ for the complete list of valid sql modes --stack-trace Print a symbolic stack trace on failure (Defaults to on; use --skip-stack-trace to disable.) @@ -45,7 +45,7 @@ --stored-program-cache=# The soft upper limit for number of cached stored routines for one connection. -@@ -807,8 +815,8 @@ +@@ -822,8 +830,8 @@ size, MySQL will automatically convert it to an on-disk MyISAM or Aria table -t, --tmpdir=name Path for temporary files. Several paths may be specified, @@ -56,15 +56,15 @@ --transaction-alloc-block-size=# Allocation block size for transactions to be stored in binary log -@@ -908,7 +916,6 @@ +@@ -923,7 +931,6 @@ key-cache-age-threshold 300 + key-cache-block-size 1024 key-cache-division-limit 100 key-cache-segments 0 - language MYSQL_SHAREDIR/ -large-pages FALSE lc-messages en_US lc-messages-dir MYSQL_SHAREDIR/ lc-time-names en_US -@@ -971,6 +978,7 @@ +@@ -986,6 +993,7 @@ myisam-repair-threads 1 myisam-sort-buffer-size 8388608 myisam-stats-method nulls_unequal myisam-use-mmap FALSE @@ -72,7 +72,7 @@ net-buffer-length 16384 net-read-timeout 30 net-retry-count 10 -@@ -1035,6 +1043,8 @@ +@@ -1051,6 +1059,8 @@ safe-user-create FALSE secure-auth FALSE secure-file-priv (No default value) server-id 0 @@ -81,7 +81,7 @@ show-slave-auth-info FALSE skip-grant-tables TRUE skip-name-resolve FALSE -@@ -1050,6 +1060,7 @@ +@@ -1067,6 +1077,7 @@ slave-transaction-retries 10 slave-type-conversions slow-launch-time 2 slow-query-log FALSE @@ -89,3 +89,4 @@ sort-buffer-size 2097152 sql-mode stack-trace TRUE + diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index 718909d1b27..c36cc96bb1a 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 @@ -909,6 +913,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/null_key.result b/mysql-test/r/null_key.result index 35c6ebe1442..ba79011f53e 100644 --- a/mysql-test/r/null_key.result +++ b/mysql-test/r/null_key.result @@ -1,6 +1,8 @@ drop table if exists t1,t2; create table t1 (a int, b int not null,unique key (a,b),index(b)) engine=myisam; insert ignore into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(null,7),(9,9),(8,8),(7,7),(null,9),(null,9),(6,6); +Warnings: +Warning 1062 Duplicate entry '6-6' for key 'a' explain select * from t1 where a is null; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref a a 5 const 3 Using where; Using index 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 d2f740a06f4..0a3d16cf48e 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/replace.result b/mysql-test/r/replace.result index 842302c89ac..59b8565f671 100644 --- a/mysql-test/r/replace.result +++ b/mysql-test/r/replace.result @@ -13,9 +13,9 @@ drop table t1; create table t1 (a tinyint not null auto_increment primary key, b char(20) default "default_value"); insert into t1 values (126,"first"),(63, "middle"),(0,"last"); insert into t1 values (0,"error"); -ERROR 23000: Duplicate entry '127' for key 'PRIMARY' +ERROR 22003: Out of range value for column 'a' at row 1 replace into t1 values (0,"error"); -ERROR 23000: Duplicate entry '127' for key 'PRIMARY' +ERROR 22003: Out of range value for column 'a' at row 1 replace into t1 values (126,"first updated"); replace into t1 values (63,default); select * from 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/strict_autoinc_1myisam.result b/mysql-test/r/strict_autoinc_1myisam.result index afcccb1c40f..b22540f295b 100644 --- a/mysql-test/r/strict_autoinc_1myisam.result +++ b/mysql-test/r/strict_autoinc_1myisam.result @@ -20,9 +20,7 @@ count(*) 0 set @@sql_mode=@org_mode; insert into t1 values(null); -Warnings: -Warning 1264 Out of range value for column 'a' at row 1 +ERROR 22003: Out of range value for column 'a' at row 1 select * from t1; a -127 drop table t1; diff --git a/mysql-test/r/strict_autoinc_2innodb.result b/mysql-test/r/strict_autoinc_2innodb.result index e534286e2a2..1cf720da12a 100644 --- a/mysql-test/r/strict_autoinc_2innodb.result +++ b/mysql-test/r/strict_autoinc_2innodb.result @@ -20,9 +20,7 @@ count(*) 0 set @@sql_mode=@org_mode; insert into t1 values(null); -Warnings: -Warning 1264 Out of range value for column 'a' at row 1 +ERROR 22003: Out of range value for column 'a' at row 1 select * from t1; a -127 drop table t1; diff --git a/mysql-test/r/strict_autoinc_3heap.result b/mysql-test/r/strict_autoinc_3heap.result index 0a31da04460..21eea537af5 100644 --- a/mysql-test/r/strict_autoinc_3heap.result +++ b/mysql-test/r/strict_autoinc_3heap.result @@ -20,9 +20,7 @@ count(*) 0 set @@sql_mode=@org_mode; insert into t1 values(null); -Warnings: -Warning 1264 Out of range value for column 'a' at row 1 +ERROR 22003: Out of range value for column 'a' at row 1 select * from t1; a -127 drop table t1; 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/subselect4.result b/mysql-test/r/subselect4.result index 0f9912fc1f3..c35075d80a1 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -206,6 +206,165 @@ default(a) aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa DROP TABLE t; # +# LP BUG#1009187, MDEV-373, MYSQL bug#58628 +# Wrong result for a query with [NOT] IN subquery predicate if +# the left part of the predicate is explicit NULL +# +CREATE TABLE t1 (pk INT NOT NULL, i INT NOT NULL); +INSERT INTO t1 VALUES (0,10), (1,20), (2,30), (3,40); +CREATE TABLE t2a (pk INT NOT NULL, i INT NOT NULL, PRIMARY KEY(i,pk)); +INSERT INTO t2a VALUES (0,0), (1,1), (2,2), (3,3); +CREATE TABLE t2b (pk INT, i INT); +INSERT INTO t2b VALUES (0,0), (1,1), (2,2), (3,3); +CREATE TABLE t2c (pk INT NOT NULL, i INT NOT NULL); +INSERT INTO t2c VALUES (0,0), (1,1), (2,2), (3,3); +create index it2c on t2c (i,pk); +CREATE TABLE t2d (pk INT NOT NULL, i INT NOT NULL, PRIMARY KEY(i)); +INSERT INTO t2d VALUES (0,0), (1,1), (2,2), (3,3); +EXPLAIN +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY t2a unique_subquery PRIMARY PRIMARY 8 const,test.t1.pk 1 Using index; Using where; Full scan on NULL key +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk); +pk i +SELECT * FROM t1 WHERE 1+NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk); +pk i +SELECT * FROM t1 WHERE NULL IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk) IS UNKNOWN; +pk i +0 10 +1 20 +2 30 +3 40 +SELECT t1.pk, NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk) FROM t1; +pk NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk) +0 NULL +1 NULL +2 NULL +3 NULL +EXPLAIN +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY t2b ALL NULL NULL NULL NULL 4 Using where +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk); +pk i +SELECT * FROM t1 WHERE NULL IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk) IS UNKNOWN; +pk i +0 10 +1 20 +2 30 +3 40 +SELECT t1.pk, NULL NOT IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk) FROM t1; +pk NULL NOT IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk) +0 NULL +1 NULL +2 NULL +3 NULL +EXPLAIN +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY t2c index_subquery it2c it2c 8 const,test.t1.pk 2 Using index; Using where; Full scan on NULL key +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk); +pk i +SELECT * FROM t1 WHERE NULL IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk) IS UNKNOWN; +pk i +0 10 +1 20 +2 30 +3 40 +SELECT t1.pk, NULL NOT IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk) FROM t1; +pk NULL NOT IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk) +0 NULL +1 NULL +2 NULL +3 NULL +EXPLAIN +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2d.i FROM t2d WHERE t2d.pk = t1.pk); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY t2d const PRIMARY PRIMARY 4 const 1 Using where; Full scan on NULL key +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2d.i FROM t2d WHERE t2d.pk = t1.pk); +pk i +SELECT * FROM t1 WHERE NULL IN (SELECT t2d.i FROM t2d WHERE t2d.pk = t1.pk) IS UNKNOWN; +pk i +0 10 +1 20 +2 30 +3 40 +SELECT t1.pk, NULL NOT IN (SELECT t2d.i FROM t2d WHERE t2d.pk = t1.pk) FROM t1; +pk NULL NOT IN (SELECT t2d.i FROM t2d WHERE t2d.pk = t1.pk) +0 NULL +1 NULL +2 NULL +3 NULL +EXPLAIN +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY t2a eq_ref PRIMARY PRIMARY 8 const,test.t1.pk 1 Using where; Using index; Full scan on NULL key +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk); +pk i +0 10 +2 30 +3 40 +SELECT (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk) from t1; +(NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk) +1 +NULL +1 +1 +EXPLAIN +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY t2b ALL NULL NULL NULL NULL 4 Using where +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk); +pk i +0 10 +2 30 +3 40 +SELECT (NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk) from t1; +(NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk) +1 +NULL +1 +1 +EXPLAIN +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY t2c ref it2c it2c 8 const,test.t1.pk 2 Using where; Using index; Full scan on NULL key +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk); +pk i +0 10 +2 30 +3 40 +SELECT (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk) from t1; +(NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk) +1 +NULL +1 +1 +EXPLAIN +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY t2d const PRIMARY PRIMARY 4 const 1 Using where; Full scan on NULL key +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk); +pk i +0 10 +2 30 +3 40 +SELECT (NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk) from t1; +(NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk) +1 +NULL +1 +1 +drop table t1, t2a, t2b, t2c, t2d; +# # End of 5.1 tests. # # @@ -271,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 7.0. 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` ; @@ -279,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 7.0. 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 @@ -466,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 7.0. 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 @@ -481,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 7.0. 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. @@ -1192,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/trigger.result b/mysql-test/r/trigger.result index ef998abafcf..6047d00c858 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -165,6 +165,8 @@ select @log; (BEFORE_INSERT: new=(id=1, data=1))(AFTER_INSERT: new=(id=1, data=1)) set @log:= ""; insert ignore t1 values (1, 2); +Warnings: +Warning 1062 Duplicate entry '1' for key 'PRIMARY' select @log; @log (BEFORE_INSERT: new=(id=1, data=2)) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index e0cfe1d346c..e055a333faf 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 7.0. +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; @@ -1060,7 +1060,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 7.0. +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/r/xtradb_mrr.result b/mysql-test/r/xtradb_mrr.result index 069d3c25826..15b750d2fd3 100644 --- a/mysql-test/r/xtradb_mrr.result +++ b/mysql-test/r/xtradb_mrr.result @@ -276,6 +276,8 @@ bb-1 NULL cc-2 NULL-1 drop table t1, t2, t3, t4; create table t1 (a int, b int not null,unique key (a,b),index(b)); insert ignore into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(null,7),(9,9),(8,8),(7,7),(null,9),(null,9),(6,6); +Warnings: +Warning 1062 Duplicate entry '6-6' for key 'a' create table t2 like t1; insert into t2 select * from t1; alter table t1 modify b blob not null, add c int not null, drop key a, add unique key (a,b(20),c), drop key b, add key (b(10)); diff --git a/mysql-test/suite/binlog/r/binlog_innodb_row.result b/mysql-test/suite/binlog/r/binlog_innodb_row.result index 61f961f16da..043f363c9c7 100644 --- a/mysql-test/suite/binlog/r/binlog_innodb_row.result +++ b/mysql-test/suite/binlog/r/binlog_innodb_row.result @@ -69,6 +69,8 @@ INSERT INTO t1 VALUES (1); START TRANSACTION; INSERT INTO t2 VALUES (1); INSERT IGNORE INTO t1 VALUES (1); +Warnings: +Warning 1062 Duplicate entry '1' for key 'PRIMARY' COMMIT; INSERT INTO t1 VALUES (2); START TRANSACTION; diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result index 95477d13b50..a3ee21b9957 100644 --- a/mysql-test/suite/binlog/r/binlog_row_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result @@ -578,13 +578,46 @@ DROP PROCEDURE p4; End of 5.0 tests reset master; create table t1 (id tinyint auto_increment primary key); +insert into t1 values(5); set insert_id=128; -insert into t1 values(null); +insert into t1 values(null) /* Not binlogged */; +ERROR 22003: Out of range value for column 'id' at row 1 +set insert_id=128; +insert ignore into t1 values(null) /* Insert 128 */; +Warnings: +Warning 167 Out of range value for column 'id' at row 1 +set insert_id=5; +insert into t1 values(null) /* Not binlogged */; +ERROR 23000: Duplicate entry '5' for key 'PRIMARY' +set insert_id=5; +insert ignore into t1 values(null) /* Insert 5 */; Warnings: -Warning 1264 Out of range value for column 'id' at row 1 +Warning 1062 Duplicate entry '5' for key 'PRIMARY' select * from t1; id -127 +5 +drop table t1; +create table t1 (id tinyint auto_increment primary key) engine=myisam; +set insert_id=128; +insert into t1 values(5),(null) /* Insert_id 128 */; +ERROR 22003: Out of range value for column 'id' at row 2 +set insert_id=128; +insert ignore into t1 values (4),(null) /* Insert_id 128 */; +Warnings: +Warning 167 Out of range value for column 'id' at row 2 +set insert_id=5; +insert into t1 values(3),(null) /* Insert_id 5 */; +ERROR 23000: Duplicate entry '5' for key 'PRIMARY' +set insert_id=5; +insert ignore into t1 values(2),(null) /* Insert_id 5 */; +Warnings: +Warning 1062 Duplicate entry '5' for key 'PRIMARY' +select * from t1 order by id; +id +2 +3 +4 +5 drop table t1; create table t1 (a int); create table if not exists t2 select * from t1; @@ -603,36 +636,19 @@ master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ -master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Query # # use `test`; create table t1 (id tinyint auto_increment primary key) engine=myisam master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t2` ( - `a` int(11) DEFAULT NULL -) -master-bin.000001 # Query # # COMMIT -master-bin.000001 # Query # # use `test`; CREATE TABLE IF NOT EXISTS `t3` ( - `a` int(11) DEFAULT NULL -) -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Table_map # # table_id: # (mysql.user) +master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # BEGIN -master-bin.000001 # Table_map # # table_id: # (mysql.user) -master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # BEGIN -master-bin.000001 # Table_map # # table_id: # (mysql.user) -master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT -drop table t1,t2,t3,tt1; -create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; -insert /* before delayed */ delayed /* after delayed */ into t1 values (207); -insert /*! delayed */ into t1 values (null); -insert delayed into t1 values (300); -FLUSH TABLES; -show binlog events from <binlog_start>; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; create table t1 (id tinyint auto_increment primary key) master-bin.000001 # Query # # BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F @@ -659,8 +675,15 @@ master-bin.000001 # Query # # BEGIN master-bin.000001 # Table_map # # table_id: # (mysql.user) master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT -master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE IF EXISTS `tt1` /* generated by server */ -master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2`,`t3` /* generated by server */ +drop table t1,t2,t3,tt1; +reset master; +create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; +insert /* before delayed */ delayed /* after delayed */ into t1 values (207); +insert /*! delayed */ into t1 values (null); +insert delayed into t1 values (300); +FLUSH TABLES; +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam master-bin.000001 # Query # # BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) diff --git a/mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result b/mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result index cdcc96b94b0..15610296d5c 100644 --- a/mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result +++ b/mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result @@ -1,3 +1,4 @@ +reset master; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; insert /* before delayed */ delayed /* after delayed */ into t1 values (207); insert /*! delayed */ into t1 values (null); @@ -5,9 +6,6 @@ insert delayed into t1 values (300); FLUSH TABLES; show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT' COLLATE 'latin1_swedish_ci')) -master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert /* before delayed */ /* after delayed */ into t1 values (207) diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result index 062f4f4e906..68e76921ff3 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result @@ -387,13 +387,46 @@ DROP PROCEDURE p4; End of 5.0 tests reset master; create table t1 (id tinyint auto_increment primary key); +insert into t1 values(5); set insert_id=128; -insert into t1 values(null); +insert into t1 values(null) /* Not binlogged */; +ERROR 22003: Out of range value for column 'id' at row 1 +set insert_id=128; +insert ignore into t1 values(null) /* Insert 128 */; +Warnings: +Warning 167 Out of range value for column 'id' at row 1 +set insert_id=5; +insert into t1 values(null) /* Not binlogged */; +ERROR 23000: Duplicate entry '5' for key 'PRIMARY' +set insert_id=5; +insert ignore into t1 values(null) /* Insert 5 */; Warnings: -Warning 1264 Out of range value for column 'id' at row 1 +Warning 1062 Duplicate entry '5' for key 'PRIMARY' select * from t1; id -127 +5 +drop table t1; +create table t1 (id tinyint auto_increment primary key) engine=myisam; +set insert_id=128; +insert into t1 values(5),(null) /* Insert_id 128 */; +ERROR 22003: Out of range value for column 'id' at row 2 +set insert_id=128; +insert ignore into t1 values (4),(null) /* Insert_id 128 */; +Warnings: +Warning 167 Out of range value for column 'id' at row 2 +set insert_id=5; +insert into t1 values(3),(null) /* Insert_id 5 */; +ERROR 23000: Duplicate entry '5' for key 'PRIMARY' +set insert_id=5; +insert ignore into t1 values(2),(null) /* Insert_id 5 */; +Warnings: +Warning 1062 Duplicate entry '5' for key 'PRIMARY' +select * from t1 order by id; +id +2 +3 +4 +5 drop table t1; create table t1 (a int); create table if not exists t2 select * from t1; @@ -408,35 +441,33 @@ show binlog events from <binlog_start>; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; create table t1 (id tinyint auto_increment primary key) master-bin.000001 # Query # # BEGIN -master-bin.000001 # Intvar # # INSERT_ID=127 -master-bin.000001 # Query # # use `test`; insert into t1 values(null) +master-bin.000001 # Query # # use `test`; insert into t1 values(5) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Intvar # # INSERT_ID=128 +master-bin.000001 # Query # # use `test`; insert ignore into t1 values(null) /* Insert 128 */ +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Intvar # # INSERT_ID=5 +master-bin.000001 # Query # # use `test`; insert ignore into t1 values(null) /* Insert 5 */ master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ -master-bin.000001 # Query # # use `test`; create table t1 (a int) -master-bin.000001 # Query # # use `test`; create table if not exists t2 select * from t1 -master-bin.000001 # Query # # use `test`; create temporary table tt1 (a int) -master-bin.000001 # Query # # use `test`; create table if not exists t3 like tt1 +master-bin.000001 # Query # # use `test`; create table t1 (id tinyint auto_increment primary key) engine=myisam master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `mysql`; INSERT INTO user SET host='localhost', user='@#@', password=password('Just a test') +master-bin.000001 # Intvar # # INSERT_ID=128 +master-bin.000001 # Query # # use `test`; insert into t1 values(5),(null) /* Insert_id 128 */ master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `mysql`; UPDATE user SET password=password('Another password') WHERE host='localhost' AND user='@#@' +master-bin.000001 # Intvar # # INSERT_ID=128 +master-bin.000001 # Query # # use `test`; insert ignore into t1 values (4),(null) /* Insert_id 128 */ master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `mysql`; DELETE FROM user WHERE host='localhost' AND user='@#@' +master-bin.000001 # Intvar # # INSERT_ID=5 +master-bin.000001 # Query # # use `test`; insert into t1 values(3),(null) /* Insert_id 5 */ master-bin.000001 # Query # # COMMIT -drop table t1,t2,t3,tt1; -create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; -insert /* before delayed */ delayed /* after delayed */ into t1 values (207); -insert /*! delayed */ into t1 values (null); -insert delayed into t1 values (300); -FLUSH TABLES; -show binlog events from <binlog_start>; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; create table t1 (id tinyint auto_increment primary key) master-bin.000001 # Query # # BEGIN -master-bin.000001 # Intvar # # INSERT_ID=127 -master-bin.000001 # Query # # use `test`; insert into t1 values(null) +master-bin.000001 # Intvar # # INSERT_ID=5 +master-bin.000001 # Query # # use `test`; insert ignore into t1 values(2),(null) /* Insert_id 5 */ master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ master-bin.000001 # Query # # use `test`; create table t1 (a int) @@ -452,8 +483,15 @@ master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `mysql`; DELETE FROM user WHERE host='localhost' AND user='@#@' master-bin.000001 # Query # # COMMIT -master-bin.000001 # Query # # use `test`; DROP TEMPORARY TABLE `tt1` /* generated by server */ -master-bin.000001 # Query # # use `test`; DROP TABLE `t1`,`t2`,`t3` /* generated by server */ +drop table t1,t2,t3,tt1; +reset master; +create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; +insert /* before delayed */ delayed /* after delayed */ into t1 values (207); +insert /*! delayed */ into t1 values (null); +insert delayed into t1 values (300); +FLUSH TABLES; +show binlog events from <binlog_start>; +Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam master-bin.000001 # Query # # BEGIN master-bin.000001 # Table_map # # table_id: # (test.t1) diff --git a/mysql-test/suite/binlog/r/binlog_unsafe.result b/mysql-test/suite/binlog/r/binlog_unsafe.result index 2cc1ebdd2d7..043b3d1e7a6 100644 --- a/mysql-test/suite/binlog/r/binlog_unsafe.result +++ b/mysql-test/suite/binlog/r/binlog_unsafe.result @@ -2682,6 +2682,7 @@ CREATE TABLE insert_2_keys (a INT UNIQUE KEY, b INT UNIQUE KEY); INSERT INTO insert_2_keys values (1, 1); INSERT IGNORE INTO insert_table SELECT * FROM filler_table; Warnings: +Warning 1062 Duplicate entry '1' for key 'PRIMARY' Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT IGNORE... SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave. TRUNCATE TABLE insert_table; INSERT INTO insert_table SELECT * FROM filler_table ON DUPLICATE KEY UPDATE a = 1; 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/auto_increment_dup.result b/mysql-test/suite/innodb/r/auto_increment_dup.result new file mode 100644 index 00000000000..5bf901cb212 --- /dev/null +++ b/mysql-test/suite/innodb/r/auto_increment_dup.result @@ -0,0 +1,33 @@ +drop table if exists t1; +CREATE TABLE t1( +id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +k INT, +c CHAR(1), +UNIQUE KEY(k)) ENGINE=InnoDB; +# +# Connection 1 +# +SET DEBUG_SYNC='ha_write_row_end SIGNAL continue2 WAIT_FOR continue1'; +affected rows: 0 +INSERT INTO t1(k) VALUES (1), (2), (3) ON DUPLICATE KEY UPDATE c='1'; +# +# Connection 2 +# +SET DEBUG_SYNC='start_ha_write_row WAIT_FOR continue2'; +affected rows: 0 +SET DEBUG_SYNC='after_mysql_insert SIGNAL continue1'; +affected rows: 0 +INSERT INTO t1(k) VALUES (2), (4), (5) ON DUPLICATE KEY UPDATE c='2'; +affected rows: 3 +info: Records: 3 Duplicates: 0 Warnings: 0 +affected rows: 4 +info: Records: 3 Duplicates: 1 Warnings: 0 +SET DEBUG_SYNC='RESET'; +SELECT * FROM t1 ORDER BY k; +id k c +1 1 NULL +4 2 1 +2 3 NULL +5 4 NULL +6 5 NULL +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb-autoinc.result b/mysql-test/suite/innodb/r/innodb-autoinc.result index 9eb89bead74..8c4c1c20590 100644 --- a/mysql-test/suite/innodb/r/innodb-autoinc.result +++ b/mysql-test/suite/innodb/r/innodb-autoinc.result @@ -2,7 +2,7 @@ drop table if exists t1; CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (9223372036854775807, null); INSERT INTO t1 (c2) VALUES ('innodb'); -Got one of the listed errors +ERROR 22003: Out of range value for column 'c1' at row 1 SELECT * FROM t1; c1 c2 9223372036854775807 NULL @@ -10,7 +10,7 @@ DROP TABLE t1; CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (127, null); INSERT INTO t1 (c2) VALUES ('innodb'); -Got one of the listed errors +ERROR 22003: Out of range value for column 'c1' at row 1 SELECT * FROM t1; c1 c2 127 NULL @@ -18,7 +18,7 @@ DROP TABLE t1; CREATE TABLE t1 (c1 TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (255, null); INSERT INTO t1 (c2) VALUES ('innodb'); -Got one of the listed errors +ERROR 22003: Out of range value for column 'c1' at row 1 SELECT * FROM t1; c1 c2 255 NULL @@ -26,7 +26,7 @@ DROP TABLE t1; CREATE TABLE t1 (c1 SMALLINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (32767, null); INSERT INTO t1 (c2) VALUES ('innodb'); -Got one of the listed errors +ERROR 22003: Out of range value for column 'c1' at row 1 SELECT * FROM t1; c1 c2 32767 NULL @@ -34,7 +34,7 @@ DROP TABLE t1; CREATE TABLE t1 (c1 SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (65535, null); INSERT INTO t1 (c2) VALUES ('innodb'); -Got one of the listed errors +ERROR 22003: Out of range value for column 'c1' at row 1 SELECT * FROM t1; c1 c2 65535 NULL @@ -42,7 +42,7 @@ DROP TABLE t1; CREATE TABLE t1 (c1 MEDIUMINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (8388607, null); INSERT INTO t1 (c2) VALUES ('innodb'); -Got one of the listed errors +ERROR 22003: Out of range value for column 'c1' at row 1 SELECT * FROM t1; c1 c2 8388607 NULL @@ -50,7 +50,7 @@ DROP TABLE t1; CREATE TABLE t1 (c1 MEDIUMINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (16777215, null); INSERT INTO t1 (c2) VALUES ('innodb'); -Got one of the listed errors +ERROR 22003: Out of range value for column 'c1' at row 1 SELECT * FROM t1; c1 c2 16777215 NULL @@ -58,7 +58,7 @@ DROP TABLE t1; CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (2147483647, null); INSERT INTO t1 (c2) VALUES ('innodb'); -Got one of the listed errors +ERROR 22003: Out of range value for column 'c1' at row 1 SELECT * FROM t1; c1 c2 2147483647 NULL @@ -66,7 +66,7 @@ DROP TABLE t1; CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (4294967295, null); INSERT INTO t1 (c2) VALUES ('innodb'); -Got one of the listed errors +ERROR 22003: Out of range value for column 'c1' at row 1 SELECT * FROM t1; c1 c2 4294967295 NULL @@ -74,7 +74,7 @@ DROP TABLE t1; CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (9223372036854775807, null); INSERT INTO t1 (c2) VALUES ('innodb'); -Got one of the listed errors +ERROR 22003: Out of range value for column 'c1' at row 1 SELECT * FROM t1; c1 c2 9223372036854775807 NULL @@ -567,7 +567,7 @@ Variable_name Value auto_increment_increment 65535 auto_increment_offset 65535 INSERT INTO t1 VALUES (NULL),(NULL); -ERROR 22003: Out of range value for column 't1' at row 167 +ERROR 22003: Out of range value for column 'c1' at row 1 SELECT * FROM t1; c1 1 @@ -858,7 +858,7 @@ PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t2 SELECT c1 FROM t1; Got one of the listed errors INSERT INTO t2 SELECT NULL FROM t1; -Got one of the listed errors +ERROR 22003: Out of range value for column 'c1' at row 1 DROP TABLE t1; DROP TABLE t2; SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; diff --git a/mysql-test/suite/innodb/r/innodb-lock.result b/mysql-test/suite/innodb/r/innodb-lock.result index 439a8d6513c..7191bcd238a 100644 --- a/mysql-test/suite/innodb/r/innodb-lock.result +++ b/mysql-test/suite/innodb/r/innodb-lock.result @@ -98,8 +98,12 @@ CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB; INSERT INTO t1 VALUES(3,1); BEGIN; INSERT IGNORE INTO t1 VALUES(3,14); +Warnings: +Warning 1062 Duplicate entry '3' for key 'PRIMARY' BEGIN; INSERT IGNORE INTO t1 VALUES(3,23); +Warnings: +Warning 1062 Duplicate entry '3' for key 'PRIMARY' SELECT * FROM t1 FOR UPDATE; COMMIT; a b diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index bb4d783ccf4..f3f1b1ed045 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -816,6 +816,8 @@ id 1 2 insert ignore into t1 values (100,1,2,'D'),(1,1,99,'D'); +Warnings: +Warning 1062 Duplicate entry '1-1' for key 'PRIMARY' commit; select id,id3 from t1; id id3 diff --git a/mysql-test/suite/innodb/r/innodb_bug56947.result b/mysql-test/suite/innodb/r/innodb_bug56947.result index b279069d834..8b864b62e81 100644 --- a/mysql-test/suite/innodb/r/innodb_bug56947.result +++ b/mysql-test/suite/innodb/r/innodb_bug56947.result @@ -3,6 +3,6 @@ SET GLOBAL innodb_file_per_table=0; create table bug56947(a int not null) engine = innodb; CREATE TABLE `bug56947#1`(a int) ENGINE=InnoDB; alter table bug56947 add unique index (a); -ERROR HY000: Table 'test.bug56947#1' already exists +ERROR 42S01: Table 'test.bug56947#1' already exists drop table `bug56947#1`; drop table bug56947; 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/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 2b3d24551c7..be2b4b28f6a 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -1480,10 +1480,15 @@ k a c 1 6 2 2 7 NULL insert ignore into t2 values (null,6,1),(10,8,1); +Warnings: +Warning 1062 Duplicate entry '6' for key 'idx_1' select last_insert_id(); last_insert_id() 0 insert ignore into t2 values (null,6,1),(null,8,1),(null,15,1),(null,20,1); +Warnings: +Warning 1062 Duplicate entry '6' for key 'idx_1' +Warning 1062 Duplicate entry '8' for key 'idx_1' select last_insert_id(); last_insert_id() 11 diff --git a/mysql-test/suite/innodb/t/auto_increment_dup.test b/mysql-test/suite/innodb/t/auto_increment_dup.test new file mode 100644 index 00000000000..ad439024f65 --- /dev/null +++ b/mysql-test/suite/innodb/t/auto_increment_dup.test @@ -0,0 +1,51 @@ +########################################################################## +# LP bug #1035225 / MySQL bug #66301: INSERT ... ON DUPLICATE KEY UPDATE + +# innodb_autoinc_lock_mode=1 is broken +########################################################################## + +--source include/have_innodb.inc +--source include/have_debug_sync.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +CREATE TABLE t1( + id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + k INT, + c CHAR(1), + UNIQUE KEY(k)) ENGINE=InnoDB; + +--enable_info + +--connect(con1, localhost, root) +--connect(con2, localhost, root) + +--connection con1 + +--echo # +--echo # Connection 1 +--echo # +SET DEBUG_SYNC='ha_write_row_end SIGNAL continue2 WAIT_FOR continue1'; +--send INSERT INTO t1(k) VALUES (1), (2), (3) ON DUPLICATE KEY UPDATE c='1' + +--connection con2 +--echo # +--echo # Connection 2 +--echo # +SET DEBUG_SYNC='start_ha_write_row WAIT_FOR continue2'; +SET DEBUG_SYNC='after_mysql_insert SIGNAL continue1'; +INSERT INTO t1(k) VALUES (2), (4), (5) ON DUPLICATE KEY UPDATE c='2'; + +--connection con1 +--reap +--disable_info +SET DEBUG_SYNC='RESET'; +SELECT * FROM t1 ORDER BY k; + +--disconnect con1 +--disconnect con2 + +--connection default + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-autoinc.test b/mysql-test/suite/innodb/t/innodb-autoinc.test index 4f54a8ff957..888c73bacdf 100644 --- a/mysql-test/suite/innodb/t/innodb-autoinc.test +++ b/mysql-test/suite/innodb/t/innodb-autoinc.test @@ -11,7 +11,7 @@ drop table if exists t1; # CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (9223372036854775807, null); --- error ER_DUP_ENTRY,1062 +-- error 167 INSERT INTO t1 (c2) VALUES ('innodb'); SELECT * FROM t1; DROP TABLE t1; @@ -22,14 +22,14 @@ DROP TABLE t1; # TINYINT CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (127, null); --- error ER_DUP_ENTRY,1062 +-- error 167 INSERT INTO t1 (c2) VALUES ('innodb'); SELECT * FROM t1; DROP TABLE t1; CREATE TABLE t1 (c1 TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (255, null); --- error ER_DUP_ENTRY,1062 +-- error 167 INSERT INTO t1 (c2) VALUES ('innodb'); SELECT * FROM t1; DROP TABLE t1; @@ -38,14 +38,14 @@ DROP TABLE t1; # CREATE TABLE t1 (c1 SMALLINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (32767, null); --- error ER_DUP_ENTRY,1062 +-- error 167 INSERT INTO t1 (c2) VALUES ('innodb'); SELECT * FROM t1; DROP TABLE t1; CREATE TABLE t1 (c1 SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (65535, null); --- error ER_DUP_ENTRY,1062 +-- error 167 INSERT INTO t1 (c2) VALUES ('innodb'); SELECT * FROM t1; DROP TABLE t1; @@ -54,14 +54,14 @@ DROP TABLE t1; # CREATE TABLE t1 (c1 MEDIUMINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (8388607, null); --- error ER_DUP_ENTRY,1062 +-- error 167 INSERT INTO t1 (c2) VALUES ('innodb'); SELECT * FROM t1; DROP TABLE t1; CREATE TABLE t1 (c1 MEDIUMINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (16777215, null); --- error ER_DUP_ENTRY,1062 +-- error 167 INSERT INTO t1 (c2) VALUES ('innodb'); SELECT * FROM t1; DROP TABLE t1; @@ -70,14 +70,14 @@ DROP TABLE t1; # CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (2147483647, null); --- error ER_DUP_ENTRY,1062 +-- error 167 INSERT INTO t1 (c2) VALUES ('innodb'); SELECT * FROM t1; DROP TABLE t1; CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (4294967295, null); --- error ER_DUP_ENTRY,1062 +-- error 167 INSERT INTO t1 (c2) VALUES ('innodb'); SELECT * FROM t1; DROP TABLE t1; @@ -86,7 +86,7 @@ DROP TABLE t1; # CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; INSERT INTO t1 VALUES (9223372036854775807, null); --- error ER_DUP_ENTRY,1062 +-- error 167 INSERT INTO t1 (c2) VALUES ('innodb'); SELECT * FROM t1; DROP TABLE t1; @@ -349,7 +349,7 @@ INSERT INTO t1 VALUES (18446744073709551610); #-- 2^64 - 2 SELECT * FROM t1; SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976; SHOW VARIABLES LIKE "%auto_inc%"; ---error ER_WARN_DATA_OUT_OF_RANGE +--error 167 INSERT INTO t1 VALUES (NULL),(NULL); SELECT * FROM t1; DROP TABLE t1; @@ -437,7 +437,7 @@ CREATE TABLE t2( PRIMARY KEY) ENGINE=InnoDB; -- error ER_DUP_ENTRY,1062 INSERT INTO t2 SELECT c1 FROM t1; --- error ER_DUP_ENTRY,1467 +-- error 167 INSERT INTO t2 SELECT NULL FROM t1; DROP TABLE t1; DROP TABLE t2; 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.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/maria/maria3.result b/mysql-test/suite/maria/maria3.result index 37613875f38..27d72b75930 100644 --- a/mysql-test/suite/maria/maria3.result +++ b/mysql-test/suite/maria/maria3.result @@ -452,6 +452,8 @@ SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO'; CREATE TABLE t1 (id int(11) PRIMARY KEY auto_increment,f1 varchar(10) NOT NULL UNIQUE); INSERT IGNORE INTO t1 (f1) VALUES ("test1"); INSERT IGNORE INTO t1 (f1) VALUES ("test1"); +Warnings: +Warning 1062 Duplicate entry 'test1' for key 'f1' INSERT IGNORE INTO t1 (f1) VALUES ("test2"); SELECT * FROM t1; id f1 diff --git a/mysql-test/suite/maria/mrr.result b/mysql-test/suite/maria/mrr.result index af7789eebff..06be64566e5 100644 --- a/mysql-test/suite/maria/mrr.result +++ b/mysql-test/suite/maria/mrr.result @@ -277,6 +277,8 @@ bb-1 NULL cc-2 NULL-1 drop table t1, t2, t3, t4; create table t1 (a int, b int not null,unique key (a,b),index(b)); insert ignore into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(null,7),(9,9),(8,8),(7,7),(null,9),(null,9),(6,6); +Warnings: +Warning 1062 Duplicate entry '6-6' for key 'a' create table t2 like t1; insert into t2 select * from t1; alter table t1 modify b blob not null, add c int not null, drop key a, add unique key (a,b(20),c), drop key b, add key (b(10)); diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug43617.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43617.result index 3c19a37c95d..505dd587d0b 100644 --- a/mysql-test/suite/optimizer_unfixed_bugs/r/bug43617.result +++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug43617.result @@ -38,7 +38,11 @@ c1 c2 c3 c4 2008-01-01 00:00:00 NULL 2008-01-02 2008-01-03 00:00:00 2009-01-29 11:11:27 2009-01-29 00:00:00 2009-01-29 2009-01-29 00:00:00 INSERT IGNORE INTO t1(c1,c2) VALUES('20070525','20070527') /* doesnt throw error */; +Warnings: +Warning 1062 Duplicate entry '2007-05-25 00:00:00' for key 'PRIMARY' INSERT IGNORE INTO t1(c1,c2) VALUES(19840905,830907) /* doesnt throw error */; +Warnings: +Warning 1062 Duplicate entry '1983-09-07 00:00:00' for key 'c2' SELECT * FROM t1 WHERE c1='20070527' /* Returns no rows */; c1 c2 c3 c4 INSERT INTO t1(c1) VALUES('20070525') ON DUPLICATE KEY UPDATE c1='20070527'; diff --git a/mysql-test/suite/perfschema/disabled.def b/mysql-test/suite/perfschema/disabled.def index 8a843692d2a..888298bbb09 100644 --- a/mysql-test/suite/perfschema/disabled.def +++ b/mysql-test/suite/perfschema/disabled.def @@ -9,4 +9,3 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -misc : bug#14113704 24/04/2012 Mayank issue reported causing failure. 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/feedback_plugin_send.test b/mysql-test/suite/plugins/t/feedback_plugin_send.test index 3324ef469fe..45b507f8e78 100644 --- a/mysql-test/suite/plugins/t/feedback_plugin_send.test +++ b/mysql-test/suite/plugins/t/feedback_plugin_send.test @@ -1,3 +1,6 @@ +# Restart of server does not work for embedded. +--source include/not_embedded.inc + source feedback_plugin_load.test; if (!$MTR_FEEDBACK_PLUGIN) { 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_auto_increment.result b/mysql-test/suite/rpl/r/rpl_auto_increment.result index 8b41a01cb6e..41bacd78f52 100644 --- a/mysql-test/suite/rpl/r/rpl_auto_increment.result +++ b/mysql-test/suite/rpl/r/rpl_auto_increment.result @@ -125,6 +125,10 @@ insert into t1 values(600),(NULL),(NULL); ERROR 23000: Duplicate entry '600' for key 'PRIMARY' set @@insert_id=600; insert ignore into t1 values(600),(NULL),(NULL),(610),(NULL); +Warnings: +Warning 1062 Duplicate entry '600' for key 'PRIMARY' +Warning 1062 Duplicate entry '600' for key 'PRIMARY' +Warning 1062 Duplicate entry '600' for key 'PRIMARY' select * from t1; a 1 @@ -186,7 +190,7 @@ set auto_increment_offset=4; insert into t1 values(null); insert into t1 values(null); insert into t1 values(null); -ERROR 23000: Duplicate entry '125' for key 'PRIMARY' +ERROR 22003: Out of range value for column 'a' at row 1 select a, mod(a-@@auto_increment_offset,@@auto_increment_increment) from t1 order by a; a mod(a-@@auto_increment_offset,@@auto_increment_increment) 103 0 @@ -196,21 +200,19 @@ create table t2 (a tinyint unsigned not null auto_increment primary key) engine= set auto_increment_increment=10; set auto_increment_offset=1; set insert_id=1000; +insert into t2 values(10); insert into t2 values(null); -Warnings: -Warning 1264 Out of range value for column 'a' at row 1 +ERROR 22003: Out of range value for column 'a' at row 1 select a, mod(a-@@auto_increment_offset,@@auto_increment_increment) from t2 order by a; a mod(a-@@auto_increment_offset,@@auto_increment_increment) -251 0 +10 9 create table t3 like t1; set auto_increment_increment=1000; set auto_increment_offset=700; insert into t3 values(null); -Warnings: -Warning 1264 Out of range value for column 'a' at row 1 +ERROR 22003: Out of range value for column 'a' at row 1 select * from t3 order by a; a -127 select * from t1 order by a; a 103 @@ -218,10 +220,9 @@ a 125 select * from t2 order by a; a -251 +10 select * from t3 order by a; a -127 drop table t1,t2,t3; set auto_increment_increment=1; set auto_increment_offset=1; 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/r/rpl_insert_delayed,stmt.rdiff b/mysql-test/suite/rpl/r/rpl_insert_delayed,stmt.rdiff index 5e0e7db5b63..ddb10d604c6 100644 --- a/mysql-test/suite/rpl/r/rpl_insert_delayed,stmt.rdiff +++ b/mysql-test/suite/rpl/r/rpl_insert_delayed,stmt.rdiff @@ -1,5 +1,5 @@ ---- suite/rpl/r/rpl_insert_delayed.result 2012-02-06 21:37:21.000000000 +0100 -+++ suite/rpl/r/rpl_insert_delayed,stmt.reject 2012-02-06 23:12:55.000000000 +0100 +--- suite/rpl/r/rpl_insert_delayed.result 2012-09-18 01:37:45.317521958 +0300 ++++ suite/rpl/r/rpl_insert_delayed,stmt.reject 2012-09-18 01:36:16.637514667 +0300 @@ -15,17 +15,17 @@ insert delayed into t1 values(10, "my name"); flush table t1; diff --git a/mysql-test/suite/rpl/r/rpl_loaddatalocal.result b/mysql-test/suite/rpl/r/rpl_loaddatalocal.result index 902bc1cda00..ae91e000c37 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddatalocal.result +++ b/mysql-test/suite/rpl/r/rpl_loaddatalocal.result @@ -14,6 +14,8 @@ select * into outfile 'MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' from t1; drop table t1; create table t1(a int primary key); load data local infile 'MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' into table t1; +Warnings: +Warning 1062 Duplicate entry '2' for key 'PRIMARY' SELECT * FROM t1 ORDER BY a; a 1 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 1ab970ad24f..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 5.6. 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 a5759237b15..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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 949d8cc8eaa..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 7.0. 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 7.0. 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 7.0. 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 9f1d5066e10..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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 e078da3f2f6..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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 5.7. 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 af61d40e84e..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 7.0. +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 7.0. +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 7.0. +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 7.0. +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 7.0. +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 7.0. +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 7.0. +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 7.0. +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 7.0. +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 7.0. +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 7.0. +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 7.0. +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 7.0. +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 7.0. +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 702273f73df..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 7.0. 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 8e85fcc57b4..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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 8595ff51734..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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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 7.0. 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/auto_increment.test b/mysql-test/t/auto_increment.test index 884e0fabb5e..15156b89d8e 100644 --- a/mysql-test/t/auto_increment.test +++ b/mysql-test/t/auto_increment.test @@ -104,7 +104,7 @@ explain extended select last_insert_id(); --error ER_DUP_ENTRY insert into t1 set i = 254; select last_insert_id(); ---error ER_DUP_ENTRY +--error 167 insert into t1 set i = null; select last_insert_id(); drop table t1; @@ -113,6 +113,7 @@ create table t1 (i tinyint unsigned not null auto_increment, key (i)); insert into t1 set i = 254; insert into t1 set i = null; select last_insert_id(); +--error 167 insert into t1 set i = null; select last_insert_id(); drop table t1; @@ -353,7 +354,7 @@ INSERT INTO t1 VALUES (18446744073709551601); SET @@SESSION.AUTO_INCREMENT_INCREMENT=10; SELECT @@SESSION.AUTO_INCREMENT_OFFSET; ---error ER_WARN_DATA_OUT_OF_RANGE +--error 167 INSERT INTO t1 VALUES (NULL), (NULL), (NULL); SELECT * FROM t1; diff --git a/mysql-test/t/auto_increment_ranges.inc b/mysql-test/t/auto_increment_ranges.inc new file mode 100644 index 00000000000..a94aa46d38e --- /dev/null +++ b/mysql-test/t/auto_increment_ranges.inc @@ -0,0 +1,240 @@ +# +# Test of auto_increment at end of range +# +--disable_warnings +drop table if exists t1; +--enable_warnings + +--echo # +--echo # Testing ranges with smallint +--echo # +let $type=smallint; +let $range_max=32767; + +eval create table t1 (a $type primary key auto_increment); +eval insert into t1 values($range_max); +--error 167 +insert into t1 values(NULL); +truncate table t1; +eval insert into t1 values($range_max-1); +insert into t1 values(NULL); +--error 167 +insert into t1 values(NULL); +select * from t1; +truncate table t1; +--error 167 +eval insert into t1 values($range_max),(NULL); +select * from t1; +truncate table t1; +--error 167 +eval insert into t1 values($range_max-1),(NULL),(NULL); +truncate table t1; +eval insert into t1 values($range_max+1); +select * from t1; +--error 167 +eval insert into t1 values(NULL); +drop table t1; + +--echo # +--echo # Testing ranges with unsigned smallint +--echo # + +let $type=smallint unsigned; +let $range_max=65535; + +eval create table t1 (a $type primary key auto_increment); +eval insert into t1 values($range_max); +--error 167 +insert into t1 values(NULL); +truncate table t1; +eval insert into t1 values($range_max-1); +insert into t1 values(NULL); +--error 167 +insert into t1 values(NULL); +select * from t1; +truncate table t1; +--error 167 +eval insert into t1 values($range_max),(NULL); +select * from t1; +truncate table t1; +--error 167 +eval insert into t1 values($range_max-1),(NULL),(NULL); +truncate table t1; +eval insert into t1 values($range_max+1); +select * from t1; +--error 167 +eval insert into t1 values(NULL); +drop table t1; + +--echo # +--echo # Testing ranges with integer +--echo # + +let $type=int; +let $range_max=2147483647; + +eval create table t1 (a $type primary key auto_increment); +eval insert into t1 values($range_max); +--error 167 +insert into t1 values(NULL); +truncate table t1; +eval insert into t1 values($range_max-1); +insert into t1 values(NULL); +--error 167 +insert into t1 values(NULL); +select * from t1; +truncate table t1; +--error 167 +eval insert into t1 values($range_max),(NULL); +select * from t1; +truncate table t1; +--error 167 +eval insert into t1 values($range_max-1),(NULL),(NULL); +truncate table t1; +eval insert into t1 values($range_max+1); +select * from t1; +--error 167 +eval insert into t1 values(NULL); +drop table t1; + +--echo # +--echo # Testing ranges with unsigned integer +--echo # + +let $type=int unsigned; +let $range_max=4294967295; + +eval create table t1 (a $type primary key auto_increment); +eval insert into t1 values($range_max); +--error 167 +insert into t1 values(NULL); +truncate table t1; +eval insert into t1 values($range_max-1); +insert into t1 values(NULL); +--error 167 +insert into t1 values(NULL); +select * from t1; +truncate table t1; +--error 167 +eval insert into t1 values($range_max),(NULL); +select * from t1; +truncate table t1; +--error 167 +eval insert into t1 values($range_max-1),(NULL),(NULL); +truncate table t1; +eval insert into t1 values($range_max+1); +select * from t1; +--error 167 +eval insert into t1 values(NULL); +drop table t1; + +--echo # +--echo # Testing ranges with bigint +--echo # + +let $type=bigint; +let $range_max=cast(9223372036854775807 as unsigned); + +eval create table t1 (a $type primary key auto_increment); +eval insert into t1 values($range_max); +--error 167 +insert into t1 values(NULL); +truncate table t1; +eval insert into t1 values($range_max-1); +insert into t1 values(NULL); +--error 167 +insert into t1 values(NULL); +select * from t1; +truncate table t1; +--error 167 +eval insert into t1 values($range_max),(NULL); +select * from t1; +truncate table t1; +--error 167 +eval insert into t1 values($range_max-1),(NULL),(NULL); +truncate table t1; +eval insert into t1 values($range_max+1); +select * from t1; +--error 167 +eval insert into t1 values(NULL); +drop table t1; + +--echo # +--echo # Testing ranges with unsigned bigint +--echo # + +let $type=bigint unsigned; +let $range_max=18446744073709551615; + +eval create table t1 (a $type primary key auto_increment); +eval insert into t1 values($range_max-1); +--error ER_AUTOINC_READ_FAILED +insert into t1 values(NULL); +--error ER_AUTOINC_READ_FAILED +insert into t1 values(NULL); +truncate table t1; +eval insert into t1 values($range_max-1); +--error ER_AUTOINC_READ_FAILED +insert into t1 values(NULL); +--error ER_AUTOINC_READ_FAILED +insert into t1 values(NULL); +select * from t1; +truncate table t1; +--error ER_AUTOINC_READ_FAILED +eval insert into t1 values($range_max),(NULL); +select * from t1; +truncate table t1; +--error ER_AUTOINC_READ_FAILED +eval insert into t1 values($range_max-1),(NULL),(NULL); +drop table t1; + +--echo # +--echo # Test IGNORE and strict mode +--echo # +create table t1 (a smallint primary key auto_increment); +insert ignore into t1 values(32766),(NULL),(NULL),(1); +select * from t1; +truncate table t1; + +set @org_mode=@@sql_mode; +set @@sql_mode='ansi,traditional'; +insert ignore into t1 values(32766),(NULL),(NULL); +truncate table t1; +--error 167 +insert into t1 values(32766),(NULL),(NULL); +set @@sql_mode=@org_mode; +drop table t1; + +--echo # +--echo # Test auto increment with negative numbers +--echo # +CREATE TABLE t1 (a INTEGER AUTO_INCREMENT, PRIMARY KEY (a)); +INSERT INTO t1 VALUES (NULL), (2), (-5), (NULL); +INSERT INTO t1 VALUES (NULL); +SELECT * FROM t1; +TRUNCATE TABLE t1; +INSERT INTO t1 VALUES (-5), (NULL); +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # Test inserting a value out-of-range into an auto increment column +--echo # +CREATE TABLE t1 (a smallint AUTO_INCREMENT, PRIMARY KEY (a)); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (32768); +--error 167 +INSERT INTO t1 VALUES (NULL); +SELECT * FROM t1; +DROP TABLE t1; + + +--echo # +--echo # Test old behaviour +--echo # +create table t1 (a smallint primary key auto_increment); +insert into t1 values(32766),(NULL); +delete from t1 where a=32767; +--error 167 +insert into t1 values(NULL); +drop table t1; diff --git a/mysql-test/t/auto_increment_ranges_innodb.test b/mysql-test/t/auto_increment_ranges_innodb.test new file mode 100644 index 00000000000..c2afee7ac66 --- /dev/null +++ b/mysql-test/t/auto_increment_ranges_innodb.test @@ -0,0 +1,7 @@ +# +# Test of auto_increment at end of range +# + +--source include/have_innodb.inc +set default_storage_engine=innodb; +--source auto_increment_ranges.inc diff --git a/mysql-test/t/auto_increment_ranges_myisam.test b/mysql-test/t/auto_increment_ranges_myisam.test new file mode 100644 index 00000000000..90e84377540 --- /dev/null +++ b/mysql-test/t/auto_increment_ranges_myisam.test @@ -0,0 +1,7 @@ +# +# Test of auto_increment at end of range +# + +set default_storage_engine=MYISAM; +--source auto_increment_ranges.inc + diff --git a/mysql-test/t/features.test b/mysql-test/t/features.test index a54b09a3fd3..cdfc9413da5 100644 --- a/mysql-test/t/features.test +++ b/mysql-test/t/features.test @@ -46,6 +46,8 @@ select * from t1 where MATCH(a,b) AGAINST ("collections"); select * from t1 where MATCH(a,b) AGAINST ("indexes"); drop table t1; +# We need the following when running with --ps-protocol +--replace_result 4 2 show status like "feature_fulltext"; @@ -68,6 +70,7 @@ create table t1 (a int); insert into t1 values (2); select (select a from t1 where t1.a=t2.a), a from t1 as t2; drop table t1; +--replace_result 8 4 show status like "feature_subquery"; --echo # @@ -104,4 +107,5 @@ SET @xml='<a aa1="aa1" aa2="aa2">a1<b ba1="ba1">b1<c>c1</c>b2</b>a2</a>'; SELECT extractValue(@xml,'/a'); select updatexml('<div><div><span>1</span><span>2</span></div></div>', '/','<tr><td>1</td><td>2</td></tr>') as upd1; +--replace_result 4 2 show status like "feature_xml"; 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/last_value.test b/mysql-test/t/last_value.test index ee793f879da..41cfdb5482d 100644 --- a/mysql-test/t/last_value.test +++ b/mysql-test/t/last_value.test @@ -27,9 +27,12 @@ DROP TABLE t1; # # Test with different types # +# PS protocol gives slightly different metadata for the length --enable_metadata +--disable_ps_protocol SELECT LAST_VALUE(@last_a:=1,@last_b:=1); select @last_b; +--enable_ps_protocol SELECT LAST_VALUE(@last_a:=1,@last_b:=1.0); select @last_b; SELECT LAST_VALUE(@last_a:=1,@last_b:="hello"); diff --git a/mysql-test/t/mysqlshow.test b/mysql-test/t/mysqlshow.test index 105e03c841b..2b6b5b631b2 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 @@ -30,4 +28,18 @@ select "---- -v -v -t ------" as ""; --exec $MYSQL_SHOW test -v -v -t DROP TABLE t1, t2; + +if (`select count(*) from information_schema.plugins where plugin_name='innodb' and plugin_auth_version > "1.1.8-29.0"`) +{ +# 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 +} + --echo End of 5.0 tests diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test index f9abb75b7e9..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:00000001:lib\(0\):func\(0\):reason\(1\)/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:00000001:lib\(0\):func\(0\):reason\(1\)/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:00000001:lib\(0\):func\(0\):reason\(1\)/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/replace.test b/mysql-test/t/replace.test index ff910bdf5cf..3d32a8c0da6 100644 --- a/mysql-test/t/replace.test +++ b/mysql-test/t/replace.test @@ -25,9 +25,9 @@ drop table t1; create table t1 (a tinyint not null auto_increment primary key, b char(20) default "default_value"); insert into t1 values (126,"first"),(63, "middle"),(0,"last"); ---error ER_DUP_ENTRY +--error 167 insert into t1 values (0,"error"); ---error ER_DUP_ENTRY +--error 167 replace into t1 values (0,"error"); replace into t1 values (126,"first updated"); replace into t1 values (63,default); 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/subselect4.test b/mysql-test/t/subselect4.test index b53967e35e5..50b34eece89 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -185,6 +185,75 @@ SELECT * FROM (SELECT default(a) FROM t GROUP BY a) d; DROP TABLE t; --echo # +--echo # LP BUG#1009187, MDEV-373, MYSQL bug#58628 +--echo # Wrong result for a query with [NOT] IN subquery predicate if +--echo # the left part of the predicate is explicit NULL +--echo # + +CREATE TABLE t1 (pk INT NOT NULL, i INT NOT NULL); +INSERT INTO t1 VALUES (0,10), (1,20), (2,30), (3,40); + +CREATE TABLE t2a (pk INT NOT NULL, i INT NOT NULL, PRIMARY KEY(i,pk)); +INSERT INTO t2a VALUES (0,0), (1,1), (2,2), (3,3); + +CREATE TABLE t2b (pk INT, i INT); +INSERT INTO t2b VALUES (0,0), (1,1), (2,2), (3,3); + +CREATE TABLE t2c (pk INT NOT NULL, i INT NOT NULL); +INSERT INTO t2c VALUES (0,0), (1,1), (2,2), (3,3); +create index it2c on t2c (i,pk); + +CREATE TABLE t2d (pk INT NOT NULL, i INT NOT NULL, PRIMARY KEY(i)); +INSERT INTO t2d VALUES (0,0), (1,1), (2,2), (3,3); + +EXPLAIN +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk); +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk); +SELECT * FROM t1 WHERE 1+NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk); +SELECT * FROM t1 WHERE NULL IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk) IS UNKNOWN; +SELECT t1.pk, NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk) FROM t1; + +EXPLAIN +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk); +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk); +SELECT * FROM t1 WHERE NULL IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk) IS UNKNOWN; +SELECT t1.pk, NULL NOT IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk) FROM t1; + +EXPLAIN +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk); +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk); +SELECT * FROM t1 WHERE NULL IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk) IS UNKNOWN; +SELECT t1.pk, NULL NOT IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk) FROM t1; + +EXPLAIN +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2d.i FROM t2d WHERE t2d.pk = t1.pk); +SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2d.i FROM t2d WHERE t2d.pk = t1.pk); +SELECT * FROM t1 WHERE NULL IN (SELECT t2d.i FROM t2d WHERE t2d.pk = t1.pk) IS UNKNOWN; +SELECT t1.pk, NULL NOT IN (SELECT t2d.i FROM t2d WHERE t2d.pk = t1.pk) FROM t1; + +EXPLAIN +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk); +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk); +SELECT (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk) from t1; + +EXPLAIN +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk); +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk); +SELECT (NULL, 1) NOT IN (SELECT t2b.i, t2b.pk FROM t2b WHERE t2b.pk = t1.pk) from t1; + +EXPLAIN +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk); +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk); +SELECT (NULL, 1) NOT IN (SELECT t2c.i, t2c.pk FROM t2c WHERE t2c.pk = t1.pk) from t1; + +EXPLAIN +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk); +SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk); +SELECT (NULL, 1) NOT IN (SELECT t2d.i, t2d.pk FROM t2d WHERE t2d.pk = t1.pk) from t1; + +drop table t1, t2a, t2b, t2c, t2d; + +--echo # --echo # End of 5.1 tests. --echo # diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 4f739b524e6..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) # @@ -4619,7 +4659,7 @@ DROP TABLE t1,t2,t3; --echo # flush status; - +--disable_ps_protocol CREATE TABLE t1 (a INT); CREATE ALGORITHM=MERGE VIEW v1 AS SELECT a1.* FROM t1 AS a1, t1 AS a2; CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM v1; @@ -4629,6 +4669,7 @@ drop view v2,v1; drop table t1; show status like '%view%'; show status like 'Opened_table%'; +--enable_ps_protocol --echo # --echo # MDEV-486 LP BUG#1010116 Incorrect query results in @@ -4660,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_getopt.c b/mysys/my_getopt.c index facc1569943..7905ad90877 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -691,15 +691,13 @@ static int setval(const struct my_option *opts, void *value, char *argument, *((double*) value)= getopt_double(argument, opts, &err); break; case GET_STR: - if (argument == enabled_my_option) - break; /* string options don't use this default of "1" */ - *((char**) value)= argument; + /* If no argument or --enable-string-option, set string to "" */ + *((char**) value)= argument == enabled_my_option ? (char*) "" : argument; break; case GET_STR_ALLOC: - if (argument == enabled_my_option) - break; /* string options don't use this default of "1" */ my_free(*((char**) value)); - if (!(*((char**) value)= my_strdup(argument, MYF(MY_WME)))) + if (!(*((char**) value)= my_strdup(argument == enabled_my_option ? "" : + argument, MYF(MY_WME)))) { res= EXIT_OUT_OF_MEMORY; goto ret; @@ -722,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 0ed94d0ffa3..91780570194 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 --loose-skip-innodb \ +mysqld_install_cmd_line() +{ + "$mysqld_bootstrap" $defaults "$mysqld_opt" --bootstrap \ + "--basedir=$basedir" "--datadir=$ldata" --log-warnings=0 --loose-skip-innodb \ --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/scripts/mytop.sh b/scripts/mytop.sh index a36fddf7368..480805e90b1 100755 --- a/scripts/mytop.sh +++ b/scripts/mytop.sh @@ -1,6 +1,6 @@ #!/usr/bin/perl -w # -# $Id: mytop,v 1.90 2010/05/23 10:51:21 mark Exp $ +# $Id: mytop,v 1.91 2012/01/18 16:49:12 mgrennan Exp $ =pod @@ -20,7 +20,7 @@ use Socket; use List::Util qw(min max); use File::Basename; -$main::VERSION = "1.9a"; +$main::VERSION = "1.91a"; my $path_for_script= dirname($0); $|=1; @@ -96,7 +96,7 @@ my %config = ( resolve => 0, slow => 10, # slow query time socket => '', - sort => 0, # default or reverse sort ("s") + sort => 1, # default or reverse sort ("s") user => 'root', fullqueries => 0 ); @@ -378,12 +378,11 @@ while (1) ## keystroke command processing (if we get this far) ## - # ! - Force past a replication error - - if ($key eq 'r') + if ($key eq '!') { - Execute("STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; START SLAVE;"); - next; + Execute("stop slave"); + Execute("set global sql_slave_skip_counter=1"); + Execute("start slave"); } # t - top @@ -415,7 +414,7 @@ while (1) next; } - ## m - mode swtich to qps + ## m - mode switch to qps if ($key eq 'm') { @@ -425,17 +424,7 @@ while (1) next; } - ## M - mode swtich to qps - - if ($key eq 'M') - { - $config{mode} = 'status'; - Clear() unless $config{batchmode}; - print "Queries Per Second [hit q to exit this mode]\n"; - next; - } - - ## c - mode swtich to command summary + ## c - mode switch to command summary if ($key eq 'c') { @@ -467,8 +456,6 @@ while (1) next; } - # Change the SLOW query value - if ($key eq 'S') { cmd_S(); @@ -755,7 +742,9 @@ while (1) ReadKey(0); } - if ($key eq 'S') + # Switch to show status mode + + if ($key eq 'M') { $config{mode} = 'status'; } @@ -931,6 +920,11 @@ sub GetData() } } + open L, "</proc/loadavg"; + my $l = <L>; + close L; + chomp $l; + $last_time = $now_time; ## Server Uptime in meaningful terms... @@ -962,6 +956,7 @@ sub GetData() printf "%-.${host_width}s %${up_width}s\n", "$server on $config{host} ($db_version)", "up $uptime $current_time"; +# "load $l up $uptime $current_time"; $lines_left--; @@ -1055,19 +1050,29 @@ sub GetData() if ($t_delta) { + my $rows_read; + if (defined($STATUS{Rows_read})) + { + $rows_read= $STATUS{Rows_read} - $OLD_STATUS{Rows_read}; + } + else + { + $rows_read= + ($STATUS{Handler_read_first}+$STATUS{Handler_read_key}+ + $STATUS{Handler_read_next}+$STATUS{Handler_read_prev}+ + $STATUS{Handler_read_rnd}+$STATUS{Handler_read_rnd_next} - + $OLD_STATUS{Handler_read_first}-$OLD_STATUS{Handler_read_key}- + $OLD_STATUS{Handler_read_next}-$OLD_STATUS{Handler_read_prev}- + $OLD_STATUS{Handler_read_rnd}- + $OLD_STATUS{Handler_read_rnd_next}); + } printf(" Handler: (R/W/U/D) %5d/%5d/%5d/%5d Tmp: R/W/U: %5d/%5d/%5d\n", - ($STATUS{Handler_read_first}+$STATUS{Handler_read_key}+ - $STATUS{Handler_read_next}+$STATUS{Handler_read_prev}+ - $STATUS{Handler_read_rnd}+$STATUS{Handler_read_rnd_next} - - $OLD_STATUS{Handler_read_first}-$OLD_STATUS{Handler_read_key}- - $OLD_STATUS{Handler_read_next}-$OLD_STATUS{Handler_read_prev}- - $OLD_STATUS{Handler_read_rnd}- - $OLD_STATUS{Handler_read_rnd_next})/$t_delta, + $rows_read/$t_delta, ($STATUS{Handler_write} - $OLD_STATUS{Handler_write}) / $t_delta, ($STATUS{Handler_update} - $OLD_STATUS{Handler_update}) / $t_delta, - ($STATUS{Handler_delete} - $OLD_STATUS{Handler_delete}) / + ($STATUS{Handler_delete} - $OLD_STATUS{Handler_delete}) / $t_delta, ($STATUS{Rows_tmp_read} - $OLD_STATUS{Rows_tmp_read}) / $t_delta, @@ -1083,7 +1088,7 @@ sub GetData() $lines_left--; - printf(" MyISAM Key Efficiency: %2.1f%% Bps in/out: %5s/%5s ", + printf(" ISAM Key Efficiency: %2.1f%% Bps in/out: %5s/%5s ", $cache_hits_percent, make_short($STATUS{Bytes_received} / $STATUS{Uptime} ), make_short($STATUS{Bytes_sent} / $STATUS{Uptime})); @@ -1095,35 +1100,40 @@ sub GetData() $lines_left--; - my($data) = Hashes('SHOW SLAVE STATUS'); - if (defined($data->{Master_Host})) + my($data) = Hashes('show global variables like "read_only"'); + if ($data->{Value} ne "OFF") { - print " Replication "; - if ($HAS_COLOR) { - print GREEN(); - print RED() if ($data->{Slave_IO_Running} ne "Yes") ; - } - print "IO:$data->{Slave_IO_Running} "; + print RED() if ($HAS_COLOR) ; + print " ReadOnly"; RESET() if ($HAS_COLOR); + } - if ($HAS_COLOR) { - print GREEN(); - print RED() if ($data->{Slave_SQL_Running} ne "Yes") ; + ($data) = Hashes('SHOW SLAVE STATUS'); + if (defined($data->{Master_Host})) + { + if (defined($data->{Seconds_Behind_Master})) + { + if ($HAS_COLOR) { + print GREEN(); + print YELLOW() if ($data->{Seconds_Behind_Master} > 60); + print MAGENTA() if ($data->{Seconds_Behind_Master} > 360); + } } + print " Replication "; + print "IO:$data->{Slave_IO_Running} "; print "SQL:$data->{Slave_SQL_Running} "; print RESET() if ($HAS_COLOR); - my $SlaveDelay = $data->{Seconds_Behind_Master}; - if ($SlaveDelay) + if (defined($data->{Seconds_Behind_Master})) { if ($HAS_COLOR) { print GREEN(); - print YELLOW() if ($SlaveDelay > 10); - print MAGENTA() if ($SlaveDelay > 120); + print YELLOW() if ($data->{Seconds_Behind_Master} > 60); + print MAGENTA() if ($data->{Seconds_Behind_Master} > 360); } - print "Delay: $SlaveDelay sec."; + print "Delay: $data->{Seconds_Behind_Master} sec."; } else { - my $free = $width - 35; + my $free = $width - 45; my $Err = substr $data->{Last_Error},0 ,$free; printf(" ERR: %-${free}s", $Err) if ( $Err ne "" ); } @@ -1198,6 +1208,7 @@ sub GetData() if ($is_ip and $config{resolve}) { $thread->{Host} =~ s/:\d+$//; +# my $host = $thread->{Host}; my $host = gethostbyaddr(inet_aton($thread->{Host}), AF_INET); # $host =~ s/^([^.]+).*/$1/; $thread->{Host} = $host; @@ -1483,7 +1494,7 @@ sub GetShowStatus() Clear() unless $config{batchmode}; my @rows = Hashes("SHOW STATUS"); - printf "%32s %10s %10s\n", 'Counter', 'Total', 'Change'; + printf "%32s %10s %10s Toggle idle with 'i'\n", 'Counter', 'Total', 'Change'; printf "%32s %10s %10s\n", '-------', '-----', '------'; for my $row (@rows) @@ -1519,9 +1530,7 @@ sub GetShowStatus() } } - if ($delta != 0) { - printf "%32s: %10s %10s\n", $name, $value, $delta; - } + printf "%32s: %10s %10s\n", $name, $value, $delta; print RESET() if $HAS_COLOR; $statcache{$name} = $value; @@ -1703,12 +1712,11 @@ sub trim($) sub PrintHelp() { my $help = qq[ -Help for mytop version $main::VERSION by Mark Grennan <${YELLOW}Mark\@Grennan.com${RESET}> -Origional work by Jeremy D. Zawodny <${YELLOW}Jeremy\@Zawodny.com${RESET}> +Help for mytop version $main::VERSION by Jeremy D. Zawodny <${YELLOW}Jeremy\@Zawodny.com${RESET}> + with updates by Mark Grennan <${YELLOW}mark\@grennan.com${RESET}> ? - display this screen # - toggle short/long numbers (not yet implemented) - ! - force past replication error c - command summary view (based on Com_* counters) C - turn color on and off d - show only a specific database @@ -1733,8 +1741,9 @@ Origional work by Jeremy D. Zawodny <${YELLOW}Jeremy\@Zawodny.com${RESET}> S - change slow quiery hightlighting t - switch to thread view (default) u - show only a specific user - V - show variablesi + V - show variables : - enter a command (not yet implemented) + ! - Skip an error that has stopped replications (at your own risk) L - show full queries (do not strip to terminal width) Base version from ${GREEN}http://www.mysqlfanboy.com/mytop${RESET} @@ -2317,11 +2326,8 @@ having the User column appear, for example. mytop was developed and is maintained by Jeremy D. Zawodny (Jeremy@Zawodny.com). -(Mark Grennan) After weeks and months of trying to get Jeremy's -attention I desided to release my own update to mytop. I use it -every day as a part of my job. Thanks Jeremy for creating mytop. -I hope you find my updates as helpful as I have. I can be -reached at (Mark@Grennan.com). +If you wish to e-mail me regarding this software, B<PLEASE> subscribe +to the B<mytop> mailing list. See the B<mytop> homepage for details. =head1 DISCLAIMER @@ -2330,12 +2336,6 @@ for it. Yahoo! does not necessarily support this software in any way. It is merely a personal idea which happened to be very useful in my job. -=head1 RECRUITING - -If you hack Perl and grok MySQL, come work at Yahoo! Contact me for -details. Or just send me your resume. Er, unless we just had layoffs, -in which case we're not hiring. :-( - =head1 SEE ALSO Please check the MySQL manual if you're not sure where some of the @@ -2344,7 +2344,6 @@ output of B<mytop> is coming from. =head1 COPYRIGHT Copyright (C) 2000-2010, Jeremy D. Zawodny. -Copyright (C) 2010, Mark T. Grennan. =head1 CREDITS @@ -2358,6 +2357,15 @@ Many thanks go to these fine folks: Added --fullqueries and reading of .my.cnf +=item Mark Grennan (mark@grennan.com) www.linuxfangoy.com + +Added updates for MySQL 5.x. Added 'S' (slow) highlighting. +Added 'C' to turn on and off Color. Added 'l' command to change +color for long running queries. Fixed a few documentation issues. +Monitors Slave status. Added color to Queue hit ratio. +Added number of rows sorted per second. +Created release 1.7. + =item Sami Ahlroos (sami@avis-net.de) Suggested the idle/noidle stuff. diff --git a/sql-common/mysql_async.c b/sql-common/mysql_async.c index c130eab5061..c7e720076ea 100644 --- a/sql-common/mysql_async.c +++ b/sql-common/mysql_async.c @@ -247,6 +247,28 @@ mysql_get_timeout_value(const MYSQL *mysql) /* + In 10.0, VIO timeouts are in milliseconds, so we support getting the + millisecond timeout value from async applications. + + In 5.5, timeouts are always in seconds, but we support the 10.0 version + that provides milliseconds, so applications can work with either version + of the library easily. + + When merging this to 10.0, this function must be removed and the 10.0 + version used. +*/ +unsigned int STDCALL +mysql_get_timeout_value_ms(const MYSQL *mysql) +{ + unsigned int timeout= mysql->options.extension->async_context->timeout_value; + if (timeout <= UINT_MAX / 1000) + return timeout*1000; + else + return UINT_MAX; +} + + +/* Now create non-blocking definitions for all the calls that may block. Each call FOO gives rise to FOO_start() that prepares the MYSQL object for 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 04b223b7db0..79ccf835c5f 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 b3f97d35033..afd773faf32 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 @@ -3107,7 +3073,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)); @@ -4407,6 +4373,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 @@ -4449,6 +4487,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 @@ -4523,11 +4565,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); } @@ -5239,6 +5281,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; @@ -5249,7 +5292,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]; @@ -5296,12 +5339,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) { @@ -5364,18 +5408,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) { @@ -5418,10 +5463,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) { @@ -7541,23 +7587,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 0f922394ec5..86d43e3750f 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -508,21 +508,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 bce48feab89..97c79291a59 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2563,6 +2563,8 @@ int handler::update_auto_increment() bool append= FALSE; THD *thd= table->in_use; struct system_variables *variables= &thd->variables; + int result=0, tmp; + enum enum_check_fields save_count_cuted_fields; DBUG_ENTER("handler::update_auto_increment"); /* @@ -2580,8 +2582,10 @@ int handler::update_auto_increment() statement (case of INSERT VALUES(null),(3763),(null): the last NULL needs to insert 3764, not the value of the first NULL plus 1). + Ignore negative values. */ - adjust_next_insert_id_after_explicit_value(nr); + if ((longlong) nr > 0 || (table->next_number_field->flags & UNSIGNED_FLAG)) + adjust_next_insert_id_after_explicit_value(nr); insert_id_for_cur_row= 0; // didn't generate anything DBUG_RETURN(0); } @@ -2640,7 +2644,6 @@ int handler::update_auto_increment() else nb_desired_values= AUTO_INC_DEFAULT_NB_MAX; } - /* This call ignores all its parameters but nr, currently */ get_auto_increment(variables->auto_increment_offset, variables->auto_increment_increment, nb_desired_values, &nr, @@ -2677,32 +2680,28 @@ int handler::update_auto_increment() } if (unlikely(nr == ULONGLONG_MAX)) - DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); + DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); - DBUG_PRINT("info",("auto_increment: %lu", (ulong) nr)); + DBUG_PRINT("info",("auto_increment: %llu",nr)); - if (unlikely(table->next_number_field->store((longlong) nr, TRUE))) - { - /* - first test if the query was aborted due to strict mode constraints - */ - if (killed_mask_hard(thd->killed) == KILL_BAD_DATA) - DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); + /* Store field without warning (Warning will be printed by insert) */ + save_count_cuted_fields= thd->count_cuted_fields; + thd->count_cuted_fields= CHECK_FIELD_IGNORE; + tmp= table->next_number_field->store((longlong) nr, TRUE); + thd->count_cuted_fields= save_count_cuted_fields; + if (unlikely(tmp)) // Out of range value in store + { /* - field refused this value (overflow) and truncated it, use the result of - the truncation (which is going to be inserted); however we try to - decrease it to honour auto_increment_* variables. - That will shift the left bound of the reserved interval, we don't - bother shifting the right bound (anyway any other value from this - interval will cause a duplicate key). + It's better to return an error here than getting a confusing + 'duplicate key error' later. */ - nr= prev_insert_id(table->next_number_field->val_int(), variables); - if (unlikely(table->next_number_field->store((longlong) nr, TRUE))) - nr= table->next_number_field->val_int(); + result= HA_ERR_AUTOINC_ERANGE; } if (append) { + DBUG_PRINT("info",("nb_reserved_values: %llu",nb_reserved_values)); + auto_inc_interval_for_cur_row.replace(nr, nb_reserved_values, variables->auto_increment_increment); auto_inc_intervals_count++; @@ -2726,6 +2725,10 @@ int handler::update_auto_increment() already set. */ insert_id_for_cur_row= nr; + + if (result) // overflow + DBUG_RETURN(result); + /* Set next insert id to point to next auto-increment value to be able to handle multi-row statements. @@ -2849,7 +2852,7 @@ void handler::ha_release_auto_increment() } -void handler::print_keydup_error(uint key_nr, const char *msg) +void handler::print_keydup_error(uint key_nr, const char *msg, myf errflag) { /* Write the duplicated key in the error message */ char key[MAX_KEY_LENGTH]; @@ -2859,7 +2862,7 @@ void handler::print_keydup_error(uint key_nr, const char *msg) { /* Key is unknown */ str.copy("", 0, system_charset_info); - my_printf_error(ER_DUP_ENTRY, msg, MYF(0), str.c_ptr(), "*UNKNOWN*"); + my_printf_error(ER_DUP_ENTRY, msg, errflag, str.c_ptr(), "*UNKNOWN*"); } else { @@ -2872,7 +2875,7 @@ void handler::print_keydup_error(uint key_nr, const char *msg) str.append(STRING_WITH_LEN("...")); } my_printf_error(ER_DUP_ENTRY, msg, - MYF(0), str.c_ptr_safe(), table->key_info[key_nr].name); + errflag, str.c_ptr_safe(), table->key_info[key_nr].name); } } @@ -2940,7 +2943,7 @@ void handler::print_error(int error, myf errflag) uint key_nr=get_dup_key(error); if ((int) key_nr >= 0) { - print_keydup_error(key_nr, ER(ER_DUP_ENTRY_WITH_KEY_NAME)); + print_keydup_error(key_nr, ER(ER_DUP_ENTRY_WITH_KEY_NAME), errflag); DBUG_VOID_RETURN; } } @@ -3103,7 +3106,10 @@ void handler::print_error(int error, myf errflag) textno= ER_AUTOINC_READ_FAILED; break; case HA_ERR_AUTOINC_ERANGE: - textno= ER_WARN_DATA_OUT_OF_RANGE; + textno= error; + my_error(textno, errflag, table->next_number_field->field_name, + table->in_use->warning_info->current_row_for_warning()); + DBUG_VOID_RETURN; break; case HA_ERR_TOO_MANY_CONCURRENT_TRXS: textno= ER_TOO_MANY_CONCURRENT_TRXS; @@ -4620,7 +4626,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); + } } @@ -4652,7 +4671,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/handler.h b/sql/handler.h index 13444a1095d..da847e2677c 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1963,7 +1963,7 @@ public: void adjust_next_insert_id_after_explicit_value(ulonglong nr); int update_auto_increment(); - void print_keydup_error(uint key_nr, const char *msg); + void print_keydup_error(uint key_nr, const char *msg, myf errflag); virtual void print_error(int error, myf errflag); virtual bool get_error_message(int error, String *buf); uint get_dup_key(int error); @@ -2012,7 +2012,8 @@ public: if (!error || ((flags & HA_CHECK_DUP_KEY) && (error == HA_ERR_FOUND_DUPP_KEY || - error == HA_ERR_FOUND_DUPP_UNIQUE))) + error == HA_ERR_FOUND_DUPP_UNIQUE)) || + error == HA_ERR_AUTOINC_ERANGE) return FALSE; return TRUE; } diff --git a/sql/item.cc b/sql/item.cc index 4d80a153785..bc98a9a3184 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -6839,7 +6839,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, @@ -9609,7 +9609,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); } @@ -9618,7 +9618,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 ebfca684ccb..cce99ec2991 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3299,23 +3299,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 @@ -3328,37 +3326,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 091eb178d68..e26c3a47912 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -220,7 +220,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) uint8 uncacheable; bool res; - status_var_increment(thd->status_var.feature_subquery); + status_var_increment(thd_param->status_var.feature_subquery); DBUG_ASSERT(fixed == 0); engine->set_thd((thd= thd_param)); @@ -735,6 +735,19 @@ bool Item_subselect::expr_cache_is_needed(THD *thd) /** + Check if the left IN argument contains NULL values. + + @retval TRUE there are NULLs + @retval FALSE otherwise +*/ + +inline bool Item_in_subselect::left_expr_has_null() +{ + return (*(optimizer->get_cache()))->null_value; +} + + +/** Check if an expression cache is needed for this subquery @param thd Thread handle @@ -1050,11 +1063,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); } @@ -1990,7 +2001,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) { @@ -3285,161 +3296,51 @@ int subselect_uniquesubquery_engine::scan_table() } -/* - Copy ref key and check for null parts in it - - SYNOPSIS - subselect_uniquesubquery_engine::copy_ref_key() - - DESCRIPTION - Copy ref key and check for null parts in it. - Depending on the nullability and conversion problems this function - recognizes and processes the following states : - 1. Partial match on top level. This means IN has a value of FALSE - regardless of the data in the subquery table. - Detected by finding a NULL in the left IN operand of a top level - expression. - We may actually skip reading the subquery, so return TRUE to skip - the table scan in subselect_uniquesubquery_engine::exec and make - the value of the IN predicate a NULL (that is equal to FALSE on - top level). - 2. No exact match when IN is nested inside another predicate. - Detected by finding a NULL in the left IN operand when IN is not - a top level predicate. - We cannot have an exact match. But we must proceed further with a - table scan to find out if it's a partial match (and IN has a value - of NULL) or no match (and IN has a value of FALSE). - So we return FALSE to continue with the scan and see if there are - any record that would constitute a partial match (as we cannot - determine that from the index). - 3. Error converting the left IN operand to the column type of the - right IN operand. This counts as no match (and IN has the value of - FALSE). We mark the subquery table cursor as having no more rows - (to ensure that the processing that follows will not find a match) - and return FALSE, so IN is not treated as returning NULL. +/** + Copy ref key for index access into the only subquery table. + @details + Copy ref key and check for conversion problems. + If there is an error converting the left IN operand to the column type of + the right IN operand count it as no match. In this case IN has the value of + FALSE. We mark the subquery table cursor as having no more rows (to ensure + that the processing that follows will not find a match) and return FALSE, + so IN is not treated as returning NULL. - RETURN - FALSE - The value of the IN predicate is not known. Proceed to find the - value of the IN predicate using the determined values of - null_keypart and table->status. - TRUE - IN predicate has a value of NULL. Stop the processing right there - and return NULL to the outer predicates. + @returns + @retval FALSE The outer ref was copied into an index lookup key. + @retval TRUE The outer ref cannot possibly match any row, IN is FALSE. */ -bool subselect_uniquesubquery_engine::copy_ref_key() +bool subselect_uniquesubquery_engine::copy_ref_key(bool skip_constants) { DBUG_ENTER("subselect_uniquesubquery_engine::copy_ref_key"); for (store_key **copy= tab->ref.key_copy ; *copy ; copy++) { - if ((*copy)->store_key_is_const()) - continue; - tab->ref.key_err= (*copy)->copy(); - - /* - When there is a NULL part in the key we don't need to make index - lookup for such key thus we don't need to copy whole key. - If we later should do a sequential scan return OK. Fail otherwise. - - See also the comment for the subselect_uniquesubquery_engine::exec() - function. - */ - null_keypart= (*copy)->null_key; - if (null_keypart) - { - bool top_level= ((Item_in_subselect *) item)->is_top_level_item(); - if (top_level) - { - /* Partial match on top level */ - DBUG_RETURN(1); - } - else - { - /* No exact match when IN is nested inside another predicate */ - break; - } - } - - /* - Check if the error is equal to STORE_KEY_FATAL. This is not expressed - using the store_key::store_key_result enum because ref.key_err is a - boolean and we want to detect both TRUE and STORE_KEY_FATAL from the - space of the union of the values of [TRUE, FALSE] and - store_key::store_key_result. - TODO: fix the variable an return types. - */ - if (tab->ref.key_err & 1) - { - /* - Error converting the left IN operand to the column type of the right - IN operand. - */ - tab->table->status= STATUS_NOT_FOUND; - break; - } - } - DBUG_RETURN(0); -} - - -/* - @retval 1 A NULL was found in the outer reference, index lookup is - not applicable, the outer ref is unsusable as a lookup key, - use some other method to find a match. - @retval 0 The outer ref was copied into an index lookup key. - @retval -1 The outer ref cannot possibly match any row, IN is FALSE. -*/ -/* TIMOUR: this method is a variant of copy_ref_key(), needs refactoring. */ - -int subselect_uniquesubquery_engine::copy_ref_key_simple() -{ - for (store_key **copy= tab->ref.key_copy ; *copy ; copy++) - { enum store_key::store_key_result store_res; + if (skip_constants && (*copy)->store_key_is_const()) + continue; store_res= (*copy)->copy(); tab->ref.key_err= store_res; - /* - When there is a NULL part in the key we don't need to make index - lookup for such key thus we don't need to copy whole key. - If we later should do a sequential scan return OK. Fail otherwise. - - See also the comment for the subselect_uniquesubquery_engine::exec() - function. - */ - null_keypart= (*copy)->null_key; - if (null_keypart) - return 1; - - /* - Check if the error is equal to STORE_KEY_FATAL. This is not expressed - using the store_key::store_key_result enum because ref.key_err is a - boolean and we want to detect both TRUE and STORE_KEY_FATAL from the - space of the union of the values of [TRUE, FALSE] and - store_key::store_key_result. - TODO: fix the variable an return types. - */ if (store_res == store_key::STORE_KEY_FATAL) { /* Error converting the left IN operand to the column type of the right IN operand. */ - return -1; + DBUG_RETURN(true); } } - return 0; + DBUG_RETURN(false); } -/* - Execute subselect - - SYNOPSIS - subselect_uniquesubquery_engine::exec() +/** + Execute subselect via unique index lookup - DESCRIPTION + @details Find rows corresponding to the ref key using index access. If some part of the lookup key is NULL, then we're evaluating NULL IN (SELECT ... ) @@ -3456,11 +3357,11 @@ int subselect_uniquesubquery_engine::copy_ref_key_simple() The result of this function (info about whether a row was found) is stored in this->empty_result_set. - NOTE - RETURN - FALSE - ok - TRUE - an error occured while scanning + @returns + @retval 0 OK + @retval 1 notify caller to call Item_subselect::reset(), + in most cases reset() sets the result to NULL */ int subselect_uniquesubquery_engine::exec() @@ -3470,32 +3371,30 @@ int subselect_uniquesubquery_engine::exec() TABLE *table= tab->table; empty_result_set= TRUE; table->status= 0; + Item_in_subselect *in_subs= (Item_in_subselect *) item; + + if (!tab->preread_init_done && tab->preread_init()) + DBUG_RETURN(1); - /* TODO: change to use of 'full_scan' here? */ - if (copy_ref_key()) + if (in_subs->left_expr_has_null()) { /* - TIMOUR: copy_ref_key() == 1 means NULL result, not error, why return 1? - Check who reiles on this result. + The case when all values in left_expr are NULL is handled by + Item_in_optimizer::val_int(). */ - DBUG_RETURN(1); + if (in_subs->is_top_level_item()) + DBUG_RETURN(1); /* notify caller to call reset() and set NULL value. */ + else + DBUG_RETURN(scan_table()); } - if (table->status) + + if (copy_ref_key(true)) { - /* - We know that there will be no rows even if we scan. - Can be set in copy_ref_key. - */ - ((Item_in_subselect *) item)->value= 0; + /* We know that there will be no rows even if we scan. */ + in_subs->value= 0; DBUG_RETURN(0); } - if (!tab->preread_init_done && tab->preread_init()) - DBUG_RETURN(1); - - if (null_keypart) - DBUG_RETURN(scan_table()); - if (!table->file->inited) table->file->ha_index_init(tab->ref.key, 0); error= table->file->ha_index_read_map(table->record[0], @@ -3571,14 +3470,10 @@ subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine() } -/* - Index-lookup subselect 'engine' - run the subquery - - SYNOPSIS - subselect_indexsubquery_engine:exec() - full_scan +/** + Execute subselect via unique index lookup - DESCRIPTION + @details The engine is used to resolve subqueries in form oe IN (SELECT key FROM tbl WHERE subq_where) @@ -3593,7 +3488,7 @@ subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine() row that satisfies subq_where. If found, return NULL, otherwise return FALSE. - TODO + @todo The step #1 can be optimized further when the index has several key parts. Consider a subquery: @@ -3618,9 +3513,10 @@ subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine() cheaper. We can use index statistics to quickly check whether "ref" scan will be cheaper than full table scan. - RETURN - 0 - 1 + @returns + @retval 0 OK + @retval 1 notify caller to call Item_subselect::reset(), + in most cases reset() sets the result to NULL */ int subselect_indexsubquery_engine::exec() @@ -3629,10 +3525,10 @@ int subselect_indexsubquery_engine::exec() int error; bool null_finding= 0; TABLE *table= tab->table; + Item_in_subselect *in_subs= (Item_in_subselect *) item; ((Item_in_subselect *) item)->value= 0; empty_result_set= TRUE; - null_keypart= 0; table->status= 0; if (check_null) @@ -3642,25 +3538,27 @@ int subselect_indexsubquery_engine::exec() ((Item_in_subselect *) item)->was_null= 0; } - /* Copy the ref key and check for nulls... */ - if (copy_ref_key()) + if (!tab->preread_init_done && tab->preread_init()) DBUG_RETURN(1); - if (table->status) + if (in_subs->left_expr_has_null()) { - /* - We know that there will be no rows even if we scan. - Can be set in copy_ref_key. + /* + The case when all values in left_expr are NULL is handled by + Item_in_optimizer::val_int(). */ - ((Item_in_subselect *) item)->value= 0; - DBUG_RETURN(0); + if (in_subs->is_top_level_item()) + DBUG_RETURN(1); /* notify caller to call reset() and set NULL value. */ + else + DBUG_RETURN(scan_table()); } - if (!tab->preread_init_done && tab->preread_init()) - DBUG_RETURN(1); - - if (null_keypart) - DBUG_RETURN(scan_table()); + if (copy_ref_key(true)) + { + /* We know that there will be no rows even if we scan. */ + in_subs->value= 0; + DBUG_RETURN(0); + } if (!table->file->inited) table->file->ha_index_init(tab->ref.key, 1); @@ -5429,37 +5327,42 @@ subselect_partial_match_engine::subselect_partial_match_engine( int subselect_partial_match_engine::exec() { Item_in_subselect *item_in= (Item_in_subselect *) item; - int copy_res, lookup_res; + int lookup_res; - /* Try to find a matching row by index lookup. */ - copy_res= lookup_engine->copy_ref_key_simple(); - if (copy_res == -1) - { - /* The result is FALSE based on the outer reference. */ - item_in->value= 0; - item_in->null_value= 0; - return 0; - } - else if (copy_res == 0) + DBUG_ASSERT(!(item_in->left_expr_has_null() && + item_in->is_top_level_item())); + + if (!item_in->left_expr_has_null()) { - /* Search for a complete match. */ - if ((lookup_res= lookup_engine->index_lookup())) + /* Try to find a matching row by index lookup. */ + if (lookup_engine->copy_ref_key(false)) { - /* An error occured during lookup(). */ + /* The result is FALSE based on the outer reference. */ item_in->value= 0; item_in->null_value= 0; - return lookup_res; + return 0; } - else if (item_in->value || !count_columns_with_nulls) + else { - /* - A complete match was found, the result of IN is TRUE. - If no match was found, and there are no NULLs in the materialized - subquery, then the result is guaranteed to be false because this - branch is executed when the outer reference has no NULLs as well. - Notice: (this->item == lookup_engine->item) - */ - return 0; + /* Search for a complete match. */ + if ((lookup_res= lookup_engine->index_lookup())) + { + /* An error occured during lookup(). */ + item_in->value= 0; + item_in->null_value= 0; + return lookup_res; + } + else if (item_in->value || !count_columns_with_nulls) + { + /* + A complete match was found, the result of IN is TRUE. + If no match was found, and there are no NULLs in the materialized + subquery, then the result is guaranteed to be false because this + branch is executed when the outer reference has no NULLs as well. + Notice: (this->item == lookup_engine->item) + */ + return 0; + } } } diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 05c4528490f..2a64c63a1be 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -591,6 +591,7 @@ public: /* Inform 'this' that it was computed, and contains a valid result. */ void set_first_execution() { if (first_execution) first_execution= FALSE; } bool expr_cache_is_needed(THD *thd); + inline bool left_expr_has_null(); int optimize(double *out_rows, double *cost); /* @@ -869,7 +870,6 @@ protected: expression is NULL. */ bool empty_result_set; - bool null_keypart; /* TRUE <=> constructed search tuple has a NULL */ public: // constructor can assign THD because it will be called after JOIN::prepare @@ -893,8 +893,7 @@ public: bool no_tables(); int index_lookup(); /* TIMOUR: this method needs refactoring. */ int scan_table(); - bool copy_ref_key(); - int copy_ref_key_simple(); /* TIMOUR: this method needs refactoring. */ + bool copy_ref_key(bool skip_constants); bool no_rows() { return empty_result_set; } virtual enum_engine_type engine_type() { return UNIQUESUBQUERY_ENGINE; } }; diff --git a/sql/log.cc b/sql/log.cc index 4dd5bb561e5..a0207510fbe 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -307,7 +307,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) { @@ -384,7 +384,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 @@ -422,8 +422,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/log_event.cc b/sql/log_event.cc index 90d517f5ecd..edb89fb85fe 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1089,6 +1089,9 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length) ulong now; bool ret; DBUG_ENTER("Log_event::write_header"); + DBUG_PRINT("enter", ("filepos: %lld length: %lu type: %d", + (longlong) my_b_tell(file), event_data_length, + (int) get_type_code())); /* Store number of bytes that will be written by this event */ data_written= event_data_length + sizeof(header); @@ -3517,6 +3520,34 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli) return do_apply_event(rli, query, q_len); } +/** + Compare if two errors should be regarded as equal. + This is to handle the case when you can get slightly different errors + on master and slave for the same thing. + @param + expected_error Error we got on master + actual_error Error we got on slave + + @return + 1 Errors are equal + 0 Errors are different +*/ + +bool test_if_equal_repl_errors(int expected_error, int actual_error) +{ + if (expected_error == actual_error) + return 1; + switch (expected_error) { + case ER_DUP_ENTRY: + case ER_AUTOINC_READ_FAILED: + return (actual_error == ER_AUTOINC_READ_FAILED || + actual_error == HA_ERR_AUTOINC_ERANGE); + default: + break; + } + return 0; +} + /** @todo @@ -3829,7 +3860,8 @@ compare_errors: DBUG_PRINT("info",("expected_error: %d sql_errno: %d", expected_error, actual_error)); - if ((expected_error && expected_error != actual_error && + if ((expected_error && + !test_if_equal_repl_errors(expected_error, actual_error) && !concurrency_error_code(expected_error)) && !ignored_error_code(actual_error) && !ignored_error_code(expected_error)) @@ -3851,7 +3883,7 @@ Default database: '%s'. Query: '%s'", If we get the same error code as expected and it is not a concurrency issue, or should be ignored. */ - else if ((expected_error == actual_error && + else if ((test_if_equal_repl_errors(expected_error, actual_error) && !concurrency_error_code(expected_error)) || ignored_error_code(actual_error)) { diff --git a/sql/mdl.cc b/sql/mdl.cc index 2e279c19592..8527c027937 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -388,7 +388,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); @@ -402,14 +403,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), @@ -494,6 +505,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]; @@ -546,6 +566,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]; @@ -1321,6 +1353,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 @@ -1342,7 +1409,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)) { @@ -1356,6 +1432,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, @@ -1367,6 +1450,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; + } } @@ -1520,8 +1621,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. @@ -1533,7 +1635,8 @@ 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]; @@ -1541,14 +1644,15 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg, #ifdef WITH_WSREP bool wsrep_can_grant= TRUE; #endif /* WITH_WSREP */ + /* 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; @@ -1891,7 +1995,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 d50de7d14c3..af7d75c1297 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -860,4 +860,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 1742392fb92..45e4f6fe905 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -277,6 +277,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[]= @@ -629,6 +631,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; @@ -1891,6 +1908,7 @@ void clean_up(bool print_message) #endif my_tz_free(); my_dboptions_cache_free(); + ignore_db_dirs_free(); #ifndef NO_EMBEDDED_ACCESS_CHECKS servers_free(1); acl_free(1); @@ -3551,6 +3569,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); @@ -3983,6 +4004,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; } @@ -7019,7 +7046,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, @@ -7656,6 +7683,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}, @@ -7663,7 +7691,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_FUNC}, {"Connections", (char*) &thread_id, SHOW_LONG_NOFLUSH}, @@ -7689,14 +7716,11 @@ SHOW_VAR status_vars[]= { {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS}, {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS}, {"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_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}, @@ -7722,12 +7746,12 @@ SHOW_VAR status_vars[]= { {"Open_table_definitions", (char*) &show_table_definitions, SHOW_FUNC}, {"Open_tables", (char*) &show_open_tables, SHOW_FUNC}, {"Opened_files", (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH}, - {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS}, {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS}, + {"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_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}, @@ -7751,9 +7775,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*) &show_slave_retried_trans, SHOW_FUNC}, {"Slave_heartbeat_period", (char*) &show_heartbeat_period, SHOW_FUNC}, {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats, SHOW_FUNC}, + {"Slave_retried_transactions",(char*) &show_slave_retried_trans, SHOW_FUNC}, {"Slave_running", (char*) &show_slave_running, SHOW_FUNC}, #endif {"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG}, @@ -7899,14 +7923,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."); @@ -8488,6 +8506,22 @@ mysqld_get_one_option(int optid, case OPT_MAX_LONG_DATA_SIZE: max_long_data_size_used= true; 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; } return 0; } diff --git a/sql/mysqld.h b/sql/mysqld.h index 07beda50e42..02db7f9d959 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -376,19 +376,23 @@ 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_POOL_OF_THREADS, OPT_REPLICATE_DO_DB, @@ -414,8 +418,6 @@ enum options_mysqld OPT_SSL_KEY, OPT_UPDATE_LOG, OPT_WANT_CORE, - OPT_ENGINE_CONDITION_PUSHDOWN, - OPT_LOG_ERROR, #ifdef WITH_WSREP OPT_WSREP_PROVIDER, OPT_WSREP_PROVIDER_OPTIONS, @@ -424,7 +426,7 @@ enum options_mysqld OPT_WSREP_SST_AUTH, OPT_WSREP_RECOVER, #endif - OPT_MAX_LONG_DATA_SIZE + OPT_which_is_always_the_last }; #endif diff --git a/sql/opt_range.cc b/sql/opt_range.cc index dba72d76bb4..791af42521a 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/set_var.cc b/sql/set_var.cc index 8e2f90b9bfd..4e6354d9af4 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -134,9 +134,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, @@ -145,11 +145,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) { /* @@ -175,12 +176,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 @@ -275,21 +270,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 006498773b8..ec6d2c28e6a 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -79,7 +79,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: @@ -88,7 +88,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 31a6f13e52f..d3b7e651b62 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6342,8 +6342,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 f0ddf16bd0f..07bdb93930c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5008,8 +5008,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 @@ -5022,10 +5020,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()) @@ -5046,12 +5053,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; } } @@ -5348,6 +5349,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 7604227740f..68f85ea579f 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -278,6 +278,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 @@ -410,6 +468,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 @@ -431,6 +500,7 @@ my_socket thd_get_fd(THD *thd) { return thd->net.vio->sd; } +#endif /** Get thread attributes for connection threads diff --git a/sql/sql_class.h b/sql/sql_class.h index 98766cabeca..451624e902c 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1702,7 +1702,7 @@ public: my_hrtime_t user_time; // track down slow pthread_create ulonglong prior_thr_create_utime, thr_create_utime; - ulonglong start_utime, utime_after_lock; + ulonglong start_utime, utime_after_lock, utime_after_query; // Process indicator struct { @@ -2547,8 +2547,8 @@ public: */ void update_server_status() { - ulonglong end_utime_of_query= current_utime(); - if (end_utime_of_query > utime_after_lock + variables.long_query_time) + utime_after_query= current_utime(); + if (utime_after_query > utime_after_lock + variables.long_query_time) server_status|= SERVER_QUERY_WAS_SLOW; } inline ulonglong found_rows(void) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 5c165e4ec7d..4bf116eaebe 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -329,7 +329,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, /* - Check update fields for the timestamp field. + Check update fields for the timestamp and auto_increment fields. SYNOPSIS check_update_fields() @@ -342,6 +342,9 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, If the update fields include the timestamp field, remove TIMESTAMP_AUTO_SET_ON_UPDATE from table->timestamp_field_type. + If the update fields include an autoinc field, set the + table->next_number_field_updated flag. + RETURN 0 OK -1 Error @@ -353,7 +356,9 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, { TABLE *table= insert_table_list->table; my_bool timestamp_mark; + my_bool autoinc_mark; LINT_INIT(timestamp_mark); + LINT_INIT(autoinc_mark); if (table->timestamp_field) { @@ -365,6 +370,19 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, table->timestamp_field->field_index); } + table->next_number_field_updated= FALSE; + + if (table->found_next_number_field) + { + /* + Unmark the auto_increment field so that we can check if this is modified + by update_fields + */ + autoinc_mark= bitmap_test_and_clear(table->write_set, + table->found_next_number_field-> + field_index); + } + /* Check the fields we are going to modify */ if (setup_fields(thd, 0, update_fields, MARK_COLUMNS_WRITE, 0, 0)) return -1; @@ -386,6 +404,18 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, bitmap_set_bit(table->write_set, table->timestamp_field->field_index); } + + if (table->found_next_number_field) + { + if (bitmap_is_set(table->write_set, + table->found_next_number_field->field_index)) + table->next_number_field_updated= TRUE; + + if (autoinc_mark) + bitmap_set_bit(table->write_set, + table->found_next_number_field->field_index); + } + return 0; } @@ -1567,6 +1597,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) MY_BITMAP *save_read_set, *save_write_set; ulonglong prev_insert_id= table->file->next_insert_id; ulonglong insert_id_for_cur_row= 0; + ulonglong prev_insert_id_for_cur_row= 0; DBUG_ENTER("write_record"); info->records++; @@ -1602,7 +1633,10 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) report error as usual. We will not do any duplicate key processing. */ if (info->ignore) + { + table->file->print_error(error, MYF(ME_JUST_WARNING)); goto ok_or_after_trg_err; /* Ignoring a not fatal error, return 0 */ + } goto err; } if ((int) (key_nr = table->file->get_dup_key(error)) < 0) @@ -1692,6 +1726,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (info->ignore && !table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) { + table->file->print_error(error, MYF(ME_JUST_WARNING)); goto ok_or_after_trg_err; } goto err; @@ -1709,6 +1744,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) INSERT query, which is handled separately by THD::arg_of_last_insert_id_function. */ + prev_insert_id_for_cur_row= table->file->insert_id_for_cur_row; insert_id_for_cur_row= table->file->insert_id_for_cur_row= 0; trg_error= (table->triggers && table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, @@ -1716,9 +1752,22 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) info->copied++; } - if (table->next_number_field) - table->file->adjust_next_insert_id_after_explicit_value( - table->next_number_field->val_int()); + /* + Only update next_insert_id if the AUTO_INCREMENT value was explicitly + updated, so we don't update next_insert_id with the value from the + row being updated. Otherwise reset next_insert_id to what it was + before the duplicate key error, since that value is unused. + */ + if (table->next_number_field_updated) + { + DBUG_ASSERT(table->next_number_field != NULL); + + table->file->adjust_next_insert_id_after_explicit_value(table->next_number_field->val_int()); + } + else + { + table->file->restore_auto_increment(prev_insert_id_for_cur_row); + } goto ok_or_after_trg_err; } else /* DUP_REPLACE */ @@ -1807,6 +1856,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (!info->ignore || table->file->is_fatal_error(error, HA_CHECK_DUP)) goto err; + table->file->print_error(error, MYF(ME_JUST_WARNING)); table->file->restore_auto_increment(prev_insert_id); goto ok_or_after_trg_err; } diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 91a98d8c6f1..8424dd00d93 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_parse.cc b/sql/sql_parse.cc index 6a9063d0edb..1e9561e895b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1695,38 +1695,30 @@ void log_slow_statement(THD *thd) DBUG_VOID_RETURN; // Don't set time for sub stmt /* Follow the slow log filter configuration. */ - if (!(thd->variables.log_slow_filter & thd->query_plan_flags)) + if (!thd->enable_slow_log || + !(thd->variables.log_slow_filter & thd->query_plan_flags)) DBUG_VOID_RETURN; - /* - If rate limiting of slow log writes is enabled, decide whether to log - this query to the log or not. - */ - if (thd->variables.log_slow_rate_limit > 1 && - (global_query_id % thd->variables.log_slow_rate_limit) != 0) - DBUG_VOID_RETURN; + if (((thd->server_status & SERVER_QUERY_WAS_SLOW) || + ((thd->server_status & + (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && + opt_log_queries_not_using_indexes && + !(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) && + thd->examined_row_count >= thd->variables.min_examined_row_limit) + { + thd->status_var.long_query_count++; + /* + If rate limiting of slow log writes is enabled, decide whether to log + this query to the log or not. + */ + if (thd->variables.log_slow_rate_limit > 1 && + (global_query_id % thd->variables.log_slow_rate_limit) != 0) + DBUG_VOID_RETURN; - /* - Do not log administrative statements unless the appropriate option is - set. - */ - if (thd->enable_slow_log) - { - ulonglong end_utime_of_query= thd->current_utime(); thd_proc_info(thd, "logging slow query"); - - if (((thd->server_status & SERVER_QUERY_WAS_SLOW) || - ((thd->server_status & - (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && - opt_log_queries_not_using_indexes && - !(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) && - thd->examined_row_count >= thd->variables.min_examined_row_limit) - { - thd_proc_info(thd, "logging slow query"); - thd->status_var.long_query_count++; - slow_log_print(thd, thd->query(), thd->query_length(), - end_utime_of_query); - } + slow_log_print(thd, thd->query(), thd->query_length(), + thd->utime_after_query); + thd_proc_info(thd, 0); } DBUG_VOID_RETURN; } @@ -3249,6 +3241,7 @@ end_with_restore_list: DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(act2))); };); + DEBUG_SYNC(thd, "after_mysql_insert"); break; } case SQLCOM_REPLACE_SELECT: diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 4db25bd54d5..844ca9ea0e7 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; } @@ -2157,7 +2157,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 ed437c498e6..114de41f83a 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 749e65e0902..ea89a67f210 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -364,6 +364,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 57bb9a311d7..a4b2d376e05 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -718,8 +718,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; @@ -735,9 +733,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 */ @@ -1672,12 +1667,19 @@ JOIN::optimize() 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) && @@ -3881,8 +3883,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; @@ -3896,7 +3900,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 @@ -8019,6 +8024,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 86ef6ed03da..1952a0c58b3 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -417,6 +417,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. @@ -502,6 +777,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 611e3a64c73..6e87f6097f0 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -132,4 +132,12 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table); /* These functions were under INNODB_COMPATIBILITY_HOOKS */ int get_quote_char_for_identifier(THD *thd, const char *name, uint length); +/* 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_state.c b/sql/sql_state.c index 511dc65917b..5acf97f16cc 100644 --- a/sql/sql_state.c +++ b/sql/sql_state.c @@ -17,6 +17,7 @@ #include <my_global.h> #include <mysqld_error.h> +#include <my_base.h> struct st_map_errno_to_sqlstate { @@ -27,6 +28,7 @@ struct st_map_errno_to_sqlstate struct st_map_errno_to_sqlstate sqlstate_map[]= { +#include <handler_state.h> #include <sql_state.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/sql_table.cc b/sql/sql_table.cc index 32915735f72..5e8b182e3e8 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1828,6 +1828,7 @@ int write_bin_log(THD *thd, bool clear_error, if (mysql_bin_log.is_open()) { int errcode= 0; + thd_proc_info(thd, "Writing to binlog"); if (clear_error) thd->clear_error(); else @@ -1835,6 +1836,7 @@ int write_bin_log(THD *thd, bool clear_error, error= thd->binlog_query(THD::STMT_QUERY_TYPE, query, query_length, is_trans, FALSE, FALSE, errcode); + thd_proc_info(thd, 0); } return error; } @@ -7483,7 +7485,7 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to, (to->key_info[0].key_part[0].field->flags & AUTO_INCREMENT_FLAG)) err_msg= ER(ER_DUP_ENTRY_AUTOINCREMENT_CASE); - to->file->print_keydup_error(key_nr, err_msg); + to->file->print_keydup_error(key_nr, err_msg, MYF(0)); break; } } diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 08277b9f624..49be8e79e3b 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -48,6 +48,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 @@ -568,14 +569,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(50600, "'@@debug_dbug'")); + DEPRECATED("'@@debug_dbug'")); static Sys_var_dbug Sys_debug_dbug( "debug_dbug", "Built-in DBUG debugger", sys_var::SESSION, @@ -1215,7 +1216,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(70000, "'@@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", @@ -1676,7 +1677,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(70000, 0)); + DEPRECATED("")); static Sys_var_ulong Sys_range_alloc_block_size( "range_alloc_block_size", @@ -1690,7 +1691,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(50700, "'@@mrr_buffer_size'")); + DEPRECATED("'@@mrr_buffer_size'")); static bool fix_thd_mem_root(sys_var *self, THD *thd, enum_var_type type) { @@ -2454,7 +2455,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(70000, "'@@optimizer_switch'")); + DEPRECATED("'@@optimizer_switch'")); static Sys_var_plugin Sys_default_storage_engine( "default_storage_engine", "The default storage engine for new tables", @@ -3136,7 +3137,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(70000, "'@@general_log'")); + ON_UPDATE(fix_log_state), DEPRECATED("'@@general_log'")); static Sys_var_mybool Sys_slow_query_log( "slow_query_log", @@ -3153,7 +3154,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(70000, "'@@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) { @@ -3837,6 +3838,15 @@ static Sys_var_ulong Sys_wsrep_mysql_replication_bundle( #endif /* WITH_WSREP */ +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 21bebcd762c..95a8e45f7c3 100644 --- a/sql/sys_vars.h +++ b/sql/sys_vars.h @@ -59,7 +59,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()) @@ -126,10 +126,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; @@ -238,11 +238,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=""; @@ -305,11 +305,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; @@ -352,11 +352,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; @@ -407,11 +407,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; /* @@ -502,7 +502,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; @@ -561,7 +561,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; } @@ -615,10 +615,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,11 +655,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) { @@ -739,11 +739,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; @@ -900,11 +900,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); @@ -964,11 +964,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) { @@ -1005,11 +1005,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; @@ -1116,11 +1116,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; @@ -1222,11 +1222,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; @@ -1335,11 +1335,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; @@ -1427,11 +1427,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; @@ -1500,11 +1500,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); @@ -1550,11 +1550,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); @@ -1604,11 +1604,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); @@ -1672,11 +1672,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; @@ -1744,11 +1744,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 47b2cae1a04..c0e27b9a962 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); } @@ -4967,7 +4970,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 f5ae3bcebb3..1a24fde6111 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1053,15 +1053,20 @@ public: uint db_stat; /* mode of file as in handler.h */ /* number of select if it is derived table */ uint derived_select_number; - int current_lock; /* Type of lock on table */ - bool copy_blobs; /* copy_blobs when storing */ - /* 0 or JOIN_TYPE_{LEFT|RIGHT}. Currently this is only compared to 0. If maybe_null !=0, this table is inner w.r.t. some outer join operation, and null_row may be true. */ uint maybe_null; + int current_lock; /* Type of lock on table */ + bool copy_blobs; /* copy_blobs when storing */ + /* + Set if next_number_field is in the UPDATE fields of INSERT ... ON DUPLICATE + KEY UPDATE. + */ + bool next_number_field_updated; + /* If true, the current table row is considered to have all columns set to NULL, including columns declared as "not null" (see maybe_null). @@ -1855,6 +1860,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/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index b21e0561322..e705d1dd615 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))) @@ -1630,7 +1630,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 549001ab08b..c0bf0acb523 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/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index b714219e304..c9dc9e20072 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -1844,6 +1844,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 */ @@ -2324,12 +2325,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.c b/storage/innobase/btr/btr0cur.c index 9c61e0cf763..ce43cba8525 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -1323,7 +1323,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; + } } } @@ -1459,20 +1464,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); @@ -2076,8 +2070,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)) @@ -2433,7 +2431,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) @@ -2462,7 +2465,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/btr/btr0pcur.c b/storage/innobase/btr/btr0pcur.c index 7ac96c1a1b1..c989498408a 100644 --- a/storage/innobase/btr/btr0pcur.c +++ b/storage/innobase/btr/btr0pcur.c @@ -348,44 +348,39 @@ btr_pcur_restore_position_func( /* Restore the old search mode */ cursor->search_mode = old_mode; - if (btr_pcur_is_on_user_rec(cursor)) { - switch (cursor->rel_pos) { - case BTR_PCUR_ON: - if (!cmp_dtuple_rec( - tuple, btr_pcur_get_rec(cursor), - rec_get_offsets(btr_pcur_get_rec(cursor), - index, NULL, - ULINT_UNDEFINED, &heap))) { - - /* We have to store the NEW value for - the modify clock, since the cursor can - now be on a different page! But we can - retain the value of old_rec */ - - cursor->block_when_stored = - btr_pcur_get_block(cursor); - cursor->modify_clock = - buf_block_get_modify_clock( - cursor->block_when_stored); - cursor->old_stored = BTR_PCUR_OLD_STORED; - - mem_heap_free(heap); - - return(TRUE); - } - - break; - case BTR_PCUR_BEFORE: - page_cur_move_to_next(btr_pcur_get_page_cur(cursor)); - break; - case BTR_PCUR_AFTER: - page_cur_move_to_prev(btr_pcur_get_page_cur(cursor)); - break; + switch (cursor->rel_pos) { + case BTR_PCUR_ON: + if (btr_pcur_is_on_user_rec(cursor) + && !cmp_dtuple_rec( + tuple, btr_pcur_get_rec(cursor), + rec_get_offsets(btr_pcur_get_rec(cursor), + index, NULL, + ULINT_UNDEFINED, &heap))) { + + /* We have to store the NEW value for + the modify clock, since the cursor can + now be on a different page! But we can + retain the value of old_rec */ + + cursor->block_when_stored = + btr_pcur_get_block(cursor); + cursor->modify_clock = + buf_block_get_modify_clock( + cursor->block_when_stored); + cursor->old_stored = BTR_PCUR_OLD_STORED; + + mem_heap_free(heap); + + return(TRUE); + } #ifdef UNIV_DEBUG - default: - ut_error; + /* fall through */ + case BTR_PCUR_BEFORE: + case BTR_PCUR_AFTER: + break; + default: + ut_error; #endif /* UNIV_DEBUG */ - } } mem_heap_free(heap); diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 32d376136e6..70841a168ab 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -294,14 +294,7 @@ be effective only if PFS_GROUP_BUFFER_SYNC is defined. */ # endif /* !PFS_SKIP_BUFFER_MUTEX_RWLOCK */ #endif /* UNIV_PFS_MUTEX || UNIV_PFS_RWLOCK */ -/** A chunk of buffers. The buffer pool is allocated in chunks. */ -struct buf_chunk_struct{ - ulint mem_size; /*!< allocated size of the chunk */ - ulint size; /*!< size of frames[] and blocks[] */ - void* mem; /*!< pointer to the memory area which - was allocated for the frames */ - buf_block_t* blocks; /*!< array of buffer control blocks */ -}; + /********************************************************************//** Gets the smallest oldest_modification lsn for any page in the pool. Returns @@ -4424,7 +4417,7 @@ buf_stats_aggregate_pool_info( Collect buffer pool stats information for a buffer pool. Also record aggregated stats if there are more than one buffer pool in the server */ -static +UNIV_INTERN void buf_stats_get_pool_info( /*====================*/ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a1b7eab5deb..2e1732d7d25 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1527,6 +1527,15 @@ innobase_next_autoinc( ut_a(block > 0); ut_a(max_value > 0); + /* + Allow auto_increment to go over max_value up to max ulonglong. + This allows us to detect that all values are exhausted. + If we don't do this, we will return max_value several times + and get duplicate key errors instead of auto increment value + out of range. + */ + max_value= (~(ulonglong) 0); + /* Current value should never be greater than the maximum. */ ut_a(current <= max_value); @@ -5679,7 +5688,10 @@ no_commit: goto report_error; } - /* MySQL errors are passed straight back. */ + /* MySQL errors are passed straight back. except for + HA_ERR_AUTO_INC_READ_FAILED. This can only happen + for values out of range. + */ error_result = (int) error; goto func_exit; } @@ -11053,13 +11065,17 @@ ha_innobase::get_auto_increment( /* Not in the middle of a mult-row INSERT. */ } else if (prebuilt->autoinc_last_value == 0) { set_if_bigger(*first_value, autoinc); - /* Check for -ve values. */ - } else if (*first_value > col_max_value && trx->n_autoinc_rows > 0) { - /* Set to next logical value. */ - ut_a(autoinc > trx->n_autoinc_rows); - *first_value = (autoinc - trx->n_autoinc_rows) - 1; } + if (*first_value > col_max_value) + { + /* Out of range number. Let handler::update_auto_increment() + take care of this */ + prebuilt->autoinc_last_value = 0; + dict_table_autoinc_unlock(prebuilt->table); + *nb_reserved_values= 0; + return; + } *nb_reserved_values = trx->n_autoinc_rows; /* With old style AUTOINC locking we only update the table's @@ -11068,7 +11084,7 @@ ha_innobase::get_auto_increment( ulonglong current; ulonglong next_value; - current = *first_value > col_max_value ? autoinc : *first_value; + current = *first_value; /* Compute the last value in the interval */ next_value = innobase_next_autoinc( @@ -12917,7 +12933,10 @@ 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_cmpmem_reset, +i_s_innodb_buffer_page, +i_s_innodb_buffer_page_lru, +i_s_innodb_buffer_stats mysql_declare_plugin_end; /** @brief Initialize the default value of innodb_commit_concurrency. diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index abbb8b10ce7..59ea065c5c7 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -45,8 +45,93 @@ extern "C" { #include "srv0start.h" /* for srv_was_started */ #include "trx0i_s.h" #include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */ +#include "btr0btr.h" +#include "page0zip.h" +#include "log0log.h" } +/** structure associates a name string with a file page type and/or buffer +page state. */ +struct buffer_page_desc_str_struct{ + const char* type_str; /*!< String explain the page + type/state */ + ulint type_value; /*!< Page type or page state */ +}; + +typedef struct buffer_page_desc_str_struct buf_page_desc_str_t; + +/** Any states greater than FIL_PAGE_TYPE_LAST would be treated as unknown. */ +#define I_S_PAGE_TYPE_UNKNOWN (FIL_PAGE_TYPE_LAST + 1) + +/** We also define I_S_PAGE_TYPE_INDEX as the Index Page's position +in i_s_page_type[] array */ +#define I_S_PAGE_TYPE_INDEX 1 + +/** Name string for File Page Types */ +static buf_page_desc_str_t i_s_page_type[] = { + {"ALLOCATED", FIL_PAGE_TYPE_ALLOCATED}, + {"INDEX", FIL_PAGE_INDEX}, + {"UNDO_LOG", FIL_PAGE_UNDO_LOG}, + {"INODE", FIL_PAGE_INODE}, + {"IBUF_FREE_LIST", FIL_PAGE_IBUF_FREE_LIST}, + {"IBUF_BITMAP", FIL_PAGE_IBUF_BITMAP}, + {"SYSTEM", FIL_PAGE_TYPE_SYS}, + {"TRX_SYSTEM", FIL_PAGE_TYPE_TRX_SYS}, + {"FILE_SPACE_HEADER", FIL_PAGE_TYPE_FSP_HDR}, + {"EXTENT_DESCRIPTOR", FIL_PAGE_TYPE_XDES}, + {"BLOB", FIL_PAGE_TYPE_BLOB}, + {"COMPRESSED_BLOB", FIL_PAGE_TYPE_ZBLOB}, + {"COMPRESSED_BLOB2", FIL_PAGE_TYPE_ZBLOB2}, + {"UNKNOWN", I_S_PAGE_TYPE_UNKNOWN} +}; + +/* Check if we can hold all page type in a 4 bit value */ +#if I_S_PAGE_TYPE_UNKNOWN > 1<<4 +# error "i_s_page_type[] is too large" +#endif + +/** This structure defines information we will fetch from pages +currently cached in the buffer pool. It will be used to populate +table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE */ +struct buffer_page_info_struct{ + ulint block_id; /*!< Buffer Pool block ID */ + unsigned space_id:32; /*!< Tablespace ID */ + unsigned page_num:32; /*!< Page number/offset */ + unsigned access_time:32; /*!< Time of first access */ + unsigned pool_id:MAX_BUFFER_POOLS_BITS; + /*!< Buffer Pool ID. Must be less than + MAX_BUFFER_POOLS */ + unsigned flush_type:2; /*!< Flush type */ + unsigned io_fix:2; /*!< type of pending I/O operation */ + unsigned fix_count:19; /*!< Count of how manyfold this block + is bufferfixed */ + unsigned hashed:1; /*!< Whether hash index has been + built on this page */ + unsigned is_old:1; /*!< TRUE if the block is in the old + blocks in buf_pool->LRU_old */ + unsigned freed_page_clock:31; /*!< the value of + buf_pool->freed_page_clock */ + unsigned zip_ssize:PAGE_ZIP_SSIZE_BITS; + /*!< Compressed page size */ + unsigned page_state:BUF_PAGE_STATE_BITS; /*!< Page state */ + unsigned page_type:4; /*!< Page type */ + unsigned num_recs:UNIV_PAGE_SIZE_SHIFT-2; + /*!< Number of records on Page */ + unsigned data_size:UNIV_PAGE_SIZE_SHIFT; + /*!< Sum of the sizes of the records */ + lsn_t newest_mod; /*!< Log sequence number of + the youngest modification */ + lsn_t oldest_mod; /*!< Log sequence number of + the oldest modification */ + index_id_t index_id; /*!< Index ID if a index page */ +}; + +typedef struct buffer_page_info_struct buf_page_info_t; + +/** maximum number of buffer page info we would cache. */ +#define MAX_BUF_INFO_CACHED 10000 + + #define OK(expr) \ if ((expr) != 0) { \ DBUG_RETURN(1); \ @@ -1792,6 +1877,1772 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset = STRUCT_FLD(flags, 0UL), }; +/* Fields of the dynamic table INNODB_BUFFER_POOL_STATS. */ +static ST_FIELD_INFO i_s_innodb_buffer_stats_fields_info[] = +{ +#define IDX_BUF_STATS_POOL_ID 0 + {STRUCT_FLD(field_name, "POOL_ID"), + 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)}, + +#define IDX_BUF_STATS_POOL_SIZE 1 + {STRUCT_FLD(field_name, "POOL_SIZE"), + 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)}, + +#define IDX_BUF_STATS_FREE_BUFFERS 2 + {STRUCT_FLD(field_name, "FREE_BUFFERS"), + 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)}, + +#define IDX_BUF_STATS_LRU_LEN 3 + {STRUCT_FLD(field_name, "DATABASE_PAGES"), + 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)}, + +#define IDX_BUF_STATS_OLD_LRU_LEN 4 + {STRUCT_FLD(field_name, "OLD_DATABASE_PAGES"), + 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)}, + +#define IDX_BUF_STATS_FLUSH_LIST_LEN 5 + {STRUCT_FLD(field_name, "MODIFIED_DATABASE_PAGES"), + 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)}, + +#define IDX_BUF_STATS_PENDING_ZIP 6 + {STRUCT_FLD(field_name, "PENDING_DECOMPRESS"), + 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)}, + +#define IDX_BUF_STATS_PENDING_READ 7 + {STRUCT_FLD(field_name, "PENDING_READS"), + 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)}, + +#define IDX_BUF_STATS_FLUSH_LRU 8 + {STRUCT_FLD(field_name, "PENDING_FLUSH_LRU"), + 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)}, + +#define IDX_BUF_STATS_FLUSH_LIST 9 + {STRUCT_FLD(field_name, "PENDING_FLUSH_LIST"), + 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)}, + +#define IDX_BUF_STATS_PAGE_YOUNG 10 + {STRUCT_FLD(field_name, "PAGES_MADE_YOUNG"), + 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)}, + +#define IDX_BUF_STATS_PAGE_NOT_YOUNG 11 + {STRUCT_FLD(field_name, "PAGES_NOT_MADE_YOUNG"), + 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)}, + +#define IDX_BUF_STATS_PAGE_YOUNG_RATE 12 + {STRUCT_FLD(field_name, "PAGES_MADE_YOUNG_RATE"), + STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), + STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_STATS_PAGE_NOT_YOUNG_RATE 13 + {STRUCT_FLD(field_name, "PAGES_MADE_NOT_YOUNG_RATE"), + STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), + STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_STATS_PAGE_READ 14 + {STRUCT_FLD(field_name, "NUMBER_PAGES_READ"), + 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)}, + +#define IDX_BUF_STATS_PAGE_CREATED 15 + {STRUCT_FLD(field_name, "NUMBER_PAGES_CREATED"), + 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)}, + +#define IDX_BUF_STATS_PAGE_WRITTEN 16 + {STRUCT_FLD(field_name, "NUMBER_PAGES_WRITTEN"), + 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)}, + +#define IDX_BUF_STATS_PAGE_READ_RATE 17 + {STRUCT_FLD(field_name, "PAGES_READ_RATE"), + STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), + STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_STATS_PAGE_CREATE_RATE 18 + {STRUCT_FLD(field_name, "PAGES_CREATE_RATE"), + STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), + STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_STATS_PAGE_WRITTEN_RATE 19 + {STRUCT_FLD(field_name, "PAGES_WRITTEN_RATE"), + STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), + STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_STATS_GET 20 + {STRUCT_FLD(field_name, "NUMBER_PAGES_GET"), + 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)}, + +#define IDX_BUF_STATS_HIT_RATE 21 + {STRUCT_FLD(field_name, "HIT_RATE"), + 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)}, + +#define IDX_BUF_STATS_MADE_YOUNG_PCT 22 + {STRUCT_FLD(field_name, "YOUNG_MAKE_PER_THOUSAND_GETS"), + 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)}, + +#define IDX_BUF_STATS_NOT_MADE_YOUNG_PCT 23 + {STRUCT_FLD(field_name, "NOT_YOUNG_MAKE_PER_THOUSAND_GETS"), + 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)}, + +#define IDX_BUF_STATS_READ_AHREAD 24 + {STRUCT_FLD(field_name, "NUMBER_PAGES_READ_AHEAD"), + 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)}, + +#define IDX_BUF_STATS_READ_AHEAD_EVICTED 25 + {STRUCT_FLD(field_name, "NUMBER_READ_AHEAD_EVICTED"), + 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)}, + +#define IDX_BUF_STATS_READ_AHEAD_RATE 26 + {STRUCT_FLD(field_name, "READ_AHEAD_RATE"), + STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), + STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_STATS_READ_AHEAD_EVICT_RATE 27 + {STRUCT_FLD(field_name, "READ_AHEAD_EVICTED_RATE"), + STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), + STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_STATS_LRU_IO_SUM 28 + {STRUCT_FLD(field_name, "LRU_IO_TOTAL"), + 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)}, + +#define IDX_BUF_STATS_LRU_IO_CUR 29 + {STRUCT_FLD(field_name, "LRU_IO_CURRENT"), + 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)}, + +#define IDX_BUF_STATS_UNZIP_SUM 30 + {STRUCT_FLD(field_name, "UNCOMPRESS_TOTAL"), + 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)}, + +#define IDX_BUF_STATS_UNZIP_CUR 31 + {STRUCT_FLD(field_name, "UNCOMPRESS_CURRENT"), + 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 +}; + +/*******************************************************************//** +Fill Information Schema table INNODB_BUFFER_POOL_STATS for a particular +buffer pool +@return 0 on success, 1 on failure */ +static +int +i_s_innodb_stats_fill( +/*==================*/ + THD* thd, /*!< in: thread */ + TABLE_LIST* tables, /*!< in/out: tables to fill */ + const buf_pool_info_t* info) /*!< in: buffer pool + information */ +{ + TABLE* table; + Field** fields; + + DBUG_ENTER("i_s_innodb_stats_fill"); + + table = tables->table; + + fields = table->field; + + OK(fields[IDX_BUF_STATS_POOL_ID]->store(info->pool_unique_id)); + + OK(fields[IDX_BUF_STATS_POOL_SIZE]->store(info->pool_size)); + + OK(fields[IDX_BUF_STATS_LRU_LEN]->store(info->lru_len)); + + OK(fields[IDX_BUF_STATS_OLD_LRU_LEN]->store(info->old_lru_len)); + + OK(fields[IDX_BUF_STATS_FREE_BUFFERS]->store(info->free_list_len)); + + OK(fields[IDX_BUF_STATS_FLUSH_LIST_LEN]->store( + info->flush_list_len)); + + OK(fields[IDX_BUF_STATS_PENDING_ZIP]->store(info->n_pend_unzip)); + + OK(fields[IDX_BUF_STATS_PENDING_READ]->store(info->n_pend_reads)); + + OK(fields[IDX_BUF_STATS_FLUSH_LRU]->store(info->n_pending_flush_lru)); + + OK(fields[IDX_BUF_STATS_FLUSH_LIST]->store(info->n_pending_flush_list)); + + OK(fields[IDX_BUF_STATS_PAGE_YOUNG]->store(info->n_pages_made_young)); + + OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG]->store( + info->n_pages_not_made_young)); + + OK(fields[IDX_BUF_STATS_PAGE_YOUNG_RATE]->store( + info->page_made_young_rate)); + + OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG_RATE]->store( + info->page_not_made_young_rate)); + + OK(fields[IDX_BUF_STATS_PAGE_READ]->store(info->n_pages_read)); + + OK(fields[IDX_BUF_STATS_PAGE_CREATED]->store(info->n_pages_created)); + + OK(fields[IDX_BUF_STATS_PAGE_WRITTEN]->store(info->n_pages_written)); + + OK(fields[IDX_BUF_STATS_GET]->store(info->n_page_gets)); + + OK(fields[IDX_BUF_STATS_PAGE_READ_RATE]->store(info->pages_read_rate)); + + OK(fields[IDX_BUF_STATS_PAGE_CREATE_RATE]->store(info->pages_created_rate)); + + OK(fields[IDX_BUF_STATS_PAGE_WRITTEN_RATE]->store(info->pages_written_rate)); + + if (info->n_page_get_delta) { + OK(fields[IDX_BUF_STATS_HIT_RATE]->store( + 1000 - (1000 * info->page_read_delta + / info->n_page_get_delta))); + + OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store( + 1000 * info->young_making_delta + / info->n_page_get_delta)); + + OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store( + 1000 * info->not_young_making_delta + / info->n_page_get_delta)); + } else { + OK(fields[IDX_BUF_STATS_HIT_RATE]->store(0)); + OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store(0)); + OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store(0)); + } + + OK(fields[IDX_BUF_STATS_READ_AHREAD]->store(info->n_ra_pages_read)); + + OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICTED]->store( + info->n_ra_pages_evicted)); + + OK(fields[IDX_BUF_STATS_READ_AHEAD_RATE]->store( + info->pages_readahead_rate)); + + OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICT_RATE]->store( + info->pages_evicted_rate)); + + OK(fields[IDX_BUF_STATS_LRU_IO_SUM]->store(info->io_sum)); + + OK(fields[IDX_BUF_STATS_LRU_IO_CUR]->store(info->io_cur)); + + OK(fields[IDX_BUF_STATS_UNZIP_SUM]->store(info->unzip_sum)); + + OK(fields[IDX_BUF_STATS_UNZIP_CUR]->store( info->unzip_cur)); + + DBUG_RETURN(schema_table_store_record(thd, table)); +} + +/*******************************************************************//** +This is the function that loops through each buffer pool and fetch buffer +pool stats to information schema table: I_S_INNODB_BUFFER_POOL_STATS +@return 0 on success, 1 on failure */ +static +int +i_s_innodb_buffer_stats_fill_table( +/*===============================*/ + THD* thd, /*!< in: thread */ + TABLE_LIST* tables, /*!< in/out: tables to fill */ + Item* ) /*!< in: condition (ignored) */ +{ + int status = 0; + buf_pool_info_t* pool_info; + + DBUG_ENTER("i_s_innodb_buffer_fill_general"); + + /* Only allow the PROCESS privilege holder to access the stats */ + if (check_global_access(thd, PROCESS_ACL)) { + DBUG_RETURN(0); + } + + pool_info = (buf_pool_info_t*) mem_zalloc( + srv_buf_pool_instances * sizeof *pool_info); + + /* Walk through each buffer pool */ + for (ulint i = 0; i < srv_buf_pool_instances; i++) { + buf_pool_t* buf_pool; + + buf_pool = buf_pool_from_array(i); + + /* Fetch individual buffer pool info */ + buf_stats_get_pool_info(buf_pool, i, pool_info); + + status = i_s_innodb_stats_fill(thd, tables, &pool_info[i]); + + /* If something goes wrong, break and return */ + if (status) { + break; + } + } + + mem_free(pool_info); + + DBUG_RETURN(status); +} + +/*******************************************************************//** +Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS. +@return 0 on success, 1 on failure */ +static +int +i_s_innodb_buffer_pool_stats_init( +/*==============================*/ + void* p) /*!< in/out: table schema object */ +{ + ST_SCHEMA_TABLE* schema; + + DBUG_ENTER("i_s_innodb_buffer_pool_stats_init"); + + schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p); + + schema->fields_info = i_s_innodb_buffer_stats_fields_info; + schema->fill_table = i_s_innodb_buffer_stats_fill_table; + + DBUG_RETURN(0); +} + +UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_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_BUFFER_POOL_STATS"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB Buffer Pool Statistics 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_buffer_pool_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), + + /* reserved for dependency checking */ + /* void* */ + STRUCT_FLD(__reserved1, NULL), + + /* Plugin flags */ + /* unsigned long */ + STRUCT_FLD(flags, 0UL), +}; + +/* Fields of the dynamic table INNODB_BUFFER_POOL_PAGE. */ +static ST_FIELD_INFO i_s_innodb_buffer_page_fields_info[] = +{ +#define IDX_BUFFER_POOL_ID 0 + {STRUCT_FLD(field_name, "POOL_ID"), + 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)}, + +#define IDX_BUFFER_BLOCK_ID 1 + {STRUCT_FLD(field_name, "BLOCK_ID"), + 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)}, + +#define IDX_BUFFER_PAGE_SPACE 2 + {STRUCT_FLD(field_name, "SPACE"), + 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)}, + +#define IDX_BUFFER_PAGE_NUM 3 + {STRUCT_FLD(field_name, "PAGE_NUMBER"), + 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)}, + +#define IDX_BUFFER_PAGE_TYPE 4 + {STRUCT_FLD(field_name, "PAGE_TYPE"), + STRUCT_FLD(field_length, 64), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUFFER_PAGE_FLUSH_TYPE 5 + {STRUCT_FLD(field_name, "FLUSH_TYPE"), + 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)}, + +#define IDX_BUFFER_PAGE_FIX_COUNT 6 + {STRUCT_FLD(field_name, "FIX_COUNT"), + 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)}, + +#define IDX_BUFFER_PAGE_HASHED 7 + {STRUCT_FLD(field_name, "IS_HASHED"), + STRUCT_FLD(field_length, 3), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUFFER_PAGE_NEWEST_MOD 8 + {STRUCT_FLD(field_name, "NEWEST_MODIFICATION"), + 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)}, + +#define IDX_BUFFER_PAGE_OLDEST_MOD 9 + {STRUCT_FLD(field_name, "OLDEST_MODIFICATION"), + 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)}, + +#define IDX_BUFFER_PAGE_ACCESS_TIME 10 + {STRUCT_FLD(field_name, "ACCESS_TIME"), + 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)}, + +#define IDX_BUFFER_PAGE_TABLE_NAME 11 + {STRUCT_FLD(field_name, "TABLE_NAME"), + STRUCT_FLD(field_length, 1024), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUFFER_PAGE_INDEX_NAME 12 + {STRUCT_FLD(field_name, "INDEX_NAME"), + STRUCT_FLD(field_length, 1024), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUFFER_PAGE_NUM_RECS 13 + {STRUCT_FLD(field_name, "NUMBER_RECORDS"), + 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)}, + +#define IDX_BUFFER_PAGE_DATA_SIZE 14 + {STRUCT_FLD(field_name, "DATA_SIZE"), + 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)}, + +#define IDX_BUFFER_PAGE_ZIP_SIZE 15 + {STRUCT_FLD(field_name, "COMPRESSED_SIZE"), + 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)}, + +#define IDX_BUFFER_PAGE_STATE 16 + {STRUCT_FLD(field_name, "PAGE_STATE"), + STRUCT_FLD(field_length, 64), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUFFER_PAGE_IO_FIX 17 + {STRUCT_FLD(field_name, "IO_FIX"), + STRUCT_FLD(field_length, 64), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUFFER_PAGE_IS_OLD 18 + {STRUCT_FLD(field_name, "IS_OLD"), + STRUCT_FLD(field_length, 3), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUFFER_PAGE_FREE_CLOCK 19 + {STRUCT_FLD(field_name, "FREE_PAGE_CLOCK"), + 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 +}; + +/*******************************************************************//** +Fill Information Schema table INNODB_BUFFER_PAGE with information +cached in the buf_page_info_t array +@return 0 on success, 1 on failure */ +static +int +i_s_innodb_buffer_page_fill( +/*========================*/ + THD* thd, /*!< in: thread */ + TABLE_LIST* tables, /*!< in/out: tables to fill */ + const buf_page_info_t* info_array, /*!< in: array cached page + info */ + ulint num_page, /*!< in: number of page info + cached */ + mem_heap_t* heap) /*!< in: temp heap memory */ +{ + TABLE* table; + Field** fields; + + DBUG_ENTER("i_s_innodb_buffer_page_fill"); + + table = tables->table; + + fields = table->field; + + /* Iterate through the cached array and fill the I_S table rows */ + for (ulint i = 0; i < num_page; i++) { + const buf_page_info_t* page_info; + const char* table_name; + const char* index_name; + const char* state_str; + enum buf_page_state state; + + page_info = info_array + i; + + table_name = NULL; + index_name = NULL; + state_str = NULL; + + OK(fields[IDX_BUFFER_POOL_ID]->store(page_info->pool_id)); + + OK(fields[IDX_BUFFER_BLOCK_ID]->store(page_info->block_id)); + + OK(fields[IDX_BUFFER_PAGE_SPACE]->store(page_info->space_id)); + + OK(fields[IDX_BUFFER_PAGE_NUM]->store(page_info->page_num)); + + OK(field_store_string( + fields[IDX_BUFFER_PAGE_TYPE], + i_s_page_type[page_info->page_type].type_str)); + + OK(fields[IDX_BUFFER_PAGE_FLUSH_TYPE]->store( + page_info->flush_type)); + + OK(fields[IDX_BUFFER_PAGE_FIX_COUNT]->store( + page_info->fix_count)); + + if (page_info->hashed) { + OK(field_store_string( + fields[IDX_BUFFER_PAGE_HASHED], "YES")); + } else { + OK(field_store_string( + fields[IDX_BUFFER_PAGE_HASHED], "NO")); + } + + OK(fields[IDX_BUFFER_PAGE_NEWEST_MOD]->store( + (longlong) page_info->newest_mod, true)); + + OK(fields[IDX_BUFFER_PAGE_OLDEST_MOD]->store( + (longlong) page_info->oldest_mod, true)); + + OK(fields[IDX_BUFFER_PAGE_ACCESS_TIME]->store( + page_info->access_time)); + + /* If this is an index page, fetch the index name + and table name */ + if (page_info->page_type == I_S_PAGE_TYPE_INDEX) { + const dict_index_t* index; + + mutex_enter(&dict_sys->mutex); + index = dict_index_get_if_in_cache_low( + page_info->index_id); + + /* Copy the index/table name under mutex. We + do not want to hold the InnoDB mutex while + filling the IS table */ + if (index) { + const char* name_ptr = index->name; + + if (name_ptr[0] == TEMP_INDEX_PREFIX) { + name_ptr++; + } + + index_name = mem_heap_strdup(heap, name_ptr); + + table_name = mem_heap_strdup(heap, + index->table_name); + + } + + mutex_exit(&dict_sys->mutex); + } + + OK(field_store_string( + fields[IDX_BUFFER_PAGE_TABLE_NAME], table_name)); + + OK(field_store_string( + fields[IDX_BUFFER_PAGE_INDEX_NAME], index_name)); + + OK(fields[IDX_BUFFER_PAGE_NUM_RECS]->store( + page_info->num_recs)); + + OK(fields[IDX_BUFFER_PAGE_DATA_SIZE]->store( + page_info->data_size)); + + OK(fields[IDX_BUFFER_PAGE_ZIP_SIZE]->store( + page_info->zip_ssize + ? (PAGE_ZIP_MIN_SIZE >> 1) << page_info->zip_ssize + : 0)); + +#if BUF_PAGE_STATE_BITS > 3 +# error "BUF_PAGE_STATE_BITS > 3, please ensure that all 1<<BUF_PAGE_STATE_BITS values are checked for" +#endif + state = static_cast<enum buf_page_state>(page_info->page_state); + + switch (state) { + /* First three states are for compression pages and + are not states we would get as we scan pages through + buffer blocks */ + case BUF_BLOCK_ZIP_FREE: + case BUF_BLOCK_ZIP_PAGE: + case BUF_BLOCK_ZIP_DIRTY: + state_str = NULL; + break; + case BUF_BLOCK_NOT_USED: + state_str = "NOT_USED"; + break; + case BUF_BLOCK_READY_FOR_USE: + state_str = "READY_FOR_USE"; + break; + case BUF_BLOCK_FILE_PAGE: + state_str = "FILE_PAGE"; + break; + case BUF_BLOCK_MEMORY: + state_str = "MEMORY"; + break; + case BUF_BLOCK_REMOVE_HASH: + state_str = "REMOVE_HASH"; + break; + }; + + OK(field_store_string(fields[IDX_BUFFER_PAGE_STATE], + state_str)); + + switch (page_info->io_fix) { + case BUF_IO_NONE: + OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX], + "IO_NONE")); + break; + case BUF_IO_READ: + OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX], + "IO_READ")); + break; + case BUF_IO_WRITE: + OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX], + "IO_WRITE")); + break; + case BUF_IO_PIN: + OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX], + "IO_PIN")); + break; + } + + OK(field_store_string(fields[IDX_BUFFER_PAGE_IS_OLD], + (page_info->is_old) ? "YES" : "NO")); + + OK(fields[IDX_BUFFER_PAGE_FREE_CLOCK]->store( + page_info->freed_page_clock)); + + if (schema_table_store_record(thd, table)) { + DBUG_RETURN(1); + } + } + + DBUG_RETURN(0); +} + +/*******************************************************************//** +Set appropriate page type to a buf_page_info_t structure */ +static +void +i_s_innodb_set_page_type( +/*=====================*/ + buf_page_info_t*page_info, /*!< in/out: structure to fill with + scanned info */ + ulint page_type, /*!< in: page type */ + const byte* frame) /*!< in: buffer frame */ +{ + if (page_type == FIL_PAGE_INDEX) { + const page_t* page = (const page_t*) frame; + + /* FIL_PAGE_INDEX is a bit special, its value + is defined as 17855, so we cannot use FIL_PAGE_INDEX + to index into i_s_page_type[] array, its array index + in the i_s_page_type[] array is I_S_PAGE_TYPE_INDEX + (1) */ + page_info->page_type = I_S_PAGE_TYPE_INDEX; + + page_info->index_id = btr_page_get_index_id(page); + + page_info->data_size = (ulint)(page_header_get_field( + page, PAGE_HEAP_TOP) - (page_is_comp(page) + ? PAGE_NEW_SUPREMUM_END + : PAGE_OLD_SUPREMUM_END) + - page_header_get_field(page, PAGE_GARBAGE)); + + page_info->num_recs = page_get_n_recs(page); + } else if (page_type >= I_S_PAGE_TYPE_UNKNOWN) { + /* Encountered an unknown page type */ + page_info->page_type = I_S_PAGE_TYPE_UNKNOWN; + } else { + /* Make sure we get the right index into the + i_s_page_type[] array */ + ut_a(page_type == i_s_page_type[page_type].type_value); + + page_info->page_type = page_type; + } + + if (page_info->page_type == FIL_PAGE_TYPE_ZBLOB + || page_info->page_type == FIL_PAGE_TYPE_ZBLOB2) { + page_info->page_num = mach_read_from_4( + frame + FIL_PAGE_OFFSET); + page_info->space_id = mach_read_from_4( + frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); + } +} +/*******************************************************************//** +Scans pages in the buffer cache, and collect their general information +into the buf_page_info_t array which is zero-filled. So any fields +that are not initialized in the function will default to 0 */ +static +void +i_s_innodb_buffer_page_get_info( +/*============================*/ + const buf_page_t*bpage, /*!< in: buffer pool page to scan */ + ulint pool_id, /*!< in: buffer pool id */ + ulint pos, /*!< in: buffer block position in + buffer pool or in the LRU list */ + buf_page_info_t*page_info) /*!< in: zero filled info structure; + out: structure filled with scanned + info */ +{ + ut_ad(pool_id < MAX_BUFFER_POOLS); + + page_info->pool_id = pool_id; + + page_info->block_id = pos; + + page_info->page_state = buf_page_get_state(bpage); + + /* Only fetch information for buffers that map to a tablespace, + that is, buffer page with state BUF_BLOCK_ZIP_PAGE, + BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_FILE_PAGE */ + if (buf_page_in_file(bpage)) { + const byte* frame; + ulint page_type; + + page_info->space_id = buf_page_get_space(bpage); + + page_info->page_num = buf_page_get_page_no(bpage); + + page_info->flush_type = bpage->flush_type; + + page_info->fix_count = bpage->buf_fix_count; + + page_info->newest_mod = bpage->newest_modification; + + page_info->oldest_mod = bpage->oldest_modification; + + page_info->access_time = bpage->access_time; + + page_info->zip_ssize = bpage->zip.ssize; + + page_info->io_fix = bpage->io_fix; + + page_info->is_old = bpage->old; + + page_info->freed_page_clock = bpage->freed_page_clock; + + if (page_info->page_state == BUF_BLOCK_FILE_PAGE) { + const buf_block_t*block; + + block = reinterpret_cast<const buf_block_t*>(bpage); + frame = block->frame; + page_info->hashed = (block->index != NULL); + } else { + ut_ad(page_info->zip_ssize); + frame = bpage->zip.data; + } + + page_type = fil_page_get_type(frame); + + i_s_innodb_set_page_type(page_info, page_type, frame); + } else { + page_info->page_type = I_S_PAGE_TYPE_UNKNOWN; + } +} + +/*******************************************************************//** +This is the function that goes through each block of the buffer pool +and fetch information to information schema tables: INNODB_BUFFER_PAGE. +@return 0 on success, 1 on failure */ +static +int +i_s_innodb_fill_buffer_pool( +/*========================*/ + THD* thd, /*!< in: thread */ + TABLE_LIST* tables, /*!< in/out: tables to fill */ + buf_pool_t* buf_pool, /*!< in: buffer pool to scan */ + const ulint pool_id) /*!< in: buffer pool id */ +{ + int status = 0; + mem_heap_t* heap; + + DBUG_ENTER("i_s_innodb_fill_buffer_pool"); + + heap = mem_heap_create(10000); + + /* Go through each chunk of buffer pool. Currently, we only + have one single chunk for each buffer pool */ + for (ulint n = 0; n < buf_pool->n_chunks; n++) { + const buf_block_t* block; + ulint n_blocks; + buf_page_info_t* info_buffer; + ulint num_page; + ulint mem_size; + ulint chunk_size; + ulint num_to_process = 0; + ulint block_id = 0; + + /* Get buffer block of the nth chunk */ + block = buf_get_nth_chunk_block(buf_pool, n, &chunk_size); + num_page = 0; + + while (chunk_size > 0) { + /* we cache maximum MAX_BUF_INFO_CACHED number of + buffer page info */ + num_to_process = ut_min(chunk_size, + MAX_BUF_INFO_CACHED); + + mem_size = num_to_process * sizeof(buf_page_info_t); + + /* For each chunk, we'll pre-allocate information + structures to cache the page information read from + the buffer pool. Doing so before obtain any mutex */ + info_buffer = (buf_page_info_t*) mem_heap_zalloc( + heap, mem_size); + + /* Obtain appropriate mutexes. Since this is diagnostic + buffer pool info printout, we are not required to + preserve the overall consistency, so we can + release mutex periodically */ + buf_pool_mutex_enter(buf_pool); + + /* GO through each block in the chunk */ + for (n_blocks = num_to_process; n_blocks--; block++) { + i_s_innodb_buffer_page_get_info( + &block->page, pool_id, block_id, + info_buffer + num_page); + block_id++; + num_page++; + } + + buf_pool_mutex_exit(buf_pool); + + /* Fill in information schema table with information + just collected from the buffer chunk scan */ + status = i_s_innodb_buffer_page_fill( + thd, tables, info_buffer, + num_page, heap); + + /* If something goes wrong, break and return */ + if (status) { + break; + } + + mem_heap_empty(heap); + chunk_size -= num_to_process; + num_page = 0; + } + } + + mem_heap_free(heap); + + DBUG_RETURN(status); +} + +/*******************************************************************//** +Fill page information for pages in InnoDB buffer pool to the +dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE +@return 0 on success, 1 on failure */ +static +int +i_s_innodb_buffer_page_fill_table( +/*==============================*/ + THD* thd, /*!< in: thread */ + TABLE_LIST* tables, /*!< in/out: tables to fill */ + Item* ) /*!< in: condition (ignored) */ +{ + int status = 0; + + DBUG_ENTER("i_s_innodb_buffer_page_fill_table"); + + /* deny access to user without PROCESS privilege */ + if (check_global_access(thd, PROCESS_ACL)) { + DBUG_RETURN(0); + } + + /* Walk through each buffer pool */ + for (ulint i = 0; i < srv_buf_pool_instances; i++) { + buf_pool_t* buf_pool; + + buf_pool = buf_pool_from_array(i); + + /* Fetch information from pages in this buffer pool, + and fill the corresponding I_S table */ + status = i_s_innodb_fill_buffer_pool(thd, tables, buf_pool, i); + + /* If something wrong, break and return */ + if (status) { + break; + } + } + + DBUG_RETURN(status); +} + +/*******************************************************************//** +Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE. +@return 0 on success, 1 on failure */ +static +int +i_s_innodb_buffer_page_init( +/*========================*/ + void* p) /*!< in/out: table schema object */ +{ + ST_SCHEMA_TABLE* schema; + + DBUG_ENTER("i_s_innodb_buffer_page_init"); + + schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p); + + schema->fields_info = i_s_innodb_buffer_page_fields_info; + schema->fill_table = i_s_innodb_buffer_page_fill_table; + + DBUG_RETURN(0); +} + +UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_page = +{ + /* 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_PAGE"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB Buffer Page 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_buffer_page_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), + + /* reserved for dependency checking */ + /* void* */ + STRUCT_FLD(__reserved1, NULL), + + /* Plugin flags */ + /* unsigned long */ + STRUCT_FLD(flags, 0UL), +}; + +static ST_FIELD_INFO i_s_innodb_buf_page_lru_fields_info[] = +{ +#define IDX_BUF_LRU_POOL_ID 0 + {STRUCT_FLD(field_name, "POOL_ID"), + 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)}, + +#define IDX_BUF_LRU_POS 1 + {STRUCT_FLD(field_name, "LRU_POSITION"), + 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)}, + +#define IDX_BUF_LRU_PAGE_SPACE 2 + {STRUCT_FLD(field_name, "SPACE"), + 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)}, + +#define IDX_BUF_LRU_PAGE_NUM 3 + {STRUCT_FLD(field_name, "PAGE_NUMBER"), + 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)}, + +#define IDX_BUF_LRU_PAGE_TYPE 4 + {STRUCT_FLD(field_name, "PAGE_TYPE"), + STRUCT_FLD(field_length, 64), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_LRU_PAGE_FLUSH_TYPE 5 + {STRUCT_FLD(field_name, "FLUSH_TYPE"), + 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)}, + +#define IDX_BUF_LRU_PAGE_FIX_COUNT 6 + {STRUCT_FLD(field_name, "FIX_COUNT"), + 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)}, + +#define IDX_BUF_LRU_PAGE_HASHED 7 + {STRUCT_FLD(field_name, "IS_HASHED"), + STRUCT_FLD(field_length, 3), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_LRU_PAGE_NEWEST_MOD 8 + {STRUCT_FLD(field_name, "NEWEST_MODIFICATION"), + 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)}, + +#define IDX_BUF_LRU_PAGE_OLDEST_MOD 9 + {STRUCT_FLD(field_name, "OLDEST_MODIFICATION"), + 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)}, + +#define IDX_BUF_LRU_PAGE_ACCESS_TIME 10 + {STRUCT_FLD(field_name, "ACCESS_TIME"), + 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)}, + +#define IDX_BUF_LRU_PAGE_TABLE_NAME 11 + {STRUCT_FLD(field_name, "TABLE_NAME"), + STRUCT_FLD(field_length, 1024), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_LRU_PAGE_INDEX_NAME 12 + {STRUCT_FLD(field_name, "INDEX_NAME"), + STRUCT_FLD(field_length, 1024), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_LRU_PAGE_NUM_RECS 13 + {STRUCT_FLD(field_name, "NUMBER_RECORDS"), + 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)}, + +#define IDX_BUF_LRU_PAGE_DATA_SIZE 14 + {STRUCT_FLD(field_name, "DATA_SIZE"), + 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)}, + +#define IDX_BUF_LRU_PAGE_ZIP_SIZE 15 + {STRUCT_FLD(field_name, "COMPRESSED_SIZE"), + 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)}, + +#define IDX_BUF_LRU_PAGE_STATE 16 + {STRUCT_FLD(field_name, "COMPRESSED"), + STRUCT_FLD(field_length, 3), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_LRU_PAGE_IO_FIX 17 + {STRUCT_FLD(field_name, "IO_FIX"), + STRUCT_FLD(field_length, 64), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_LRU_PAGE_IS_OLD 18 + {STRUCT_FLD(field_name, "IS_OLD"), + STRUCT_FLD(field_length, 3), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_BUF_LRU_PAGE_FREE_CLOCK 19 + {STRUCT_FLD(field_name, "FREE_PAGE_CLOCK"), + 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 +}; + +/*******************************************************************//** +Fill Information Schema table INNODB_BUFFER_PAGE_LRU with information +cached in the buf_page_info_t array +@return 0 on success, 1 on failure */ +static +int +i_s_innodb_buf_page_lru_fill( +/*=========================*/ + THD* thd, /*!< in: thread */ + TABLE_LIST* tables, /*!< in/out: tables to fill */ + const buf_page_info_t* info_array, /*!< in: array cached page + info */ + ulint num_page) /*!< in: number of page info + cached */ +{ + TABLE* table; + Field** fields; + mem_heap_t* heap; + + DBUG_ENTER("i_s_innodb_buf_page_lru_fill"); + + table = tables->table; + + fields = table->field; + + heap = mem_heap_create(1000); + + /* Iterate through the cached array and fill the I_S table rows */ + for (ulint i = 0; i < num_page; i++) { + const buf_page_info_t* page_info; + const char* table_name; + const char* index_name; + const char* state_str; + enum buf_page_state state; + + table_name = NULL; + index_name = NULL; + state_str = NULL; + + page_info = info_array + i; + + OK(fields[IDX_BUF_LRU_POOL_ID]->store(page_info->pool_id)); + + OK(fields[IDX_BUF_LRU_POS]->store(page_info->block_id)); + + OK(fields[IDX_BUF_LRU_PAGE_SPACE]->store(page_info->space_id)); + + OK(fields[IDX_BUF_LRU_PAGE_NUM]->store(page_info->page_num)); + + OK(field_store_string( + fields[IDX_BUF_LRU_PAGE_TYPE], + i_s_page_type[page_info->page_type].type_str)); + + OK(fields[IDX_BUF_LRU_PAGE_FLUSH_TYPE]->store( + page_info->flush_type)); + + OK(fields[IDX_BUF_LRU_PAGE_FIX_COUNT]->store( + page_info->fix_count)); + + if (page_info->hashed) { + OK(field_store_string( + fields[IDX_BUF_LRU_PAGE_HASHED], "YES")); + } else { + OK(field_store_string( + fields[IDX_BUF_LRU_PAGE_HASHED], "NO")); + } + + OK(fields[IDX_BUF_LRU_PAGE_NEWEST_MOD]->store( + page_info->newest_mod, true)); + + OK(fields[IDX_BUF_LRU_PAGE_OLDEST_MOD]->store( + page_info->oldest_mod, true)); + + OK(fields[IDX_BUF_LRU_PAGE_ACCESS_TIME]->store( + page_info->access_time)); + + /* If this is an index page, fetch the index name + and table name */ + if (page_info->page_type == I_S_PAGE_TYPE_INDEX) { + const dict_index_t* index; + + mutex_enter(&dict_sys->mutex); + index = dict_index_get_if_in_cache_low( + page_info->index_id); + + /* Copy the index/table name under mutex. We + do not want to hold the InnoDB mutex while + filling the IS table */ + if (index) { + const char* name_ptr = index->name; + + if (name_ptr[0] == TEMP_INDEX_PREFIX) { + name_ptr++; + } + + index_name = mem_heap_strdup(heap, name_ptr); + + table_name = mem_heap_strdup(heap, + index->table_name); + } + + mutex_exit(&dict_sys->mutex); + } + + OK(field_store_string( + fields[IDX_BUF_LRU_PAGE_TABLE_NAME], table_name)); + + OK(field_store_string( + fields[IDX_BUF_LRU_PAGE_INDEX_NAME], index_name)); + OK(fields[IDX_BUF_LRU_PAGE_NUM_RECS]->store( + page_info->num_recs)); + + OK(fields[IDX_BUF_LRU_PAGE_DATA_SIZE]->store( + page_info->data_size)); + + OK(fields[IDX_BUF_LRU_PAGE_ZIP_SIZE]->store( + page_info->zip_ssize ? + 512 << page_info->zip_ssize : 0)); + + state = static_cast<enum buf_page_state>(page_info->page_state); + + switch (state) { + /* Compressed page */ + case BUF_BLOCK_ZIP_PAGE: + case BUF_BLOCK_ZIP_DIRTY: + state_str = "YES"; + break; + /* Uncompressed page */ + case BUF_BLOCK_FILE_PAGE: + state_str = "NO"; + break; + /* We should not see following states */ + case BUF_BLOCK_ZIP_FREE: + case BUF_BLOCK_READY_FOR_USE: + case BUF_BLOCK_NOT_USED: + case BUF_BLOCK_MEMORY: + case BUF_BLOCK_REMOVE_HASH: + state_str = NULL; + break; + }; + + OK(field_store_string(fields[IDX_BUF_LRU_PAGE_STATE], + state_str)); + + switch (page_info->io_fix) { + case BUF_IO_NONE: + OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX], + "IO_NONE")); + break; + case BUF_IO_READ: + OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX], + "IO_READ")); + break; + case BUF_IO_WRITE: + OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX], + "IO_WRITE")); + break; + } + + OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IS_OLD], + (page_info->is_old) ? "YES" : "NO")); + + OK(fields[IDX_BUF_LRU_PAGE_FREE_CLOCK]->store( + page_info->freed_page_clock)); + + if (schema_table_store_record(thd, table)) { + mem_heap_free(heap); + DBUG_RETURN(1); + } + + mem_heap_empty(heap); + } + + mem_heap_free(heap); + + DBUG_RETURN(0); +} + +/*******************************************************************//** +This is the function that goes through buffer pool's LRU list +and fetch information to INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU. +@return 0 on success, 1 on failure */ +static +int +i_s_innodb_fill_buffer_lru( +/*=======================*/ + THD* thd, /*!< in: thread */ + TABLE_LIST* tables, /*!< in/out: tables to fill */ + buf_pool_t* buf_pool, /*!< in: buffer pool to scan */ + const ulint pool_id) /*!< in: buffer pool id */ +{ + int status = 0; + buf_page_info_t* info_buffer; + ulint lru_pos = 0; + const buf_page_t* bpage; + ulint lru_len; + + DBUG_ENTER("i_s_innodb_fill_buffer_lru"); + + /* Obtain buf_pool mutex before allocate info_buffer, since + UT_LIST_GET_LEN(buf_pool->LRU) could change */ + buf_pool_mutex_enter(buf_pool); + + lru_len = UT_LIST_GET_LEN(buf_pool->LRU); + + /* Print error message if malloc fail */ + info_buffer = (buf_page_info_t*) my_malloc( + lru_len * sizeof *info_buffer, MYF(MY_WME)); + + if (!info_buffer) { + status = 1; + goto exit; + } + + memset(info_buffer, 0, lru_len * sizeof *info_buffer); + + /* Walk through Pool's LRU list and print the buffer page + information */ + bpage = UT_LIST_GET_LAST(buf_pool->LRU); + + while (bpage != NULL) { + /* Use the same function that collect buffer info for + INNODB_BUFFER_PAGE to get buffer page info */ + i_s_innodb_buffer_page_get_info(bpage, pool_id, lru_pos, + (info_buffer + lru_pos)); + + bpage = UT_LIST_GET_PREV(LRU, bpage); + + lru_pos++; + } + + ut_ad(lru_pos == lru_len); + ut_ad(lru_pos == UT_LIST_GET_LEN(buf_pool->LRU)); + +exit: + buf_pool_mutex_exit(buf_pool); + + if (info_buffer) { + status = i_s_innodb_buf_page_lru_fill( + thd, tables, info_buffer, lru_len); + + my_free(info_buffer); + } + + DBUG_RETURN(status); +} + +/*******************************************************************//** +Fill page information for pages in InnoDB buffer pool to the +dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU +@return 0 on success, 1 on failure */ +static +int +i_s_innodb_buf_page_lru_fill_table( +/*===============================*/ + THD* thd, /*!< in: thread */ + TABLE_LIST* tables, /*!< in/out: tables to fill */ + Item* ) /*!< in: condition (ignored) */ +{ + int status = 0; + + DBUG_ENTER("i_s_innodb_buf_page_lru_fill_table"); + + /* deny access to any users that do not hold PROCESS_ACL */ + if (check_global_access(thd, PROCESS_ACL)) { + DBUG_RETURN(0); + } + + /* Walk through each buffer pool */ + for (ulint i = 0; i < srv_buf_pool_instances; i++) { + buf_pool_t* buf_pool; + + buf_pool = buf_pool_from_array(i); + + /* Fetch information from pages in this buffer pool's LRU list, + and fill the corresponding I_S table */ + status = i_s_innodb_fill_buffer_lru(thd, tables, buf_pool, i); + + /* If something wrong, break and return */ + if (status) { + break; + } + } + + DBUG_RETURN(status); +} + +/*******************************************************************//** +Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU. +@return 0 on success, 1 on failure */ +static +int +i_s_innodb_buffer_page_lru_init( +/*============================*/ + void* p) /*!< in/out: table schema object */ +{ + ST_SCHEMA_TABLE* schema; + + DBUG_ENTER("i_s_innodb_buffer_page_lru_init"); + + schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p); + + schema->fields_info = i_s_innodb_buf_page_lru_fields_info; + schema->fill_table = i_s_innodb_buf_page_lru_fill_table; + + DBUG_RETURN(0); +} + +UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_page_lru = +{ + /* 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_PAGE_LRU"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, plugin_author), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB Buffer Page in LRU"), + + /* 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_page_lru_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), + + /* reserved for dependency checking */ + /* void* */ + STRUCT_FLD(__reserved1, NULL), + + /* Plugin flags */ + /* unsigned long */ + STRUCT_FLD(flags, 0UL), +}; + /*******************************************************************//** Unbind a dynamic INFORMATION_SCHEMA table. @return 0 on success */ @@ -1807,3 +3658,5 @@ i_s_common_deinit( DBUG_RETURN(0); } + + diff --git a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h index dc0deef119b..6b95ce25b58 100644 --- a/storage/innobase/handler/i_s.h +++ b/storage/innobase/handler/i_s.h @@ -35,5 +35,8 @@ 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_buffer_page; +extern struct st_mysql_plugin i_s_innodb_buffer_page_lru; +extern struct st_mysql_plugin i_s_innodb_buffer_stats;; #endif /* i_s_h */ diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index e534e165c0c..c7887afef92 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -3604,11 +3604,18 @@ bitmap_fail: 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/include/buf0buf.h b/storage/innobase/include/buf0buf.h index a39592943d8..fd8620eab3b 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -68,7 +68,10 @@ Created 11/5/1995 Heikki Tuuri position of the block. */ /* @} */ -#define MAX_BUFFER_POOLS 64 /*!< The maximum number of buffer +#define MAX_BUFFER_POOLS_BITS 6 /*!< Number of bits to representing + a buffer pool ID */ +#define MAX_BUFFER_POOLS (1 << MAX_BUFFER_POOLS_BITS) + /*!< The maximum number of buffer pools that can be defined */ #define BUF_POOL_WATCH_SIZE 1 /*!< Maximum number of concurrent @@ -758,6 +761,18 @@ void buf_print_io( /*=========*/ FILE* file); /*!< in: file where to print */ +/*******************************************************************//** +Collect buffer pool stats information for a buffer pool. Also +record aggregated stats if there are more than one buffer pool +in the server */ +UNIV_INTERN +void +buf_stats_get_pool_info( +/*====================*/ + buf_pool_t* buf_pool, /*!< in: buffer pool */ + ulint pool_id, /*!< in: buffer pool ID */ + buf_pool_info_t* all_pool_info); /*!< in/out: buffer pool info + to fill */ /*********************************************************************//** Returns the ratio in percents of modified pages in the buffer pool / database pages in the buffer pool. @@ -1325,12 +1340,25 @@ void buf_get_total_stat( /*===============*/ buf_pool_stat_t*tot_stat); /*!< out: buffer pool stats */ +/*********************************************************************//** +Get the nth chunk's buffer block in the specified buffer pool. +@return the nth chunk's buffer block. */ +UNIV_INLINE +buf_block_t* +buf_get_nth_chunk_block( +/*====================*/ + const buf_pool_t* buf_pool, /*!< in: buffer pool instance */ + ulint n, /*!< in: nth chunk in the buffer pool */ + ulint* chunk_size); /*!< in: chunk size */ #endif /* !UNIV_HOTBACKUP */ /** The common buffer control block structure for compressed and uncompressed frames */ +/** Number of bits used for buffer page states. */ +#define BUF_PAGE_STATE_BITS 3 + struct buf_page_struct{ /** @name General fields None of these bit-fields must be modified without holding @@ -1345,7 +1373,8 @@ struct buf_page_struct{ unsigned offset:32; /*!< page number; also protected by buf_pool->mutex. */ - unsigned state:3; /*!< state of the control block; also + unsigned state:BUF_PAGE_STATE_BITS; + /*!< state of the control block; also protected by buf_pool->mutex. State transitions from BUF_BLOCK_READY_FOR_USE to diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index 0d9687e6b2a..84c0ab9d610 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -36,6 +36,15 @@ Created 11/5/1995 Heikki Tuuri #include "buf0lru.h" #include "buf0rea.h" +/** A chunk of buffers. The buffer pool is allocated in chunks. */ +struct buf_chunk_struct{ + ulint mem_size; /*!< allocated size of the chunk */ + ulint size; /*!< size of frames[] and blocks[] */ + void* mem; /*!< pointer to the memory area which + was allocated for the frames */ + buf_block_t* blocks; /*!< array of buffer control blocks */ +}; + /*********************************************************************//** Gets the current size of buffer buf_pool in bytes. @return size in bytes */ @@ -1276,4 +1285,21 @@ buf_pool_mutex_exit_all(void) buf_pool_mutex_exit(buf_pool); } } +/*********************************************************************//** +Get the nth chunk's buffer block in the specified buffer pool. +@return the nth chunk's buffer block. */ +UNIV_INLINE +buf_block_t* +buf_get_nth_chunk_block( +/*====================*/ + const buf_pool_t* buf_pool, /*!< in: buffer pool instance */ + ulint n, /*!< in: nth chunk in the buffer pool */ + ulint* chunk_size) /*!< in: chunk size */ +{ + const buf_chunk_t* chunk; + + chunk = buf_pool->chunks + n; + *chunk_size = chunk->size; + return(chunk->blocks); +} #endif /* !UNIV_HOTBACKUP */ diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 610bd4b0e5c..ed47ccff052 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -142,6 +142,8 @@ extern fil_addr_t fil_addr_null; #define FIL_PAGE_TYPE_BLOB 10 /*!< Uncompressed BLOB page */ #define FIL_PAGE_TYPE_ZBLOB 11 /*!< First compressed BLOB page */ #define FIL_PAGE_TYPE_ZBLOB2 12 /*!< Subsequent compressed BLOB page */ +#define FIL_PAGE_TYPE_LAST FIL_PAGE_TYPE_ZBLOB2 + /*!< Last page type */ /* @} */ /** Space types @{ */ diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index 30250d4fd27..5524272d811 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -41,6 +41,9 @@ Created 12/9/1995 Heikki Tuuri #include "sync0rw.h" #endif /* !UNIV_HOTBACKUP */ +/* Type used for all log sequence number storage and arithmetics */ +typedef ib_uint64_t lsn_t; + /** Redo log buffer */ typedef struct log_struct log_t; /** Redo log group */ diff --git a/storage/innobase/page/page0page.c b/storage/innobase/page/page0page.c index 5f0380cb55f..946ec0e1c43 100644 --- a/storage/innobase/page/page0page.c +++ b/storage/innobase/page/page0page.c @@ -781,12 +781,18 @@ page_copy_rec_list_start( if (UNIV_LIKELY_NULL(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 @@ -807,15 +813,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.c b/storage/innobase/row/row0ins.c index da0ab015642..0b9993e2969 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -2215,9 +2215,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.c b/storage/innobase/row/row0merge.c index 750f9d72cf2..7c9fb8812e6 100644 --- a/storage/innobase/row/row0merge.c +++ b/storage/innobase/row/row0merge.c @@ -1235,11 +1235,25 @@ row_merge_read_clustered_index( goto err_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 2817e11681c..9ca198873d1 100644 --- a/storage/maria/CMakeLists.txt +++ b/storage/maria/CMakeLists.txt @@ -68,7 +68,7 @@ SET_TARGET_PROPERTIES(aria_dump_log PROPERTIES COMPILE_FLAGS "-DMARIA_DUMP_LOG") MYSQL_ADD_EXECUTABLE(aria_pack maria_pack.c COMPONENT Server) TARGET_LINK_LIBRARIES(aria_pack aria) -IF(WITH_UNIT_TESTS AND FALSE) +IF(WITH_UNIT_TESTS) ADD_EXECUTABLE(ma_test1 ma_test1.c) TARGET_LINK_LIBRARIES(ma_test1 aria) 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/maria/ma_test_all.sh b/storage/maria/ma_test_all.sh index 041fbf3abe6..4e9be4a5beb 100755 --- a/storage/maria/ma_test_all.sh +++ b/storage/maria/ma_test_all.sh @@ -7,13 +7,22 @@ # # +PRG='unittest/ma_test_all-t' +UTST='../../unittest/unit.pl' + +if [ ! -x $PRG ] ; then + DIR=`dirname $0` + PRG="$DIR/unittest/ma_test_all-t" + UTST="$DIR/../../unittest/unit.pl" +fi + if test -n "$1"; then # unit.pl can't pass options to ma_test_all-t, so if anything # was passed as an argument, assume the purpose was to pass # them to ma_test_all-t and call it directly - unittest/ma_test_all-t $@ + $PRG $@ else - perl ../../unittest/unit.pl run unittest/ma_test_all-t + perl $UTST run $PRG fi diff --git a/storage/myisam/CMakeLists.txt b/storage/myisam/CMakeLists.txt index 97c1bc78d95..f58c942b4d7 100644 --- a/storage/myisam/CMakeLists.txt +++ b/storage/myisam/CMakeLists.txt @@ -46,7 +46,7 @@ TARGET_LINK_LIBRARIES(myisamlog myisam) MYSQL_ADD_EXECUTABLE(myisampack myisampack.c COMPONENT Server) TARGET_LINK_LIBRARIES(myisampack myisam) -IF(WITH_UNIT_TESTS AND FALSE) +IF(WITH_UNIT_TESTS) ADD_EXECUTABLE(mi_test1 mi_test1.c) TARGET_LINK_LIBRARIES(mi_test1 myisam) diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 73e0fadd530..df534242f87 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/myisam/mi_test_all.sh b/storage/myisam/mi_test_all.sh index 641f1cc0a35..c9c89a9ecac 100755 --- a/storage/myisam/mi_test_all.sh +++ b/storage/myisam/mi_test_all.sh @@ -99,7 +99,7 @@ if test -f mi_test1$MACH ; then suffix=$MACH ; else suffix=""; fi # check of myisampack / myisamchk ./myisampack$suffix --force -s test1 # Ignore error for index file -./myisamchk$suffix -es test1 2>&1 >& /dev/null +./myisamchk$suffix -es test1 2>&1 > /dev/null ./myisamchk$suffix -rqs test1 ./myisamchk$suffix -es test1 ./myisamchk$suffix -rs test1 diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt index 1d2b0b29dea..4c098049fd4 100644 --- a/storage/xtradb/CMakeLists.txt +++ b/storage/xtradb/CMakeLists.txt @@ -91,12 +91,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( @@ -240,7 +269,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 e6c1f97debc..4258299c486 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -390,7 +390,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 */ @@ -400,7 +401,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 */ @@ -1715,6 +1717,15 @@ innobase_next_autoinc( ut_a(block > 0); ut_a(max_value > 0); + /* + Allow auto_increment to go over max_value up to max ulonglong. + This allows us to detect that all values are exhausted. + If we don't do this, we will return max_value several times + and get duplicate key errors instead of auto increment value + out of range. + */ + max_value= (~(ulonglong) 0); + /* Current value should never be greater than the maximum. */ ut_a(current <= max_value); @@ -6439,7 +6450,10 @@ no_commit: goto report_error; } - /* MySQL errors are passed straight back. */ + /* MySQL errors are passed straight back. except for + HA_ERR_AUTO_INC_READ_FAILED. This can only happen + for values out of range. + */ error_result = (int) error; goto func_exit; } @@ -11986,13 +12000,17 @@ ha_innobase::get_auto_increment( /* Not in the middle of a mult-row INSERT. */ } else if (prebuilt->autoinc_last_value == 0) { set_if_bigger(*first_value, autoinc); - /* Check for -ve values. */ - } else if (*first_value > col_max_value && trx->n_autoinc_rows > 0) { - /* Set to next logical value. */ - ut_a(autoinc > trx->n_autoinc_rows); - *first_value = (autoinc - trx->n_autoinc_rows) - 1; } + if (*first_value > col_max_value) + { + /* Out of range number. Let handler::update_auto_increment() + take care of this */ + prebuilt->autoinc_last_value = 0; + dict_table_autoinc_unlock(prebuilt->table); + *nb_reserved_values = 0; + return; + } *nb_reserved_values = trx->n_autoinc_rows; /* With old style AUTOINC locking we only update the table's @@ -12001,7 +12019,7 @@ ha_innobase::get_auto_increment( ulonglong current; ulonglong next_value; - current = *first_value > col_max_value ? autoinc : *first_value; + current = *first_value; /* Compute the last value in the interval */ next_value = innobase_next_autoinc( @@ -13644,9 +13662,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 @@ -13849,6 +13867,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, @@ -14047,7 +14077,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); @@ -14069,7 +14099,7 @@ static MYSQL_SYSVAR_ENUM(corrupt_table_action, srv_pass_corrupt_table, "Warn corruptions of user tables as 'corrupt table' instead of not crashing itself, " "when used with file_per_table. " "All file io for the datafile after detected as corrupt are disabled, " - "except for the deletion.", + "except for the deletion. Possible options are 'assert', 'warn' & 'salvage'", NULL, NULL, 0, &corrupt_table_action_typelib); static MYSQL_SYSVAR_ULINT(lazy_drop_table, srv_lazy_drop_table, @@ -14134,8 +14164,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), @@ -14167,6 +14197,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 */ @@ -14207,32 +14239,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 4d9dafd8436..e07a84b0789 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; @@ -406,6 +419,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 */ @@ -701,6 +715,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 30b43d43da7..b42c6300ef5 100644 --- a/storage/xtradb/os/os0file.c +++ b/storage/xtradb/os/os0file.c @@ -164,6 +164,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 */ @@ -2166,6 +2167,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 598e0505506..91ee6197d56 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" @@ -180,6 +181,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 @@ -782,6 +787,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 @@ -1121,6 +1130,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; @@ -3144,6 +3156,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 4d7b1de6cb1..aeedd652d73 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -267,6 +267,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 @@ -427,6 +430,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 @@ -510,6 +523,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 @@ -1204,6 +1224,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 Dec 07 2011 Alexey Yurchenko <alexey.yurchenko@codership.com> - wsrep-related cleanups. 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 a0b18f1f717..95fc61f2b72 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 a1c2010912b..8da9b7dca26 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); } @@ -216,6 +220,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; |