diff --git a/.clang-format b/.clang-format index 7ce45951173..3633507cb13 100644 --- a/.clang-format +++ b/.clang-format @@ -70,7 +70,6 @@ IndentPPDirectives: None IndentWidth: 2 IndentWrappedFunctionNames: false KeepEmptyLinesAtTheStartOfBlocks: true -Language: Cpp MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 32049e9484d..73009a0bf76 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -508,9 +508,9 @@ mini-benchmark: - | mariadb --skip-column-names -e "SELECT @@version, @@version_comment" | tee /tmp/version grep $MARIADB_MAJOR_VERSION /tmp/version || echo "MariaDB didn't install properly" - - yum install -y sysbench procps-ng perf util-linux || yum install -y https://kojipkgs.fedoraproject.org//packages/luajit/2.0.4/3.el7/x86_64/luajit-2.0.4-3.el7.x86_64.rpm https://kojipkgs.fedoraproject.org//packages/sysbench/1.0.17/2.el7/x86_64/sysbench-1.0.17-2.el7.x86_64.rpm https://kojipkgs.fedoraproject.org//packages/ck/0.5.2/2.el7/x86_64/ck-0.5.2-2.el7.x86_64.rpm + - yum install -y sysbench procps-ng perf flamegraph flamegraph-stackcollapse-perf util-linux dnf-utils - /usr/share/mariadb/mini-benchmark - - cp -av */sysbench-run-*.log */metrics.txt .. # Move files one level down so they can be saved as artifacts + - cp -av */sysbench-run-*.log */metrics.txt . # Move files one level down so they can be saved as artifacts artifacts: when: always paths: diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 0defa2d41f1..5b02a8aaa24 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -267,6 +267,12 @@ if test `$CC -v 2>&1 | tail -1 | sed 's/ .*$//'` = 'gcc' ; then fi fi +if test `$CC -v 2>&1 | head -1 | sed 's/ .*$//'` = 'clang' ; then + dbug_cflags="$dbug_cflags -Wframe-larger-than=16384 -fno-inline" + c_warnings="$c_warnings -Wframe-larger-than=16384" + cxx_warnings="$cxx_warnings -Wframe-larger-than=16384" +fi + # If ccache (a compiler cache which reduces build time) # (http://samba.org/ccache) is installed, use it. diff --git a/CMakeLists.txt b/CMakeLists.txt index ba1f422f602..1a555aa27fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ ENDIF() # in RPM's: #set(CPACK_RPM_SPEC_MORE_DEFINE "%define __spec_install_post /bin/true") -FOREACH(p CMP0022 CMP0046 CMP0040 CMP0048 CMP0054 CMP0075 CMP0069 CMP0135) +FOREACH(p CMP0022 CMP0046 CMP0040 CMP0048 CMP0054 CMP0074 CMP0075 CMP0069 CMP0135) IF(POLICY ${p}) CMAKE_POLICY(SET ${p} NEW) ENDIF() @@ -188,7 +188,7 @@ ENDIF() OPTION (WITH_UNIT_TESTS "Compile MySQL with unit tests" ON) IF (WITHOUT_SERVER) - SET (SKIP_COMPONENTS "Server|IniFiles|SuportFiles|Readme") + SET (SKIP_COMPONENTS "Server|IniFiles|SupportFiles|Readme") ELSE() SET (SKIP_COMPONENTS "N-O-N-E") ENDIF() @@ -200,8 +200,9 @@ OPTION(NOT_FOR_DISTRIBUTION "Allow linking with GPLv2-incompatible system librar # Can be switched on only for debug build. # OPTION(WITH_PROTECT_STATEMENT_MEMROOT "Enable protection of statement's memory root after first SP/PS execution. Turned into account only for debug build" OFF) -IF (CMAKE_BUILD_TYPE MATCHES "Debug" AND WITH_PROTECT_STATEMENT_MEMROOT) - ADD_DEFINITIONS(-DPROTECT_STATEMENT_MEMROOT) +IF (WITH_PROTECT_STATEMENT_MEMROOT) + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DPROTECT_STATEMENT_MEMROOT") + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DPROTECT_STATEMENT_MEMROOT") ENDIF() INCLUDE(check_compiler_flag) @@ -265,8 +266,6 @@ IF(SECURITY_HARDENED AND NOT WITH_ASAN AND NOT WITH_UBSAN AND NOT WITH_TSAN AND MY_CHECK_AND_SET_COMPILER_FLAG("-D_FORTIFY_SOURCE=2" RELEASE RELWITHDEBINFO) ENDIF() -INCLUDE(wsrep) - OPTION(WITH_DBUG_TRACE "Enable DBUG_ENTER()/DBUG_RETURN()/DBUG_PRINT()" ON) IF(WITH_DBUG_TRACE) FOREACH(LANG C CXX) @@ -277,7 +276,12 @@ ENDIF() # Always enable debug sync for debug builds. SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DENABLED_DEBUG_SYNC") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DENABLED_DEBUG_SYNC") - + +IF(CMAKE_COMPILER_IS_GNUCC AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "10") + # Enable extra checks when using a recent enough version of GNU libstdc++ + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG -D_GLIBCXX_ASSERTIONS") +ENDIF() + OPTION(ENABLE_GCOV "Enable gcov (debug, Linux builds only)" OFF) IF (ENABLE_GCOV) MY_CHECK_AND_SET_COMPILER_FLAG("-DHAVE_gcov -fprofile-arcs -ftest-coverage -lgcov" DEBUG) @@ -338,6 +342,8 @@ ELSEIF(TRASH_FREED_MEMORY MATCHES "AUTO" AND NOT WIN32 AND NOT WITH_VALGRIND AND SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DTRASH_FREED_MEMORY") ENDIF() +INCLUDE(wsrep) + # Set commonly used variables IF(WIN32) SET(DEFAULT_MYSQL_HOME "C:/Program Files/MariaDB ${MYSQL_BASE_VERSION}") diff --git a/README.md b/README.md index d632eed4b39..e123e5b64c9 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Code status: * [![Appveyor CI status](https://ci.appveyor.com/api/projects/status/4u6pexmtpuf8jq66?svg=true)](https://ci.appveyor.com/project/rasmushoj/server) ci.appveyor.com -## MariaDB: The open source relational database +## MariaDB: The innovative open source database MariaDB was designed as a drop-in replacement of MySQL(R) with more features, new storage engines, fewer bugs, and better performance. @@ -33,28 +33,23 @@ https://mariadb.com/kb/en/mariadb-versus-mysql-compatibility/ https://mariadb.com/kb/en/new-and-old-releases/ +Getting the code, building it and testing it +--------------------------------------------------------------- + +Refer to the following guide: https://mariadb.org/get-involved/getting-started-for-developers/get-code-build-test/ which outlines how to correctly build the source code and run the MariaDB testing framework. + Help ----- More help is available from the Maria Discuss mailing list -https://launchpad.net/~maria-discuss, MariaDB's Zulip +https://lists.mariadb.org/postorius/lists/discuss.lists.mariadb.org/ and MariaDB's Zulip instance, https://mariadb.zulipchat.com/ -Live QA for beginner contributors ----- -MariaDB has a dedicated time each week when we answer new contributor questions live on Zulip. -From 8:00 to 10:00 UTC on Mondays, and 10:00 to 12:00 UTC on Thursdays, -anyone can ask any questions they’d like, and a live developer will be available to assist. - -New contributors can ask questions any time, but we will provide immediate feedback during that interval. - Licensing --------- *************************************************************************** -NOTE: - MariaDB is specifically available only under version 2 of the GNU General Public License (GPLv2). (I.e. Without the "any later version" clause.) This is inherited from MySQL. Please see the README file in diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 3aa59299437..b21402ad930 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -18,7 +18,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/include ${PCRE_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/mysys_ssl - ${ZLIB_INCLUDE_DIR} + ${ZLIB_INCLUDE_DIRS} ${SSL_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/sql ${CMAKE_SOURCE_DIR}/strings diff --git a/client/client_priv.h b/client/client_priv.h index 882323badd5..46c0a897dcf 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -1,6 +1,6 @@ /* Copyright (c) 2001, 2012, Oracle and/or its affiliates. - Copyright (c) 2009, 2022, MariaDB + Copyright (c) 2009, 2024, MariaDB 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 @@ -38,75 +38,35 @@ enum options_client { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_PAGER, OPT_TEE, - OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS, - OPT_DROP, OPT_LOCKS, OPT_KEYWORDS, OPT_DELAYED, OPT_OPTIMIZE, - OPT_FTB, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_TABLES, - OPT_MASTER_DATA, OPT_AUTOCOMMIT, OPT_AUTO_REHASH, - OPT_LINE_NUMBERS, OPT_COLUMN_NAMES, OPT_CONNECT_TIMEOUT, - OPT_MAX_ALLOWED_PACKET, OPT_NET_BUFFER_LENGTH, - OPT_SELECT_LIMIT, OPT_MAX_JOIN_SIZE, OPT_SSL_SSL, + OPT_OPTIMIZE, + OPT_TABLES, + OPT_MASTER_DATA, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH, - OPT_SSL_CIPHER, OPT_TLS_VERSION, OPT_SHUTDOWN_TIMEOUT, OPT_LOCAL_INFILE, - OPT_DELETE_MASTER_LOGS, OPT_COMPACT, - OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL, - OPT_FRM, OPT_SKIP_OPTIMIZATION, - OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH, - OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_SERVER_ARG, - OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME, - OPT_SIGINT_IGNORE, OPT_HEXBLOB, OPT_ORDER_BY_PRIMARY, OPT_COUNT, - OPT_FLUSH_TABLES, - OPT_TRIGGERS, - OPT_MYSQL_ONLY_PRINT, - OPT_MYSQL_LOCK_DIRECTORY, - OPT_USE_THREADS, - OPT_IMPORT_USE_THREADS, - OPT_MYSQL_NUMBER_OF_QUERY, + OPT_TLS_VERSION, + OPT_SSL_CIPHER, OPT_LOCAL_INFILE, + OPT_COMPACT, + OPT_MYSQL_PROTOCOL, + OPT_SKIP_OPTIMIZATION, + OPT_COMPATIBLE, OPT_DELIMITER, + OPT_SERVER_ARG, + OPT_START_DATETIME, OPT_STOP_DATETIME, OPT_IGNORE_DATABASE, - OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE, - OPT_TZ_UTC, OPT_CREATE_SLAP_SCHEMA, - OPT_MYSQLDUMP_SLAVE_APPLY, + OPT_IGNORE_TABLE, OPT_MYSQLDUMP_SLAVE_DATA, - OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT, -#ifdef WHEN_FLASHBACK_REVIEW_READY - OPT_REVIEW, - OPT_REVIEW_DBNAME, OPT_REVIEW_TABLENAME, -#endif - OPT_SLAP_CSV, OPT_SLAP_CREATE_STRING, - OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE, OPT_SLAP_AUTO_GENERATE_WRITE_NUM, - OPT_SLAP_AUTO_GENERATE_ADD_AUTO, - OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY, - OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES, - OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES, - OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM, - OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM, - OPT_SLAP_PRE_QUERY, - OPT_SLAP_POST_QUERY, - OPT_SLAP_PRE_SYSTEM, - OPT_SLAP_POST_SYSTEM, - OPT_SLAP_COMMIT, - OPT_SLAP_DETACH, - OPT_SLAP_NO_DROP, - OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT_MODE, OPT_SERVER_ID, - OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT, - OPT_AUTO_VERTICAL_OUTPUT, - OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE, - OPT_WRITE_BINLOG, OPT_DUMP_DATE, - OPT_INIT_COMMAND, + OPT_SLAP_CSV, + OPT_BASE64_OUTPUT_MODE, + OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, + OPT_WRITE_BINLOG, OPT_PLUGIN_DIR, OPT_DEFAULT_AUTH, - OPT_ABORT_SOURCE_ON_ERROR, OPT_REWRITE_DB, - OPT_REPORT_PROGRESS, - OPT_SKIP_ANNOTATE_ROWS_EVENTS, OPT_SSL_CRL, OPT_SSL_CRLPATH, OPT_IGNORE_DATA, OPT_PRINT_ROW_COUNT, OPT_PRINT_ROW_EVENT_POSITIONS, OPT_CHECK_IF_UPGRADE_NEEDED, OPT_COMPATIBILTY_CLEARTEXT_PLUGIN, - OPT_SHUTDOWN_WAIT_FOR_SLAVES, - OPT_COPY_S3_TABLES, - OPT_PRINT_TABLE_METADATA, - OPT_ASOF_TIMESTAMP, + OPT_STOP_POSITION, + OPT_SERVER_ID, OPT_IGNORE_DOMAIN_IDS, OPT_DO_DOMAIN_IDS, OPT_IGNORE_SERVER_IDS, diff --git a/client/mysql.cc b/client/mysql.cc index 9ef1b75d5bd..ca659786cdb 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2018, Oracle and/or its affiliates. - Copyright (c) 2009, 2022, MariaDB Corporation. + Copyright (c) 2009, 2024, MariaDB Corporation. 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 @@ -226,7 +226,7 @@ typedef struct st_status ulong query_start_line; char *file_name; LINE_BUFFER *line_buff; - bool batch,add_to_history; + bool batch, add_to_history, sandbox; } STATUS; @@ -244,7 +244,7 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0, vertical=0, line_numbers=1, column_names=1,opt_html=0, opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0, tty_password= 0, opt_nobeep=0, opt_reconnect=1, - opt_secure_auth= 0, + opt_secure_auth= 0, default_pager_set= 0, opt_sigint_ignore= 0, auto_vertical_output= 0, show_query_cost= 0, show_warnings= 0, executing_query= 0, @@ -324,7 +324,8 @@ static int com_quit(String *str,char*), com_rehash(String *str, char*), com_tee(String *str, char*), com_notee(String *str, char*), com_charset(String *str,char*), com_prompt(String *str, char*), com_delimiter(String *str, char*), - com_warnings(String *str, char*), com_nowarnings(String *str, char*); + com_warnings(String *str, char*), com_nowarnings(String *str, char*), + com_sandbox(String *str, char*); static int com_query_cost(String *str, char*); #ifdef USE_POPEN @@ -373,11 +374,12 @@ typedef struct { static COMMANDS commands[] = { { "?", '?', com_help, 1, "Synonym for `help'." }, + { "charset", 'C', com_charset, 1, + "Switch to another charset. Might be needed for processing binlog with multi-byte charsets." }, { "clear", 'c', com_clear, 0, "Clear the current input statement."}, { "connect",'r', com_connect,1, "Reconnect to the server. Optional arguments are db and host." }, - { "delimiter", 'd', com_delimiter, 1, - "Set statement delimiter." }, + { "delimiter", 'd', com_delimiter, 1, "Set statement delimiter." }, #ifdef USE_POPEN { "edit", 'e', com_edit, 0, "Edit command with $EDITOR."}, #endif @@ -390,6 +392,8 @@ static COMMANDS commands[] = { { "nopager",'n', com_nopager,0, "Disable pager, print to stdout." }, #endif { "notee", 't', com_notee, 0, "Don't write into outfile." }, + { "nowarning", 'w', com_nowarnings, 0, + "Don't show warnings after every statement." }, #ifdef USE_POPEN { "pager", 'P', com_pager, 1, "Set PAGER [to_pager]. Print the query results via PAGER." }, @@ -400,6 +404,8 @@ static COMMANDS commands[] = { { "costs", 'Q', com_query_cost, 0, "Toggle showing query costs after each query" }, { "rehash", '#', com_rehash, 0, "Rebuild completion hash." }, + { "sandbox", '-', com_sandbox, 0, + "Disallow commands that access the file system (except \\P without an argument and \\e)." }, { "source", '.', com_source, 1, "Execute an SQL script file. Takes a file name as an argument."}, { "status", 's', com_status, 0, "Get status information from the server."}, @@ -410,12 +416,8 @@ static COMMANDS commands[] = { "Set outfile [to_outfile]. Append everything into given outfile." }, { "use", 'u', com_use, 1, "Use another database. Takes database name as argument." }, - { "charset", 'C', com_charset, 1, - "Switch to another charset. Might be needed for processing binlog with multi-byte charsets." }, { "warnings", 'W', com_warnings, 0, "Show warnings after every statement." }, - { "nowarning", 'w', com_nowarnings, 0, - "Don't show warnings after every statement." }, /* Get bash-like expansion for some commands */ { "create table", 0, 0, 0, ""}, { "create database", 0, 0, 0, ""}, @@ -1642,35 +1644,47 @@ static struct my_option my_long_options[] = 0, 0, 0, 0, 0}, {"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"abort-source-on-error", OPT_ABORT_SOURCE_ON_ERROR, + {"abort-source-on-error", 0, "Abort 'source filename' operations in case of errors", &batch_abort_on_error, &batch_abort_on_error, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"auto-rehash", OPT_AUTO_REHASH, + {"auto-rehash", 0, "Enable automatic rehashing. One doesn't need to use 'rehash' to get table " - "and field completion, but startup and reconnecting may take a longer time. " - "Disable with --disable-auto-rehash.", - &opt_rehash, &opt_rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, - 0, 0}, + "and field completion, but startup and reconnecting may take a longer time.", + &opt_rehash, &opt_rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"no-auto-rehash", 'A', "No automatic rehashing. One has to use 'rehash' to get table and field " "completion. This gives a quicker start of mysql and disables rehashing " "on reconnect.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT, + {"auto-vertical-output", 0, "Automatically switch to vertical output mode if the result is wider " - "than the terminal width.", - &auto_vertical_output, &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, - 0, 0, 0, 0, 0}, + "than the terminal width.", &auto_vertical_output, &auto_vertical_output, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"batch", 'B', "Don't use history file. Disable interactive behavior. (Enables --silent.)", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"binary-as-hex", 0, "Print binary data as hex", &opt_binhex, &opt_binhex, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"binary-mode", 0, + "Binary mode allows certain character sequences to be processed as data " + "that would otherwise be treated with a special meaning by the parser. " + "Specifically, this switch turns off parsing of all client commands except " + "\\C and DELIMITER in non-interactive mode (i.e., when binary mode is " + "combined with either 1) piped input, 2) the --batch mysql option, or 3) " + "the 'source' command). Also, in binary mode, occurrences of '\\r\\n' and " + "ASCII '\\0' are preserved within strings, whereas by default, '\\r\\n' is " + "translated to '\\n' and '\\0' is disallowed in user input.", + &opt_binary_mode, &opt_binary_mode, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"character-sets-dir", OPT_CHARSETS_DIR, "Directory for character set files.", &charsets_dir, &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"column-type-info", OPT_COLUMN_TYPES, "Display column type information.", + {"column-names", 0, "Write column names in results.", + &column_names, &column_names, 0, GET_BOOL, + NO_ARG, 1, 0, 0, 0, 0, 0}, + {"skip-column-names", 'N', "Don't write column names in results.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"column-type-info", 0, "Display column type information.", &column_types_flag, &column_types_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"comments", 'c', "Preserve comments. Send comments to the server." @@ -1680,6 +1694,16 @@ static struct my_option my_long_options[] = {"compress", 'C', "Use compression in server/client protocol.", &opt_compress, &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"connect-expired-password", 0, + "Notify the server that this client is prepared to handle expired " + "password sandbox mode even if --batch was specified.", + &opt_connect_expired_password, &opt_connect_expired_password, 0, GET_BOOL, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"connect_timeout", 0, "Number of seconds before connection timeout.", + &opt_connect_timeout, &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, + 0, 0, 3600*12, 0, 0, 0}, + {"database", 'D', "Database to use.", ¤t_db, + ¤t_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef DBUG_OFF {"debug", '#', "This is a non-debug version. Catch this and exit.", 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, @@ -1687,70 +1711,64 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log.", &default_dbug_option, &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", + {"debug-check", 0, "Check memory and open file usage at exit.", &debug_check_flag, &debug_check_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"debug-info", 'T', "Print some debug info at exit.", &debug_info_flag, &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"database", 'D', "Database to use.", ¤t_db, - ¤t_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"default-character-set", OPT_DEFAULT_CHARSET, + {"default-auth", 0, "Default authentication client-side plugin to use.", + &opt_default_auth, &opt_default_auth, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"default-character-set", 0, "Set the default character set.", &default_charset, &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"delimiter", OPT_DELIMITER, "Delimiter to be used.", &delimiter_str, &delimiter_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"enable-cleartext-plugin", OPT_COMPATIBILTY_CLEARTEXT_PLUGIN, + "Obsolete option. Exists only for MySQL compatibility.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"execute", 'e', "Execute command and quit. (Disables --force and history file.)", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"enable-cleartext-plugin", OPT_COMPATIBILTY_CLEARTEXT_PLUGIN, "Obsolete option. Exists only for MySQL compatibility.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"vertical", 'E', "Print the output of a query (rows) vertically.", - &vertical, &vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, - 0}, - {"force", 'f', "Continue even if we get an SQL error. Sets abort-source-on-error to 0", - &ignore_errors, &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0, - 0, 0, 0, 0}, + {"force", 'f', + "Continue even if we get an SQL error. Sets abort-source-on-error to 0", + &ignore_errors, &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"host", 'h', "Connect to host.", ¤t_host, + ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"html", 'H', "Produce HTML output.", &opt_html, &opt_html, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"ignore-spaces", 'i', "Ignore space after function names.", + &ignore_spaces, &ignore_spaces, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"init-command", 0, + "SQL Command to execute when connecting to MariaDB server. Will " + "automatically be re-executed when reconnecting.", &opt_init_command, + &opt_init_command, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"line-numbers", 0, "Write line numbers for errors.", + &line_numbers, &line_numbers, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + {"skip-line-numbers", 'L', "Don't write line number for errors.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"local-infile", OPT_LOCAL_INFILE, "Enable LOAD DATA LOCAL INFILE.", + &opt_local_infile, &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"max-allowed-packet", 0, + "The maximum packet length to send to or receive from server.", + &opt_max_allowed_packet, &opt_max_allowed_packet, 0, GET_ULONG, + REQUIRED_ARG, 16*1024LL*1024LL, 4096, 2*1024LL*1024LL*1024LL, 0, 1024, 0}, + {"max-join-size", 0, + "Automatic limit for rows in a join when using --safe-updates.", + &max_join_size, &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, + 1, ULONG_MAX, 0, 1, 0}, {"named-commands", 'G', "Enable named commands. Named commands mean this program's internal " "commands; see mysql> help . When enabled, the named commands can be " "used from any line of the query, otherwise only from the first line, " "before an enter. Disable with --disable-named-commands. This option " "is disabled by default.", - &named_cmds, &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, - 0, 0}, - {"ignore-spaces", 'i', "Ignore space after function names.", - &ignore_spaces, &ignore_spaces, 0, GET_BOOL, NO_ARG, 0, 0, - 0, 0, 0, 0}, - {"init-command", OPT_INIT_COMMAND, - "SQL Command to execute when connecting to MariaDB server. Will " - "automatically be re-executed when reconnecting.", - &opt_init_command, &opt_init_command, 0, - GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.", - &opt_local_infile, &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, + &named_cmds, &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"net-buffer-length", 0, + "The buffer size for TCP/IP and socket communication.", + &opt_net_buffer_length, &opt_net_buffer_length, 0, GET_ULONG, + REQUIRED_ARG, 16384, 1024, 512*1024ULL*1024ULL, MALLOC_OVERHEAD, 1024, 0}, {"no-beep", 'b', "Turn off beep on error.", &opt_nobeep, &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"host", 'h', "Connect to host.", ¤t_host, - ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"html", 'H', "Produce HTML output.", &opt_html, &opt_html, - 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"xml", 'X', "Produce XML output.", &opt_xml, &opt_xml, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.", - &line_numbers, &line_numbers, 0, GET_BOOL, - NO_ARG, 1, 0, 0, 0, 0, 0}, - {"skip-line-numbers", 'L', "Don't write line number for errors.", 0, 0, 0, GET_NO_ARG, - NO_ARG, 0, 0, 0, 0, 0, 0}, - {"unbuffered", 'n', "Flush buffer after each query.", &unbuffered, - &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"column-names", OPT_COLUMN_NAMES, "Write column names in results.", - &column_names, &column_names, 0, GET_BOOL, - NO_ARG, 1, 0, 0, 0, 0, 0}, - {"skip-column-names", 'N', - "Don't write column names in results.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"sigint-ignore", OPT_SIGINT_IGNORE, "Ignore SIGINT (CTRL-C).", - &opt_sigint_ignore, &opt_sigint_ignore, 0, GET_BOOL, - NO_ARG, 0, 0, 0, 0, 0, 0}, {"one-database", 'o', "Ignore statements except those that occur while the default " "database is the one named at the command line.", @@ -1771,19 +1789,20 @@ static struct my_option my_long_options[] = {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif + {"plugin-dir", 0, "Directory for client-side plugins.", &opt_plugin_dir, + &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection or 0 for default to, in " "order of preference, my.cnf, $MYSQL_TCP_PORT, " #if MYSQL_PORT_DEFAULT == 0 "/etc/services, " #endif - "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").", - &opt_mysql_port, - &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"progress-reports", OPT_REPORT_PROGRESS, + "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").", &opt_mysql_port, + &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"progress-reports", 0, "Get progress reports for long running commands (like ALTER TABLE)", &opt_progress_reports, &opt_progress_reports, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, - {"prompt", OPT_PROMPT, "Set the command line prompt to this value.", + {"prompt", 0, "Set the command line prompt to this value.", ¤t_prompt, ¤t_prompt, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"protocol", OPT_MYSQL_PROTOCOL, "The protocol to use for connection (tcp, socket, pipe).", @@ -1794,11 +1813,29 @@ static struct my_option my_long_options[] = "if the output is suspended. Doesn't use history file.", &quick, &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"raw", 'r', "Write fields without conversion. Used with --batch.", - &opt_raw_data, &opt_raw_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, - 0, 0, 0}, - {"reconnect", OPT_RECONNECT, "Reconnect if the connection is lost. Disable " - "with --disable-reconnect. This option is enabled by default.", + &opt_raw_data, &opt_raw_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"reconnect", 0, "Reconnect if the connection is lost.", &opt_reconnect, &opt_reconnect, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + {"safe-updates", 'U', "Only allow UPDATE and DELETE that uses keys.", + &safe_updates, &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"i-am-a-dummy", 'U', "Synonym for option --safe-updates, -U.", + &safe_updates, &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"sandbox", 0, "Disallow commands that access the file system (except \\P without an argument and \\e).", + &status.sandbox, &status.sandbox, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"secure-auth", 0, "Refuse client connecting to server if it" + " uses old (pre-4.1.1) protocol.", &opt_secure_auth, + &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"select-limit", 0, + "Automatic limit for SELECT when using --safe-updates.", &select_limit, + &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ULONG_MAX, 0, 1, 0}, + {"server-arg", OPT_SERVER_ARG, "Send embedded server this as a parameter.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"show-query-costs", 0, "Show query cost after every statement.", + &show_query_cost, &show_query_cost, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"show-warnings", 0, "Show warnings after every statement.", + &show_warnings, &show_warnings, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"sigint-ignore", 0, "Ignore SIGINT (CTRL-C).", &opt_sigint_ignore, + &opt_sigint_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"silent", 's', "Be more silent. Print results with a tab as separator, " "each row on new line.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"socket", 'S', "The socket file to use for connection.", @@ -1812,77 +1849,22 @@ static struct my_option my_long_options[] = "Does not work in batch mode. Disable with --disable-tee. " "This option is disabled by default.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"unbuffered", 'n', "Flush buffer after each query.", &unbuffered, + &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DONT_ALLOW_USER_CHANGE {"user", 'u', "User for login if not current user.", ¤t_user, ¤t_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"safe-updates", 'U', "Only allow UPDATE and DELETE that uses keys.", - &safe_updates, &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0, - 0, 0, 0, 0}, - {"i-am-a-dummy", 'U', "Synonym for option --safe-updates, -U.", - &safe_updates, &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0, - 0, 0, 0, 0}, {"verbose", 'v', "Write more. (-v -v -v gives the table output format).", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"vertical", 'E', "Print the output of a query (rows) vertically.", + &vertical, &vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"connect_timeout", OPT_CONNECT_TIMEOUT, - "Number of seconds before connection timeout.", - &opt_connect_timeout, &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, - 0, 0, 3600*12, 0, 0, 0}, - {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, - "The maximum packet length to send to or receive from server.", - &opt_max_allowed_packet, &opt_max_allowed_packet, 0, - GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096, - (longlong) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, - {"net_buffer_length", OPT_NET_BUFFER_LENGTH, - "The buffer size for TCP/IP and socket communication.", - &opt_net_buffer_length, &opt_net_buffer_length, 0, GET_ULONG, - REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0}, - {"select_limit", OPT_SELECT_LIMIT, - "Automatic limit for SELECT when using --safe-updates.", - &select_limit, &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, - 1, ULONG_MAX, 0, 1, 0}, - {"max_join_size", OPT_MAX_JOIN_SIZE, - "Automatic limit for rows in a join when using --safe-updates.", - &max_join_size, &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, - 1, ULONG_MAX, 0, 1, 0}, - {"secure-auth", OPT_SECURE_AUTH, "Refuse client connecting to server if it" - " uses old (pre-4.1.1) protocol.", &opt_secure_auth, - &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"server-arg", OPT_SERVER_ARG, "Send embedded server this as a parameter.", - 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"show-warnings", OPT_SHOW_WARNINGS, "Show warnings after every statement.", - &show_warnings, &show_warnings, 0, GET_BOOL, NO_ARG, - 0, 0, 0, 0, 0, 0}, - {"show-query-costs", OPT_SHOW_WARNINGS, - "Show query cost after every statement.", - &show_query_cost, &show_query_cost, 0, GET_BOOL, NO_ARG, - 0, 0, 0, 0, 0, 0}, - {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", - &opt_plugin_dir, &opt_plugin_dir, 0, - GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"default_auth", OPT_DEFAULT_AUTH, - "Default authentication client-side plugin to use.", - &opt_default_auth, &opt_default_auth, 0, - GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"binary-mode", 0, - "Binary mode allows certain character sequences to be processed as data " - "that would otherwise be treated with a special meaning by the parser. " - "Specifically, this switch turns off parsing of all client commands except " - "\\C and DELIMITER in non-interactive mode (i.e., when binary mode is " - "combined with either 1) piped input, 2) the --batch mysql option, or 3) " - "the 'source' command). Also, in binary mode, occurrences of '\\r\\n' and " - "ASCII '\\0' are preserved within strings, whereas by default, '\\r\\n' is " - "translated to '\\n' and '\\0' is disallowed in user input.", - &opt_binary_mode, &opt_binary_mode, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"connect-expired-password", 0, - "Notify the server that this client is prepared to handle expired " - "password sandbox mode even if --batch was specified.", - &opt_connect_expired_password, &opt_connect_expired_password, 0, GET_BOOL, - NO_ARG, 0, 0, 0, 0, 0, 0}, + {"xml", 'X', "Produce XML output.", &opt_xml, &opt_xml, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -2934,9 +2916,7 @@ static void initialize_readline () array of matches, or NULL if there aren't any. */ -static char **new_mysql_completion(const char *text, - int start __attribute__((unused)), - int end __attribute__((unused))) +static char **new_mysql_completion(const char *text, int, int) { if (!status.batch && !quick) #if defined(USE_NEW_READLINE_INTERFACE) @@ -3259,8 +3239,7 @@ static void print_help_item(MYSQL_ROW *cur, int num_name, int num_cat, char *las } -static int com_server_help(String *buffer __attribute__((unused)), - char *line __attribute__((unused)), char *help_arg) +static int com_server_help(String *buffer, char *, char *help_arg) { MYSQL_ROW cur; const char *server_cmd; @@ -3362,18 +3341,16 @@ err: return error; } -static int -com_help(String *buffer __attribute__((unused)), - char *line __attribute__((unused))) +static int com_help(String *buffer, char *line) { int i, j; char * help_arg= strchr(line,' '), buff[32], *end; if (help_arg) { - while (my_isspace(charset_info,*help_arg)) + while (my_isspace(charset_info, *help_arg)) help_arg++; if (*help_arg) - return com_server_help(buffer,line,help_arg); + return com_server_help(buffer, line, help_arg); } put_info("\nGeneral information about MariaDB can be found at\n" @@ -3396,9 +3373,7 @@ com_help(String *buffer __attribute__((unused)), } - /* ARGSUSED */ -static int -com_clear(String *buffer,char *line __attribute__((unused))) +static int com_clear(String *buffer,char *) { #ifdef HAVE_READLINE if (status.add_to_history) @@ -3423,9 +3398,7 @@ static void adjust_console_codepage(const char *name __attribute__((unused))) } - /* ARGSUSED */ -static int -com_charset(String *buffer __attribute__((unused)), char *line) +static int com_charset(String *, char *line) { char buff[256], *param; CHARSET_INFO * new_cs; @@ -3458,8 +3431,7 @@ com_charset(String *buffer __attribute__((unused)), char *line) */ -static int -com_go(String *buffer,char *line __attribute__((unused))) +static int com_go(String *buffer, char *) { char buff[200]; /* about 110 chars used so far */ char time_buff[53+3+1]; /* time max + space & parens + NUL */ @@ -4044,9 +4016,7 @@ tee_print_sized_data(const char *data, unsigned int data_length, unsigned int to } - -static void -print_table_data_html(MYSQL_RES *result) +static void print_table_data_html(MYSQL_RES *result) { MYSQL_ROW cur; MYSQL_FIELD *field; @@ -4369,15 +4339,15 @@ print_tab_data(MYSQL_RES *result) } } -static int -com_tee(String *buffer __attribute__((unused)), - char *line __attribute__((unused))) +static int com_tee(String *, char *line) { char file_name[FN_REFLEN], *end, *param; + if (status.sandbox) + return put_info("Not allowed in the sandbox mode", INFO_ERROR, 0); if (status.batch) return 0; - while (my_isspace(charset_info,*line)) + while (my_isspace(charset_info, *line)) line++; if (!(param = strchr(line, ' '))) // if outfile wasn't given, use the default { @@ -4414,9 +4384,7 @@ com_tee(String *buffer __attribute__((unused)), } -static int -com_notee(String *buffer __attribute__((unused)), - char *line __attribute__((unused))) +static int com_notee(String *, char *) { if (opt_outfile) end_tee(); @@ -4429,9 +4397,7 @@ com_notee(String *buffer __attribute__((unused)), */ #ifdef USE_POPEN -static int -com_pager(String *buffer __attribute__((unused)), - char *line __attribute__((unused))) +static int com_pager(String *, char *line) { char pager_name[FN_REFLEN], *end, *param; @@ -4459,6 +4425,8 @@ com_pager(String *buffer __attribute__((unused)), } else { + if (status.sandbox) + return put_info("Not allowed in the sandbox mode", INFO_ERROR, 0); end= strmake_buf(pager_name, param); while (end > pager_name && (my_isspace(charset_info,end[-1]) || my_iscntrl(charset_info,end[-1]))) @@ -4473,9 +4441,7 @@ com_pager(String *buffer __attribute__((unused)), } -static int -com_nopager(String *buffer __attribute__((unused)), - char *line __attribute__((unused))) +static int com_nopager(String *, char *) { strmov(pager, "stdout"); opt_nopager=1; @@ -4487,7 +4453,7 @@ com_nopager(String *buffer __attribute__((unused)), #ifdef USE_POPEN static int -com_edit(String *buffer,char *line __attribute__((unused))) +com_edit(String *buffer,char *) { char filename[FN_REFLEN],buff[160]; int fd,tmp,error; @@ -4534,17 +4500,15 @@ err: /* If arg is given, exit without errors. This happens on command 'quit' */ -static int -com_quit(String *buffer __attribute__((unused)), - char *line __attribute__((unused))) +static int com_quit(String *, char *) { status.exit_status=0; return 1; } static int -com_rehash(String *buffer __attribute__((unused)), - char *line __attribute__((unused))) +com_rehash(String *, + char *) { #ifdef HAVE_READLINE build_completion_hash(1, 0); @@ -4554,12 +4518,13 @@ com_rehash(String *buffer __attribute__((unused)), #ifdef USE_POPEN -static int -com_shell(String *buffer __attribute__((unused)), - char *line __attribute__((unused))) +static int com_shell(String *, char *line) { char *shell_cmd; + if (status.sandbox) + return put_info("Not allowed in the sandbox mode", INFO_ERROR, 0); + /* Skip space from line begin */ while (my_isspace(charset_info, *line)) line++; @@ -4582,8 +4547,7 @@ com_shell(String *buffer __attribute__((unused)), #endif -static int -com_print(String *buffer,char *line __attribute__((unused))) +static int com_print(String *buffer,char *) { tee_puts("--------------", stdout); (void) tee_fputs(buffer->c_ptr(), stdout); @@ -4593,9 +4557,8 @@ com_print(String *buffer,char *line __attribute__((unused))) return 0; /* If empty buffer */ } - /* ARGSUSED */ -static int -com_connect(String *buffer, char *line) + +static int com_connect(String *buffer, char *line) { char *tmp, buff[256]; my_bool save_rehash= opt_rehash; @@ -4648,8 +4611,7 @@ com_connect(String *buffer, char *line) } -static int com_source(String *buffer __attribute__((unused)), - char *line) +static int com_source(String *, char *line) { char source_name[FN_REFLEN], *end, *param; LINE_BUFFER *line_buff; @@ -4658,6 +4620,9 @@ static int com_source(String *buffer __attribute__((unused)), FILE *sql_file; my_bool save_ignore_errors; + if (status.sandbox) + return put_info("Not allowed in the sandbox mode", INFO_ERROR, 0); + /* Skip space from file name */ while (my_isspace(charset_info,*line)) line++; @@ -4692,6 +4657,7 @@ static int com_source(String *buffer __attribute__((unused)), bfill((char*) &status,sizeof(status),(char) 0); status.batch=old_status.batch; // Run in batch mode + status.sandbox=old_status.sandbox; status.line_buff=line_buff; status.file_name=source_name; glob_buffer.length(0); // Empty command buffer @@ -4713,9 +4679,7 @@ static int com_source(String *buffer __attribute__((unused)), } - /* ARGSUSED */ -static int -com_delimiter(String *buffer __attribute__((unused)), char *line) +static int com_delimiter(String *, char *line) { char buff[256], *tmp; @@ -4742,9 +4706,7 @@ com_delimiter(String *buffer __attribute__((unused)), char *line) return 0; } - /* ARGSUSED */ -static int -com_use(String *buffer __attribute__((unused)), char *line) +static int com_use(String *, char *line) { char *tmp, buff[FN_REFLEN + 1]; int select_db; @@ -4817,18 +4779,21 @@ com_use(String *buffer __attribute__((unused)), char *line) return 0; } -static int -com_warnings(String *buffer __attribute__((unused)), - char *line __attribute__((unused))) +static int com_sandbox(String *, char *) +{ + status.sandbox= 1; + put_info("Sandbox mode.", INFO_INFO); + return 0; +} + +static int com_warnings(String *, char *) { show_warnings = 1; put_info("Show warnings enabled.",INFO_INFO); return 0; } -static int -com_nowarnings(String *buffer __attribute__((unused)), - char *line __attribute__((unused))) +static int com_nowarnings(String *, char *) { show_warnings = 0; put_info("Show warnings disabled.",INFO_INFO); @@ -5092,10 +5057,7 @@ sql_connect(char *host,char *database,char *user,char *password,uint silent) } - -static int -com_status(String *buffer __attribute__((unused)), - char *line __attribute__((unused))) +static int com_status(String *, char *) { const char *status_str; char buff[40]; @@ -5220,8 +5182,7 @@ select_limit, max_join_size); return 0; } -static const char * -server_version_string(MYSQL *con) +static const char * server_version_string(MYSQL *con) { /* Only one thread calls this, so no synchronization is needed */ if (server_version == NULL) @@ -5346,8 +5307,7 @@ put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate) } -static int -put_error(MYSQL *con) +static int put_error(MYSQL *con) { return put_info(mysql_error(con), INFO_ERROR, mysql_errno(con), mysql_sqlstate(con)); @@ -5413,7 +5373,7 @@ void tee_putc(int c, FILE *file) len("4294967296 days, 23 hours, 59 minutes, 60.000 seconds") -> 53 */ -static void nice_time(double sec,char *buff,bool part_second) +static void nice_time(double sec, char *buff, bool part_second) { ulong tmp; if (sec >= 3600.0*24) @@ -5694,8 +5654,7 @@ static void init_username() } } -static int com_prompt(String *buffer __attribute__((unused)), - char *line) +static int com_prompt(String *, char *line) { char *ptr=strchr(line, ' '); prompt_counter = 0; diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 1f4bd6fc7b0..3f60d169edc 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -1,6 +1,6 @@ /* Copyright (c) 2006, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2017, MariaDB + Copyright (c) 2010, 2024, MariaDB 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 @@ -86,10 +86,10 @@ static struct my_option my_long_options[]= {"basedir", 'b', "Not used by mysql_upgrade. Only for backward compatibility.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"character-sets-dir", OPT_CHARSETS_DIR, + {"character-sets-dir", 0, "Not used by mysql_upgrade. Only for backward compatibility.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, - {"compress", OPT_COMPRESS, + {"compress", 0, "Not used by mysql_upgrade. Only for backward compatibility.", ¬_used, ¬_used, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"datadir", 'd', @@ -102,12 +102,12 @@ static struct my_option my_long_options[]= {"debug", '#', "Output debug log.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", + {"debug-check", 0, "Check memory and open file usage at exit.", &debug_check_flag, &debug_check_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"debug-info", 'T', "Print some debug info at exit.", &debug_info_flag, &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"default-character-set", OPT_DEFAULT_CHARSET, + {"default-character-set", 0, "Not used by mysql_upgrade. Only for backward compatibility.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default_auth", OPT_DEFAULT_AUTH, diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index c0b58807e9e..77bcdf506c8 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2014, Oracle and/or its affiliates. - Copyright (c) 2010, 2019, MariaDB + Copyright (c) 2010, 2024, MariaDB 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 @@ -124,10 +124,10 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", + {"debug-check", 0, "Check memory and open file usage at exit.", &debug_check_flag, &debug_check_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + {"debug-info", 0, "Print some debug info at exit.", &debug_info_flag, &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"force", 'f', @@ -141,7 +141,7 @@ static struct my_option my_long_options[] = {"character-sets-dir", OPT_CHARSETS_DIR, "Directory for character set files.", &charsets_dir, &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"default-character-set", OPT_DEFAULT_CHARSET, + {"default-character-set", 0, "Set the default character set.", &default_charset, &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, @@ -195,21 +195,21 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, {"wait", 'w', "Wait and retry if connection is down.", 0, 0, 0, GET_UINT, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"connect_timeout", OPT_CONNECT_TIMEOUT, "", &opt_connect_timeout, + {"connect_timeout", 0, "", &opt_connect_timeout, &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 3600*12, 0, 3600*12, 0, 1, 0}, - {"shutdown_timeout", OPT_SHUTDOWN_TIMEOUT, "", &opt_shutdown_timeout, + {"shutdown_timeout", 0, "", &opt_shutdown_timeout, &opt_shutdown_timeout, 0, GET_ULONG, REQUIRED_ARG, SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0}, - {"wait_for_all_slaves", OPT_SHUTDOWN_WAIT_FOR_SLAVES, + {"wait_for_all_slaves", 0, "Defers shutdown until after all binlogged events have been sent to " "all connected slaves", &opt_shutdown_wait_for_slaves, &opt_shutdown_wait_for_slaves, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", + {"plugin_dir", 0, "Directory for client-side plugins.", &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"default_auth", OPT_DEFAULT_AUTH, + {"default_auth", 0, "Default authentication client-side plugin to use.", &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -1342,7 +1342,9 @@ static void usage(void) refresh Flush all tables and close and open logfiles\n\ shutdown Take server down\n\ status Gives a short status message from the server\n\ + start-all-slaves Start all slaves\n\ start-slave Start slave\n\ + stop-all-slaves Stop all slaves\n\ stop-slave Stop slave\n\ variables Prints variables available\n\ version Get version info from server"); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index c79392988c1..a998fb48848 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2014, Oracle and/or its affiliates. - Copyright (c) 2009, 2020, MariaDB + Copyright (c) 2009, 2024, MariaDB 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 @@ -1441,7 +1441,7 @@ static struct my_option my_options[] = like this: SET @`a`:=_cp850 0x4DFC6C6C6572 COLLATE `cp850_general_ci`; */ - {"character-sets-dir", OPT_CHARSETS_DIR, + {"character-sets-dir", 0, "Directory for character set files.", &charsets_dir, &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"database", 'd', "List entries for just this database (local log only).", @@ -1451,13 +1451,13 @@ static struct my_option my_options[] = {"debug", '#', "Output debug log.", ¤t_dbug_option, ¤t_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit .", + {"debug-check", 0, "Check memory and open file usage at exit .", &debug_check_flag, &debug_check_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + {"debug-info", 0, "Print some debug info at exit.", &debug_info_flag, &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"default_auth", OPT_DEFAULT_AUTH, + {"default_auth", 0, "Default authentication client-side plugin to use.", &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -1493,7 +1493,7 @@ static struct my_option my_options[] = 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"password", 'p', "Password to connect to remote server.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", + {"plugin_dir", 0, "Directory for client-side plugins.", &opt_plugindir, &opt_plugindir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection or 0 for default to, in " @@ -1519,14 +1519,14 @@ static struct my_option my_options[] = &result_file_name, &result_file_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef WHEN_FLASHBACK_REVIEW_READY - {"review", opt_flashback_review, "Print review sql in output file.", + {"review", 0, "Print review sql in output file.", &opt_flashback_review, &opt_flashback_review, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"review-dbname", opt_flashback_flashback_review_dbname, + {"review-dbname", 0, "Writing flashback original row data into this db", &flashback_review_dbname, &flashback_review_dbname, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"review-tablename", opt_flashback_flashback_review_tablename, + {"review-tablename", 0, "Writing flashback original row data into this table", &flashback_review_tablename, &flashback_review_tablename, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -1576,7 +1576,7 @@ static struct my_option my_options[] = "Alias for --do-server-ids.", &server_id_str, &server_id_str, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"set-charset", OPT_SET_CHARSET, + {"set-charset", 0, "Add 'SET NAMES character_set' to the output.", &charset, &charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"short-form", 's', "Just show regular queries: no extra info, no " @@ -1659,7 +1659,7 @@ that may lead to an endless loop.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"open_files_limit", OPT_OPEN_FILES_LIMIT, + {"open_files_limit", 0, "Used to reserve file descriptors for use by this program.", &open_files_limit, &open_files_limit, 0, GET_ULONG, REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0}, @@ -1685,12 +1685,12 @@ that may lead to an endless loop.", "Updates to a database with a different name than the original. \ Example: rewrite-db='from->to'.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"skip-annotate-row-events", OPT_SKIP_ANNOTATE_ROWS_EVENTS, + {"skip-annotate-row-events", 0, "Don't print Annotate_rows events stored in the binary log.", (uchar**) &opt_skip_annotate_row_events, (uchar**) &opt_skip_annotate_row_events, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"print-table-metadata", OPT_PRINT_TABLE_METADATA, + {"print-table-metadata", 0, "Print metadata stored in Table_map_log_event", &opt_print_table_metadata, &opt_print_table_metadata, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -2115,11 +2115,6 @@ get_one_option(const struct my_option *opt, const char *argument, die(1); } break; -#ifdef WHEN_FLASHBACK_REVIEW_READY - case opt_flashback_review: - opt_flashback_review= 1; - break; -#endif case OPT_START_DATETIME: start_datetime= convert_str_to_timestamp(start_datetime_str); break; @@ -3232,7 +3227,8 @@ int main(int argc, char** argv) { if (!opt_version) { - usage(); + error("Please provide the log file(s). Run with '--help' for usage " + "instructions."); retval= ERROR_STOP; } goto err; diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index d3bacad93bd..aa9a78ef778 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2012, MariaDB + Copyright (c) 2010, 2024, MariaDB 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 @@ -82,11 +82,11 @@ static struct my_option my_long_options[] = "Instead of issuing one query for each table, use one query per database, naming all tables in the database in a comma-separated list.", &opt_all_in_1, &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"auto-repair", OPT_AUTO_REPAIR, + {"auto-repair", 0, "If a checked table is corrupted, automatically fix it. Repairing will be done after all tables have been checked, if corrupted ones were found.", &opt_auto_repair, &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"character-sets-dir", OPT_CHARSETS_DIR, + {"character-sets-dir", 0, "Directory for character set files.", (char**) &charsets_dir, (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"check", 'c', "Check table for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, @@ -97,7 +97,7 @@ static struct my_option my_long_options[] = {"check-upgrade", 'g', "Check tables for version-dependent changes. May be used with --auto-repair to correct tables requiring version-dependent updates.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"compress", OPT_COMPRESS, "Use compression in server/client protocol.", + {"compress", 0, "Use compression in server/client protocol.", &opt_compress, &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"databases", 'B', @@ -111,16 +111,16 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", + {"debug-check", 0, "Check memory and open file usage at exit.", &debug_check_flag, &debug_check_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + {"debug-info", 0, "Print some debug info at exit.", &debug_info_flag, &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"default-character-set", OPT_DEFAULT_CHARSET, + {"default-character-set", 0, "Set the default character set.", &default_charset, &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"default_auth", OPT_DEFAULT_AUTH, + {"default_auth", 0, "Default authentication client-side plugin to use.", &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -140,7 +140,7 @@ static struct my_option my_long_options[] = "If you are using this option with CHECK TABLE, it will ensure that the table is 100 percent consistent, but will take a long time. If you are using this option with REPAIR TABLE, it will force using old slow repair with keycache method, instead of much faster repair by sorting.", &opt_extended, &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"flush", OPT_FLUSH_TABLES, "Flush each table after check. This is useful if you don't want to have the checked tables take up space in the caches after the check", + {"flush", 0, "Flush each table after check. This is useful if you don't want to have the checked tables take up space in the caches after the check", &opt_flush_tables, &opt_flush_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, @@ -150,7 +150,7 @@ static struct my_option my_long_options[] = {"medium-check", 'm', "Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"write-binlog", OPT_WRITE_BINLOG, + {"write-binlog", 0, "Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Use --skip-write-binlog " "when commands should not be sent to replication slaves.", &opt_write_binlog, &opt_write_binlog, 0, GET_BOOL, NO_ARG, @@ -168,7 +168,7 @@ static struct my_option my_long_options[] = {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", + {"plugin_dir", 0, "Directory for client-side plugins.", &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection or 0 for default to, in " @@ -199,7 +199,7 @@ static struct my_option my_long_options[] = #include {"tables", OPT_TABLES, "Overrides option --databases (-B).", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"use-frm", OPT_FRM, + {"use-frm", 0, "When used with REPAIR, get table structure from .frm file, so the table can be repaired even if .MYI header is corrupted.", &opt_frm, &opt_frm, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -889,6 +889,7 @@ static int disable_binlog() return run_query("SET SQL_LOG_BIN=0", 0); } + static int handle_request_for_tables(char *tables, size_t length, my_bool view, my_bool dont_quote) { @@ -1020,7 +1021,10 @@ static void insert_table_name(DYNAMIC_ARRAY *arr, char *in, size_t dblen) insert_dynamic(arr, (uchar*) buf); } -static void print_result() +/* Ok as mysqlcheck is not multi threaded */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + +static void __attribute__((noinline)) print_result() { MYSQL_RES *res; MYSQL_ROW row; @@ -1111,6 +1115,7 @@ static void print_result() mysql_free_result(res); DBUG_VOID_RETURN; } +PRAGMA_REENABLE_CHECK_STACK_FRAME static int dbConnect(char *host, char *user, char *passwd) diff --git a/client/mysqldump.cc b/client/mysqldump.cc index 1b05e45f478..e3952c27452 100644 --- a/client/mysqldump.cc +++ b/client/mysqldump.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2020, MariaDB Corporation. + Copyright (c) 2010, 2024, MariaDB Corporation. 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 @@ -166,7 +166,6 @@ static my_bool server_supports_switching_charsets= TRUE; static ulong opt_compatible_mode= 0; #define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1 #define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2 -#define MYSQL_OPT_MAX_STATEMENT_TIME 0 #define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1 #define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2 static uint opt_mysql_port= 0, opt_master_data; @@ -252,41 +251,36 @@ static struct my_option my_long_options[] = { {"all-databases", 'A', "Dump all the databases. This will be same as --databases with all databases selected.", - &opt_alldbs, &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, - 0, 0}, + &opt_alldbs, &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"all-tablespaces", 'Y', "Dump all the tablespaces.", - &opt_alltspcs, &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, - 0, 0}, + &opt_alltspcs, &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"no-tablespaces", 'y', "Do not dump any tablespace information.", - &opt_notspcs, &opt_notspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, - 0, 0}, - {"add-drop-database", OPT_DROP_DATABASE, "Add a DROP DATABASE before each create.", + &opt_notspcs, &opt_notspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"add-drop-database", 0, "Add a DROP DATABASE before each create.", &opt_drop_database, &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"add-drop-table", OPT_DROP, "Add a DROP TABLE before each create.", - &opt_drop, &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, - 0}, + {"add-drop-table", 0, "Add a DROP TABLE before each create.", + &opt_drop, &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"add-drop-trigger", 0, "Add a DROP TRIGGER before each create.", &opt_drop_trigger, &opt_drop_trigger, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"add-locks", OPT_LOCKS, "Add locks around INSERT statements.", - &opt_lock, &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, - 0}, - {"allow-keywords", OPT_KEYWORDS, + {"add-locks", 0, "Add locks around INSERT statements.", + &opt_lock, &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + {"allow-keywords", 0, "Allow creation of column names that are keywords.", &opt_keywords, &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"apply-slave-statements", OPT_MYSQLDUMP_SLAVE_APPLY, + {"apply-slave-statements", 0, "Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.", - &opt_slave_apply, &opt_slave_apply, 0, GET_BOOL, NO_ARG, - 0, 0, 0, 0, 0, 0}, - {"as-of", OPT_ASOF_TIMESTAMP, + &opt_slave_apply, &opt_slave_apply, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"as-of", 0, "Dump system versioned table(s) as of specified timestamp. " "Argument is interpreted according to the --tz-utc setting. " "Table structures are always dumped as of current timestamp.", - &opt_asof_timestamp, &opt_asof_timestamp, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"character-sets-dir", OPT_CHARSETS_DIR, + &opt_asof_timestamp, &opt_asof_timestamp, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, + {"character-sets-dir", 0, "Directory for character set files.", (char **)&charsets_dir, (char **)&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"comments", 'i', "Write additional information.", @@ -311,21 +305,18 @@ static struct my_option my_long_options[] = &opt_complete_insert, &opt_complete_insert, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"compress", 'C', "Use compression in server/client protocol.", - &opt_compress, &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, - 0, 0, 0}, - {"copy_s3_tables", OPT_COPY_S3_TABLES, + &opt_compress, &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"copy_s3_tables", 0, "If 'no' S3 tables will be ignored, otherwise S3 tables will be copied as " " Aria tables and then altered to S3", &opt_copy_s3_tables, &opt_copy_s3_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"create-options", 'a', "Include all MariaDB specific create options.", - &create_options, &create_options, 0, GET_BOOL, NO_ARG, 1, - 0, 0, 0, 0, 0}, + &create_options, &create_options, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"databases", 'B', "Dump several databases. Note the difference in usage; in this case no tables are given. All name arguments are regarded as database names. 'USE db_name;' will be included in the output.", - &opt_databases, &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0, - 0, 0, 0, 0}, + &opt_databases, &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef DBUG_OFF {"debug", '#', "This is a non-debug version. Catch this and exit.", 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, @@ -333,19 +324,17 @@ static struct my_option my_long_options[] = {"debug", '#', "Output debug log.", (char *)&default_dbug_option, (char *)&default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", + {"debug-check", 0, "Check memory and open file usage at exit.", &debug_check_flag, &debug_check_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", - &debug_info_flag, &debug_info_flag, - 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"debug-info", 0, "Print some debug info at exit.", &debug_info_flag, + &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"default-character-set", OPT_DEFAULT_CHARSET, "Set the default character set.", &default_charset, &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED.", - &opt_delayed, &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, - 0, 0}, - {"delete-master-logs", OPT_DELETE_MASTER_LOGS, + {"delayed-insert", 0, "Insert rows with INSERT DELAYED.", + &opt_delayed, &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"delete-master-logs", 0, "Delete logs on master after backup. This automatically enables --master-data.", &opt_delete_master_logs, &opt_delete_master_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -353,9 +342,8 @@ static struct my_option my_long_options[] = "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER " "TABLE tb_name ENABLE KEYS */; will be put in the output.", &opt_disable_keys, &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, - {"dump-date", OPT_DUMP_DATE, "Put a dump date to the end of the output.", - &opt_dump_date, &opt_dump_date, 0, - GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + {"dump-date", 0, "Put a dump date to the end of the output.", + &opt_dump_date, &opt_dump_date, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"dump-history", 'H', "Dump system-versioned tables with history (only for " "timestamp based versioning)", &opt_dump_history, &opt_dump_history, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -372,24 +360,23 @@ static struct my_option my_long_options[] = "Option automatically turns --lock-tables off.", &opt_slave_data, &opt_slave_data, 0, GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0}, - {"events", 'E', "Dump events.", - &opt_events, &opt_events, 0, GET_BOOL, - NO_ARG, 0, 0, 0, 0, 0, 0}, + {"events", 'E', "Dump events.", &opt_events, &opt_events, 0, GET_BOOL, + NO_ARG, 0, 0, 0, 0, 0, 0}, {"extended-insert", 'e', "Use multiple-row INSERT syntax that include several VALUES lists.", &extended_insert, &extended_insert, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, - {"fields-terminated-by", OPT_FTB, + {"fields-terminated-by", 0, "Fields in the output file are terminated by the given string.", &fields_terminated, &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"fields-enclosed-by", OPT_ENC, + {"fields-enclosed-by", 0, "Fields in the output file are enclosed by the given character.", &enclosed, &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0}, - {"fields-optionally-enclosed-by", OPT_O_ENC, + {"fields-optionally-enclosed-by", 0, "Fields in the output file are optionally enclosed by the given character.", &opt_enclosed, &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0}, - {"fields-escaped-by", OPT_ESC, + {"fields-escaped-by", 0, "Fields in the output file are escaped by the given character.", &escaped, &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"flush-logs", 'F', "Flush logs file in server before starting dump. " @@ -401,29 +388,26 @@ static struct my_option my_long_options[] = "to the moment all tables are locked. So if you want your dump and " "the log flush to happen at the same exact moment you should use " "--lock-all-tables or --master-data with --flush-logs.", - &flush_logs, &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, - 0, 0}, - {"flush-privileges", OPT_ESC, "Emit a FLUSH PRIVILEGES statement " + &flush_logs, &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"flush-privileges", 0, "Emit a FLUSH PRIVILEGES statement " "after dumping the mysql database. This option should be used any " "time the dump contains the mysql database and any other database " "that depends on the data in the mysql database for proper restore. ", &flush_privileges, &flush_privileges, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"force", 'f', "Continue even if we get an SQL error.", - &ignore_errors, &ignore_errors, 0, GET_BOOL, NO_ARG, - 0, 0, 0, 0, 0, 0}, + &ignore_errors, &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"gtid", 0, "Used together with --master-data=1 or --dump-slave=1." "When enabled, the output from those options will set the GTID position " "instead of the binlog file and offset; the file/offset will appear only as " "a comment. When disabled, the GTID position will still appear in the " "output, but only commented.", - &opt_use_gtid, &opt_use_gtid, 0, GET_BOOL, NO_ARG, - 0, 0, 0, 0, 0, 0}, + &opt_use_gtid, &opt_use_gtid, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"header", 0, "Used together with --tab. When enabled, adds header with column names to the top of output txt files.", &opt_header, &opt_header, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"hex-blob", OPT_HEXBLOB, "Dump binary strings (BINARY, " + {"hex-blob", 0, "Dump binary strings (BINARY, " "VARBINARY, BLOB) in hexadecimal format.", &opt_hex_blob, &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", ¤t_host, @@ -445,15 +429,13 @@ static struct my_option my_long_options[] = "be specified with both database and table names, e.g., " "--ignore-table=database.table.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"include-master-host-port", OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT, + {"include-master-host-port", 0, "Adds 'MASTER_HOST=, MASTER_PORT=' to 'CHANGE MASTER TO..' " "in dump produced with --dump-slave.", &opt_include_master_host_port, - &opt_include_master_host_port, 0, GET_BOOL, NO_ARG, - 0, 0, 0, 0, 0, 0}, - {"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.", - &opt_ignore, &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, - 0, 0}, - {"lines-terminated-by", OPT_LTB, + &opt_include_master_host_port, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"insert-ignore", 0, "Insert rows with INSERT IGNORE.", + &opt_ignore, &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"lines-terminated-by", 0, "Lines in the output file are terminated by the given string.", &lines_terminated, &lines_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -464,7 +446,7 @@ static struct my_option my_long_options[] = 0, 0, 0, 0, 0, 0}, {"lock-tables", 'l', "Lock all tables for read.", &lock_tables, &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, - {"log-error", OPT_ERROR_LOG_FILE, "Append warnings and errors to given file.", + {"log-error", 0, "Append warnings and errors to given file.", &log_error_file, &log_error_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"log-queries", 0, "When restoring the dump, the server will, if logging turned on, log the queries to the general and slow query log.", @@ -481,30 +463,28 @@ static struct my_option my_long_options[] = "Option automatically turns --lock-tables off.", &opt_master_data, &opt_master_data, 0, GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_MASTER_DATA_COMMENTED_SQL, 0, 0, 0}, - {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, + {"max_allowed_packet", 0, "The maximum packet length to send to or receive from server.", &opt_max_allowed_packet, &opt_max_allowed_packet, 0, GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096, (longlong) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, - {"max-statement-time", MYSQL_OPT_MAX_STATEMENT_TIME, + {"max-statement-time", 0, "Max statement execution time. If unset, overrides server default with 0.", &opt_max_statement_time, &opt_max_statement_time, 0, GET_DOUBLE, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"net_buffer_length", OPT_NET_BUFFER_LENGTH, + {"net_buffer_length", 0, "The buffer size for TCP/IP and socket communication.", &opt_net_buffer_length, &opt_net_buffer_length, 0, GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L, MALLOC_OVERHEAD-1024, 1024, 0}, - {"no-autocommit", OPT_AUTOCOMMIT, + {"no-autocommit", 0, "Wrap tables with autocommit/commit statements.", - &opt_autocommit, &opt_autocommit, 0, GET_BOOL, NO_ARG, - 0, 0, 0, 0, 0, 0}, + &opt_autocommit, &opt_autocommit, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"no-create-db", 'n', "Suppress the CREATE DATABASE ... IF EXISTS statement that normally is " "output for each dumped database if --all-databases or --databases is " "given.", - &opt_create_db, &opt_create_db, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + &opt_create_db, &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"no-create-info", 't', "Don't write table creation info.", &opt_no_create_info, &opt_no_create_info, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -518,7 +498,7 @@ static struct my_option my_long_options[] = {"opt", OPT_OPTIMIZE, "Same as --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys. Enabled by default, disable with --skip-opt.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"order-by-primary", OPT_ORDER_BY_PRIMARY, + {"order-by-primary", 0, "Sorts each table's rows by primary key, or first unique key, if such a key exists. Useful when dumping a MyISAM table to be loaded into an InnoDB table, but will make the dump itself take considerably longer.", &opt_order_by_primary, &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"order-by-size", 0, @@ -545,27 +525,24 @@ static struct my_option my_long_options[] = {"quote-names",'Q', "Quote table and column names with backticks (`).", &opt_quoted, &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, - {"replace", OPT_MYSQL_REPLACE_INTO, "Use REPLACE INTO instead of INSERT INTO.", - &opt_replace_into, &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, - 0, 0}, + {"replace", 0, "Use REPLACE INTO instead of INSERT INTO.", &opt_replace_into, + &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"result-file", 'r', "Direct output to a given file. This option should be used in systems " "(e.g., DOS, Windows) that use carriage-return linefeed pairs (\\r\\n) " "to separate text lines. This option ensures that only a single newline " "is used.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"routines", 'R', "Dump stored routines (functions and procedures).", - &opt_routines, &opt_routines, 0, GET_BOOL, - NO_ARG, 0, 0, 0, 0, 0, 0}, - {"set-charset", OPT_SET_CHARSET, - "Add 'SET NAMES default_character_set' to the output.", - &opt_set_charset, &opt_set_charset, 0, GET_BOOL, NO_ARG, 1, - 0, 0, 0, 0, 0}, + &opt_routines, &opt_routines, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"set-charset", 0, + "Add 'SET NAMES default_character_set' to the output.", &opt_set_charset, + &opt_set_charset, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, /* Note that the combination --single-transaction --master-data will give bullet-proof binlog position only if server >=4.1.3. That's the old "FLUSH TABLES WITH READ LOCK does not block commit" fixed bug. */ - {"single-transaction", OPT_TRANSACTION, + {"single-transaction", 0, "Creates a consistent snapshot by dumping all tables in a single " "transaction. Works ONLY for tables stored in storage engines which " "support multiversioning (currently only InnoDB does); the dump is NOT " @@ -584,7 +561,7 @@ static struct my_option my_long_options[] = &opt_mysql_unix_port, &opt_mysql_unix_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #include - {"system", 256, "Dump system tables as portable SQL", + {"system", 0, "Dump system tables as portable SQL", &opt_system, &opt_system, &opt_system_types, GET_SET, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"tab",'T', "Create tab-separated textfile for each table to given path. (Create .sql " @@ -593,17 +570,16 @@ static struct my_option my_long_options[] = &path, &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"tables", OPT_TABLES, "Overrides option --databases (-B).", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"triggers", OPT_TRIGGERS, "Dump triggers for each dumped table.", + {"triggers", 0, "Dump triggers for each dumped table.", &opt_dump_triggers, &opt_dump_triggers, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, - {"tz-utc", OPT_TZ_UTC, + {"tz-utc", 0, "Set connection time zone to UTC before commencing the dump and add " "SET TIME_ZONE=´+00:00´ to the top of the dump file.", &opt_tz_utc, &opt_tz_utc, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, #ifndef DONT_ALLOW_USER_CHANGE - {"user", 'u', "User for login if not current user.", - ¤t_user, ¤t_user, 0, GET_STR, REQUIRED_ARG, - 0, 0, 0, 0, 0, 0}, + {"user", 'u', "User for login if not current user.", ¤t_user, + ¤t_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif {"verbose", 'v', "Print info about the various stages.", &verbose, &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -613,11 +589,10 @@ static struct my_option my_long_options[] = &where, &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", + {"plugin_dir", 0, "Directory for client-side plugins.", &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"default_auth", OPT_DEFAULT_AUTH, - "Default authentication client-side plugin to use.", + {"default_auth", 0, "Default authentication client-side plugin to use.", &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} @@ -767,56 +742,57 @@ static void write_header(FILE *sql_file, const char *db_name) fputs(">\n", sql_file); check_io(sql_file); } - else if (!opt_compact) + else { - print_comment(sql_file, 0, - "-- MariaDB dump %s-%s, for %s (%s)\n--\n", - VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, - MACHINE_TYPE); - print_comment(sql_file, 0, "-- Host: %s ", - fix_for_comment(current_host ? current_host : "localhost")); - print_comment(sql_file, 0, "Database: %s\n", - fix_for_comment(db_name ? db_name : "")); - print_comment(sql_file, 0, - "-- ------------------------------------------------------\n" - ); - print_comment(sql_file, 0, "-- Server version\t%s\n", - mysql_get_server_info(mysql)); - - if (!opt_logging) - fprintf(sql_file, -"\n/*M!100101 SET LOCAL SQL_LOG_OFF=0, LOCAL LOG_SLOW_QUERY=0 */;"); - - if (opt_set_charset) - fprintf(sql_file, -"\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" -"\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" -"\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" -"\n/*!40101 SET NAMES %s */;\n",default_charset); - - if (opt_tz_utc) + fprintf(sql_file, "/*!999999\\- enable the sandbox mode */ \n"); + if (!opt_compact) { - fprintf(sql_file, "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;\n"); - fprintf(sql_file, "/*!40103 SET TIME_ZONE='+00:00' */;\n"); - } + print_comment(sql_file, 0, "-- MariaDB dump %s-%s, for %s (%s)\n--\n", + VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); + print_comment(sql_file, 0, "-- Host: %s ", + fix_for_comment(current_host ? current_host : "localhost")); + print_comment(sql_file, 0, "Database: %s\n", + fix_for_comment(db_name ? db_name : "")); + print_comment(sql_file, 0, + "-- ------------------------------------------------------\n" + ); + print_comment(sql_file, 0, "-- Server version\t%s\n", + mysql_get_server_info(mysql)); - if (!path) - { - if (!opt_no_create_info) + if (!opt_logging) + fprintf(sql_file, + "\n/*M!100101 SET LOCAL SQL_LOG_OFF=0, LOCAL LOG_SLOW_QUERY=0 */;"); + + if (opt_set_charset) + fprintf(sql_file, + "\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" + "\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" + "\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" + "\n/*!40101 SET NAMES %s */;\n",default_charset); + + if (opt_tz_utc) { - /* We don't need unique checks as the table is created just before */ - fprintf(md_result_file,"\ -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n"); + fprintf(sql_file, "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;\n"); + fprintf(sql_file, "/*!40103 SET TIME_ZONE='+00:00' */;\n"); } - fprintf(md_result_file,"\ -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;\n\ -"); + + if (!path) + { + if (!opt_no_create_info) + { + /* We don't need unique checks as the table is created just before */ + fprintf(md_result_file, + "/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n"); + } + fprintf(md_result_file, + "/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;\n"); + } + fprintf(sql_file, + "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='%s%s%s' */;\n" + "/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */;\n", + path?"":"NO_AUTO_VALUE_ON_ZERO",compatible_mode_normal_str[0]==0?"":",", + compatible_mode_normal_str); } - fprintf(sql_file, - "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='%s%s%s' */;\n" - "/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */;\n", - path?"":"NO_AUTO_VALUE_ON_ZERO",compatible_mode_normal_str[0]==0?"":",", - compatible_mode_normal_str); check_io(sql_file); } } /* write_header */ @@ -1270,8 +1246,9 @@ static int get_options(int *argc, char ***argv) if (opt_slave_data) { opt_lock_all_tables= !opt_single_transaction; - opt_master_data= 0; opt_delete_master_logs= 0; + if (opt_slave_data != MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) + opt_master_data= 0; } /* Ensure consistency of the set of binlog & locking options */ @@ -1284,10 +1261,7 @@ static int get_options(int *argc, char ***argv) return(EX_USAGE); } if (opt_master_data) - { opt_lock_all_tables= !opt_single_transaction; - opt_slave_data= 0; - } if (opt_single_transaction || opt_lock_all_tables) lock_tables= 0; if (enclosed && opt_enclosed) @@ -3135,8 +3109,9 @@ static uint get_table_structure(const char *table, const char *db, char *table_t if (opt_header) dynstr_set_checked(&select_field_names_for_header, ""); } - insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " : - delayed ? " DELAYED " : opt_ignore ? " IGNORE " : ""); + + insert_option= ((delayed && opt_ignore) ? "DELAYED IGNORE " : + delayed ? "DELAYED " : opt_ignore ? "IGNORE " : ""); verbose_msg("-- Retrieving table structure for table %s...\n", table); @@ -6264,17 +6239,12 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos, } - /* SHOW MASTER STATUS reports file and position */ - print_comment(md_result_file, 0, - "\n--\n-- Position to start replication or point-in-time " - "recovery from\n--\n\n"); - fprintf(md_result_file, - "%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", - (use_gtid ? "-- " : comment_prefix), file, offset); + /* gtid */ if (have_mariadb_gtid) { print_comment(md_result_file, 0, - "\n--\n-- GTID to start replication from\n--\n\n"); + "\n-- Preferably use GTID to start replication from GTID " + "position:\n\n"); if (use_gtid) fprintf(md_result_file, "%sCHANGE MASTER TO MASTER_USE_GTID=slave_pos;\n", @@ -6283,6 +6253,19 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos, "%sSET GLOBAL gtid_slave_pos='%s';\n", (!use_gtid ? "-- " : comment_prefix), gtid_pos); } + + /* SHOW MASTER STATUS reports file and position */ + print_comment(md_result_file, 0, + "\n--\n-- Alternately, following is the position of the binary " + "logging from SHOW MASTER STATUS at point of backup." + "\n-- Use this when creating a replica of the primary server " + "where the backup was made." + "\n-- The new server will be connecting to the primary server " + "where the backup was taken." + "\n--\n\n"); + fprintf(md_result_file, + "%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", + (use_gtid ? "-- " : comment_prefix), file, offset); check_io(md_result_file); if (!consistent_binlog_pos) @@ -6361,7 +6344,6 @@ static int do_show_slave_status(MYSQL *mysql_con, int use_gtid, (opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : ""; const char *gtid_comment_prefix= (use_gtid ? comment_prefix : "-- "); const char *nogtid_comment_prefix= (!use_gtid ? comment_prefix : "-- "); - int set_gtid_done= 0; if (mysql_query_with_error_report(mysql_con, &slave, multi_source ? @@ -6377,23 +6359,36 @@ static int do_show_slave_status(MYSQL *mysql_con, int use_gtid, return 1; } + print_comment(md_result_file, 0, + "\n--\n-- The following is the SQL position of the replication " + "taken from SHOW SLAVE STATUS at the time of backup.\n" + "-- Use this position when creating a clone of, or replacement " + "server, from where the backup was taken." + "\n-- This new server will connects to the same primary " + "server%s.\n--\n", + multi_source ? "(s)" : ""); + + if (multi_source) + { + char gtid_pos[MAX_GTID_LENGTH]; + if (have_mariadb_gtid && get_gtid_pos(gtid_pos, 0)) + { + mysql_free_result(slave); + return 1; + } + print_comment(md_result_file, 0, + "-- GTID position to start replication:\n"); + fprintf(md_result_file, "%sSET GLOBAL gtid_slave_pos='%s';\n", + gtid_comment_prefix, gtid_pos); + } + if (use_gtid) + print_comment(md_result_file, 0, + "\n-- Use only the MASTER_USE_GTID=slave_pos or " + "MASTER_LOG_FILE/MASTER_LOG_POS in the statements below." + "\n\n"); + while ((row= mysql_fetch_row(slave))) { - if (multi_source && !set_gtid_done) - { - char gtid_pos[MAX_GTID_LENGTH]; - if (have_mariadb_gtid && get_gtid_pos(gtid_pos, 0)) - { - mysql_free_result(slave); - return 1; - } - if (opt_comments) - fprintf(md_result_file, "\n--\n-- Gtid position to start replication " - "from\n--\n\n"); - fprintf(md_result_file, "%sSET GLOBAL gtid_slave_pos='%s';\n", - gtid_comment_prefix, gtid_pos); - set_gtid_done= 1; - } if (row[9 + multi_source] && row[21 + multi_source]) { if (use_gtid) @@ -6407,11 +6402,6 @@ static int do_show_slave_status(MYSQL *mysql_con, int use_gtid, } /* SHOW MASTER STATUS reports file and position */ - if (opt_comments) - fprintf(md_result_file, - "\n--\n-- Position to start replication or point-in-time " - "recovery from (the master of this slave)\n--\n\n"); - if (multi_source) fprintf(md_result_file, "%sCHANGE MASTER '%.80s' TO ", nogtid_comment_prefix, row[0]); @@ -6432,6 +6422,7 @@ static int do_show_slave_status(MYSQL *mysql_con, int use_gtid, check_io(md_result_file); } } + fprintf(md_result_file, "\n"); mysql_free_result(slave); return 0; } diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 9e6c98e3add..2f8a75c890a 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2011, 2022, MariaDB + Copyright (c) 2011, 2024, MariaDB 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 @@ -70,10 +70,10 @@ static char **argv_to_free; static struct my_option my_long_options[] = { - {"character-sets-dir", OPT_CHARSETS_DIR, + {"character-sets-dir", 0, "Directory for character set files.", (char**) &charsets_dir, (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"default-character-set", OPT_DEFAULT_CHARSET, + {"default-character-set", 0, "Set the default character set.", &default_charset, &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"columns", 'c', @@ -85,31 +85,31 @@ static struct my_option my_long_options[] = 0, 0, 0}, {"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", + {"debug-check", 0, "Check memory and open file usage at exit.", &debug_check_flag, &debug_check_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + {"debug-info", 0, "Print some debug info at exit.", &debug_info_flag, &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"default_auth", OPT_DEFAULT_AUTH, + {"default_auth", 0, "Default authentication client-side plugin to use.", &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"delete", 'd', "First delete all rows from table.", &opt_delete, &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"fields-terminated-by", OPT_FTB, + {"fields-terminated-by", 0, "Fields in the input file are terminated by the given string.", &fields_terminated, &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"fields-enclosed-by", OPT_ENC, + {"fields-enclosed-by", 0, "Fields in the import file are enclosed by the given character.", &enclosed, &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"fields-optionally-enclosed-by", OPT_O_ENC, + {"fields-optionally-enclosed-by", 0, "Fields in the input file are optionally enclosed by the given character.", &opt_enclosed, &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"fields-escaped-by", OPT_ESC, + {"fields-escaped-by", 0, "Fields in the input file are escaped by the given character.", &escaped, &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -126,10 +126,10 @@ static struct my_option my_long_options[] = "Disable foreign key checks while importing the data.", &ignore_foreign_keys, &ignore_foreign_keys, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"ignore-lines", OPT_IGN_LINES, "Ignore first n lines of data infile.", + {"ignore-lines", 0, "Ignore first n lines of data infile.", &opt_ignore_lines, &opt_ignore_lines, 0, GET_LL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"lines-terminated-by", OPT_LTB, + {"lines-terminated-by", 0, "Lines in the input file are terminated by the given string.", &lines_terminated, &lines_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -138,7 +138,7 @@ static struct my_option my_long_options[] = {"lock-tables", 'l', "Lock all tables for write (this disables threads).", &lock_tables, &lock_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"low-priority", OPT_LOW_PRIORITY, + {"low-priority", 0, "Use LOW_PRIORITY when updating the table.", &opt_low_priority, &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"password", 'p', @@ -151,7 +151,7 @@ static struct my_option my_long_options[] = {"parallel", 'j', "Number of LOAD DATA jobs executed in parallel", &opt_use_threads, &opt_use_threads, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", + {"plugin_dir", 0, "Directory for client-side plugins.", &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection or 0 for default to, in " @@ -173,7 +173,7 @@ static struct my_option my_long_options[] = &opt_mysql_unix_port, &opt_mysql_unix_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #include - {"use-threads", OPT_USE_THREADS, "Synonym for --parallel option", + {"use-threads", 0, "Synonym for --parallel option", &opt_use_threads, &opt_use_threads, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DONT_ALLOW_USER_CHANGE diff --git a/client/mysqlshow.c b/client/mysqlshow.c index ddaa65ace3b..7124b233022 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2010, 2019, MariaDB + Copyright (c) 2010, 2024, MariaDB 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 @@ -180,10 +180,10 @@ static struct my_option my_long_options[] = {"character-sets-dir", 'c', "Directory for character set files.", (char**) &charsets_dir, (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"default-character-set", OPT_DEFAULT_CHARSET, + {"default-character-set", 0, "Set the default character set.", &default_charset, &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"count", OPT_COUNT, + {"count", 0, "Show number of rows per table (may be slow for non-MyISAM tables).", &opt_count, &opt_count, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -192,13 +192,13 @@ static struct my_option my_long_options[] = 0, 0, 0}, {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", + {"debug-check", 0, "Check memory and open file usage at exit.", &debug_check_flag, &debug_check_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.", + {"debug-info", 0, "Print some debug info at exit.", &debug_info_flag, &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"default_auth", OPT_DEFAULT_AUTH, + {"default_auth", 0, "Default authentication client-side plugin to use.", &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -215,7 +215,7 @@ static struct my_option my_long_options[] = "Password to use when connecting to server. If password is not given, it's " "solicited on the tty.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", + {"plugin_dir", 0, "Directory for client-side plugins.", &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection or 0 for default to, in " diff --git a/client/mysqlslap.c b/client/mysqlslap.c index ca1c06d0f1f..a52269f89ec 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -1,6 +1,6 @@ /* Copyright (c) 2005, 2015, Oracle and/or its affiliates. - Copyright (c) 2010, 2022, MariaDB + Copyright (c) 2010, 2024, MariaDB 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 @@ -524,50 +524,45 @@ static struct my_option my_long_options[] = "Generate SQL where not supplied by file or command line.", &auto_generate_sql, &auto_generate_sql, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"auto-generate-sql-add-autoincrement", OPT_SLAP_AUTO_GENERATE_ADD_AUTO, + {"auto-generate-sql-add-autoincrement", 0, "Add an AUTO_INCREMENT column to auto-generated tables.", - &auto_generate_sql_autoincrement, - &auto_generate_sql_autoincrement, + &auto_generate_sql_autoincrement, &auto_generate_sql_autoincrement, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"auto-generate-sql-execute-number", OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES, + {"auto-generate-sql-execute-number", 0, "Set this number to generate a set number of queries to run.", &auto_actual_queries, &auto_actual_queries, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"auto-generate-sql-guid-primary", OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY, + {"auto-generate-sql-guid-primary", 0, "Add GUID based primary keys to auto-generated tables.", - &auto_generate_sql_guid_primary, - &auto_generate_sql_guid_primary, + &auto_generate_sql_guid_primary, &auto_generate_sql_guid_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"auto-generate-sql-load-type", OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE, + {"auto-generate-sql-load-type", 0, "Specify test load type: mixed, update, write, key, or read; default is mixed.", (char**) &auto_generate_sql_type, (char**) &auto_generate_sql_type, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"auto-generate-sql-secondary-indexes", - OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES, + {"auto-generate-sql-secondary-indexes", 0, "Number of secondary indexes to add to auto-generated tables.", &auto_generate_sql_secondary_indexes, &auto_generate_sql_secondary_indexes, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"auto-generate-sql-unique-query-number", - OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM, + {"auto-generate-sql-unique-query-number", 0, "Number of unique queries to generate for automatic tests.", &auto_generate_sql_unique_query_number, &auto_generate_sql_unique_query_number, 0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0}, - {"auto-generate-sql-unique-write-number", - OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM, + {"auto-generate-sql-unique-write-number", 0, "Number of unique queries to generate for auto-generate-sql-write-number.", &auto_generate_sql_unique_write_number, &auto_generate_sql_unique_write_number, 0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0}, - {"auto-generate-sql-write-number", OPT_SLAP_AUTO_GENERATE_WRITE_NUM, + {"auto-generate-sql-write-number", 0, "Number of row inserts to perform for each thread (default is 100).", &auto_generate_sql_number, &auto_generate_sql_number, 0, GET_ULL, REQUIRED_ARG, 100, 0, 0, 0, 0, 0}, {"character-sets-dir", OPT_CHARSETS_DIR, "Directory for character set files.", (char **)&charsets_dir, (char **)&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"commit", OPT_SLAP_COMMIT, "Commit records every X number of statements.", + {"commit", 0, "Commit records every X number of statements.", &commit_rate, &commit_rate, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"compress", 'C', "Use compression in server/client protocol.", @@ -576,10 +571,10 @@ static struct my_option my_long_options[] = {"concurrency", 'c', "Number of clients to simulate for query to run.", (char**) &concurrency_str, (char**) &concurrency_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"create", OPT_SLAP_CREATE_STRING, "File or string to use create tables.", + {"create", 0, "File or string to use create tables.", &create_string, &create_string, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"create-schema", OPT_CREATE_SLAP_SCHEMA, "Schema to run tests in.", + {"create-schema", 0, "Schema to run tests in.", (char**) &create_schema_string, (char**) &create_schema_string, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"csv", OPT_SLAP_CSV, @@ -593,12 +588,12 @@ static struct my_option my_long_options[] = (char**) &default_dbug_option, (char**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", + {"debug-check", 0, "Check memory and open file usage at exit.", &debug_check_flag, &debug_check_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"debug-info", 'T', "Print some debug info at exit.", &debug_info_flag, &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"default_auth", OPT_DEFAULT_AUTH, + {"default_auth", 0, "Default authentication client-side plugin to use.", &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -606,7 +601,7 @@ static struct my_option my_long_options[] = "Delimiter to use in SQL statements supplied in file or command line.", (char**) &delimiter, (char**) &delimiter, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"detach", OPT_SLAP_DETACH, + {"detach", 0, "Detach (close and reopen) connections after X number of requests.", &detach_rate, &detach_rate, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -618,14 +613,14 @@ static struct my_option my_long_options[] = GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", &host, &host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"init-command", OPT_INIT_COMMAND, + {"init-command", 0, "SQL Command to execute when connecting to MariaDB server. Will " "automatically be re-executed when reconnecting.", &opt_init_command, &opt_init_command, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"iterations", 'i', "Number of times to run the tests.", &iterations, &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0}, - {"no-drop", OPT_SLAP_NO_DROP, "Do not drop the schema after the test.", + {"no-drop", 0, "Do not drop the schema after the test.", &opt_no_drop, &opt_no_drop, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"number-char-cols", 'x', "Number of VARCHAR columns to create in table if specifying --auto-generate-sql.", @@ -635,11 +630,11 @@ static struct my_option my_long_options[] = "Number of INT columns to create in table if specifying --auto-generate-sql.", (char**) &num_int_cols_opt, (char**) &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"number-of-queries", OPT_MYSQL_NUMBER_OF_QUERY, + {"number-of-queries", 0, "Limit each client to this number of queries (this is not exact).", &num_of_query, &num_of_query, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"only-print", OPT_MYSQL_ONLY_PRINT, + {"only-print", 0, "Do not connect to the databases, but instead print out what would have " "been done.", &opt_only_print, &opt_only_print, 0, GET_BOOL, NO_ARG, @@ -651,25 +646,25 @@ static struct my_option my_long_options[] = {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.", + {"plugin_dir", 0, "Directory for client-side plugins.", &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection.", &opt_mysql_port, &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0}, - {"post-query", OPT_SLAP_POST_QUERY, + {"post-query", 0, "Query to run or file containing query to execute after tests have completed.", &user_supplied_post_statements, &user_supplied_post_statements, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"post-system", OPT_SLAP_POST_SYSTEM, + {"post-system", 0, "system() string to execute after tests have completed.", &post_system, &post_system, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"pre-query", OPT_SLAP_PRE_QUERY, + {"pre-query", 0, "Query to run or file containing query to execute before running tests.", &user_supplied_pre_statements, &user_supplied_pre_statements, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"pre-system", OPT_SLAP_PRE_SYSTEM, + {"pre-system", 0, "system() string to execute before running tests.", &pre_system, &pre_system, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -1631,6 +1626,9 @@ drop_primary_key_list(void) return 0; } + +PRAGMA_DISABLE_CHECK_STACK_FRAME + static int create_schema(MYSQL *mysql, const char *db, statement *stmt, option_string *engine_stmt) @@ -1726,6 +1724,7 @@ limit_not_met: DBUG_RETURN(0); } +PRAGMA_REENABLE_CHECK_STACK_FRAME static int drop_schema(MYSQL *mysql, const char *db) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index c7d20446c7f..595352623db 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -78,7 +78,7 @@ static my_bool non_blocking_api_enabled= 0; #define MAX_DELIMITER_LENGTH 16 #define DEFAULT_MAX_CONN 64 -#define DIE_BUFF_SIZE 256*1024 +#define DIE_BUFF_SIZE 15*1024 #define RESULT_STRING_INIT_MEM 2048 #define RESULT_STRING_INCREMENT_MEM 2048 @@ -404,7 +404,7 @@ enum enum_commands { Q_IF, Q_DISABLE_PARSING, Q_ENABLE_PARSING, Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, - Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP, + Q_WRITE_FILE, Q_WRITE_LINE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP, Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES, Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR, Q_LIST_FILES, Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE, @@ -508,6 +508,7 @@ const char *command_names[]= "remove_file", "file_exists", "write_file", + "write_line", "copy_file", "perl", "die", @@ -623,7 +624,7 @@ void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds, const char *from); ATTRIBUTE_NORETURN -static void cleanup_and_exit(int exit_code); +static void cleanup_and_exit(int exit_code, bool called_from_die); ATTRIBUTE_NORETURN static void really_die(const char *msg); @@ -940,6 +941,7 @@ pthread_attr_t cn_thd_attrib; pthread_handler_t connection_thread(void *arg) { struct st_connection *cn= (struct st_connection*)arg; + DBUG_ENTER("connection_thread"); mysql_thread_init(); while (cn->command != EMB_END_CONNECTION) @@ -951,6 +953,7 @@ pthread_handler_t connection_thread(void *arg) pthread_cond_wait(&cn->query_cond, &cn->query_mutex); pthread_mutex_unlock(&cn->query_mutex); } + DBUG_PRINT("info", ("executing command: %d", cn->command)); switch (cn->command) { case EMB_END_CONNECTION: @@ -971,24 +974,26 @@ pthread_handler_t connection_thread(void *arg) break; case EMB_CLOSE_STMT: cn->result= mysql_stmt_close(cn->stmt); + cn->stmt= 0; break; default: DBUG_ASSERT(0); } - cn->command= 0; pthread_mutex_lock(&cn->result_mutex); cn->query_done= 1; + cn->command= 0; pthread_cond_signal(&cn->result_cond); pthread_mutex_unlock(&cn->result_mutex); } end_thread: - cn->query_done= 1; + DBUG_ASSERT(cn->stmt == 0); mysql_close(cn->mysql); cn->mysql= 0; + cn->query_done= 1; mysql_thread_end(); pthread_exit(0); - return 0; + DBUG_RETURN(0); } static void wait_query_thread_done(struct st_connection *con) @@ -1006,12 +1011,16 @@ static void wait_query_thread_done(struct st_connection *con) static void signal_connection_thd(struct st_connection *cn, int command) { + DBUG_ENTER("signal_connection_thd"); + DBUG_PRINT("enter", ("command: %d", command)); + DBUG_ASSERT(cn->has_thread); cn->query_done= 0; - cn->command= command; pthread_mutex_lock(&cn->query_mutex); + cn->command= command; pthread_cond_signal(&cn->query_cond); pthread_mutex_unlock(&cn->query_mutex); + DBUG_VOID_RETURN; } @@ -1076,27 +1085,37 @@ static int do_stmt_execute(struct st_connection *cn) static int do_stmt_close(struct st_connection *cn) { DBUG_ENTER("do_stmt_close"); - /* The cn->stmt is already set. */ if (!cn->has_thread) - DBUG_RETURN(mysql_stmt_close(cn->stmt)); + { + /* The cn->stmt is already set. */ + int res= mysql_stmt_close(cn->stmt); + cn->stmt= 0; + DBUG_RETURN(res); + } + wait_query_thread_done(cn); signal_connection_thd(cn, EMB_CLOSE_STMT); wait_query_thread_done(cn); + DBUG_ASSERT(cn->stmt == 0); DBUG_RETURN(cn->result); } static void emb_close_connection(struct st_connection *cn) { + DBUG_ENTER("emb_close_connection"); if (!cn->has_thread) - return; + DBUG_VOID_RETURN; wait_query_thread_done(cn); signal_connection_thd(cn, EMB_END_CONNECTION); pthread_join(cn->tid, NULL); cn->has_thread= FALSE; + DBUG_ASSERT(cn->mysql == 0); + DBUG_ASSERT(cn->stmt == 0); pthread_mutex_destroy(&cn->query_mutex); pthread_cond_destroy(&cn->query_cond); pthread_mutex_destroy(&cn->result_mutex); pthread_cond_destroy(&cn->result_cond); + DBUG_VOID_RETURN; } @@ -1120,7 +1139,13 @@ static void init_connection_thd(struct st_connection *cn) #define do_read_query_result(cn) mysql_read_query_result(cn->mysql) #define do_stmt_prepare(cn, q, q_len) mysql_stmt_prepare(cn->stmt, q, (ulong)q_len) #define do_stmt_execute(cn) mysql_stmt_execute(cn->stmt) -#define do_stmt_close(cn) mysql_stmt_close(cn->stmt) + +static int do_stmt_close(struct st_connection *cn) +{ + int res= mysql_stmt_close(cn->stmt); + cn->stmt= 0; + return res; +} #endif /*EMBEDDED_LIBRARY*/ @@ -1448,7 +1473,6 @@ void close_statements() { if (con->stmt) do_stmt_close(con); - con->stmt= 0; } DBUG_VOID_RETURN; } @@ -1519,8 +1543,8 @@ void free_used_memory() void ha_pre_shutdown(); #endif - -ATTRIBUTE_NORETURN static void cleanup_and_exit(int exit_code) +ATTRIBUTE_NORETURN static void cleanup_and_exit(int exit_code, + bool called_from_die) { #ifdef EMBEDDED_LIBRARY if (server_initialized) @@ -1533,16 +1557,6 @@ ATTRIBUTE_NORETURN static void cleanup_and_exit(int exit_code) if (server_initialized) mysql_server_end(); - /* - mysqltest is fundamentally written in a way that makes impossible - to free all memory before exit (consider memory allocated - for frame local DYNAMIC_STRING's and die() invoked down the stack. - - We close stderr here to stop unavoidable safemalloc reports - from polluting the output. - */ - fclose(stderr); - my_end(my_end_arg); if (!silent) { @@ -1562,6 +1576,11 @@ ATTRIBUTE_NORETURN static void cleanup_and_exit(int exit_code) } } + /* + Report memory leaks, if not called from 'die()', as die() will not release + all memory. + */ + sf_leaking_memory= called_from_die; exit(exit_code); } @@ -1628,7 +1647,7 @@ static void really_die(const char *msg) second time, just exit */ if (dying) - cleanup_and_exit(1); + cleanup_and_exit(1, 1); dying= 1; log_file.show_tail(opt_tail_lines); @@ -1640,7 +1659,7 @@ static void really_die(const char *msg) if (cur_con && !cur_con->pending) show_warnings_before_error(cur_con->mysql); - cleanup_and_exit(1); + cleanup_and_exit(1, 1); } void report_or_die(const char *fmt, ...) @@ -1694,7 +1713,7 @@ void abort_not_supported_test(const char *fmt, ...) } va_end(args); - cleanup_and_exit(62); + cleanup_and_exit(62, 0); } @@ -2241,14 +2260,14 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) check_result RETURN VALUES - error - the function will not return - + 0 ok + 1 error */ -void check_result() +int check_result() { const char *mess= 0; - + int error= 1; DBUG_ENTER("check_result"); DBUG_ASSERT(result_file_name); DBUG_PRINT("enter", ("result_file_name: %s", result_file_name)); @@ -2256,7 +2275,10 @@ void check_result() switch (compare_files(log_file.file_name(), result_file_name)) { case RESULT_OK: if (!error_count) + { + error= 0; break; /* ok */ + } mess= "Got errors while running test"; /* Fallthrough */ case RESULT_LENGTH_MISMATCH: @@ -2295,14 +2317,13 @@ void check_result() log_file.file_name(), reject_file, errno); show_diff(NULL, result_file_name, reject_file); - die("%s", mess); + fprintf(stderr, "%s", mess); break; } default: /* impossible */ die("Unknown error code from dyn_string_cmp()"); } - - DBUG_VOID_RETURN; + DBUG_RETURN(error); } @@ -4356,6 +4377,49 @@ void do_write_file(struct st_command *command) do_write_file_command(command, FALSE); } +/** + Write a line to the start of the file. + Truncates existing file, creates new one if it doesn't exist. + + Usage + write_line ; + + Example + --write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + + @note Both the file and the line parameters are evaluated + (can be variables). + + @note This is a better alternative to + exec echo > file, as it doesn't depend on shell, + and can better handle sporadic file access errors caused + by antivirus or backup software on Windows. +*/ +void do_write_line(struct st_command *command) +{ + DYNAMIC_STRING ds_line; + DYNAMIC_STRING ds_filename; + + struct command_arg write_line_args[] = { + { "line", ARG_STRING, FALSE, &ds_line, "line to add" }, + { "filename", ARG_STRING, TRUE, &ds_filename, "File to write to" }, + }; + DBUG_ENTER("do_write_line"); + + check_command_args(command, + command->first_argument, + write_line_args, + sizeof(write_line_args)/sizeof(struct command_arg), + ' '); + + if (bad_path(ds_filename.str)) + DBUG_VOID_RETURN; + dynstr_append_mem(&ds_line, "\n", 1); + str_to_file2(ds_filename.str, ds_line.str, ds_line.length, FALSE); + dynstr_free(&ds_filename); + dynstr_free(&ds_line); + DBUG_VOID_RETURN; +} /* SYNOPSIS @@ -5302,7 +5366,11 @@ void do_shutdown_server(struct st_command *command) */ if (timeout && mysql_shutdown(mysql, SHUTDOWN_DEFAULT)) - die("mysql_shutdown failed"); + { + handle_error(command, mysql_errno(mysql), mysql_error(mysql), + mysql_sqlstate(mysql), &ds_res); + DBUG_VOID_RETURN; + } if (!timeout || wait_until_dead(pid, timeout)) { @@ -5730,7 +5798,6 @@ void do_close_connection(struct st_command *command) #endif /*!EMBEDDED_LIBRARY*/ if (con->stmt) do_stmt_close(con); - con->stmt= 0; #ifdef EMBEDDED_LIBRARY /* As query could be still executed in a separate thread @@ -7429,17 +7496,17 @@ get_one_option(const struct my_option *opt, const char *argument, const char *) break; case 'V': print_version(); - exit(0); + cleanup_and_exit(0,0); case OPT_MYSQL_PROTOCOL: #ifndef EMBEDDED_LIBRARY if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib, opt->name)) <= 0) - exit(1); + cleanup_and_exit(1,0); #endif break; case '?': usage(); - exit(0); + cleanup_and_exit(0,0); } return 0; } @@ -7451,12 +7518,12 @@ int parse_args(int argc, char **argv) default_argv= argv; if ((handle_options(&argc, &argv, my_long_options, get_one_option))) - exit(1); + cleanup_and_exit(1, 0); if (argc > 1) { usage(); - exit(1); + cleanup_and_exit(1, 0); } if (argc == 1) opt_db= *argv; @@ -7523,7 +7590,7 @@ void str_to_file2(const char *fname, char *str, size_t size, my_bool append) die("Could not open '%s' for writing, errno: %d", buff, errno); if (append && my_seek(fd, 0, SEEK_END, MYF(0)) == MY_FILEPOS_ERROR) die("Could not find end of file '%s', errno: %d", buff, errno); - if (my_write(fd, (uchar*)str, size, MYF(MY_WME|MY_FNABP))) + if (size > 0 && my_write(fd, (uchar*)str, size, MYF(MY_WME|MY_FNABP))) die("write failed, errno: %d", errno); my_close(fd, MYF(0)); } @@ -8318,7 +8385,7 @@ static int match_expected_error(struct st_command *command, SYNOPSIS handle_error() - q - query context + command - command err_errno - error number err_error - error message err_sqlstate - sql state @@ -8577,7 +8644,7 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, my_bool ds_res_1st_execution_init = FALSE; my_bool compare_2nd_execution = TRUE; int query_match_ps2_re; - + MYSQL_RES *res; DBUG_ENTER("run_query_stmt"); DBUG_PRINT("query", ("'%-.60s'", query)); DBUG_PRINT("info", @@ -8783,10 +8850,13 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, The --enable_prepare_warnings command can be used to change this so that warnings from both the prepare and execute phase are shown. */ - if ((mysql_stmt_result_metadata(stmt) != NULL) && - !disable_warnings && - !prepare_warnings_enabled) - dynstr_set(&ds_prepare_warnings, NULL); + if ((res= mysql_stmt_result_metadata(stmt))) + { + if (!disable_warnings && + !prepare_warnings_enabled) + dynstr_set(&ds_prepare_warnings, NULL); + mysql_free_result(res); + } /* Fetch info before fetching warnings, since it will be reset @@ -9915,6 +9985,7 @@ static sig_handler signal_handler(int sig) fflush(stderr); my_write_core(sig); #ifndef _WIN32 + sf_leaking_memory= 1; exit(1); // Shouldn't get here but just in case #endif } @@ -9988,12 +10059,10 @@ int main(int argc, char **argv) uint command_executed= 0, last_command_executed= 0; char save_file[FN_REFLEN]; bool empty_result= FALSE; + int error= 0; MY_INIT(argv[0]); DBUG_ENTER("main"); - /* mysqltest has no way to free all its memory correctly */ - sf_leaking_memory= 1; - save_file[0]= 0; TMPDIR[0]= 0; @@ -10308,6 +10377,7 @@ int main(int argc, char **argv) break; case Q_FILE_EXIST: do_file_exist(command); break; case Q_WRITE_FILE: do_write_file(command); break; + case Q_WRITE_LINE: do_write_line(command); break; case Q_APPEND_FILE: do_append_file(command); break; case Q_DIFF_FILES: do_diff_files(command); break; case Q_SEND_QUIT: do_send_quit(command); break; @@ -10675,7 +10745,7 @@ int main(int argc, char **argv) die("Test ended with parsing disabled"); /* - The whole test has been executed _successfully_. + The whole test has been executed successfully. Time to compare result or save it to record file. The entire output from test is in the log file */ @@ -10698,7 +10768,7 @@ int main(int argc, char **argv) else { /* Check that the output from test is equal to result file */ - check_result(); + error= check_result(); } } } @@ -10708,7 +10778,8 @@ int main(int argc, char **argv) if (! result_file_name || record || compare_files (log_file.file_name(), result_file_name)) { - die("The test didn't produce any output"); + fprintf(stderr, "mysqltest: The test didn't produce any output\n"); + error= 1; } else { @@ -10717,12 +10788,15 @@ int main(int argc, char **argv) } if (!command_executed && result_file_name && !empty_result) - die("No queries executed but non-empty result file found!"); + { + fprintf(stderr, "mysqltest: No queries executed but non-empty result file found!\n"); + error= 1; + } - verbose_msg("Test has succeeded!"); + if (!error) + verbose_msg("Test has succeeded!"); timer_output(); - /* Yes, if we got this far the test has succeeded! Sakila smiles */ - cleanup_and_exit(0); + cleanup_and_exit(error, 0); return 0; /* Keep compiler happy too */ } diff --git a/cmake/FindPMEM.cmake b/cmake/FindPMEM.cmake deleted file mode 100644 index 024436444d2..00000000000 --- a/cmake/FindPMEM.cmake +++ /dev/null @@ -1,18 +0,0 @@ -if(PMEM_LIBRARIES) - set(PMEM_FOUND TRUE) - return() -endif() -if(DEFINED PMEM_LIBRARIES) - set(PMEM_FOUND FALSE) - return() -endif() - -find_path(PMEM_INCLUDE_DIRS NAMES libpmem.h) -find_library(PMEM_LIBRARIES NAMES pmem) - -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS( - PMEM DEFAULT_MSG - PMEM_LIBRARIES PMEM_INCLUDE_DIRS) - -mark_as_advanced(PMEM_INCLUDE_DIRS PMEM_LIBRARIES) diff --git a/cmake/libutils.cmake b/cmake/libutils.cmake index 74853c36a74..3263c08ec44 100644 --- a/cmake/libutils.cmake +++ b/cmake/libutils.cmake @@ -379,5 +379,11 @@ FUNCTION (MAYBE_DISABLE_IPO target) INTERPROCEDURAL_OPTIMIZATION_RELEASE OFF INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO OFF INTERPROCEDURAL_OPTIMIZATION_MINSIZEREL OFF) + IF(CMAKE_CONFIGURATION_TYPES) + FOREACH(cfg ${CMAKE_CONFIGURATION_TYPES}) + STRING(TOUPPER "${cfg}" cfg_upper) + SET_TARGET_PROPERTIES(${target} PROPERTIES INTERPROCEDURAL_OPTIMIZATION_${cfg_upper} OFF) + ENDFOREACH() + ENDIF() ENDIF() ENDFUNCTION() diff --git a/cmake/mariadb_connector_c.cmake b/cmake/mariadb_connector_c.cmake index a9b103345cd..b4f56597775 100644 --- a/cmake/mariadb_connector_c.cmake +++ b/cmake/mariadb_connector_c.cmake @@ -40,6 +40,13 @@ SET(CLIENT_PLUGIN_PVIO_SOCKET STATIC) MESSAGE("== Configuring MariaDB Connector/C") ADD_SUBDIRECTORY(libmariadb) +IF(MSVC AND TARGET mariadb_obj AND TARGET mariadbclient) + # With MSVC, do not produce LTCG-compiled static client libraries. + # They are not usable by end-users, being tied to exact compiler version + MAYBE_DISABLE_IPO(mariadb_obj) + MAYBE_DISABLE_IPO(mariadbclient) +ENDIF() + IF(UNIX) INSTALL(CODE "EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E make_directory \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}) diff --git a/cmake/os/AIX.cmake b/cmake/os/AIX.cmake index 7513c4f42c2..299b79198c6 100644 --- a/cmake/os/AIX.cmake +++ b/cmake/os/AIX.cmake @@ -34,8 +34,5 @@ ELSE() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -maix64 -pthread -mcmodel=large") ENDIF() -# fcntl(fd, F_SETFL, O_DIRECT) is not supported; O_DIRECT is an open(2) flag -SET(HAVE_FCNTL_DIRECT 0 CACHE INTERNAL "") - # make it WARN by default, not AUTO (that implies -Werror) SET(MYSQL_MAINTAINER_MODE "WARN" CACHE STRING "Enable MariaDB maintainer-specific warnings. One of: NO (warnings are disabled) WARN (warnings are enabled) ERR (warnings are errors) AUTO (warnings are errors in Debug only)") diff --git a/cmake/os/SunOS.cmake b/cmake/os/SunOS.cmake index 3d99d34789a..3a9d2dccb87 100644 --- a/cmake/os/SunOS.cmake +++ b/cmake/os/SunOS.cmake @@ -17,10 +17,6 @@ INCLUDE(CheckSymbolExists) INCLUDE(CheckCSourceRuns) INCLUDE(CheckCSourceCompiles) -# fcntl(fd, F_SETFL, O_DIRECT) is not supported, -# and directio(3C) would only work on UFS or NFS, not ZFS. -SET(HAVE_FCNTL_DIRECT 0 CACHE INTERNAL "") - # Enable 64 bit file offsets SET(_FILE_OFFSET_BITS 64) diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake index 16f6060fdff..e224fcbd0a0 100644 --- a/cmake/os/WindowsCache.cmake +++ b/cmake/os/WindowsCache.cmake @@ -43,7 +43,6 @@ SET(HAVE_EXECINFO_H CACHE INTERNAL "") SET(HAVE_FCHMOD CACHE INTERNAL "") SET(HAVE_FCNTL CACHE INTERNAL "") SET(HAVE_FCNTL_H 1 CACHE INTERNAL "") -SET(HAVE_FCNTL_DIRECT 0 CACHE INTERNAL "") SET(HAVE_FCNTL_NONBLOCK CACHE INTERNAL "") SET(HAVE_FDATASYNC CACHE INTERNAL "") SET(HAVE_DECL_FDATASYNC CACHE INTERNAL "") diff --git a/cmake/pcre.cmake b/cmake/pcre.cmake index 3c427b881fc..f42db939bd3 100644 --- a/cmake/pcre.cmake +++ b/cmake/pcre.cmake @@ -4,6 +4,9 @@ SET(WITH_PCRE "auto" CACHE STRING "Which pcre to use (possible values are 'bundled', 'system', or 'auto')") MACRO(BUNDLE_PCRE2) + SET(WITH_PCRE "bundled" CACHE STRING + "Which pcre to use (possible values are 'bundled', 'system', or 'auto')") + SET(dir "${CMAKE_BINARY_DIR}/extra/pcre2") SET(PCRE_INCLUDE_DIRS ${dir}/src/pcre2-build ${dir}/src/pcre2/src) MESSAGE(STATUS "Will download and bundle pcre2") @@ -41,21 +44,21 @@ MACRO(BUNDLE_PCRE2) SET(byproducts ${byproducts} BUILD_BYPRODUCTS ${file} ${file_d}) SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LOCATION ${file}) ENDFOREACH() + FOREACH(v "" "_DEBUG" "_RELWITHDEBINFO" "_RELEASE" "_MINSIZEREL") - STRING(REPLACE "/WX" "" pcre2_flags${v} "${CMAKE_C_FLAGS${v}}") - SET(pcre2_flags${v} "${pcre2_flags${v}} -std=c99 ") + SET(pcre2_flags${v} "${CMAKE_C_FLAGS${v}}") IF(MSVC) + STRING(REPLACE "/WX" "" pcre2_flags${v} "${pcre2_flags${v}}") # Suppress a warning - STRING(APPEND pcre2_flags${v} " /wd4244 " ) - # Disable asan support - STRING(REPLACE "-fsanitize=address" "" pcre2_flags${v} "${CMAKE_C_FLAGS${v}}") + STRING(APPEND pcre2_flags${v} " /wd4244 /wd4267 " ) ENDIF() ENDFOREACH() + ExternalProject_Add( pcre2 PREFIX "${dir}" - URL "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.zip" - URL_MD5 fe90992fbfb03f854bd9f344074f49eb + URL "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.43/pcre2-10.43.zip" + URL_MD5 b58f050f2fdd6f2ca5774a2975377a85 INSTALL_COMMAND "" CMAKE_ARGS "-DCMAKE_WARN_DEPRECATED=FALSE" diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index e8ba59f2873..43b9db15712 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -46,7 +46,7 @@ MACRO(MYSQL_ADD_PLUGIN) ${CMAKE_SOURCE_DIR}/sql ${PCRE_INCLUDE_DIRS} ${SSL_INCLUDE_DIRS} - ${ZLIB_INCLUDE_DIR}) + ${ZLIB_INCLUDE_DIRS}) LIST(GET ARG_UNPARSED_ARGUMENTS 0 plugin) SET(SOURCES ${ARG_UNPARSED_ARGUMENTS}) diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake index 4cddba6f9a5..a050a2ba343 100644 --- a/cmake/ssl.cmake +++ b/cmake/ssl.cmake @@ -53,12 +53,13 @@ MACRO (MYSQL_USE_BUNDLED_SSL) ${CMAKE_SOURCE_DIR}/extra/wolfssl/wolfssl ${CMAKE_SOURCE_DIR}/extra/wolfssl/wolfssl/wolfssl ) - SET(SSL_LIBRARIES wolfssl wolfcrypt) + SET(SSL_LIBRARIES wolfssl) SET(SSL_INCLUDE_DIRS ${INC_DIRS}) SET(SSL_DEFINES "-DHAVE_OPENSSL -DHAVE_WOLFSSL -DWOLFSSL_USER_SETTINGS") SET(HAVE_ERR_remove_thread_state ON CACHE INTERNAL "wolfssl doesn't have ERR_remove_thread_state") SET(HAVE_EncryptAes128Ctr ON CACHE INTERNAL "wolfssl does support AES-CTR") SET(HAVE_EncryptAes128Gcm OFF CACHE INTERNAL "wolfssl does not support AES-GCM") + SET(HAVE_des ON CACHE INTERNAL "wolfssl does support DES API") SET(HAVE_hkdf ON CACHE INTERNAL "wolfssl does support EVP_PKEY API") CHANGE_SSL_SETTINGS("bundled") ADD_SUBDIRECTORY(extra/wolfssl) @@ -156,6 +157,8 @@ MACRO (MYSQL_CHECK_SSL) HAVE_EncryptAes128Ctr) CHECK_SYMBOL_EXISTS(EVP_aes_128_gcm "openssl/evp.h" HAVE_EncryptAes128Gcm) + CHECK_SYMBOL_EXISTS(DES_set_key_unchecked "openssl/des.h" + HAVE_des) CHECK_SYMBOL_EXISTS(EVP_PKEY_CTX_set_hkdf_md "string.h;stdarg.h;openssl/kdf.h" HAVE_hkdf) SET(CMAKE_REQUIRED_INCLUDES) diff --git a/cmake/zlib.cmake b/cmake/zlib.cmake index 9e085189e4f..a933194cd33 100644 --- a/cmake/zlib.cmake +++ b/cmake/zlib.cmake @@ -14,9 +14,12 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA MACRO (MYSQL_USE_BUNDLED_ZLIB) - SET(ZLIB_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/zlib ${CMAKE_BINARY_DIR}/zlib) + SET(ZLIB_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/zlib ${CMAKE_BINARY_DIR}/zlib) SET(BUILD_BUNDLED_ZLIB 1) - SET(ZLIB_LIBRARY zlib CACHE INTERNAL "Bundled zlib library") + SET(ZLIB_LIBRARIES zlib CACHE INTERNAL "Bundled zlib library") + # temporarily define ZLIB_LIBRARY and ZLIB_INCLUDE_DIR for libmariadb + SET(ZLIB_LIBRARY ${ZLIB_LIBRARIES}) + SET(ZLIB_INCLUDE_DIR ${ZLIB_INCLUDE_DIRS}) SET(ZLIB_FOUND TRUE) SET(WITH_ZLIB "bundled" CACHE STRING "Use bundled zlib") ADD_SUBDIRECTORY(zlib) @@ -29,7 +32,7 @@ ENDMACRO() # If this is set,we use bundled zlib # If this is not set,search for system zlib. # if system zlib is not found, use bundled copy -# ZLIB_LIBRARIES, ZLIB_INCLUDE_DIR and ZLIB_SOURCES +# ZLIB_LIBRARIES, ZLIB_INCLUDE_DIRS # are set after this macro has run MACRO (MYSQL_CHECK_ZLIB_WITH_COMPRESS) @@ -37,10 +40,14 @@ MACRO (MYSQL_CHECK_ZLIB_WITH_COMPRESS) IF(WITH_ZLIB STREQUAL "bundled") MYSQL_USE_BUNDLED_ZLIB() ELSE() - INCLUDE(FindZLIB) + FIND_PACKAGE(PkgConfig QUIET) + IF(PKG_CONFIG_FOUND AND (COMMAND PKG_GET_VARIABLE) AND (NOT WIN32)) + PKG_GET_VARIABLE(ZLIB_ROOT zlib prefix) + ENDIF() + FIND_PACKAGE(ZLIB) IF(ZLIB_FOUND) INCLUDE(CheckFunctionExists) - SET(CMAKE_REQUIRED_LIBRARIES z) + SET(CMAKE_REQUIRED_LIBRARIES ${ZLIB_LIBRARIES}) CHECK_FUNCTION_EXISTS(crc32 HAVE_CRC32) CHECK_FUNCTION_EXISTS(compressBound HAVE_COMPRESSBOUND) CHECK_FUNCTION_EXISTS(deflateBound HAVE_DEFLATEBOUND) @@ -48,7 +55,6 @@ MACRO (MYSQL_CHECK_ZLIB_WITH_COMPRESS) IF(HAVE_CRC32 AND HAVE_COMPRESSBOUND AND HAVE_DEFLATEBOUND) SET(WITH_ZLIB "system" CACHE STRING "Which zlib to use (possible values are 'bundled' or 'system')") - SET(ZLIB_SOURCES "") ELSE() SET(ZLIB_FOUND FALSE CACHE INTERNAL "Zlib found but not usable") MESSAGE(STATUS "system zlib found but not usable") diff --git a/config.h.cmake b/config.h.cmake index 4dbeb45d561..11e62b51355 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -30,7 +30,6 @@ #cmakedefine HAVE_DLFCN_H 1 #cmakedefine HAVE_EXECINFO_H 1 #cmakedefine HAVE_FCNTL_H 1 -#cmakedefine HAVE_FCNTL_DIRECT 1 #cmakedefine HAVE_FENV_H 1 #cmakedefine HAVE_FLOAT_H 1 #cmakedefine HAVE_FNMATCH_H 1 @@ -499,6 +498,7 @@ #cmakedefine HAVE_COMPRESS 1 #cmakedefine HAVE_EncryptAes128Ctr 1 #cmakedefine HAVE_EncryptAes128Gcm 1 +#cmakedefine HAVE_des 1 #cmakedefine HAVE_hkdf 1 /* diff --git a/configure.cmake b/configure.cmake index c46b8cc71ab..85cf352eba6 100644 --- a/configure.cmake +++ b/configure.cmake @@ -60,15 +60,6 @@ IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang" AND (NOT MSVC)) ENDIF() ENDIF() -# workaround for old gcc on x86, gcc atomic ops only work under -march=i686 -IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "i686" AND CMAKE_COMPILER_IS_GNUCC AND - CMAKE_C_COMPILER_VERSION VERSION_LESS "4.4.0") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i686") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=i686") - # query_response_time.cc causes "error: unable to find a register to spill" - SET(PLUGIN_QUERY_RESPONSE_TIME NO CACHE BOOL "Disabled, gcc is too old") -ENDIF() - # use runtime atomic-support detection in aarch64 IF(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") MY_CHECK_AND_SET_COMPILER_FLAG("-moutline-atomics") @@ -705,7 +696,6 @@ CHECK_SYMBOL_EXISTS(O_NONBLOCK "unistd.h;fcntl.h" HAVE_FCNTL_NONBLOCK) IF(NOT HAVE_FCNTL_NONBLOCK) SET(NO_FCNTL_NONBLOCK 1) ENDIF() -CHECK_SYMBOL_EXISTS(O_DIRECT "fcntl.h" HAVE_FCNTL_DIRECT) # # Test for how the C compiler does inline, if at all @@ -985,3 +975,8 @@ IF(have_C__Werror) ) SET(CMAKE_REQUIRED_FLAGS ${SAVE_CMAKE_REQUIRED_FLAGS}) ENDIF() + +IF(CMAKE_C_COMPILER_ID MATCHES "Intel") + MY_CHECK_AND_SET_COMPILER_FLAG("-no-ansi-alias") + MY_CHECK_AND_SET_COMPILER_FLAG("-fp-model precise") +ENDIF() diff --git a/debian/autobake-deb.sh b/debian/autobake-deb.sh index faf443f8628..0e1b771b6cc 100755 --- a/debian/autobake-deb.sh +++ b/debian/autobake-deb.sh @@ -51,12 +51,6 @@ replace_uring_with_aio() -e '/-DWITH_URING=ON/d' -i debian/rules } -disable_pmem() -{ - sed '/libpmem-dev/d' -i debian/control - sed '/-DWITH_PMEM=ON/d' -i debian/rules -} - disable_libfmt() { # 7.0+ required @@ -96,10 +90,6 @@ in "buster") disable_libfmt replace_uring_with_aio - if [ ! "$architecture" = amd64 ] - then - disable_pmem - fi ;& "bullseye") add_lsb_base_depends @@ -107,10 +97,6 @@ in "bookworm") # mariadb-plugin-rocksdb in control is 4 arches covered by the distro rocksdb-tools # so no removal is necessary. - if [[ ! "$architecture" =~ amd64|arm64|ppc64el ]] - then - disable_pmem - fi if [[ ! "$architecture" =~ amd64|arm64|armel|armhf|i386|mips64el|mipsel|ppc64el|s390x ]] then replace_uring_with_aio @@ -129,10 +115,6 @@ in add_lsb_base_depends ;& "lunar"|"mantic") - if [[ ! "$architecture" =~ amd64|arm64|ppc64el ]] - then - disable_pmem - fi if [[ ! "$architecture" =~ amd64|arm64|armhf|ppc64el|s390x ]] then replace_uring_with_aio diff --git a/debian/control b/debian/control index 153f0802819..945a11a3cef 100644 --- a/debian/control +++ b/debian/control @@ -5,7 +5,7 @@ Maintainer: MariaDB Developers Build-Depends: bison, cmake, cracklib-runtime , - debhelper (>= 10), + debhelper (>= 11), default-jdk, dh-exec, flex [amd64], @@ -35,7 +35,6 @@ Build-Depends: bison, libnuma-dev [linux-any], libpam0g-dev, libpcre2-dev, - libpmem-dev [amd64 arm64 ppc64el riscv64], libsnappy-dev, libssl-dev, libssl-dev:native, diff --git a/debian/mariadb-server.install b/debian/mariadb-server.install index 9023894b183..c0f6dc1e32e 100644 --- a/debian/mariadb-server.install +++ b/debian/mariadb-server.install @@ -8,6 +8,10 @@ etc/logrotate.d/mariadb etc/security/user_map.conf lib/*/security/pam_user_map.so lib/systemd/system/mariadb@bootstrap.service.d/use_galera_new_cluster.conf +lib/systemd/system/mariadb-extra@.socket +lib/systemd/system/mariadb.service +lib/systemd/system/mariadb@.service +lib/systemd/system/mariadb@.socket lib/systemd/system/mysql.service lib/systemd/system/mysqld.service support-files/rpm/enable_encryption.preset etc/mysql/mariadb.conf.d/99-enable-encryption.cnf.preset @@ -69,6 +73,7 @@ usr/share/man/man1/myisam_ftdump.1 usr/share/man/man1/myisamchk.1 usr/share/man/man1/myisamlog.1 usr/share/man/man1/myisampack.1 +usr/share/man/man1/wsrep_sst_backup.1 usr/share/man/man1/wsrep_sst_common.1 usr/share/man/man1/wsrep_sst_mariabackup.1 usr/share/man/man1/wsrep_sst_mysqldump.1 diff --git a/debian/mariadb-server.mariadb.init b/debian/mariadb-server.mariadb.init index 960e5de60cf..26439cf44e4 100644 --- a/debian/mariadb-server.mariadb.init +++ b/debian/mariadb-server.mariadb.init @@ -88,7 +88,7 @@ sanity_checks() { # If datadir location is not changed int configuration # then it's not printed with /usr/sbin/mariadbd --print-defaults # then we use 'sane' default. - if [ -z "$datadir"] + if [ -z "$datadir" ] then datadir="/var/lib/mysql" fi diff --git a/debian/mariadb-server.postinst b/debian/mariadb-server.postinst index 59d6735fb63..298f551fdcf 100644 --- a/debian/mariadb-server.postinst +++ b/debian/mariadb-server.postinst @@ -285,28 +285,5 @@ esac db_stop # in case invoke fails -# dh_systemd_start doesn't emit anything since we still ship /etc/init.d/mariadb. -# Thus MariaDB server is started via init.d script, which in turn redirects to -# systemctl. If we upgrade from MySQL mysql.service may be masked, which also -# means init.d script is disabled. Unmask mysql service explicitly. -# Check first that the command exists, to avoid emitting any warning messages. -if [ -x "$(command -v deb-systemd-helper)" ] -then - deb-systemd-helper unmask mysql.service > /dev/null -fi - #DEBHELPER# -# Modified dh_systemd_start snippet that's not added automatically -if [ -d /run/systemd/system ] -then - systemctl --system daemon-reload >/dev/null || true - deb-systemd-invoke start mariadb.service >/dev/null || true - # Modified dh_installinit snippet to only run with sysvinit -elif [ -x "/etc/init.d/mariadb" ] -then - if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] - then - invoke-rc.d mariadb start || exit $? - fi -fi diff --git a/debian/mariadb-server.postrm b/debian/mariadb-server.postrm index 4b62a8910fa..841be00b6c6 100644 --- a/debian/mariadb-server.postrm +++ b/debian/mariadb-server.postrm @@ -12,50 +12,7 @@ fi ${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*" 1>&2 } -MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf" - -# Try to stop the server in a sane way. If it does not success let the admin -# do it himself. No database directories should be removed while the server -# is running! Another mariadbd in e.g. a different chroot is fine for us. -stop_server() { - # Return immediately if there are no mysqld processes running - # as there is no point in trying to shutdown in that case. - if ! pgrep -x --nslist pid --ns $$ "mysqld|mariadbd" > /dev/null - then - return - fi - - set +e - invoke-rc.d mariadb stop - invoke-rc.d mysql stop # Backwards compatibility - errno=$? - set -e - - # systemctl could emit exit code 100=no init script (fresh install) - if [ "$errno" != 0 ] && [ "$errno" != 100 ] - then - echo "Attempt to stop MariaDB/MySQL server returned exitcode $errno" 1>&2 - echo "There is a MariaDB/MySQL server running, but we failed in our attempts to stop it." 1>&2 - echo "Stop it yourself and try again!" 1>&2 - db_stop - exit 1 - fi -} - - -case "$1" in - purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) - if [ -n "$($MYADMIN ping 2>/dev/null)" ] - then - stop_server - sleep 2 - fi - ;; - *) - echo "postrm called with unknown argument '$1'" 1>&2 - exit 1 - ;; -esac +#DEBHELPER# # # - Purge logs and data only if they are ours (#307473) diff --git a/debian/mariadb-server.prerm b/debian/mariadb-server.prerm deleted file mode 100644 index e46f1d7817a..00000000000 --- a/debian/mariadb-server.prerm +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -set -e - -#DEBHELPER# - -# Modified dh_systemd_start snippet that's not added automatically -if [ -d /run/systemd/system ] -then - deb-systemd-invoke stop mariadb.service >/dev/null - # Modified dh_installinit snippet to only run with sysvinit -elif [ -x "/etc/init.d/mariadb" ] -then - invoke-rc.d mariadb stop || exit $? -fi diff --git a/debian/not-installed b/debian/not-installed index 25b94333982..705d8c906f9 100644 --- a/debian/not-installed +++ b/debian/not-installed @@ -5,11 +5,7 @@ etc/mysql/mariadb.conf.d/enable_encryption.preset # Debian packaging uses files etc/mysql/mariadb.conf.d/mysql-clients.cnf # Debian packaging uses files from debian/additions/mariadb.cnf.d/ etc/mysql/mariadb.conf.d/server.cnf # Debian packaging uses files from debian/additions/mariadb.cnf.d/ lib/systemd/system/mariadb-extra.socket # Installed by rules file -lib/systemd/system/mariadb-extra@.socket # Installed by rules file -lib/systemd/system/mariadb.service # Installed by rules file -lib/systemd/system/mariadb@.service # Installed by rules file lib/systemd/system/mariadb.socket # Installed by rules file -lib/systemd/system/mariadb@.socket # Installed by rules file usr/bin/mariadb-embedded # Shipping the embedded server in distro packaging does not make sense usr/bin/mysql_config # Debian packaging has mysql_config as symlink to mariadb_config usr/bin/mysql_embedded # Symlink to mariadb-embedded which is intentionally not included diff --git a/debian/rules b/debian/rules index 10915411a45..d010a880f13 100755 --- a/debian/rules +++ b/debian/rules @@ -24,7 +24,7 @@ ifneq (,$(filter linux,$(DEB_HOST_ARCH_OS))) endif BUILDDIR := builddir -DEB_VERSION_REVISION := $(shell echo $(DEB_VERSION) | sed -e 's/^.*-//') +DEB_VERSION_REVISION := $(shell echo $(DEB_VERSION) | sed -e 's/.*[~-]\(.*\)/\1/') DEB_VERSION_VERSION := $(shell echo $(DEB_VERSION) | sed -e 's/^.*:\(.*\)\(-\|+\).*/\1/') DEB_VERSION_MAJOR := $(shell echo $(DEB_VERSION_VERSION) | sed -e 's/^\(.*\)\..*$$/\1/') RELEASE := $(shell lsb_release -r -s) # Use changelog based DEB_DISTRIBUTION instead? @@ -51,12 +51,6 @@ ifeq (32,$(DEB_HOST_ARCH_BITS)) CMAKEFLAGS += -DPLUGIN_ROCKSDB=NO endif -# Only attempt to build with PMEM on archs that have package libpmem-dev available -# See https://packages.debian.org/search?searchon=names&keywords=libpmem-dev -ifneq (,$(filter $(DEB_HOST_ARCH),amd64 arm64 ppc64el riscv64)) - CMAKEFLAGS += -DWITH_PMEM=ON -endif - # Add support for verbose builds MAKEFLAGS += VERBOSE=1 @@ -98,7 +92,6 @@ endif -DCOMPILATION_COMMENT="mariadb.org binary distribution" \ -DMYSQL_SERVER_SUFFIX="-$(DEB_VERSION_REVISION)" \ -DSYSTEM_TYPE="debian-$(DEB_HOST_GNU_SYSTEM)" \ - -DCMAKE_SYSTEM_PROCESSOR=$(DEB_HOST_ARCH) \ -DBUILD_CONFIG=mysql_release \ -DCONC_DEFAULT_CHARSET=utf8mb4 \ -DPLUGIN_AWS_KEY_MANAGEMENT=NO \ @@ -133,16 +126,6 @@ override_dh_auto_install: dh_testdir dh_testroot -ifneq (,$(filter linux,$(DEB_HOST_ARCH_OS))) - # Copy systemd files to a location available for dh_installinit - cp $(BUILDDIR)/support-files/mariadb.service debian/mariadb-server.mariadb.service - cp $(BUILDDIR)/support-files/mariadb.socket debian/mariadb-server.mariadb.socket - cp $(BUILDDIR)/support-files/mariadb-extra.socket debian/mariadb-server.mariadb-extra.socket - cp $(BUILDDIR)/support-files/mariadb@.service debian/mariadb-server.mariadb@.service - cp $(BUILDDIR)/support-files/mariadb@.socket debian/mariadb-server.mariadb@.socket - cp $(BUILDDIR)/support-files/mariadb-extra@.socket debian/mariadb-server.mariadb-extra@.socket -endif - # Run 'make install' without output since it is uninteresting and # silencing it helps to make overall build log shorter and more readable @echo "Running $(MAKE) install DESTDIR=$(TMP) ..." @@ -185,8 +168,8 @@ endif # Move test plugins that are only needed by the client to the libmariadb path mv -v $(TMP)/usr/lib/mysql/plugin/qa_auth_client.so $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb3/plugin/ -override_dh_systemd_enable: - dh_systemd_enable --name=mariadb +override_dh_installsystemd: + dh_systemd_enable --name=mariadb mariadb.service dh_systemd_enable --no-enable --name=mariadb mariadb.socket dh_systemd_enable --no-enable --name=mariadb-extra mariadb-extra.socket dh_systemd_enable --no-enable --name=mariadb@ mariadb.socket @@ -196,7 +179,7 @@ override_dh_systemd_enable: # Start MariaDB at sequence number 19 before 20 where apache, proftpd etc gets # started which might depend on a running database server. override_dh_installinit-arch: - dh_installinit --name=mariadb --no-start -- defaults 19 21 + dh_installinit --name=mariadb -- defaults 19 21 dh_systemd_start --restart-after-upgrade # Use custom server version string variable diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt index 34a83d19e32..0bcbb4f5f6a 100644 --- a/extra/CMakeLists.txt +++ b/extra/CMakeLists.txt @@ -13,7 +13,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${ZLIB_INCLUDE_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${ZLIB_INCLUDE_DIRS}) # Default install component for the files is Server here SET(MYSQL_INSTALL_COMPONENT Server) diff --git a/extra/mariabackup/CMakeLists.txt b/extra/mariabackup/CMakeLists.txt index 9b39321628b..fbc415ce0d4 100644 --- a/extra/mariabackup/CMakeLists.txt +++ b/extra/mariabackup/CMakeLists.txt @@ -31,6 +31,7 @@ ENDIF() INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql + ${CMAKE_SOURCE_DIR}/storage/maria ${CMAKE_CURRENT_SOURCE_DIR}/quicklz ${CMAKE_CURRENT_SOURCE_DIR} ) @@ -49,14 +50,9 @@ ADD_DEFINITIONS(-UMYSQL_SERVER) ADD_DEFINITIONS(-DPCRE_STATIC=1) ADD_DEFINITIONS(${SSL_DEFINES}) -IF(PMEM_FOUND) - ADD_COMPILE_FLAGS(xtrabackup.cc COMPILE_FLAGS "-DHAVE_PMEM") -ENDIF() - MYSQL_ADD_EXECUTABLE(mariadb-backup xtrabackup.cc innobackupex.cc - changed_page_bitmap.cc datasink.cc ds_buffer.cc ds_compress.cc @@ -72,8 +68,12 @@ MYSQL_ADD_EXECUTABLE(mariadb-backup xbstream_write.cc backup_mysql.cc backup_copy.cc - xb_plugin.cc + encryption_plugin.cc ${PROJECT_BINARY_DIR}/sql/sql_builtin.cc + aria_backup_client.cc + thread_pool.cc + ddl_log.cc + common_engine.cc ${PROJECT_SOURCE_DIR}/sql/net_serv.cc ${PROJECT_SOURCE_DIR}/libmysqld/libmysql.c COMPONENT Backup @@ -82,7 +82,8 @@ MYSQL_ADD_EXECUTABLE(mariadb-backup # Export all symbols on Unix, for better crash callstacks SET_TARGET_PROPERTIES(mariadb-backup PROPERTIES ENABLE_EXPORTS TRUE) -TARGET_LINK_LIBRARIES(mariadb-backup sql sql_builtins) +TARGET_LINK_LIBRARIES(mariadb-backup sql sql_builtins aria) + IF(NOT HAVE_SYSTEM_REGEX) TARGET_LINK_LIBRARIES(mariadb-backup pcre2-posix) ENDIF() diff --git a/extra/mariabackup/aria_backup_client.cc b/extra/mariabackup/aria_backup_client.cc new file mode 100644 index 00000000000..25468148fe4 --- /dev/null +++ b/extra/mariabackup/aria_backup_client.cc @@ -0,0 +1,1016 @@ +#include +#include +extern "C" { +#include "maria_def.h" +} +#undef LSN_MAX +#include "aria_backup_client.h" +#include "backup_copy.h" +#include "common.h" +#include "sql_table.h" +#include "ma_checkpoint.h" +#include "ma_recovery.h" +#include "backup_debug.h" +#include "aria_backup.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace aria { + +const char *log_preffix = "aria_log."; + + +static std::string log_file_name_only(size_t log_num) { + std::string log_file; + { + std::stringstream ss; + ss << std::setw(8) << std::setfill('0') << log_num; + log_file.append(log_preffix).append(ss.str()); + } + return log_file; +} + + +static std::string log_file_name(const char *datadir_path, size_t log_num) { + std::string log_file(datadir_path); + return log_file.append("/").append(log_file_name_only(log_num)); +} + + +class LogFileCollection +{ + uint32 m_first; + uint32 m_count; +public: + uint32 first() const { return m_first; } + uint32 count() const { return m_count; } + uint32 last() const + { + DBUG_ASSERT(m_count > 0); + return m_first + m_count - 1; + } + + // Initialize by checking existing log files on the disk + LogFileCollection(const char *datadir, uint32 max_log_no) + { + uint32 end= find_greatest_existing_log(datadir, max_log_no); + if (!end) + { + // No log files were found at all + m_first= 0; + m_count= 0; + } + else if (end == 1) + { + // Just the very first one log file (aria_log.00000001) was found. + m_first= 1; + m_count= 1; + } + else + { + // Multiple files were found + m_first= find_greatest_missing_log(datadir, end - 1) + 1; + m_count= 1 + end - m_first; + } + } + + /* + Skip all missing log files and find the greatest existing log file, or + Skip all existing log files and find the greatest missing log file. + + @param datadir - Search files in this directory + @param start - Start searching from this log number and go downto 1. + @param kind - true - search for an existing file + false - search for a missing file. + @returns - [1..start] - the greatest found log file + of the searched kind + - 0 - if no log files of this kind + were found in the range [1..start]. + */ + static uint32 find_greatest_existing_or_missing_log(const char *datadir, + uint32 start, + bool kind) + { + DBUG_ASSERT(start > 0); + for (uint32 i= start; i > 0; i--) + { + if (file_exists(log_file_name(datadir, i).c_str()) == kind) + return i; + } + return 0; // No log files of the searched kind were found + } + + static uint32 find_greatest_existing_log(const char *datadir, uint32 start) + { + return find_greatest_existing_or_missing_log(datadir, start, true); + } + + static uint32 find_greatest_missing_log(const char *datadir, uint32 start) + { + return find_greatest_existing_or_missing_log(datadir, start, false); + } + + /* + In some scenarios (e.g. log rotate) some new log files can appear + outside of the initially assumed [first,last] log number range. + This function adds all extra files behind "last". + */ + void find_logs_after_last(const char *datadir) + { + DBUG_ASSERT(m_count > 0); + for ( ; + file_exists(log_file_name(datadir, last() + 1).c_str()) ; + m_count++) + { } + } + + void report_found(unsigned thread_num) const + { + if (m_count) + msg(thread_num, + "Found %u aria log files, " + "minimum log number %u, " + "maximum log number %u", + m_count, m_first, last()); + } + + void die_if_missing(uint32 logno) const + { + DBUG_ASSERT(logno > 0); + if (!m_count || m_first > logno || last() < logno) + die("Aria log file %u does not exists.", logno); + } +}; + + +class Table { +public: + struct Partition { + std::string m_file_path; + File m_index_file = -1; + MY_STAT m_index_file_stat; + File m_data_file = -1; + MY_STAT m_data_file_stat; + }; + Table() = default; + Table (Table &&other) = delete; + Table & operator= (Table &&other) = delete; + Table(const Table &) = delete; + Table & operator= (const Table &) = delete; + ~Table(); + bool init(const char *data_file_path); + bool open(MYSQL *con, bool opt_no_lock, unsigned thread_num); + bool close(); + bool copy(ds_ctxt_t *ds, unsigned thread_num); + + bool is_online_backup_safe() const { + DBUG_ASSERT(is_opened()); + return m_cap.online_backup_safe; + } + bool is_stats() const { + return is_stats_table(m_db.c_str(), m_table.c_str()); + } + bool is_log() const { + return is_log_table(m_db.c_str(), m_table.c_str()); + } + bool is_opened() const { + return !m_partitions.empty() && + m_partitions[0].m_index_file >= 0 && m_partitions[0].m_data_file >= 0; + }; + std::string &get_full_name() { + return m_full_name; + } + std::string &get_db() { return m_db; } + std::string &get_table() { return m_table; } + std::string &get_version() { return m_table_version; } + bool is_partitioned() const { return m_partitioned; } + void add_partition(const Table &partition) { + DBUG_ASSERT(is_partitioned()); + m_partitions.push_back(partition.m_partitions[0]); + } +#ifndef DBUG_OFF + const std::string& get_sql_name() const { return m_sql_name; } +#endif //DBUG_OFF +private: + + bool copy(ds_ctxt_t *ds, bool is_index, unsigned thread_num); + // frm and par files will be copied under BLOCK_DDL stage in + // backup_copy_non_system() + bool copy_frm_and_par(ds_ctxt_t *ds, unsigned thread_num); + bool read_table_version_id(File file); + + std::string m_db; + std::string m_table; + std::string m_full_name; + std::string m_frm_par_path; + std::string m_table_version; +#ifndef DBUG_OFF + std::string m_sql_name; +#endif //DBUG_OFF + bool m_partitioned = false; + std::vector m_partitions; + ARIA_TABLE_CAPABILITIES m_cap; +}; + +Table::~Table() { + (void)close(); +} + +bool Table::init(const char *data_file_path) { + DBUG_ASSERT(data_file_path); + + const char *ext_pos = strrchr(data_file_path, '.'); + if (!ext_pos) + return false; + + char db_name_orig[FN_REFLEN]; + char table_name_orig[FN_REFLEN]; + parse_db_table_from_file_path( + data_file_path, db_name_orig, table_name_orig); + if (!db_name_orig[0] || !table_name_orig[0]) + return false; + char db_name_conv[FN_REFLEN]; + char table_name_conv[FN_REFLEN]; + filename_to_tablename(db_name_orig, db_name_conv, sizeof(db_name_conv)); + filename_to_tablename( + table_name_orig, table_name_conv, sizeof(table_name_conv)); + if (!db_name_conv[0] || !table_name_conv[0]) + return false; + + if (strstr(data_file_path, "#P#")) + m_partitioned = true; + + const char *table_name_begin = strrchr(data_file_path, FN_LIBCHAR); + if (!table_name_begin) + return false; + m_frm_par_path.assign(data_file_path, table_name_begin + 1). + append(table_name_orig); + + m_db.assign(db_name_conv); + m_table.assign(table_name_conv); + // TODO: find the correct way to represent quoted table/db names + m_full_name.assign("`").append(m_db).append("`.`"). + append(m_table).append("`"); +#ifndef DBUG_OFF + m_sql_name.assign(m_db).append("/").append(m_table); +#endif // DBUG_OFF + Partition partition; + partition.m_file_path.assign(data_file_path, ext_pos - data_file_path); + m_partitions.push_back(std::move(partition)); + return true; +} + +bool Table::read_table_version_id(File file) { + m_table_version = ::read_table_version_id(file); + return m_table_version.empty(); +} + +bool Table::open(MYSQL *con, bool opt_no_lock, unsigned thread_num) { + int error= 1; + bool have_capabilities = false; + File frm_file = -1; + + if (!opt_no_lock && !backup_lock(con, m_full_name.c_str())) { + msg(thread_num, "Error on BACKUP LOCK for aria table %s", + m_full_name.c_str()); + goto exit; + } + + for (Partition &partition : m_partitions) { + std::string file_path = partition.m_file_path + ".MAI"; + if ((partition.m_index_file= my_open(file_path.c_str(), + O_RDONLY | O_SHARE | O_NOFOLLOW | O_CLOEXEC, + MYF(MY_WME))) < 0) { + msg(thread_num, "Error on aria table file open %s", file_path.c_str()); + goto exit; + } + if (!my_stat(file_path.c_str(), &partition.m_index_file_stat, MYF(0))) { + msg(thread_num, "Error on aria table file stat %s", file_path.c_str()); + goto exit; + } + if (!have_capabilities) { + if ((error= aria_get_capabilities(partition.m_index_file, &m_cap))) { + msg(thread_num, "aria_get_capabilities failed: %d", error); + goto exit; + } + have_capabilities = true; + } + + file_path = partition.m_file_path + ".MAD"; + if ((partition.m_data_file= my_open(file_path.c_str(), + O_RDONLY | O_SHARE | O_NOFOLLOW | O_CLOEXEC, MYF(MY_WME))) < 0) { + msg(thread_num, "Error on aria table file open %s", file_path.c_str()); + goto exit; + } + if (!my_stat(file_path.c_str(), &partition.m_data_file_stat, MYF(0))) { + msg(thread_num, "Error on aria table file stat %s", file_path.c_str()); + goto exit; + } + } + + if ((frm_file = mysql_file_open( + key_file_frm, (m_frm_par_path + ".frm").c_str(), + O_RDONLY | O_SHARE, MYF(0))) < 0) { + msg(thread_num, "Error on aria table %s file open", + (m_frm_par_path + ".frm").c_str()); + goto exit; + } + + error = 0; + +exit: + if (!opt_no_lock && !backup_unlock(con)) { + msg(thread_num, "Error on BACKUP UNLOCK for aria table %s", + m_full_name.c_str()); + error = 1; + } + if (error) + (void)close(); + else { + (void)read_table_version_id(frm_file); + mysql_file_close(frm_file, MYF(MY_WME)); + } + return !error; +} + +bool Table::close() { + for (Partition &partition : m_partitions) { + if (partition.m_index_file >= 0) { + my_close(partition.m_index_file, MYF(MY_WME)); + partition.m_index_file = -1; + } + if (partition.m_data_file >= 0) { + my_close(partition.m_data_file, MYF(MY_WME)); + partition.m_data_file = -1; + } + } + return true; +} + +bool Table::copy(ds_ctxt_t *ds, unsigned thread_num) { + DBUG_ASSERT(is_opened()); + DBUG_MARIABACKUP_EVENT_LOCK("before_aria_table_copy", + fil_space_t::name_type(m_sql_name.data(), m_sql_name.size())); + bool result = +// copy_frm_and_par(ds, thread_num) && + copy(ds, true, thread_num) && copy(ds, false, thread_num); + return result; +} + +bool Table::copy(ds_ctxt_t *ds, bool is_index, unsigned thread_num) { + DBUG_ASSERT(ds); + const char *ext = is_index ? ".MAI" : ".MAD"; + int error= 1; + for (const Partition &partition : m_partitions) { + ds_file_t *dst_file = nullptr; + uchar *copy_buffer = nullptr; + std::string full_name = partition.m_file_path + ext; + const char *dst_path = + (xtrabackup_copy_back || xtrabackup_move_back) ? + full_name.c_str() : trim_dotslash(full_name.c_str()); + + dst_file = ds_open(ds, dst_path, + is_index ? &partition.m_index_file_stat : &partition.m_data_file_stat); + if (!dst_file) { + msg(thread_num, "error: cannot open the destination stream for %s", + dst_path); + goto err; + } + + copy_buffer = + reinterpret_cast(my_malloc(PSI_NOT_INSTRUMENTED, + m_cap.block_size, MYF(0))); + + DBUG_MARIABACKUP_EVENT_LOCK( + is_index ? + "before_aria_index_file_copy": + "before_aria_data_file_copy", + fil_space_t::name_type(m_sql_name.data(), + m_sql_name.size())); + + for (ulonglong block= 0 ; ; block++) { + size_t length = m_cap.block_size; + if (is_index) { + if ((error= aria_read_index( + partition.m_index_file, &m_cap, block, copy_buffer) == + HA_ERR_END_OF_FILE)) + break; + } else { + if ((error= aria_read_data( + partition.m_data_file, &m_cap, block, copy_buffer, &length) == + HA_ERR_END_OF_FILE)) + break; + } + if (error) { + msg(thread_num, "error: aria_read %s failed: %d", + is_index ? "index" : "data", error); + goto err; + } + xtrabackup_io_throttling(); + if ((error = ds_write(dst_file, copy_buffer, length))) { + msg(thread_num, "error: aria_write failed: %d", error); + goto err; + } + } + + DBUG_MARIABACKUP_EVENT_LOCK( + is_index ? + "after_aria_index_file_copy": + "after_aria_data_file_copy", + fil_space_t::name_type(m_sql_name.data(), + m_sql_name.size())); + + error = 0; + msg(thread_num, "aria table file %s is copied successfully.", + full_name.c_str()); + + err: + if (dst_file) + ds_close(dst_file); + if (copy_buffer) + my_free(copy_buffer); + if (error) + break; + } + return !error; +} + +class BackupImpl { +public: + BackupImpl( + const char *datadir_path, + const char *aria_log_path, + ds_ctxt_t *datasink, bool opt_no_lock, + std::vector &con_pool, ThreadPool &thread_pool) : + m_datadir_path(datadir_path), + m_aria_log_dir_path(aria_log_path), + m_ds(datasink), m_con_pool(con_pool), + m_tasks_group(thread_pool), m_thread_pool(thread_pool) { } + ~BackupImpl() { destroy(); } + bool init(); + bool start(bool no_lock); + bool wait_for_finish(); + bool copy_offline_tables( + const std::unordered_set *exclude_tables, bool no_lock, + bool copy_stats); + bool finalize(); + void set_post_copy_table_hook(const post_copy_table_hook_t &hook) { + m_table_post_copy_hook = hook; + } + bool copy_log_tail() { return copy_log_tail(0, false); } +private: + void destroy(); + void scan_job(bool no_lock, unsigned thread_num); + bool copy_log_tail(unsigned thread_num, bool finalize); + void copy_log_file_job(size_t log_num, unsigned thread_num); + void destroy_log_tail(); + void process_table_job(Table *table, bool online_only, bool copy_stats, + bool no_lock, unsigned thread_num); + + const char *m_datadir_path; + const char *m_aria_log_dir_path; + std::string aria_log_dir_path() const + { + if (!m_aria_log_dir_path || !m_aria_log_dir_path[0]) + return m_datadir_path; + if (is_absolute_path(m_aria_log_dir_path)) + return m_aria_log_dir_path; + return std::string(m_datadir_path).append("/") + .append(m_aria_log_dir_path); + } + ds_ctxt_t *m_ds; + std::vector &m_con_pool; + + TasksGroup m_tasks_group; + + std::mutex m_offline_tables_mutex; + std::vector> m_offline_tables; + post_copy_table_hook_t m_table_post_copy_hook; + + ThreadPool &m_thread_pool; + + size_t m_last_log_num = 0; + ds_file_t* m_last_log_dst = nullptr; + File m_last_log_src = -1; +}; + +bool BackupImpl::init() { + DBUG_ASSERT(m_tasks_group.is_finished()); + return true; +}; + +void BackupImpl::destroy() { + DBUG_ASSERT(m_tasks_group.is_finished()); + destroy_log_tail(); +} + +bool BackupImpl::start(bool no_lock) { + DBUG_ASSERT(m_tasks_group.is_finished()); + m_tasks_group.push_task( + std::bind(&BackupImpl::scan_job, this, no_lock, std::placeholders::_1)); + return true; +} + +void BackupImpl::process_table_job( + Table *table_ptr, bool online_only, bool copy_stats, bool no_lock, + unsigned thread_num) { + DBUG_ASSERT(table_ptr); + DBUG_ASSERT(thread_num < m_con_pool.size()); + std::unique_ptr table(table_ptr); + bool is_online; + bool is_stats; + bool need_copy; + int result = 1; + + if (!m_tasks_group.get_result()) + goto exit; + + if (!table->open(m_con_pool[thread_num], no_lock, thread_num)) { + // if table can't be opened, it might be removed or renamed, this is not + // error for transactional tables + table->close(); // Close opened table files + goto exit; + } + + is_online = table->is_online_backup_safe(); + is_stats = table->is_stats(); + + need_copy = (!online_only || is_online) && (copy_stats || !is_stats); + + if (need_copy && !table->copy(m_ds, thread_num)) { + table->close(); + DBUG_MARIABACKUP_EVENT_LOCK("after_aria_table_copy", + fil_space_t::name_type(table->get_sql_name().data(), + table->get_sql_name().size())); + // if table is opened, it must be copied, + // the corresponding diagnostic messages must be issued in Table::copy() + result = 0; + goto exit; + } + + if (!table->close()) { + msg(thread_num, "Can't close aria table %s.\n", + table->get_full_name().c_str()); + result = 0; + goto exit; + } + + if (!need_copy) { + std::lock_guard lock(m_offline_tables_mutex); + m_offline_tables.push_back(std::move(table)); + } + else { + DBUG_MARIABACKUP_EVENT_LOCK("after_aria_table_copy", + fil_space_t::name_type(table->get_sql_name().data(), + table->get_sql_name().size())); + if (m_table_post_copy_hook) + m_table_post_copy_hook( + std::move(table->get_db()), + std::move(table->get_table()), + std::move(table->get_version())); + } +exit: + m_tasks_group.finish_task(result); +} + + +void BackupImpl::scan_job(bool no_lock, unsigned thread_num) { + std::unordered_map> partitioned_tables; + + std::string aria_log_dir_path_cache(aria_log_dir_path()); + std::string log_control_file_path(aria_log_dir_path_cache); + log_control_file_path.append("/aria_log_control"); + if (!m_ds->copy_file( + log_control_file_path.c_str(), "aria_log_control", + 0, false)) { + msg("Aria log control file copying error."); + m_tasks_group.finish_task(0); + return; + } + + msg(thread_num, "Loading aria_log_control."); + aria_readonly= 1; + maria_data_root= aria_log_dir_path_cache.c_str(); + if (ma_control_file_open(FALSE, FALSE, FALSE, O_RDONLY)) + die("Can't open Aria control file (%d)", errno); + uint32 aria_log_control_last_log_number= last_logno; + msg(thread_num, "aria_log_control: last_log_number: %d", + aria_log_control_last_log_number); + ma_control_file_end(); + + msg(thread_num, "Start scanning aria tables."); + + foreach_file_in_db_dirs(m_datadir_path, [&](const char *file_path)->bool { + + if (check_if_skip_table(file_path)) { + msg(thread_num, "Skipping %s.", file_path); + return true; + } + + if (!ends_with(file_path, ".MAD")) + return true; + + std::unique_ptr
table(new Table()); + if (!table->init(file_path)) { + msg(thread_num, "Can't init aria table %s.\n", file_path); + return true; + } + + if (table->is_log()) + return true; + + if (table->is_partitioned()) { + auto table_it = partitioned_tables.find(table->get_full_name()); + if (table_it == partitioned_tables.end()) { + partitioned_tables[table->get_full_name()] = std::move(table); + } else { + table_it->second->add_partition(*table); + } + return true; + } + + m_tasks_group.push_task( + std::bind(&BackupImpl::process_table_job, this, table.release(), true, + false, no_lock, std::placeholders::_1)); + return true; + }); + + for (auto &table_it : partitioned_tables) { + m_tasks_group.push_task( + std::bind(&BackupImpl::process_table_job, this, table_it.second.release(), + true, false, no_lock, std::placeholders::_1)); + } + + msg(thread_num, "Start scanning aria log files."); + + LogFileCollection logs(aria_log_dir_path_cache.c_str(), + aria_log_control_last_log_number); + logs.report_found(thread_num); + logs.die_if_missing(aria_log_control_last_log_number); + + m_last_log_num= logs.last(); + + DBUG_MARIABACKUP_EVENT("after_scanning_log_files", {}); + + for (uint32 i= logs.first(); i <= logs.last(); ++i) + m_tasks_group.push_task( + std::bind(&BackupImpl::copy_log_file_job, this, + i, std::placeholders::_1)); + + msg(thread_num, "Stop scanning aria tables."); + + m_tasks_group.finish_task(1); +} + +template +T align_down(T n, ulint align_no) +{ + DBUG_ASSERT(align_no > 0); + DBUG_ASSERT(ut_is_2pow(align_no)); + return n & ~(static_cast(align_no) - 1); +} + +static ssize_t copy_file_chunk(File src, ds_file_t* dst, size_t size) { + size_t bytes_read; + static const size_t max_buf_size = 10 * 1024 * 1024; + size_t buf_size = size ? std::min(size, max_buf_size) : max_buf_size; + std::unique_ptr buf(new uchar[buf_size]); + ssize_t copied_size = 0; + bool unlim = !size; + while((unlim || size) && (bytes_read = my_read(src, buf.get(), + unlim ? buf_size : std::min(buf_size, size), MY_WME))) { + if (bytes_read == size_t(-1)) + return -1; + xtrabackup_io_throttling(); + if (ds_write(dst, buf.get(), bytes_read)) + return -1; + copied_size += bytes_read; + if (!unlim) + size -= bytes_read; + } + return copied_size; +} + +bool BackupImpl::copy_log_tail(unsigned thread_num, bool finalize) { + bool result = false; + std::string log_file = log_file_name(aria_log_dir_path().c_str(), m_last_log_num); + std::string prev_log_file; + ssize_t total_bytes_copied = 0; + MY_STAT stat_info; + my_off_t file_offset = 0; + size_t to_copy_size = 0; + +repeat: + memset(&stat_info, 0, sizeof(MY_STAT)); + if (!m_tasks_group.get_result()) { + msg(thread_num, "Skip copying aria lof file tail %s due to error.", + log_file.c_str()); + result = true; + goto exit; + } + + msg(thread_num, "Start copying aria log file tail: %s", log_file.c_str()); + + if (m_last_log_src < 0 && (m_last_log_src = + my_open(log_file.c_str(), O_RDONLY | O_SHARE | O_NOFOLLOW | O_CLOEXEC, + MYF(MY_WME))) < 0) { + msg("Aria log file %s open failed: %d", log_file.c_str(), my_errno); + goto exit; + } + + if (!m_last_log_dst && + !(m_last_log_dst = ds_open(m_ds, + log_file_name_only(m_last_log_num).c_str(), + &stat_info, false))) { + msg(thread_num, "error: failed to open the target stream for " + "aria log file %s.", + log_file.c_str()); + goto exit; + } + +// If there is no need to finalize log file copying, calculate the size to copy +// without the last page, which can be rewritten by the server +// (see translog_force_current_buffer_to_finish()). + if (!finalize) { + if (my_fstat(m_last_log_src, &stat_info, MYF(0))) { + msg(thread_num, "error: failed to get file size for aria log file: %s.", + log_file.c_str()); + goto exit; + } + if ((file_offset = my_tell(m_last_log_src, MYF(0))) == (my_off_t)(-1)) { + msg(thread_num, "error: failed to get file offset for aria log file: %s.", + log_file.c_str()); + goto exit; + } + DBUG_ASSERT(file_offset <= static_cast(stat_info.st_size)); + to_copy_size = static_cast(stat_info.st_size - file_offset); + to_copy_size = to_copy_size >= TRANSLOG_PAGE_SIZE ? + (align_down(to_copy_size, TRANSLOG_PAGE_SIZE) - TRANSLOG_PAGE_SIZE) : 0; + } + +// Copy from the last position to the end of file, +// excluding the last page is there is no need to finalize the copy. + if ((to_copy_size || finalize) && + (total_bytes_copied = copy_file_chunk(m_last_log_src, + m_last_log_dst, to_copy_size)) < 0) { + msg(thread_num, "Aria log file %s chunk copy error", log_file.c_str()); + goto exit; + } + + msg(thread_num, "Stop copying aria log file tail: %s, copied %zu bytes", + log_file.c_str(), total_bytes_copied); + +// Check if there is new log file, if yes, then copy the last page of the old +// one, and fix it last LSN in the log header, as it is changed on new +// log file creating by the server (see translog_create_new_file() and +// translog_max_lsn_to_header()). Then close the old log file and repeat +// the copying for the new log file. + prev_log_file = std::move(log_file); + log_file = log_file_name(aria_log_dir_path().c_str(), m_last_log_num + 1); + if (file_exists(log_file.c_str())) { + uchar lsn_buff[LSN_STORE_SIZE]; + msg(thread_num, "Found new aria log tail file: %s, start copy %s tail", + log_file.c_str(), prev_log_file.c_str()); + if ((total_bytes_copied = copy_file_chunk(m_last_log_src, + m_last_log_dst, 0)) < 0) { + msg(thread_num, "Aria log file %s tail copy error", + prev_log_file.c_str()); + goto exit; + } + + if (my_pread(m_last_log_src, lsn_buff, LSN_STORE_SIZE, + (LOG_HEADER_DATA_SIZE - LSN_STORE_SIZE), MYF(0)) < LSN_STORE_SIZE) { + msg(thread_num, "Aria lsn store read error for log file %s", + prev_log_file.c_str()); + goto exit; + } + + if (ds_seek_set(m_last_log_dst, (LOG_HEADER_DATA_SIZE - LSN_STORE_SIZE))) { + msg(thread_num, "Set aria log pointer error for log file %s", + prev_log_file.c_str()); + goto exit; + } + + if (ds_write(m_last_log_dst, lsn_buff, LSN_STORE_SIZE)) { + msg(thread_num, "LSN write error for aria log file %s", + prev_log_file.c_str()); + goto exit; + } + + msg(thread_num, "The last %zu bytes were copied for %s.", + total_bytes_copied, prev_log_file.c_str()); + destroy_log_tail(); + ++m_last_log_num; + goto repeat; + } + + result = true; + +exit: + if (!result) + destroy_log_tail(); + return result; +} + +void BackupImpl::copy_log_file_job(size_t log_num, unsigned thread_num) { + DBUG_ASSERT(log_num <= m_last_log_num); + + if (!m_tasks_group.get_result()) { + msg(thread_num, "Skip copying %zu aria log file due to error", log_num); + m_tasks_group.finish_task(0); + return; + } + +// Copy log file if the file is not the last one. + if (log_num < m_last_log_num) { + std::string log_file = log_file_name(aria_log_dir_path().c_str(), log_num); + if (!m_ds->copy_file(log_file.c_str(), + log_file_name_only(log_num).c_str(), + thread_num, false)) { + msg(thread_num, "Error on copying %s aria log file.", log_file.c_str()); + m_tasks_group.finish_task(0); + } + else + m_tasks_group.finish_task(1); + return; + } +// Copy the last log file. + m_tasks_group.finish_task(copy_log_tail(thread_num, false) ? 1 : 0); +} + +void BackupImpl::destroy_log_tail() { + if (m_last_log_src >= 0) { + my_close(m_last_log_src, MYF(MY_WME)); + m_last_log_src = -1; + } + if (m_last_log_dst) { + ds_close(m_last_log_dst); + m_last_log_dst = nullptr; + } +} + +bool BackupImpl::wait_for_finish() { + return m_tasks_group.wait_for_finish(); +} + +bool BackupImpl::copy_offline_tables( + const std::unordered_set *exclude_tables, bool no_lock, + bool copy_stats) { + DBUG_ASSERT(m_tasks_group.is_finished()); + + std::vector> ignored_tables; + + while (true) { + std::unique_lock lock(m_offline_tables_mutex); + if (m_offline_tables.empty()) + break; + auto table = std::move(m_offline_tables.back()); + m_offline_tables.pop_back(); + lock.unlock(); + if ((exclude_tables && + exclude_tables->count(table_key(table->get_db(), table->get_table()))) || + (!copy_stats && table->is_stats())) { + ignored_tables.push_back(std::move(table)); + continue; + } + m_tasks_group.push_task( + std::bind(&BackupImpl::process_table_job, this, table.release(), false, + copy_stats, no_lock, std::placeholders::_1)); + } + + if (!ignored_tables.empty()) { + std::lock_guard lock(m_offline_tables_mutex); + m_offline_tables = std::move(ignored_tables); + } + + return true; +} + +bool BackupImpl::finalize() { + DBUG_ASSERT(m_tasks_group.is_finished()); + DBUG_ASSERT(!m_con_pool.empty()); + bool result = true; + msg("Start copying statistics aria tables."); + copy_offline_tables(nullptr, true, true); + while (!m_tasks_group.is_finished()) + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + msg("Stop copying statistics aria tables."); + copy_log_tail(0, true); + destroy_log_tail(); + return result; +} + +Backup::Backup(const char *datadir_path, + const char *aria_log_path, + ds_ctxt_t *datasink, + std::vector &con_pool, ThreadPool &thread_pool) : + m_backup_impl( + new BackupImpl(datadir_path, aria_log_path, + datasink, opt_no_lock, con_pool, + thread_pool)) { } + +Backup::~Backup() { + delete m_backup_impl; +} + +bool Backup::init() { + return m_backup_impl->init(); +} + +bool Backup::start(bool no_lock) { + return m_backup_impl->start(no_lock); +} + +bool Backup::wait_for_finish() { + return m_backup_impl->wait_for_finish(); +} + +bool Backup::copy_offline_tables( + const std::unordered_set *exclude_tables, bool no_lock, + bool copy_stats) { + return m_backup_impl->copy_offline_tables(exclude_tables, no_lock, + copy_stats); +} + +bool Backup::finalize() { + return m_backup_impl->finalize(); +} + +bool Backup::copy_log_tail() { + return m_backup_impl->copy_log_tail(); +} + +void Backup::set_post_copy_table_hook(const post_copy_table_hook_t &hook) { + m_backup_impl->set_post_copy_table_hook(hook); +} + +bool prepare(const char *target_dir) { + maria_data_root= (char *)target_dir; + + if (maria_init()) + die("Can't init Aria engine (%d)", errno); + + maria_block_size= 0; /* Use block size from file */ + /* we don't want to create a control file, it MUST exist */ + if (ma_control_file_open(FALSE, TRUE, TRUE, control_file_open_flags)) + die("Can't open Aria control file (%d)", errno); + + if (last_logno == FILENO_IMPOSSIBLE) + die("Can't find any Aria log"); + + LogFileCollection logs(target_dir, last_logno); + logs.die_if_missing(last_logno); // Fatal, a broken backup. + /* + "mariadb-backup --backup" can put extra log files, + with log number greater than last_logno. For example, + this combination of files is possible: + - aria_log_control (with last_logno==1) + - aria_log.00000001 (last_logno) + - aria_log.00000002 (last_logno+1, the extra log file) + This can happen if during the ealier run of + "mariadb-backup --backup" a log rotate happened. + The extra log file is copied to the backup directory, + but last_logno in aria_log_control does not get updated. + This mismatch is probably not good and should eventually be fixed. + But during "mariadb-backup --prepare" this mismatch goes away: + aria_log_control gets fixed to say last_logno==2. + See mysql-test/suite/mariabackup/aria_log_rotate_during_backup.test, + it covers the scenario with one extra file created during --backup. + */ + logs.find_logs_after_last(target_dir); + last_logno= logs.last(); // Update last_logno if extra logs were found + + if (init_pagecache(maria_pagecache, 1024L*1024L, 0, 0, + static_cast(maria_block_size), 0, MY_WME) == 0) + die("Got error in Aria init_pagecache() (errno: %d)", errno); + + if (init_pagecache(maria_log_pagecache, 1024L*1024L, + 0, 0, TRANSLOG_PAGE_SIZE, 0, MY_WME) == 0 || + translog_init(maria_data_root, TRANSLOG_FILE_SIZE, + 0, 0, maria_log_pagecache, TRANSLOG_DEFAULT_FLAGS, FALSE)) + die("Can't init Aria loghandler (%d)", errno); + + if (maria_recovery_from_log()) + die("Aria log apply FAILED"); + + if (maria_recovery_changed_data || recovery_failures) { + if (ma_control_file_write_and_force(last_checkpoint_lsn, last_logno, + max_trid_in_control_file, 0)) + die("Aria control file update error"); +// TODO: find out do we need checkpoint here + } + + maria_end(); + return true; +} + +} // namespace aria diff --git a/extra/mariabackup/aria_backup_client.h b/extra/mariabackup/aria_backup_client.h new file mode 100644 index 00000000000..7a581b5862e --- /dev/null +++ b/extra/mariabackup/aria_backup_client.h @@ -0,0 +1,38 @@ +#pragma once +#include "my_global.h" +#include "datasink.h" +#include "backup_mysql.h" +#include "thread_pool.h" +#include "xtrabackup.h" + +namespace aria { + +bool prepare(const char *target_dir); + +class BackupImpl; + +class Backup { + public: + Backup(const char *datadir_path, + const char *aria_log_path, + ds_ctxt_t *datasink, + std::vector &con_pool, ThreadPool &thread_pool); + ~Backup(); + Backup (Backup &&other) = delete; + Backup & operator= (Backup &&other) = delete; + Backup(const Backup &) = delete; + Backup & operator= (const Backup &) = delete; + bool init(); + bool start(bool no_lock); + bool wait_for_finish(); + bool copy_offline_tables( + const std::unordered_set *exclude_tables, bool no_lock, + bool copy_stats); + bool finalize(); + bool copy_log_tail(); + void set_post_copy_table_hook(const post_copy_table_hook_t &hook); + private: + BackupImpl *m_backup_impl; +}; + +} // namespace aria diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc index 53b3664b5c3..83ed8e4e5f9 100644 --- a/extra/mariabackup/backup_copy.cc +++ b/extra/mariabackup/backup_copy.cc @@ -41,6 +41,9 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA *******************************************************/ #include +#include +#include +#include #include #include #include @@ -66,19 +69,26 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA #include #endif +#ifdef MYSQL_CLIENT +#define WAS_MYSQL_CLIENT 1 +#undef MYSQL_CLIENT +#endif + +#include "table.h" + +#ifdef WAS_MYSQL_CLIENT +#define MYSQL_CLIENT 1 +#undef WAS_MYSQL_CLIENT +#endif #define ROCKSDB_BACKUP_DIR "#rocksdb" -/* list of files to sync for --rsync mode */ -static std::set rsync_list; /* locations of tablespaces read from .isl files */ static std::map tablespace_locations; /* Whether LOCK BINLOG FOR BACKUP has been issued during backup */ bool binlog_locked; -static void rocksdb_create_checkpoint(); -static bool has_rocksdb_plugin(); static void rocksdb_backup_checkpoint(ds_ctxt *ds_data); static void rocksdb_copy_back(ds_ctxt *ds_data); @@ -135,10 +145,6 @@ struct datadir_thread_ctxt_t { bool ret; }; -static bool backup_files_from_datadir(ds_ctxt_t *ds_data, - const char *dir_path, - const char *prefix); - /************************************************************************ Retirn true if character if file separator */ bool @@ -585,7 +591,6 @@ datafile_read(datafile_cur_t *cursor) Check to see if a file exists. Takes name of the file to check. @return true if file exists. */ -static bool file_exists(const char *filename) { @@ -601,7 +606,6 @@ file_exists(const char *filename) /************************************************************************ Trim leading slashes from absolute path so it becomes relative */ -static const char * trim_dotslash(const char *path) { @@ -634,7 +638,7 @@ ends_with(const char *str, const char *suffix) && strcmp(str + str_len - suffix_len, suffix) == 0); } -static bool starts_with(const char *str, const char *prefix) +bool starts_with(const char *str, const char *prefix) { return strncmp(str, prefix, strlen(prefix)) == 0; } @@ -785,7 +789,6 @@ directory_exists_and_empty(const char *dir, const char *comment) /************************************************************************ Check if file name ends with given set of suffixes. @return true if it does. */ -static bool filename_matches(const char *filename, const char **ext_list) { @@ -800,6 +803,115 @@ filename_matches(const char *filename, const char **ext_list) return(false); } +// TODO: the code can be used to find storage engine of partitions +/* +static +bool is_aria_frm_or_par(const char *path) { + if (!ends_with(path, ".frm") && !ends_with(path, ".par")) + return false; + + const char *frm_path = path; + if (ends_with(path, ".par")) { + size_t frm_path_len = strlen(path); + DBUG_ASSERT(frm_path_len > strlen("frm")); + frm_path = strdup(path); + strcpy(const_cast(frm_path) + frm_path_len - strlen("frm"), "frm"); + } + + bool result = false; + File file; + uchar header[40]; + legacy_db_type dbt; + + if ((file= mysql_file_open(key_file_frm, frm_path, O_RDONLY | O_SHARE, MYF(0))) + < 0) + goto err; + + if (mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP))) + goto err; + + if (!strncmp((char*) header, "TYPE=VIEW\n", 10)) + goto err; + + if (!is_binary_frm_header(header)) + goto err; + + dbt = (legacy_db_type)header[3]; + + if (dbt == DB_TYPE_ARIA) { + result = true; + } + else if (dbt == DB_TYPE_PARTITION_DB) { + MY_STAT state; + uchar *frm_image= 0; +// uint n_length; + + if (mysql_file_fstat(file, &state, MYF(MY_WME))) + goto err; + + if (mysql_file_seek(file, 0, SEEK_SET, MYF(MY_WME))) + goto err; + + if (read_string(file, &frm_image, (size_t)state.st_size)) + goto err; + + dbt = (legacy_db_type)frm_image[61]; + if (dbt == DB_TYPE_ARIA) { + result = true; + } + my_free(frm_image); + } + +err: + if (file >= 0) + mysql_file_close(file, MYF(MY_WME)); + if (frm_path != path) + free(const_cast(frm_path)); + return result; +} +*/ + +void parse_db_table_from_file_path( + const char *filepath, char *dbname, char *tablename) { + dbname[0] = '\0'; + tablename[0] = '\0'; + const char *dbname_start = nullptr; + const char *tablename_start = filepath; + const char *const_ptr; + while ((const_ptr = strchr(tablename_start, FN_LIBCHAR)) != NULL) { + dbname_start = tablename_start; + tablename_start = const_ptr + 1; + } + if (!dbname_start) + return; + size_t dbname_len = tablename_start - dbname_start - 1; + if (dbname_len >= FN_REFLEN) + dbname_len = FN_REFLEN-1; + strmake(dbname, dbname_start, dbname_len); + strmake(tablename, tablename_start, FN_REFLEN-1); + char *ptr; + if ((ptr = strchr(tablename, '.'))) + *ptr = '\0'; + if ((ptr = strstr(tablename, "#P#"))) + *ptr = '\0'; +} + +bool is_system_table(const char *dbname, const char *tablename) +{ + DBUG_ASSERT(dbname); + DBUG_ASSERT(tablename); + + LEX_CSTRING lex_dbname; + LEX_CSTRING lex_tablename; + lex_dbname.str = dbname; + lex_dbname.length = strlen(dbname); + lex_tablename.str = tablename; + lex_tablename.length = strlen(tablename); + + TABLE_CATEGORY tg = get_table_category(&lex_dbname, &lex_tablename); + + return (tg == TABLE_CATEGORY_LOG) || (tg == TABLE_CATEGORY_SYSTEM); +} /************************************************************************ Copy data file for backup. Also check if it is allowed to copy by @@ -810,9 +922,8 @@ static bool datafile_copy_backup(ds_ctxt *ds_data, const char *filepath, uint thread_n) { - const char *ext_list[] = {"frm", "isl", "MYD", "MYI", "MAD", "MAI", - "MRG", "TRG", "TRN", "ARM", "ARZ", "CSM", "CSV", "opt", "par", - NULL}; + const char *ext_list[] = {".frm", ".isl", ".TRG", ".TRN", ".opt", ".par", + NULL}; /* Get the name and the path for the tablespace. node->name always contains the path (which may be absolute for remote tablespaces in @@ -830,42 +941,7 @@ datafile_copy_backup(ds_ctxt *ds_data, const char *filepath, uint thread_n) if (filename_matches(filepath, ext_list)) { return ds_data->copy_file(filepath, filepath, thread_n); - } - - return(true); -} - - -/************************************************************************ -Same as datafile_copy_backup, but put file name into the list for -rsync command. */ -static -bool -datafile_rsync_backup(const char *filepath, bool save_to_list, FILE *f) -{ - const char *ext_list[] = {"frm", "isl", "MYD", "MYI", "MAD", "MAI", - "MRG", "TRG", "TRN", "ARM", "ARZ", "CSM", "CSV", "opt", "par", - NULL}; - - /* Get the name and the path for the tablespace. node->name always - contains the path (which may be absolute for remote tablespaces in - 5.6+). space->name contains the tablespace name in the form - "./database/table.ibd" (in 5.5-) or "database/table" (in 5.6+). For a - multi-node shared tablespace, space->name contains the name of the first - node, but that's irrelevant, since we only need node_name to match them - against filters, and the shared tablespace is always copied regardless - of the filters value. */ - - if (check_if_skip_table(filepath)) { - return(true); - } - - if (filename_matches(filepath, ext_list)) { - fprintf(f, "%s\n", filepath); - if (save_to_list) { - rsync_list.insert(filepath); - } - } + } return(true); } @@ -1004,16 +1080,15 @@ Copy file for backup/restore. bool ds_ctxt_t::copy_file(const char *src_file_path, const char *dst_file_path, - uint thread_n) + uint thread_n, + bool rewrite) { char dst_name[FN_REFLEN]; ds_file_t *dstfile = NULL; datafile_cur_t cursor; xb_fil_cur_result_t res; DBUG_ASSERT(datasink->remove); - const char *dst_path = - (xtrabackup_copy_back || xtrabackup_move_back)? - dst_file_path : trim_dotslash(dst_file_path); + const char *dst_path = convert_dst(dst_file_path); if (!datafile_open(src_file_path, &cursor, thread_n)) { goto error_close; @@ -1021,7 +1096,7 @@ ds_ctxt_t::copy_file(const char *src_file_path, strncpy(dst_name, cursor.rel_path, sizeof(dst_name)); - dstfile = ds_open(this, dst_path, &cursor.statinfo); + dstfile = ds_open(this, dst_path, &cursor.statinfo, rewrite); if (dstfile == NULL) { msg(thread_n,"error: " "cannot open the destination stream for %s", dst_name); @@ -1245,278 +1320,45 @@ cleanup: } - - -static bool -backup_files(ds_ctxt *ds_data, const char *from, bool prep_mode) +backup_files(ds_ctxt *ds_data, const char *from) { - char rsync_tmpfile_name[FN_REFLEN]; - FILE *rsync_tmpfile = NULL; datadir_iter_t *it; datadir_node_t node; bool ret = true; - - if (prep_mode && !opt_rsync) { - return(true); - } - - if (opt_rsync) { - snprintf(rsync_tmpfile_name, sizeof(rsync_tmpfile_name), - "%s/%s%d", opt_mysql_tmpdir, - "xtrabackup_rsyncfiles_pass", - prep_mode ? 1 : 2); - rsync_tmpfile = fopen(rsync_tmpfile_name, "w"); - if (rsync_tmpfile == NULL) { - msg("Error: can't create file %s", - rsync_tmpfile_name); - return(false); - } - } - - msg("Starting %s non-InnoDB tables and files", - prep_mode ? "prep copy of" : "to backup"); - + msg("Starting to backup non-InnoDB tables and files"); datadir_node_init(&node); it = datadir_iter_new(from); - while (datadir_iter_next(it, &node)) { - if (!node.is_empty_dir) { - if (opt_rsync) { - ret = datafile_rsync_backup(node.filepath, - !prep_mode, rsync_tmpfile); - } else { - ret = datafile_copy_backup(ds_data, node.filepath, 1); - } + ret = datafile_copy_backup(ds_data, node.filepath, 1); if (!ret) { msg("Failed to copy file %s", node.filepath); goto out; } - } else if (!prep_mode) { + } else { /* backup fake file into empty directory */ char path[FN_REFLEN]; - snprintf(path, sizeof(path), - "%s/db.opt", node.filepath); - if (!(ret = ds_data->backup_file_printf( - trim_dotslash(path), "%s", ""))) { + snprintf(path, sizeof(path), "%s/db.opt", node.filepath); + if (!(ret = ds_data->backup_file_printf(trim_dotslash(path), "%s", ""))) { msg("Failed to create file %s", path); goto out; } } } - - if (opt_rsync) { - std::stringstream cmd; - int err; - - if (buffer_pool_filename && file_exists(buffer_pool_filename)) { - fprintf(rsync_tmpfile, "%s\n", buffer_pool_filename); - rsync_list.insert(buffer_pool_filename); - } - if (file_exists("ib_lru_dump")) { - fprintf(rsync_tmpfile, "%s\n", "ib_lru_dump"); - rsync_list.insert("ib_lru_dump"); - } - - fclose(rsync_tmpfile); - rsync_tmpfile = NULL; - - cmd << "rsync -t . --files-from=" << rsync_tmpfile_name - << " " << xtrabackup_target_dir; - - msg("Starting rsync as: %s", cmd.str().c_str()); - if ((err = system(cmd.str().c_str()) && !prep_mode) != 0) { - msg("Error: rsync failed with error code %d", err); - ret = false; - goto out; - } - msg("rsync finished successfully."); - - if (!prep_mode && !opt_no_lock) { - char path[FN_REFLEN]; - char dst_path[FN_REFLEN]; - char *newline; - - /* Remove files that have been removed between first and - second passes. Cannot use "rsync --delete" because it - does not work with --files-from. */ - snprintf(rsync_tmpfile_name, sizeof(rsync_tmpfile_name), - "%s/%s", opt_mysql_tmpdir, - "xtrabackup_rsyncfiles_pass1"); - - rsync_tmpfile = fopen(rsync_tmpfile_name, "r"); - if (rsync_tmpfile == NULL) { - msg("Error: can't open file %s", - rsync_tmpfile_name); - ret = false; - goto out; - } - - while (fgets(path, sizeof(path), rsync_tmpfile)) { - - newline = strchr(path, '\n'); - if (newline) { - *newline = 0; - } - if (rsync_list.count(path) < 1) { - snprintf(dst_path, sizeof(dst_path), - "%s/%s", xtrabackup_target_dir, - path); - msg("Removing %s", dst_path); - unlink(dst_path); - } - } - - fclose(rsync_tmpfile); - rsync_tmpfile = NULL; - } - } - - msg("Finished %s non-InnoDB tables and files", - prep_mode ? "a prep copy of" : "backing up"); - + msg("Finished backing up non-InnoDB tables and files"); out: datadir_iter_free(it); datadir_node_free(&node); - - if (rsync_tmpfile != NULL) { - fclose(rsync_tmpfile); - } - return(ret); } - -lsn_t get_current_lsn(MYSQL *connection) -{ - static const char lsn_prefix[] = "\nLog sequence number "; - lsn_t lsn = 0; - if (MYSQL_RES *res = xb_mysql_query(connection, - "SHOW ENGINE INNODB STATUS", - true, false)) { - if (MYSQL_ROW row = mysql_fetch_row(res)) { - const char *p= strstr(row[2], lsn_prefix); - DBUG_ASSERT(p); - if (p) { - p += sizeof lsn_prefix - 1; - lsn = lsn_t(strtoll(p, NULL, 10)); - } - } - mysql_free_result(res); - } - return lsn; -} - lsn_t server_lsn_after_lock; extern void backup_wait_for_lsn(lsn_t lsn); -/** Start --backup */ -bool backup_start(ds_ctxt *ds_data, ds_ctxt *ds_meta, - CorruptedPages &corrupted_pages) -{ - if (!opt_no_lock) { - if (opt_safe_slave_backup) { - if (!wait_for_safe_slave(mysql_connection)) { - return(false); - } - } - if (!backup_files(ds_data, fil_path_to_mysql_datadir, true)) { - return(false); - } - - history_lock_time = time(NULL); - - if (!lock_tables(mysql_connection)) { - return(false); - } - server_lsn_after_lock = get_current_lsn(mysql_connection); - } - - if (!backup_files(ds_data, fil_path_to_mysql_datadir, false)) { - return(false); - } - - if (!backup_files_from_datadir(ds_data, fil_path_to_mysql_datadir, - "aws-kms-key") || - !backup_files_from_datadir(ds_data, - aria_log_dir_path, - "aria_log")) { - return false; - } - - if (has_rocksdb_plugin()) { - rocksdb_create_checkpoint(); - } - - msg("Waiting for log copy thread to read lsn %llu", (ulonglong)server_lsn_after_lock); - backup_wait_for_lsn(server_lsn_after_lock); - DBUG_EXECUTE_FOR_KEY("sleep_after_waiting_for_lsn", {}, - { - ulong milliseconds = strtoul(dbug_val, NULL, 10); - msg("sleep_after_waiting_for_lsn"); - my_sleep(milliseconds*1000UL); - }); - - corrupted_pages.backup_fix_ddl(ds_data, ds_meta); - - // There is no need to stop slave thread before coping non-Innodb data when - // --no-lock option is used because --no-lock option requires that no DDL or - // DML to non-transaction tables can occur. - if (opt_no_lock) { - if (opt_safe_slave_backup) { - if (!wait_for_safe_slave(mysql_connection)) { - return(false); - } - } - } - - if (opt_slave_info) { - lock_binlog_maybe(mysql_connection); - - if (!write_slave_info(ds_data, mysql_connection)) { - return(false); - } - } - - /* The only reason why Galera/binlog info is written before - wait_for_ibbackup_log_copy_finish() is that after that call the xtrabackup - binary will start streamig a temporary copy of REDO log to stdout and - thus, any streaming from innobackupex would interfere. The only way to - avoid that is to have a single process, i.e. merge innobackupex and - xtrabackup. */ - if (opt_galera_info) { - if (!write_galera_info(ds_data, mysql_connection)) { - return(false); - } - } - - if (opt_binlog_info == BINLOG_INFO_ON) { - - lock_binlog_maybe(mysql_connection); - write_binlog_info(ds_data, mysql_connection); - } - - if (!opt_no_lock) { - msg("Executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS..."); - xb_mysql_query(mysql_connection, - "FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS", false); - } - - return(true); -} - -/** Release resources after backup_start() */ +/** Release resources after backup_files() */ void backup_release() { - /* release all locks */ - if (!opt_no_lock) { - unlock_all(mysql_connection); - history_lock_time = 0; - } else { - history_lock_time = time(NULL) - history_lock_time; - } - if (opt_lock_ddl_per_table) { mdl_unlock_all(); } @@ -1530,11 +1372,11 @@ void backup_release() static const char *default_buffer_pool_file = "ib_buffer_pool"; -/** Finish after backup_start() and backup_release() */ +/** Finish after backup_files() and backup_release() */ bool backup_finish(ds_ctxt *ds_data) { /* Copy buffer pool dump or LRU dump */ - if (!opt_rsync && opt_galera_info) { + if (opt_galera_info) { if (buffer_pool_filename && file_exists(buffer_pool_filename)) { ds_data->copy_file(buffer_pool_filename, default_buffer_pool_file, 0); } @@ -1897,8 +1739,6 @@ copy_back() return(false); } - srv_max_n_threads = 1000; - /* copy undo tablespaces */ Copy_back_dst_dir dst_dir_buf; @@ -1926,7 +1766,8 @@ copy_back() dst_dir = dst_dir_buf.make(srv_log_group_home_dir); - /* --backup generates a single ib_logfile0, which we must copy. */ + /* --backup generates a single LOG_FILE_NAME, which we must copy + if it exists. */ ds_tmp = ds_create(dst_dir, DS_TYPE_LOCAL); if (!(ret = copy_or_move_file(ds_tmp, LOG_FILE_NAME, LOG_FILE_NAME, @@ -2163,8 +2004,6 @@ decrypt_decompress() bool ret; datadir_iter_t *it = NULL; - srv_max_n_threads = 1000; - /* cd to backup directory */ if (my_setwd(xtrabackup_target_dir, MYF(MY_WME))) { @@ -2177,8 +2016,6 @@ decrypt_decompress() it = datadir_iter_new(".", false); - ut_a(xtrabackup_parallel >= 0); - ret = run_data_threads(it, decrypt_decompress_thread_func, xtrabackup_parallel ? xtrabackup_parallel : 1); @@ -2200,9 +2037,9 @@ decrypt_decompress() Do not copy the Innodb files (ibdata1, redo log files), as this is done in a separate step. */ -static bool backup_files_from_datadir(ds_ctxt_t *ds_data, - const char *dir_path, - const char *prefix) +bool backup_files_from_datadir(ds_ctxt_t *ds_data, + const char *dir_path, + const char *prefix) { os_file_dir_t dir = os_file_opendir(dir_path); if (dir == IF_WIN(INVALID_HANDLE_VALUE, nullptr)) return false; @@ -2226,10 +2063,6 @@ static bool backup_files_from_datadir(ds_ctxt_t *ds_data, pname = info.name; if (!starts_with(pname, prefix)) - /* For ES exchange the above line with the following code: - (!xtrabackup_prepare || !xtrabackup_incremental_dir || - !starts_with(pname, "aria_log"))) - */ continue; if (xtrabackup_prepare && xtrabackup_incremental_dir && @@ -2252,7 +2085,7 @@ static int rocksdb_remove_checkpoint_directory() return 0; } -static bool has_rocksdb_plugin() +bool has_rocksdb_plugin() { static bool first_time = true; static bool has_plugin= false; @@ -2398,7 +2231,7 @@ static void rocksdb_unlock_checkpoint() #define MARIADB_CHECKPOINT_DIR "mariabackup-checkpoint" static char rocksdb_checkpoint_dir[FN_REFLEN]; -static void rocksdb_create_checkpoint() +void rocksdb_create_checkpoint() { MYSQL_RES *result = xb_mysql_query(mysql_connection, "SELECT @@rocksdb_datadir,@@datadir", true, true); MYSQL_ROW row = mysql_fetch_row(result); @@ -2478,3 +2311,39 @@ static void rocksdb_copy_back(ds_ctxt *ds_data) { mkdirp(rocksdb_home_dir, 0777, MYF(0)); ds_data->copy_or_move_dir(ROCKSDB_BACKUP_DIR, rocksdb_home_dir, xtrabackup_copy_back, xtrabackup_copy_back); } + +void foreach_file_in_db_dirs( + const char *dir_path, std::function func) { + DBUG_ASSERT(dir_path); + + datadir_iter_t *it; + datadir_node_t node; + + datadir_node_init(&node); + it = datadir_iter_new(dir_path); + + while (datadir_iter_next(it, &node)) + if (!node.is_empty_dir && !func(node.filepath)) + break; + + datadir_iter_free(it); + datadir_node_free(&node); +} + +void foreach_file_in_datadir( + const char *dir_path, std::function func) +{ + DBUG_ASSERT(dir_path); + os_file_dir_t dir = os_file_opendir(dir_path); + os_file_stat_t info; + while (os_file_readdir_next_file(dir_path, dir, &info) == 0) { + if (info.type != OS_FILE_TYPE_FILE) + continue; + const char *pname = strrchr(info.name, IF_WIN('\\', '/')); + if (!pname) + pname = info.name; + if (!func(pname)) + break; + } + os_file_closedir(dir); +} diff --git a/extra/mariabackup/backup_copy.h b/extra/mariabackup/backup_copy.h index e6002e8e66b..869bfff19a3 100644 --- a/extra/mariabackup/backup_copy.h +++ b/extra/mariabackup/backup_copy.h @@ -2,6 +2,7 @@ #ifndef XTRABACKUP_BACKUP_COPY_H #define XTRABACKUP_BACKUP_COPY_H +#include #include #include #include "datasink.h" @@ -29,11 +30,10 @@ bool equal_paths(const char *first, const char *second); /** Start --backup */ -bool backup_start(ds_ctxt *ds_data, ds_ctxt *ds_meta, - CorruptedPages &corrupted_pages); -/** Release resources after backup_start() */ +bool backup_files(ds_ctxt *ds_data, const char *from); +/** Release resources after backup_files() */ void backup_release(); -/** Finish after backup_start() and backup_release() */ +/** Finish after backup_files() and backup_release() */ bool backup_finish(ds_ctxt *ds_data); bool apply_log_finish(); @@ -46,7 +46,25 @@ is_path_separator(char); bool directory_exists(const char *dir, bool create); -lsn_t -get_current_lsn(MYSQL *connection); +bool has_rocksdb_plugin(); +void rocksdb_create_checkpoint(); +void foreach_file_in_db_dirs( + const char *dir_path, std::function func); +void foreach_file_in_datadir( + const char *dir_path, std::function func); +bool ends_with(const char *str, const char *suffix); +bool starts_with(const char *str, const char *prefix); +void parse_db_table_from_file_path( + const char *filepath, char *dbname, char *tablename); +const char *trim_dotslash(const char *path); +bool backup_files_from_datadir(ds_ctxt_t *ds_data, + const char *dir_path, + const char *prefix); +bool is_system_table(const char *dbname, const char *tablename); +std::unique_ptr> + find_files(const char *dir_path, const char *prefix, const char *suffix); +bool file_exists(const char *filename); +bool +filename_matches(const char *filename, const char **ext_list); #endif diff --git a/extra/mariabackup/backup_debug.h b/extra/mariabackup/backup_debug.h index 777b4f4adeb..9286bc7b4e2 100644 --- a/extra/mariabackup/backup_debug.h +++ b/extra/mariabackup/backup_debug.h @@ -1,5 +1,6 @@ #pragma once #include "my_dbug.h" + #ifndef DBUG_OFF char *dbug_mariabackup_get_val(const char *event, fil_space_t::name_type key); /* @@ -14,11 +15,21 @@ To use this facility, you need to for the variable) 3. start mariabackup with --dbug=+d,debug_mariabackup_events */ -#define DBUG_EXECUTE_FOR_KEY(EVENT, KEY, CODE) \ - DBUG_EXECUTE_IF("mariabackup_inject_code", \ - { char *dbug_val= dbug_mariabackup_get_val(EVENT, KEY); \ - if (dbug_val) CODE }) +extern void dbug_mariabackup_event( + const char *event, const fil_space_t::name_type key, bool need_lock); +#define DBUG_MARIABACKUP_EVENT(A, B) \ + DBUG_EXECUTE_IF("mariabackup_events", \ + dbug_mariabackup_event(A,B,false);); +#define DBUG_MARIABACKUP_EVENT_LOCK(A, B) \ + DBUG_EXECUTE_IF("mariabackup_events", \ + dbug_mariabackup_event(A,B, true);); +#define DBUG_EXECUTE_FOR_KEY(EVENT, KEY, CODE) \ + DBUG_EXECUTE_IF("mariabackup_inject_code", {\ + char *dbug_val = dbug_mariabackup_get_val(EVENT, KEY); \ + if (dbug_val && *dbug_val) CODE \ + }) #else +#define DBUG_MARIABACKUP_EVENT(A,B) +#define DBUG_MARIABACKUP_EVENT_LOCK(A,B) #define DBUG_EXECUTE_FOR_KEY(EVENT, KEY, CODE) #endif - diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc index ec0420c53a1..33d6b0a9ba7 100644 --- a/extra/mariabackup/backup_mysql.cc +++ b/extra/mariabackup/backup_mysql.cc @@ -47,6 +47,12 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA #include #include #include +#ifdef HAVE_PWD_H +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#include +#endif #include "common.h" #include "xtrabackup.h" #include "srv0srv.h" @@ -54,19 +60,19 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA #include "backup_copy.h" #include "backup_mysql.h" #include "mysqld.h" -#include "xb_plugin.h" +#include "encryption_plugin.h" #include #include #include "page0zip.h" +#include "backup_debug.h" char *tool_name; -char tool_args[2048]; +char tool_args[8192]; ulong mysql_server_version; /* server capabilities */ bool have_changed_page_bitmaps = false; -bool have_backup_locks = false; bool have_lock_wait_timeout = false; bool have_galera_enabled = false; bool have_multi_threaded_slave = false; @@ -92,11 +98,54 @@ MYSQL *mysql_connection; extern my_bool opt_ssl_verify_server_cert, opt_use_ssl; + +/* + get_os_user() + Ressemles read_user_name() from libmariadb/libmariadb/mariadb_lib.c. +*/ + +#if !defined(_WIN32) + +#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL) +struct passwd *getpwuid(uid_t); +char* getlogin(void); +#endif + +static const char *get_os_user() // Posix +{ + if (!geteuid()) + return "root"; +#ifdef HAVE_GETPWUID + struct passwd *pw; + const char *str; + if ((pw= getpwuid(geteuid())) != NULL) + return pw->pw_name; + if ((str= getlogin()) != NULL) + return str; +#endif + if ((str= getenv("USER")) || + (str= getenv("LOGNAME")) || + (str= getenv("LOGIN"))) + return str; + return NULL; +} + +#else + +static const char *get_os_user() // Windows +{ + return getenv("USERNAME"); +} + +#endif // _WIN32 + + MYSQL * xb_mysql_connect() { MYSQL *connection = mysql_init(NULL); char mysql_port_str[std::numeric_limits::digits10 + 3]; + const char *user= opt_user ? opt_user : get_os_user(); sprintf(mysql_port_str, "%d", opt_port); @@ -126,7 +175,7 @@ xb_mysql_connect() msg("Connecting to MariaDB server host: %s, user: %s, password: %s, " "port: %s, socket: %s", opt_host ? opt_host : "localhost", - opt_user ? opt_user : "not set", + user ? user : "not set", opt_password ? "set" : "not set", opt_port != 0 ? mysql_port_str : "not set", opt_socket ? opt_socket : "not set"); @@ -149,7 +198,7 @@ xb_mysql_connect() if (!mysql_real_connect(connection, opt_host ? opt_host : "localhost", - opt_user, + user, opt_password, "" /*database*/, opt_port, opt_socket, 0)) { @@ -205,13 +254,14 @@ struct mysql_variable { static -void +uint read_mysql_variables(MYSQL *connection, const char *query, mysql_variable *vars, bool vertical_result) { MYSQL_RES *mysql_result; MYSQL_ROW row; mysql_variable *var; + uint n_values=0; mysql_result = xb_mysql_query(connection, query, true); @@ -225,6 +275,7 @@ read_mysql_variables(MYSQL *connection, const char *query, mysql_variable *vars, if (strcmp(var->name, name) == 0 && value != NULL) { *(var->value) = strdup(value); + n_values++; } } } @@ -241,6 +292,7 @@ read_mysql_variables(MYSQL *connection, const char *query, mysql_variable *vars, if (strcmp(var->name, name) == 0 && value != NULL) { *(var->value) = strdup(value); + n_values++; } } ++i; @@ -249,6 +301,7 @@ read_mysql_variables(MYSQL *connection, const char *query, mysql_variable *vars, } mysql_free_result(mysql_result); + return n_values; } @@ -313,7 +366,6 @@ bool get_mysql_vars(MYSQL *connection) { char *gtid_mode_var= NULL; char *version_var= NULL; - char *have_backup_locks_var= NULL; char *log_bin_var= NULL; char *lock_wait_timeout_var= NULL; char *wsrep_on_var= NULL; @@ -338,7 +390,6 @@ bool get_mysql_vars(MYSQL *connection) bool ret= true; mysql_variable mysql_vars[]= { - {"have_backup_locks", &have_backup_locks_var}, {"log_bin", &log_bin_var}, {"lock_wait_timeout", &lock_wait_timeout_var}, {"gtid_mode", >id_mode_var}, @@ -363,11 +414,6 @@ bool get_mysql_vars(MYSQL *connection) read_mysql_variables(connection, "SHOW VARIABLES", mysql_vars, true); - if (have_backup_locks_var != NULL && !opt_no_backup_locks) - { - have_backup_locks= true; - } - if (opt_binlog_info == BINLOG_INFO_AUTO) { if (log_bin_var != NULL && !strcmp(log_bin_var, "ON")) @@ -514,24 +560,6 @@ Query the server to find out what backup capabilities it supports. bool detect_mysql_capabilities_for_backup() { - const char *query = "SELECT 'INNODB_CHANGED_PAGES', COUNT(*) FROM " - "INFORMATION_SCHEMA.PLUGINS " - "WHERE PLUGIN_NAME LIKE 'INNODB_CHANGED_PAGES'"; - char *innodb_changed_pages = NULL; - mysql_variable vars[] = { - {"INNODB_CHANGED_PAGES", &innodb_changed_pages}, {NULL, NULL}}; - - if (xtrabackup_incremental) { - - read_mysql_variables(mysql_connection, query, vars, true); - - ut_ad(innodb_changed_pages != NULL); - - have_changed_page_bitmaps = (atoi(innodb_changed_pages) == 1); - - free_mysql_variables(vars); - } - /* do some sanity checks */ if (opt_galera_info && !have_galera_enabled) { msg("--galera-info is specified on the command " @@ -839,11 +867,11 @@ static void stop_query_killer() /*********************************************************************//** -Function acquires either a backup tables lock, if supported -by the server, or a global read lock (FLUSH TABLES WITH READ LOCK) -otherwise. +Function acquires backup locks @returns true if lock acquired */ -bool lock_tables(MYSQL *connection) + +bool +lock_for_backup_stage_start(MYSQL *connection) { if (have_lock_wait_timeout || opt_lock_wait_timeout) { @@ -856,12 +884,6 @@ bool lock_tables(MYSQL *connection) xb_mysql_query(connection, buf, false); } - if (have_backup_locks) - { - msg("Executing LOCK TABLES FOR BACKUP..."); - xb_mysql_query(connection, "LOCK TABLES FOR BACKUP", false); - return (true); - } if (opt_lock_wait_timeout) { @@ -886,8 +908,6 @@ bool lock_tables(MYSQL *connection) xb_mysql_query(connection, "BACKUP STAGE START", true); DBUG_MARIABACKUP_EVENT("after_backup_stage_start", {}); - xb_mysql_query(connection, "BACKUP STAGE BLOCK_COMMIT", true); - DBUG_MARIABACKUP_EVENT("after_backup_stage_block_commit", {}); /* Set the maximum supported session value for lock_wait_timeout to prevent unnecessary timeouts when the global value is changed from the default */ @@ -903,24 +923,68 @@ bool lock_tables(MYSQL *connection) return (true); } -/*********************************************************************//** -If backup locks are used, execute LOCK BINLOG FOR BACKUP provided that we are -not in the --no-lock mode and the lock has not been acquired already. -@returns true if lock acquired */ bool -lock_binlog_maybe(MYSQL *connection) -{ - if (have_backup_locks && !opt_no_lock && !binlog_locked) { - msg("Executing LOCK BINLOG FOR BACKUP..."); - xb_mysql_query(connection, "LOCK BINLOG FOR BACKUP", false); - binlog_locked = true; - - return(true); +lock_for_backup_stage_flush(MYSQL *connection) { + if (opt_kill_long_queries_timeout) { + start_query_killer(); } - - return(false); + xb_mysql_query(connection, "BACKUP STAGE FLUSH", true); + if (opt_kill_long_queries_timeout) { + stop_query_killer(); + } + return true; } +bool +lock_for_backup_stage_block_ddl(MYSQL *connection) { + if (opt_kill_long_queries_timeout) { + start_query_killer(); + } + xb_mysql_query(connection, "BACKUP STAGE BLOCK_DDL", true); + DBUG_MARIABACKUP_EVENT("after_backup_stage_block_ddl", {}); + if (opt_kill_long_queries_timeout) { + stop_query_killer(); + } + return true; +} + +bool +lock_for_backup_stage_commit(MYSQL *connection) { + if (opt_kill_long_queries_timeout) { + start_query_killer(); + } + xb_mysql_query(connection, "BACKUP STAGE BLOCK_COMMIT", true); + DBUG_MARIABACKUP_EVENT("after_backup_stage_block_commit", {}); + if (opt_kill_long_queries_timeout) { + stop_query_killer(); + } + return true; +} + +bool backup_lock(MYSQL *con, const char *table_name) { + static const std::string backup_lock_prefix("BACKUP LOCK "); + std::string backup_lock_query = backup_lock_prefix + table_name; + xb_mysql_query(con, backup_lock_query.c_str(), true); + return true; +} + +bool backup_unlock(MYSQL *con) { + xb_mysql_query(con, "BACKUP UNLOCK", true); + return true; +} + +std::unordered_set +get_tables_in_use(MYSQL *con) { + std::unordered_set result; + MYSQL_RES *q_res = + xb_mysql_query(con, "SHOW OPEN TABLES WHERE In_use = 1", true); + while (MYSQL_ROW row = mysql_fetch_row(q_res)) { + auto tk = table_key(row[0], row[1]); + msg("Table %s is in use", tk.c_str()); + result.insert(std::move(tk)); + } + return result; +} /*********************************************************************//** Releases either global read lock acquired with FTWRL and the binlog @@ -1355,77 +1419,103 @@ write_slave_info(ds_ctxt *datasink, MYSQL *connection) /*********************************************************************//** -Retrieves MySQL Galera and -saves it in a file. It also prints it to stdout. */ +Retrieves MySQL Galera and saves it in a file. It also prints it to stdout. + +We should create xtrabackup_galelera_info file even when backup locks +are used because donor's wsrep_gtid_domain_id is needed later in joiner. +Note that at this stage wsrep_local_state_uuid and wsrep_last_committed +are inconsistent but they are not used in joiner. Joiner will rewrite this file +at mariabackup --prepare phase and thus there is extra file donor_galera_info. +Information is needed to maitain wsrep_gtid_domain_id and gtid_binlog_pos +same across the cluster. If joiner node have different wsrep_gtid_domain_id +we should still receive effective domain id from the donor node, +and use it. +*/ bool write_galera_info(ds_ctxt *datasink, MYSQL *connection) { - char *state_uuid = NULL, *state_uuid55 = NULL; - char *last_committed = NULL, *last_committed55 = NULL; - char *domain_id = NULL, *domain_id55 = NULL; - bool result; + char *state_uuid = NULL, *state_uuid55 = NULL; + char *last_committed = NULL, *last_committed55 = NULL; + char *domain_id = NULL, *domain_id55 = NULL; + bool result=true; + uint n_values=0; + char *wsrep_on = NULL, *wsrep_on55 = NULL; - mysql_variable status[] = { - {"Wsrep_local_state_uuid", &state_uuid}, - {"wsrep_local_state_uuid", &state_uuid55}, - {"Wsrep_last_committed", &last_committed}, - {"wsrep_last_committed", &last_committed55}, - {NULL, NULL} - }; + mysql_variable vars[] = { + {"Wsrep_on", &wsrep_on}, + {"wsrep_on", &wsrep_on55}, + {NULL, NULL} + }; - mysql_variable value[] = { - {"Wsrep_gtid_domain_id", &domain_id}, - {"wsrep_gtid_domain_id", &domain_id55}, - {NULL, NULL} - }; + mysql_variable status[] = { + {"Wsrep_local_state_uuid", &state_uuid}, + {"wsrep_local_state_uuid", &state_uuid55}, + {"Wsrep_last_committed", &last_committed}, + {"wsrep_last_committed", &last_committed55}, + {NULL, NULL} + }; - /* When backup locks are supported by the server, we should skip - creating MB_GALERA_INFO file on the backup stage, because - wsrep_local_state_uuid and wsrep_last_committed will be inconsistent - without blocking commits. The state file will be created on the prepare - stage using the WSREP recovery procedure. */ - if (have_backup_locks) { - return(true); - } + mysql_variable value[] = { + {"Wsrep_gtid_domain_id", &domain_id}, + {"wsrep_gtid_domain_id", &domain_id55}, + {NULL, NULL} + }; - read_mysql_variables(connection, "SHOW STATUS", status, true); + n_values= read_mysql_variables(connection, "SHOW VARIABLES", vars, true); - if ((state_uuid == NULL && state_uuid55 == NULL) - || (last_committed == NULL && last_committed55 == NULL)) { - msg("Warning: failed to get master wsrep state from SHOW STATUS."); - result = true; - goto cleanup; - } + if (n_values == 0 || (wsrep_on == NULL && wsrep_on55 == NULL)) + { + msg("Server is not Galera node thus --galera-info does not " + "have any effect."); + result = true; + goto cleanup; + } - read_mysql_variables(connection, "SHOW VARIABLES LIKE 'wsrep%'", value, true); + read_mysql_variables(connection, "SHOW STATUS", status, true); - if (domain_id == NULL && domain_id55 == NULL) { - msg("Warning: failed to get master wsrep state from SHOW VARIABLES."); - result = true; - goto cleanup; - } + if ((state_uuid == NULL && state_uuid55 == NULL) + || (last_committed == NULL && last_committed55 == NULL)) + { + msg("Warning: failed to get master wsrep state from SHOW STATUS."); + result = true; + goto cleanup; + } - result = datasink->backup_file_printf(MB_GALERA_INFO, - "%s:%s %s\n", state_uuid ? state_uuid : state_uuid55, - last_committed ? last_committed : last_committed55, - domain_id ? domain_id : domain_id55); + n_values= read_mysql_variables(connection, "SHOW VARIABLES LIKE 'wsrep%'", value, true); - if (result) - { - result= datasink->backup_file_printf(XTRABACKUP_DONOR_GALERA_INFO, - "%s:%s %s\n", state_uuid ? state_uuid : state_uuid55, - last_committed ? last_committed : last_committed55, - domain_id ? domain_id : domain_id55); - } - if (result) - { - write_current_binlog_file(datasink, connection); - } + if (n_values == 0 || (domain_id == NULL && domain_id55 == NULL)) + { + msg("Warning: failed to get master wsrep state from SHOW VARIABLES."); + result = true; + goto cleanup; + } + + result= datasink->backup_file_printf(MB_GALERA_INFO, + "%s:%s %s\n", state_uuid ? state_uuid : state_uuid55, + last_committed ? last_committed : last_committed55, + domain_id ? domain_id : domain_id55); + + if (result) + { + result= datasink->backup_file_printf(XTRABACKUP_DONOR_GALERA_INFO, + "%s:%s %s\n", state_uuid ? state_uuid : state_uuid55, + last_committed ? last_committed : last_committed55, + domain_id ? domain_id : domain_id55); + } + + if (result) + write_current_binlog_file(datasink, connection); + + if (result) + msg("Writing Galera info succeeded with %s:%s %s", + state_uuid ? state_uuid : state_uuid55, + last_committed ? last_committed : last_committed55, + domain_id ? domain_id : domain_id55); cleanup: - free_mysql_variables(status); + free_mysql_variables(status); - return(result); + return(result); } @@ -1468,8 +1558,6 @@ write_current_binlog_file(ds_ctxt *datasink, MYSQL *connection) if (gtid_exists) { size_t log_bin_dir_length; - lock_binlog_maybe(connection); - xb_mysql_query(connection, "FLUSH BINARY LOGS", false); read_mysql_variables(connection, "SHOW MASTER STATUS", @@ -1828,13 +1916,13 @@ bool write_backup_config_file(ds_ctxt *datasink) srv_log_file_size, srv_page_size, srv_undo_dir, - srv_undo_tablespaces, + (uint) srv_undo_tablespaces, page_zip_level, innobase_buffer_pool_filename ? "innodb_buffer_pool_filename=" : "", innobase_buffer_pool_filename ? innobase_buffer_pool_filename : "", - xb_plugin_get_config()); + encryption_plugin_get_config()); return rc; } @@ -1853,9 +1941,11 @@ char *make_argv(char *buf, size_t len, int argc, char **argv) if (strncmp(*argv, "--password", strlen("--password")) == 0) { arg = "--password=..."; } - left-= snprintf(buf + len - left, left, + uint l= snprintf(buf + len - left, left, "%s%c", arg, argc > 1 ? ' ' : 0); ++argv; --argc; + if (l < left) + left-= l; } return buf; @@ -1884,18 +1974,6 @@ select_history() return(true); } -bool -flush_changed_page_bitmaps() -{ - if (xtrabackup_incremental && have_changed_page_bitmaps && - !xtrabackup_incremental_force_scan) { - xb_mysql_query(mysql_connection, - "FLUSH NO_WRITE_TO_BINLOG CHANGED_PAGE_BITMAPS", false); - } - return(true); -} - - /*********************************************************************//** Deallocate memory, disconnect from server, etc. @return true on success. */ @@ -1971,3 +2049,23 @@ mdl_unlock_all() mysql_close(mdl_con); spaceid_to_tablename.clear(); } + +ulonglong get_current_lsn(MYSQL *connection) +{ + static const char lsn_prefix[] = "\nLog sequence number "; + ulonglong lsn = 0; + if (MYSQL_RES *res = xb_mysql_query(connection, + "SHOW ENGINE INNODB STATUS", + true, false)) { + if (MYSQL_ROW row = mysql_fetch_row(res)) { + const char *p= strstr(row[2], lsn_prefix); + DBUG_ASSERT(p); + if (p) { + p += sizeof lsn_prefix - 1; + lsn = lsn_t(strtoll(p, NULL, 10)); + } + } + mysql_free_result(res); + } + return lsn; +} diff --git a/extra/mariabackup/backup_mysql.h b/extra/mariabackup/backup_mysql.h index 4b08da0b939..c87efd21c11 100644 --- a/extra/mariabackup/backup_mysql.h +++ b/extra/mariabackup/backup_mysql.h @@ -2,13 +2,15 @@ #define XTRABACKUP_BACKUP_MYSQL_H #include +#include +#include +#include "datasink.h" /* MariaDB version */ extern ulong mysql_server_version; /* server capabilities */ extern bool have_changed_page_bitmaps; -extern bool have_backup_locks; extern bool have_lock_wait_timeout; extern bool have_galera_enabled; extern bool have_multi_threaded_slave; @@ -35,9 +37,6 @@ capture_tool_command(int argc, char **argv); bool select_history(); -bool -flush_changed_page_bitmaps(); - void backup_cleanup(); @@ -75,7 +74,21 @@ bool lock_binlog_maybe(MYSQL *connection); bool -lock_tables(MYSQL *connection); +lock_for_backup_stage_start(MYSQL *connection); + +bool +lock_for_backup_stage_flush(MYSQL *connection); + +bool +lock_for_backup_stage_block_ddl(MYSQL *connection); + +bool +lock_for_backup_stage_commit(MYSQL *connection); + +bool backup_lock(MYSQL *con, const char *table_name); +bool backup_unlock(MYSQL *con); + +std::unordered_set get_tables_in_use(MYSQL *con); bool wait_for_safe_slave(MYSQL *connection); @@ -86,5 +99,6 @@ write_galera_info(ds_ctxt *datasink, MYSQL *connection); bool write_slave_info(ds_ctxt *datasink, MYSQL *connection); +ulonglong get_current_lsn(MYSQL *connection); #endif diff --git a/extra/mariabackup/changed_page_bitmap.cc b/extra/mariabackup/changed_page_bitmap.cc deleted file mode 100644 index 39a07a25224..00000000000 --- a/extra/mariabackup/changed_page_bitmap.cc +++ /dev/null @@ -1,1040 +0,0 @@ -/****************************************************** -XtraBackup: hot backup tool for InnoDB -(c) 2009-2012 Percona Inc. -Originally Created 3/3/2009 Yasufumi Kinoshita -Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko, -Yasufumi Kinoshita, Ignacio Nin and Baron Schwartz. - -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*******************************************************/ - -/* Changed page bitmap implementation */ - -#include "changed_page_bitmap.h" - -#include "common.h" -#include "xtrabackup.h" -#include "srv0srv.h" - -/* TODO: copy-pasted shared definitions from the XtraDB bitmap write code. -Remove these on the first opportunity, i.e. single-binary XtraBackup. */ - -/* log0online.h */ - -/** Single bitmap file information */ -struct log_online_bitmap_file_t { - char name[FN_REFLEN]; /*!< Name with full path */ - pfs_os_file_t file; /*!< Handle to opened file */ - ib_uint64_t size; /*!< Size of the file */ - ib_uint64_t offset; /*!< Offset of the next read, - or count of already-read bytes - */ -}; - -/** A set of bitmap files containing some LSN range */ -struct log_online_bitmap_file_range_t { - size_t count; /*!< Number of files */ - /*!< Dynamically-allocated array of info about individual files */ - struct files_t { - char name[FN_REFLEN];/*!< Name of a file */ - lsn_t start_lsn; /*!< Starting LSN of data in this - file */ - ulong seq_num; /*!< Sequence number of this file */ - } *files; -}; - -/* log0online.c */ - -/** File name stem for bitmap files. */ -static const char* bmp_file_name_stem = "ib_modified_log_"; - -/** 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 */ -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 }; - -typedef ib_uint64_t bitmap_word_t; - -/****************************************************************//** -Calculate a bitmap block checksum. Algorithm borrowed from -log_block_calc_checksum. -@return checksum */ -UNIV_INLINE -ulint -log_online_calc_checksum( -/*=====================*/ - const byte* block); /*! p2 -*/ -static -int -log_online_compare_bmp_keys( -/*========================*/ - const void* p1, /*! k2_start_page ? 1 : 0; - } - return k1_space < k2_space ? -1 : 1; -} - -/****************************************************************//** -Calculate a bitmap block checksum. Algorithm borrowed from -log_block_calc_checksum. -@return checksum */ -UNIV_INLINE -ulint -log_online_calc_checksum( -/*=====================*/ - const byte* block) /*! 24) { - - sh = 0; - } - } - - return sum; -} - -/****************************************************************//** -Read one bitmap data page and check it for corruption. - -@return TRUE if page read OK, FALSE if I/O error */ -static -ibool -log_online_read_bitmap_page( -/*========================*/ - log_online_bitmap_file_t *bitmap_file, /*!size >= MODIFIED_PAGE_BLOCK_SIZE); - ut_a(bitmap_file->offset - <= bitmap_file->size - MODIFIED_PAGE_BLOCK_SIZE); - ut_a(bitmap_file->offset % MODIFIED_PAGE_BLOCK_SIZE == 0); - if (DB_SUCCESS != - os_file_read(IORequestRead, bitmap_file->file, page, - bitmap_file->offset, MODIFIED_PAGE_BLOCK_SIZE, - nullptr)) { - /* The following call prints an error message */ - os_file_get_last_error(TRUE); - msg("InnoDB: Warning: failed reading changed page bitmap " - "file \'%s\'", bitmap_file->name); - return FALSE; - } - - bitmap_file->offset += MODIFIED_PAGE_BLOCK_SIZE; - ut_ad(bitmap_file->offset <= bitmap_file->size); - - checksum = mach_read_from_4(page + MODIFIED_PAGE_BLOCK_CHECKSUM); - actual_checksum = log_online_calc_checksum(page); - *checksum_ok = (checksum == actual_checksum); - - return TRUE; -} - -/*********************************************************************//** -Check the name of a given file if it's a changed page bitmap file and -return file sequence and start LSN name components if it is. If is not, -the values of output parameters are undefined. - -@return TRUE if a given file is a changed page bitmap file. */ -static -ibool -log_online_is_bitmap_file( -/*======================*/ - const os_file_stat_t* file_info, /*!name) < OS_FILE_MAX_PATH); - - return ((file_info->type == OS_FILE_TYPE_FILE - || file_info->type == OS_FILE_TYPE_LINK) - && (sscanf(file_info->name, "%[a-z_]%lu_" LSN_PF ".xdb", stem, - bitmap_file_seq_num, bitmap_file_start_lsn) == 3) - && (!strcmp(stem, bmp_file_name_stem))); -} - -/*********************************************************************//** -List the bitmap files in srv_data_home and setup their range that contains the -specified LSN interval. This range, if non-empty, will start with a file that -has the greatest LSN equal to or less than the start LSN and will include all -the files up to the one with the greatest LSN less than the end LSN. Caller -must free bitmap_files->files when done if bitmap_files set to non-NULL and -this function returned TRUE. Field bitmap_files->count might be set to a -larger value than the actual count of the files, and space for the unused array -slots will be allocated but cleared to zeroes. - -@return TRUE if succeeded -*/ -static -ibool -log_online_setup_bitmap_file_range( -/*===============================*/ - log_online_bitmap_file_range_t *bitmap_files, /*!= range_start); - - bitmap_files->count = 0; - bitmap_files->files = NULL; - - /* 1st pass: size the info array */ - - bitmap_dir = os_file_opendir(srv_data_home); - if (UNIV_UNLIKELY(bitmap_dir == IF_WIN(INVALID_HANDLE_VALUE, NULL))) { - msg("InnoDB: Error: failed to open bitmap directory \'%s\'", - srv_data_home); - return FALSE; - } - - while (!os_file_readdir_next_file(srv_data_home, bitmap_dir, - &bitmap_dir_file_info)) { - - ulong file_seq_num; - lsn_t file_start_lsn; - - if (!log_online_is_bitmap_file(&bitmap_dir_file_info, - &file_seq_num, - &file_start_lsn) - || file_start_lsn >= range_end) { - - continue; - } - - if (file_seq_num > last_file_seq_num) { - - last_file_seq_num = file_seq_num; - } - - if (file_start_lsn >= range_start - || file_start_lsn == first_file_start_lsn - || first_file_start_lsn > range_start) { - - /* A file that falls into the range */ - - if (file_start_lsn < first_file_start_lsn) { - - first_file_start_lsn = file_start_lsn; - } - if (file_seq_num < first_file_seq_num) { - - first_file_seq_num = file_seq_num; - } - } else if (file_start_lsn > first_file_start_lsn) { - - /* A file that has LSN closer to the range start - but smaller than it, replacing another such file */ - first_file_start_lsn = file_start_lsn; - first_file_seq_num = file_seq_num; - } - } - - if (UNIV_UNLIKELY(os_file_closedir_failed(bitmap_dir))) { - os_file_get_last_error(TRUE); - msg("InnoDB: Error: cannot close \'%s\'",srv_data_home); - return FALSE; - } - - if (first_file_seq_num == ULONG_MAX && last_file_seq_num == 0) { - - bitmap_files->count = 0; - return TRUE; - } - - bitmap_files->count = last_file_seq_num - first_file_seq_num + 1; - - /* 2nd pass: get the file names in the file_seq_num order */ - - bitmap_dir = os_file_opendir(srv_data_home); - if (UNIV_UNLIKELY(bitmap_dir == IF_WIN(INVALID_HANDLE_VALUE, NULL))) { - msg("InnoDB: Error: failed to open bitmap directory \'%s\'", - srv_data_home); - return FALSE; - } - - bitmap_files->files = - static_cast - (malloc(bitmap_files->count * sizeof(bitmap_files->files[0]))); - memset(bitmap_files->files, 0, - bitmap_files->count * sizeof(bitmap_files->files[0])); - - while (!os_file_readdir_next_file(srv_data_home, bitmap_dir, - &bitmap_dir_file_info)) { - - ulong file_seq_num; - lsn_t file_start_lsn; - size_t array_pos; - - if (!log_online_is_bitmap_file(&bitmap_dir_file_info, - &file_seq_num, - &file_start_lsn) - || file_start_lsn >= range_end - || file_start_lsn < first_file_start_lsn) { - - continue; - } - - array_pos = file_seq_num - first_file_seq_num; - if (UNIV_UNLIKELY(array_pos >= bitmap_files->count)) { - - msg("InnoDB: Error: inconsistent bitmap file " - "directory"); - os_file_closedir(bitmap_dir); - free(bitmap_files->files); - return FALSE; - } - - if (file_seq_num > bitmap_files->files[array_pos].seq_num) { - - bitmap_files->files[array_pos].seq_num = file_seq_num; - strncpy(bitmap_files->files[array_pos].name, - bitmap_dir_file_info.name, FN_REFLEN - 1); - bitmap_files->files[array_pos].name[FN_REFLEN - 1] - = '\0'; - bitmap_files->files[array_pos].start_lsn - = file_start_lsn; - } - } - - if (UNIV_UNLIKELY(os_file_closedir_failed(bitmap_dir))) { - os_file_get_last_error(TRUE); - msg("InnoDB: Error: cannot close \'%s\'", srv_data_home); - free(bitmap_files->files); - return FALSE; - } - -#ifdef UNIV_DEBUG - ut_ad(bitmap_files->files[0].seq_num == first_file_seq_num); - - for (size_t i = 1; i < bitmap_files->count; i++) { - if (!bitmap_files->files[i].seq_num) { - - break; - } - ut_ad(bitmap_files->files[i].seq_num - > bitmap_files->files[i - 1].seq_num); - ut_ad(bitmap_files->files[i].start_lsn - >= bitmap_files->files[i - 1].start_lsn); - } -#endif - - return TRUE; -} - -/****************************************************************//** -Open a bitmap file for reading. - -@return whether opened successfully */ -static -bool -log_online_open_bitmap_file_read_only( -/*==================================*/ - const char* name, /*!name, FN_REFLEN, "%s%s", srv_data_home, name); - bitmap_file->file = os_file_create_simple_no_error_handling( - 0, bitmap_file->name, - OS_FILE_OPEN, OS_FILE_READ_ONLY, true, &success); - if (UNIV_UNLIKELY(!success)) { - - /* Here and below assume that bitmap file names do not - contain apostrophes, thus no need for ut_print_filename(). */ - msg("InnoDB: Warning: error opening the changed page " - "bitmap \'%s\'", bitmap_file->name); - return success; - } - - bitmap_file->size = os_file_get_size(bitmap_file->file); - bitmap_file->offset = 0; - -#ifdef __linux__ - posix_fadvise(bitmap_file->file, 0, 0, POSIX_FADV_SEQUENTIAL); - posix_fadvise(bitmap_file->file, 0, 0, POSIX_FADV_NOREUSE); -#endif - - return success; -} - -/****************************************************************//** -Diagnose one or both of the following situations if we read close to -the end of bitmap file: -1) Warn if the remainder of the file is less than one page. -2) Error if we cannot read any more full pages but the last read page -did not have the last-in-run flag set. - -@return FALSE for the error */ -static -ibool -log_online_diagnose_bitmap_eof( -/*===========================*/ - const log_online_bitmap_file_t* bitmap_file, /*!< in: bitmap file */ - ibool last_page_in_run)/*!< in: "last page in - run" flag value in the - last read page */ -{ - /* Check if we are too close to EOF to read a full page */ - if ((bitmap_file->size < MODIFIED_PAGE_BLOCK_SIZE) - || (bitmap_file->offset - > bitmap_file->size - MODIFIED_PAGE_BLOCK_SIZE)) { - - if (UNIV_UNLIKELY(bitmap_file->offset != bitmap_file->size)) { - - /* If we are not at EOF and we have less than one page - to read, it's junk. This error is not fatal in - itself. */ - - msg("InnoDB: Warning: junk at the end of changed " - "page bitmap file \'%s\'.", bitmap_file->name); - } - - if (UNIV_UNLIKELY(!last_page_in_run)) { - - /* We are at EOF but the last read page did not finish - a run */ - /* It's a "Warning" here because it's not a fatal error - for the whole server */ - msg("InnoDB: Warning: changed page bitmap " - "file \'%s\' does not contain a complete run " - "at the end.", bitmap_file->name); - return FALSE; - } - } - return TRUE; -} - -/* End of copy-pasted definitions */ - -/** Iterator structure over changed page bitmap */ -struct xb_page_bitmap_range_struct { - const xb_page_bitmap *bitmap; /* Bitmap with data */ - ulint space_id; /* Space id for this - iterator */ - ulint bit_i; /* Bit index of the iterator - position in the current page */ - const ib_rbt_node_t *bitmap_node; /* Current bitmap tree node */ - const byte *bitmap_page; /* Current bitmap page */ - ulint current_page_id;/* Current page id */ -}; - -/****************************************************************//** -Print a diagnostic message on missing bitmap data for an LSN range. */ -static -void -xb_msg_missing_lsn_data( -/*====================*/ - lsn_t missing_interval_start, /*!size >= MODIFIED_PAGE_BLOCK_SIZE); - - *page_end_lsn = 0; - - while ((*page_end_lsn <= lsn) - && (bitmap_file->offset - <= bitmap_file->size - MODIFIED_PAGE_BLOCK_SIZE)) { - - next_to_last_page_ok = last_page_ok; - if (!log_online_read_bitmap_page(bitmap_file, page, - &last_page_ok)) { - - return FALSE; - } - - *page_end_lsn = mach_read_from_8(page + MODIFIED_PAGE_END_LSN); - } - - /* We check two pages here because the last read page already contains - the required LSN data. If the next to the last one page is corrupted, - then we have no way of telling if that page contained the required LSN - range data too */ - return last_page_ok && next_to_last_page_ok; -} - -/****************************************************************//** -Read the disk bitmap and build the changed page bitmap tree for the -LSN interval incremental_lsn to log_sys.next_checkpoint_lsn. - -@return the built bitmap tree or NULL if unable to read the full interval for -any reason. */ -xb_page_bitmap* -xb_page_bitmap_init(void) -/*=====================*/ -{ - log_online_bitmap_file_t bitmap_file; - lsn_t bmp_start_lsn = incremental_lsn; - const lsn_t bmp_end_lsn{log_sys.next_checkpoint_lsn}; - byte page[MODIFIED_PAGE_BLOCK_SIZE]; - lsn_t current_page_end_lsn; - xb_page_bitmap *result; - ibool last_page_in_run= FALSE; - log_online_bitmap_file_range_t bitmap_files; - size_t bmp_i; - ibool last_page_ok = TRUE; - - if (UNIV_UNLIKELY(bmp_start_lsn > bmp_end_lsn)) { - - msg("mariabackup: incremental backup LSN " LSN_PF - " is larger than than the last checkpoint LSN " LSN_PF - , bmp_start_lsn, bmp_end_lsn); - return NULL; - } - - if (!log_online_setup_bitmap_file_range(&bitmap_files, bmp_start_lsn, - bmp_end_lsn)) { - - return NULL; - } - - /* Only accept no bitmap files returned if start LSN == end LSN */ - if (bitmap_files.count == 0 && bmp_end_lsn != bmp_start_lsn) { - - return NULL; - } - - result = rbt_create(MODIFIED_PAGE_BLOCK_SIZE, - log_online_compare_bmp_keys); - - if (bmp_start_lsn == bmp_end_lsn) { - - /* Empty range - empty bitmap */ - return result; - } - - bmp_i = 0; - - if (UNIV_UNLIKELY(bitmap_files.files[bmp_i].start_lsn - > bmp_start_lsn)) { - - /* The 1st file does not have the starting LSN data */ - xb_msg_missing_lsn_data(bmp_start_lsn, - bitmap_files.files[bmp_i].start_lsn); - rbt_free(result); - free(bitmap_files.files); - return NULL; - } - - /* Skip any zero-sized files at the start */ - while ((bmp_i < bitmap_files.count - 1) - && (bitmap_files.files[bmp_i].start_lsn - == bitmap_files.files[bmp_i + 1].start_lsn)) { - - bmp_i++; - } - - /* Is the 1st bitmap file missing? */ - if (UNIV_UNLIKELY(bitmap_files.files[bmp_i].name[0] == '\0')) { - - /* TODO: this is not the exact missing range */ - xb_msg_missing_lsn_data(bmp_start_lsn, bmp_end_lsn); - rbt_free(result); - free(bitmap_files.files); - return NULL; - } - - /* Open the 1st bitmap file */ - if (UNIV_UNLIKELY(!log_online_open_bitmap_file_read_only( - bitmap_files.files[bmp_i].name, - &bitmap_file))) { - - rbt_free(result); - free(bitmap_files.files); - return NULL; - } - - /* If the 1st file is truncated, no data. Not merged with the case - below because zero-length file indicates not a corruption but missing - subsequent files instead. */ - if (UNIV_UNLIKELY(bitmap_file.size < MODIFIED_PAGE_BLOCK_SIZE)) { - - xb_msg_missing_lsn_data(bmp_start_lsn, bmp_end_lsn); - rbt_free(result); - free(bitmap_files.files); - os_file_close(bitmap_file.file); - return NULL; - } - - /* Find the start of the required LSN range in the file */ - if (UNIV_UNLIKELY(!xb_find_lsn_in_bitmap_file(&bitmap_file, page, - ¤t_page_end_lsn, - bmp_start_lsn))) { - - msg("mariabackup: Warning: changed page bitmap file " - "\'%s\' corrupted", bitmap_file.name); - rbt_free(result); - free(bitmap_files.files); - os_file_close(bitmap_file.file); - return NULL; - } - - last_page_in_run - = mach_read_from_4(page + MODIFIED_PAGE_IS_LAST_BLOCK); - - if (UNIV_UNLIKELY(!log_online_diagnose_bitmap_eof(&bitmap_file, - last_page_in_run))) { - - rbt_free(result); - free(bitmap_files.files); - os_file_close(bitmap_file.file); - return NULL; - } - - if (UNIV_UNLIKELY(current_page_end_lsn < bmp_start_lsn)) { - - xb_msg_missing_lsn_data(current_page_end_lsn, bmp_start_lsn); - rbt_free(result); - free(bitmap_files.files); - os_file_close(bitmap_file.file); - return NULL; - } - - /* 1st bitmap page found, add it to the tree. */ - rbt_insert(result, page, page); - - /* Read next pages/files until all required data is read */ - while (last_page_ok - && (current_page_end_lsn < bmp_end_lsn - || (current_page_end_lsn == bmp_end_lsn - && !last_page_in_run))) { - - ib_rbt_bound_t tree_search_pos; - - /* If EOF, advance the file skipping over any empty files */ - while (bitmap_file.size < MODIFIED_PAGE_BLOCK_SIZE - || (bitmap_file.offset - > bitmap_file.size - MODIFIED_PAGE_BLOCK_SIZE)) { - - os_file_close(bitmap_file.file); - - if (UNIV_UNLIKELY( - !log_online_diagnose_bitmap_eof( - &bitmap_file, last_page_in_run))) { - - rbt_free(result); - free(bitmap_files.files); - return NULL; - } - - bmp_i++; - - if (UNIV_UNLIKELY(bmp_i == bitmap_files.count - || (bitmap_files.files[bmp_i].seq_num - == 0))) { - - xb_msg_missing_lsn_data(current_page_end_lsn, - bmp_end_lsn); - rbt_free(result); - free(bitmap_files.files); - return NULL; - } - - /* Is the next file missing? */ - if (UNIV_UNLIKELY(bitmap_files.files[bmp_i].name[0] - == '\0')) { - - /* TODO: this is not the exact missing range */ - xb_msg_missing_lsn_data(bitmap_files.files - [bmp_i - 1].start_lsn, - bmp_end_lsn); - rbt_free(result); - free(bitmap_files.files); - return NULL; - } - - if (UNIV_UNLIKELY( - !log_online_open_bitmap_file_read_only( - bitmap_files.files[bmp_i].name, - &bitmap_file))) { - - rbt_free(result); - free(bitmap_files.files); - return NULL; - } - } - - if (UNIV_UNLIKELY( - !log_online_read_bitmap_page(&bitmap_file, page, - &last_page_ok))) { - - rbt_free(result); - free(bitmap_files.files); - os_file_close(bitmap_file.file); - return NULL; - } - - if (UNIV_UNLIKELY(!last_page_ok)) { - - msg("mariabackup: warning: changed page bitmap file " - "\'%s\' corrupted.", bitmap_file.name); - rbt_free(result); - free(bitmap_files.files); - os_file_close(bitmap_file.file); - return NULL; - } - - /* Merge the current page with an existing page or insert a new - page into the tree */ - - if (!rbt_search(result, &tree_search_pos, page)) { - - /* Merge the bitmap pages */ - byte *existing_page - = rbt_value(byte, tree_search_pos.last); - bitmap_word_t *bmp_word_1 = (bitmap_word_t *) - (existing_page + MODIFIED_PAGE_BLOCK_BITMAP); - bitmap_word_t *bmp_end = (bitmap_word_t *) - (existing_page + MODIFIED_PAGE_BLOCK_UNUSED_2); - bitmap_word_t *bmp_word_2 = (bitmap_word_t *) - (page + MODIFIED_PAGE_BLOCK_BITMAP); - while (bmp_word_1 < bmp_end) { - - *bmp_word_1++ |= *bmp_word_2++; - } - xb_a (bmp_word_1 == bmp_end); - } else { - - /* Add a new page */ - rbt_add_node(result, &tree_search_pos, page); - } - - current_page_end_lsn - = mach_read_from_8(page + MODIFIED_PAGE_END_LSN); - last_page_in_run - = mach_read_from_4(page + MODIFIED_PAGE_IS_LAST_BLOCK); - } - - xb_a (current_page_end_lsn >= bmp_end_lsn); - - free(bitmap_files.files); - os_file_close(bitmap_file.file); - - return result; -} - -/****************************************************************//** -Free the bitmap tree. */ -void -xb_page_bitmap_deinit( -/*==================*/ - xb_page_bitmap* bitmap) /*!bitmap_page has been -already found/bumped by rbt_search()/rbt_next(). - -@return FALSE if no more bitmap data for the range space ID */ -static -ibool -xb_page_bitmap_setup_next_page( -/*===========================*/ - xb_page_bitmap_range* bitmap_range) /*!bitmap_node == NULL) { - - bitmap_range->current_page_id = ULINT_UNDEFINED; - return FALSE; - } - - bitmap_range->bitmap_page = rbt_value(byte, bitmap_range->bitmap_node); - - new_space_id = mach_read_from_4(bitmap_range->bitmap_page - + MODIFIED_PAGE_SPACE_ID); - if (new_space_id != bitmap_range->space_id) { - - /* No more data for the current page id. */ - xb_a(new_space_id > bitmap_range->space_id); - bitmap_range->current_page_id = ULINT_UNDEFINED; - return FALSE; - } - - new_1st_page_id = mach_read_from_4(bitmap_range->bitmap_page + - MODIFIED_PAGE_1ST_PAGE_ID); - xb_a (new_1st_page_id >= bitmap_range->current_page_id - || bitmap_range->current_page_id == ULINT_UNDEFINED); - - bitmap_range->current_page_id = new_1st_page_id; - bitmap_range->bit_i = 0; - - return TRUE; -} - -/** Find the node with the smallest key that greater than equal to search key. -@param[in] tree red-black tree -@param[in] key search key -@return node with the smallest greater-than-or-equal key -@retval NULL if none was found */ -static -const ib_rbt_node_t* -rbt_lower_bound(const ib_rbt_t* tree, const void* key) -{ - ut_ad(!tree->cmp_arg); - const ib_rbt_node_t* ge = NULL; - - for (const ib_rbt_node_t *node = tree->root->left; - node != tree->nil; ) { - int result = tree->compare(node->value, key); - - if (result < 0) { - node = node->right; - } else { - ge = node; - if (result == 0) { - break; - } - - node = node->left; - } - } - - return(ge); -} - -/****************************************************************//** -Set up a new bitmap range iterator over a given space id changed -pages in a given bitmap. - -@return bitmap range iterator */ -xb_page_bitmap_range* -xb_page_bitmap_range_init( -/*======================*/ - xb_page_bitmap* bitmap, /*!< in: bitmap to iterate over */ - ulint space_id) /*!< in: space id */ -{ - byte search_page[MODIFIED_PAGE_BLOCK_SIZE]; - xb_page_bitmap_range *result - = static_cast(malloc(sizeof(*result))); - - memset(result, 0, sizeof(*result)); - result->bitmap = bitmap; - result->space_id = space_id; - result->current_page_id = ULINT_UNDEFINED; - - /* Search for the 1st page for the given space id */ - /* This also sets MODIFIED_PAGE_1ST_PAGE_ID to 0, which is what we - want. */ - memset(search_page, 0, MODIFIED_PAGE_BLOCK_SIZE); - mach_write_to_4(search_page + MODIFIED_PAGE_SPACE_ID, space_id); - - result->bitmap_node = rbt_lower_bound(result->bitmap, search_page); - - xb_page_bitmap_setup_next_page(result); - - return result; -} - -/****************************************************************//** -Get the value of the bitmap->range->bit_i bitmap bit - -@return the current bit value */ -static inline -ibool -is_bit_set( -/*=======*/ - const xb_page_bitmap_range* bitmap_range) /*!< in: bitmap - range */ -{ - return ((*(((bitmap_word_t *)(bitmap_range->bitmap_page - + MODIFIED_PAGE_BLOCK_BITMAP)) - + (bitmap_range->bit_i >> 6))) - & (1ULL << (bitmap_range->bit_i & 0x3F))) ? TRUE : FALSE; -} - -/****************************************************************//** -Get the next page id that has its bit set or cleared, i.e. equal to -bit_value. - -@return page id */ -ulint -xb_page_bitmap_range_get_next_bit( -/*==============================*/ - xb_page_bitmap_range* bitmap_range, /*!< in/out: bitmap range */ - ibool bit_value) /*!< in: bit value */ -{ - if (UNIV_UNLIKELY(bitmap_range->current_page_id - == ULINT_UNDEFINED)) { - - return ULINT_UNDEFINED; - } - - do { - while (bitmap_range->bit_i < MODIFIED_PAGE_BLOCK_ID_COUNT) { - - while (is_bit_set(bitmap_range) != bit_value - && (bitmap_range->bit_i - < MODIFIED_PAGE_BLOCK_ID_COUNT)) { - - bitmap_range->current_page_id++; - bitmap_range->bit_i++; - } - - if (bitmap_range->bit_i - < MODIFIED_PAGE_BLOCK_ID_COUNT) { - - ulint result = bitmap_range->current_page_id; - bitmap_range->current_page_id++; - bitmap_range->bit_i++; - return result; - } - } - - bitmap_range->bitmap_node - = rbt_next(bitmap_range->bitmap, - bitmap_range->bitmap_node); - - } while (xb_page_bitmap_setup_next_page(bitmap_range)); - - return ULINT_UNDEFINED; -} - -/****************************************************************//** -Free the bitmap range iterator. */ -void -xb_page_bitmap_range_deinit( -/*========================*/ - xb_page_bitmap_range* bitmap_range) /*! in/out: bitmap range */ -{ - free(bitmap_range); -} diff --git a/extra/mariabackup/changed_page_bitmap.h b/extra/mariabackup/changed_page_bitmap.h deleted file mode 100644 index 8d5043596bf..00000000000 --- a/extra/mariabackup/changed_page_bitmap.h +++ /dev/null @@ -1,85 +0,0 @@ -/****************************************************** -XtraBackup: hot backup tool for InnoDB -(c) 2009-2012 Percona Inc. -Originally Created 3/3/2009 Yasufumi Kinoshita -Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko, -Yasufumi Kinoshita, Ignacio Nin and Baron Schwartz. - -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*******************************************************/ - -/* Changed page bitmap interface */ - -#ifndef XB_CHANGED_PAGE_BITMAP_H -#define XB_CHANGED_PAGE_BITMAP_H - -#include -#include - -/* The changed page bitmap structure */ -typedef ib_rbt_t xb_page_bitmap; - -struct xb_page_bitmap_range_struct; - -/* The bitmap range iterator over one space id */ -typedef struct xb_page_bitmap_range_struct xb_page_bitmap_range; - -/****************************************************************//** -Read the disk bitmap and build the changed page bitmap tree for the -LSN interval incremental_lsn to log_sys.next_checkpoint_lsn. - -@return the built bitmap tree */ -xb_page_bitmap* -xb_page_bitmap_init(void); -/*=====================*/ - -/****************************************************************//** -Free the bitmap tree. */ -void -xb_page_bitmap_deinit( -/*==================*/ - xb_page_bitmap* bitmap); /*! #include -#include #include #include @@ -143,7 +142,7 @@ static inline ATTRIBUTE_FORMAT(printf, 1,2) ATTRIBUTE_NORETURN void die(const ch # define POSIX_FADV_NORMAL # define POSIX_FADV_SEQUENTIAL # define POSIX_FADV_DONTNEED -# define posix_fadvise(a,b,c,d) do {} while(0) +# define posix_fadvise(fd, offset, len, advice) do { (void)offset; } while(0) #endif /*********************************************************************** diff --git a/extra/mariabackup/common_engine.cc b/extra/mariabackup/common_engine.cc new file mode 100644 index 00000000000..a4a8706243a --- /dev/null +++ b/extra/mariabackup/common_engine.cc @@ -0,0 +1,512 @@ +#include "common_engine.h" +#include "backup_copy.h" +#include "xtrabackup.h" +#include "common.h" +#include "backup_debug.h" + +#include +#include +#include +#include + +namespace common_engine { + +class Table { +public: + Table(std::string &db, std::string &table, std::string &fs_name) : + m_db(std::move(db)), m_table(std::move(table)), + m_fs_name(std::move(fs_name)) {} + virtual ~Table() {} + void add_file_name(const char *file_name) { m_fnames.push_back(file_name); } + virtual bool copy(ds_ctxt_t *ds, MYSQL *con, bool no_lock, + bool finalize, unsigned thread_num); + std::string &get_db() { return m_db; } + std::string &get_table() { return m_table; } + std::string &get_version() { return m_version; } + +protected: + std::string m_db; + std::string m_table; + std::string m_fs_name; + std::string m_version; + std::vector m_fnames; +}; + +bool +Table::copy(ds_ctxt_t *ds, MYSQL *con, bool no_lock, bool, unsigned thread_num) { + static const size_t buf_size = 10 * 1024 * 1024; + std::unique_ptr buf; + bool result = false; + File frm_file = -1; + std::vector files; + bool locked = false; + std::string full_tname("`"); + full_tname.append(m_db).append("`.`").append(m_table).append("`"); + + if (!no_lock && !backup_lock(con, full_tname.c_str())) { + msg(thread_num, "Error on executing BACKUP LOCK for table %s", + full_tname.c_str()); + goto exit; + } + else + locked = !no_lock; + + if ((frm_file = mysql_file_open(key_file_frm, (m_fs_name + ".frm").c_str(), + O_RDONLY | O_SHARE, MYF(0))) < 0 && !m_fnames.empty() && + !ends_with(m_fnames[0].c_str(), ".ARZ") && + !ends_with(m_fnames[0].c_str(), ".ARM")) { + // Don't treat it as error, as the table can be dropped after it + // was added to queue for copying + result = true; + goto exit; + } + + for (const auto &fname : m_fnames) { + File file = mysql_file_open(0, fname.c_str(),O_RDONLY | O_SHARE, MYF(0)); + if (file < 0) { + msg(thread_num, "Error on file %s open during %s table copy", + fname.c_str(), full_tname.c_str()); + goto exit; + } + files.push_back(file); + } + + if (locked && !backup_unlock(con)) { + msg(thread_num, "Error on BACKUP UNLOCK for table %s", full_tname.c_str()); + locked = false; + goto exit; + } + + locked = false; + + buf.reset(new uchar[buf_size]); + + for (size_t i = 0; i < m_fnames.size(); ++i) { + ds_file_t *dst_file = nullptr; + size_t bytes_read; + size_t copied_size = 0; + MY_STAT stat_info; + + if (my_fstat(files[i], &stat_info, MYF(0))) { + msg(thread_num, "error: failed to get stat info for file %s of " + "table %s", m_fnames[i].c_str(), full_tname.c_str()); + goto exit; + } + + const char *dst_path = + (xtrabackup_copy_back || xtrabackup_move_back) ? + m_fnames[i].c_str() : trim_dotslash(m_fnames[i].c_str()); + + dst_file = ds_open(ds, dst_path, &stat_info, false); + if (!dst_file) { + msg(thread_num, "error: cannot open destination stream for %s, table %s", + dst_path, full_tname.c_str()); + goto exit; + } + + while ((bytes_read = my_read(files[i], buf.get(), buf_size, MY_WME))) { + if (bytes_read == size_t(-1)) { + msg(thread_num, "error: file %s read for table %s", + m_fnames[i].c_str(), full_tname.c_str()); + ds_close(dst_file); + goto exit; + } + xtrabackup_io_throttling(); + if (ds_write(dst_file, buf.get(), bytes_read)) { + msg(thread_num, "error: file %s write for table %s", + dst_path, full_tname.c_str()); + ds_close(dst_file); + goto exit; + } + copied_size += bytes_read; + } + mysql_file_close(files[i], MYF(MY_WME)); + files[i] = -1; + ds_close(dst_file); + msg(thread_num, "Copied file %s for table %s, %zu bytes", + m_fnames[i].c_str(), full_tname.c_str(), copied_size); + } + + result = true; + +#ifndef DBUG_OFF + { + std::string sql_name(m_db); + sql_name.append("/").append(m_table); + DBUG_MARIABACKUP_EVENT_LOCK("after_ce_table_copy", fil_space_t::name_type(sql_name.data(), sql_name.size())); + } +#endif // DBUG_OFF +exit: + if (frm_file >= 0) { + m_version = ::read_table_version_id(frm_file); + mysql_file_close(frm_file, MYF(MY_WME)); + } + if (locked && !backup_unlock(con)) { + msg(thread_num, "Error on BACKUP UNLOCK for table %s", full_tname.c_str()); + result = false; + } + for (auto file : files) + if (file >= 0) + mysql_file_close(file, MYF(MY_WME)); + return result; +} + +// Append-only tables +class LogTable : public Table { + public: + LogTable(std::string &db, std::string &table, std::string &fs_name) : + Table(db, table, fs_name) {} + + virtual ~LogTable() { (void)close(); } + bool + copy(ds_ctxt_t *ds, MYSQL *con, bool no_lock, bool finalize, + unsigned thread_num) override; + bool close(); + private: + bool open(ds_ctxt_t *ds, unsigned thread_num); + std::vector m_src; + std::vector m_dst; +}; + +bool +LogTable::open(ds_ctxt_t *ds, unsigned thread_num) { + DBUG_ASSERT(m_src.empty()); + DBUG_ASSERT(m_dst.empty()); + + std::string full_tname("`"); + full_tname.append(m_db).append("`.`").append(m_table).append("`"); + + for (const auto &fname : m_fnames) { + File file = mysql_file_open(0, fname.c_str(),O_RDONLY | O_SHARE, MYF(0)); + if (file < 0) { + msg(thread_num, "Error on file %s open during %s log table copy", + fname.c_str(), full_tname.c_str()); + return false; + } + m_src.push_back(file); + + MY_STAT stat_info; + if (my_fstat(file, &stat_info, MYF(0))) { + msg(thread_num, "error: failed to get stat info for file %s of " + "log table %s", fname.c_str(), full_tname.c_str()); + return false; + } + const char *dst_path = + (xtrabackup_copy_back || xtrabackup_move_back) ? + fname.c_str() : trim_dotslash(fname.c_str()); + ds_file_t *dst_file = ds_open(ds, dst_path, &stat_info, false); + if (!dst_file) { + msg(thread_num, "error: cannot open destination stream for %s, " + "log table %s", dst_path, full_tname.c_str()); + return false; + } + m_dst.push_back(dst_file); + } + + File frm_file; + if ((frm_file = mysql_file_open(key_file_frm, (m_fs_name + ".frm").c_str(), + O_RDONLY | O_SHARE, MYF(0))) < 0 && !m_fnames.empty() && + !ends_with(m_fnames[0].c_str(), ".ARZ") && + !ends_with(m_fnames[0].c_str(), ".ARM")) { + msg(thread_num, "Error on .frm file open for log table %s", + full_tname.c_str()); + return false; + } + + m_version = ::read_table_version_id(frm_file); + mysql_file_close(frm_file, MYF(MY_WME)); + + return true; +} + +bool LogTable::close() { + while (!m_src.empty()) { + auto f = m_src.back(); + m_src.pop_back(); + mysql_file_close(f, MYF(MY_WME)); + } + while (!m_dst.empty()) { + auto f = m_dst.back(); + m_dst.pop_back(); + ds_close(f); + } + return true; +} + +bool +LogTable::copy(ds_ctxt_t *ds, MYSQL *con, bool no_lock, bool finalize, + unsigned thread_num) { + static const size_t buf_size = 10 * 1024 * 1024; + DBUG_ASSERT(ds); + DBUG_ASSERT(con); + if (m_src.empty() && !open(ds, thread_num)) { + close(); + return false; + } + DBUG_ASSERT(m_src.size() == m_dst.size()); + + std::unique_ptr buf(new uchar[buf_size]); + for (size_t i = 0; i < m_src.size(); ++i) { + // .CSM can be rewritten (see write_meta_file() usage in ha_tina.cc) + if (!finalize && ends_with(m_fnames[i].c_str(), ".CSM")) + continue; + size_t bytes_read; + size_t copied_size = 0; + while ((bytes_read = my_read(m_src[i], buf.get(), buf_size, MY_WME))) { + if (bytes_read == size_t(-1)) { + msg(thread_num, "error: file %s read for log table %s", + m_fnames[i].c_str(), + std::string("`").append(m_db).append("`.`"). + append(m_table).append("`").c_str()); + close(); + return false; + } + xtrabackup_io_throttling(); + if (ds_write(m_dst[i], buf.get(), bytes_read)) { + msg(thread_num, "error: file %s write for log table %s", + m_fnames[i].c_str(), std::string("`").append(m_db).append("`.`"). + append(m_table).append("`").c_str()); + close(); + return false; + } + copied_size += bytes_read; + } + msg(thread_num, "Copied file %s for log table %s, %zu bytes", + m_fnames[i].c_str(), std::string("`").append(m_db).append("`.`"). + append(m_table).append("`").c_str(), copied_size); + } + + return true; +} + +class BackupImpl { + public: + BackupImpl( + const char *datadir_path, ds_ctxt_t *datasink, + std::vector &con_pool, ThreadPool &thread_pool) : + m_datadir_path(datadir_path), m_ds(datasink), m_con_pool(con_pool), + m_process_table_jobs(thread_pool) {} + ~BackupImpl() { } + bool scan( + const std::unordered_set &exclude_tables, + std::unordered_set *out_processed_tables, + bool no_lock, bool collect_log_and_stats); + void set_post_copy_table_hook(const post_copy_table_hook_t &hook) { + m_table_post_copy_hook = hook; + } + bool copy_log_tables(bool finalize); + bool copy_stats_tables(); + bool wait_for_finish(); + bool close_log_tables(); + private: + + void process_table_job(Table *table, bool no_lock, bool delete_table, + bool finalize, unsigned thread_num); + + const char *m_datadir_path; + ds_ctxt_t *m_ds; + std::vector &m_con_pool; + TasksGroup m_process_table_jobs; + + post_copy_table_hook_t m_table_post_copy_hook; + std::unordered_map> m_log_tables; + std::unordered_map> m_stats_tables; +}; + +void BackupImpl::process_table_job(Table *table, bool no_lock, + bool delete_table, bool finalize, unsigned thread_num) { + int result = 0; + + if (!m_process_table_jobs.get_result()) + goto exit; + + if (!table->copy(m_ds, m_con_pool[thread_num], no_lock, finalize, thread_num)) + goto exit; + + if (m_table_post_copy_hook) + m_table_post_copy_hook(table->get_db(), table->get_table(), + table->get_version()); + + result = 1; + +exit: + if (delete_table) + delete table; + m_process_table_jobs.finish_task(result); +} + +bool BackupImpl::scan(const std::unordered_set &exclude_tables, + std::unordered_set *out_processed_tables, bool no_lock, + bool collect_log_and_stats) { + + msg("Start scanning common engine tables, need backup locks: %d, " + "collect log and stat tables: %d", no_lock, collect_log_and_stats); + + std::unordered_map> found_tables; + + foreach_file_in_db_dirs(m_datadir_path, + [&](const char *file_path)->bool { + + static const char *ext_list[] = + {".MYD", ".MYI", ".MRG", ".ARM", ".ARZ", ".CSM", ".CSV", NULL}; + + bool is_aria = ends_with(file_path, ".MAD") || ends_with(file_path, ".MAI"); + + if (!collect_log_and_stats && is_aria) + return true; + + if (!is_aria && !filename_matches(file_path, ext_list)) + return true; + + if (check_if_skip_table(file_path)) { + msg("Skipping %s.", file_path); + return true; + } + + auto db_table_fs = convert_filepath_to_tablename(file_path); + auto tk = + table_key(std::get<0>(db_table_fs), std::get<1>(db_table_fs)); + + // log and stats tables are only collected in this function, + // so there is no need to filter out them with exclude_tables. + if (collect_log_and_stats) { + if (is_log_table(std::get<0>(db_table_fs).c_str(), + std::get<1>(db_table_fs).c_str())) { + auto table_it = m_log_tables.find(tk); + if (table_it == m_log_tables.end()) { + msg("Log table found: %s", tk.c_str()); + table_it = m_log_tables.emplace(tk, + std::unique_ptr(new LogTable(std::get<0>(db_table_fs), + std::get<1>(db_table_fs), std::get<2>(db_table_fs)))).first; + } + msg("Collect log table file: %s", file_path); + table_it->second->add_file_name(file_path); + return true; + } + // Aria can handle statistics tables + else if (is_stats_table(std::get<0>(db_table_fs).c_str(), + std::get<1>(db_table_fs).c_str()) && !is_aria) { + auto table_it = m_stats_tables.find(tk); + if (table_it == m_stats_tables.end()) { + msg("Stats table found: %s", tk.c_str()); + table_it = m_stats_tables.emplace(tk, + std::unique_ptr
(new Table(std::get<0>(db_table_fs), + std::get<1>(db_table_fs), std::get<2>(db_table_fs)))).first; + } + msg("Collect stats table file: %s", file_path); + table_it->second->add_file_name(file_path); + return true; + } + } else if (is_log_table(std::get<0>(db_table_fs).c_str(), + std::get<1>(db_table_fs).c_str()) || + is_stats_table(std::get<0>(db_table_fs).c_str(), + std::get<1>(db_table_fs).c_str())) + return true; + + if (is_aria) + return true; + + if (exclude_tables.count(tk)) { + msg("Skip table %s at it is in exclude list", tk.c_str()); + return true; + } + + auto table_it = found_tables.find(tk); + if (table_it == found_tables.end()) { + table_it = found_tables.emplace(tk, + std::unique_ptr
(new Table(std::get<0>(db_table_fs), + std::get<1>(db_table_fs), std::get<2>(db_table_fs)))).first; + } + + table_it->second->add_file_name(file_path); + + return true; + }); + + for (auto &table_it : found_tables) { + m_process_table_jobs.push_task( + std::bind(&BackupImpl::process_table_job, this, table_it.second.release(), + no_lock, true, false, std::placeholders::_1)); + if (out_processed_tables) + out_processed_tables->insert(table_it.first); + } + + msg("Stop scanning common engine tables"); + return true; +} + +bool BackupImpl::copy_log_tables(bool finalize) { + for (auto &table_it : m_log_tables) { + // Do not execute BACKUP LOCK for log tables as it's supposed + // that they must be copied on BLOCK_DDL and BLOCK_COMMIT locks. + m_process_table_jobs.push_task( + std::bind(&BackupImpl::process_table_job, this, table_it.second.get(), + true, false, finalize, std::placeholders::_1)); + } + return true; +} + +bool BackupImpl::copy_stats_tables() { + for (auto &table_it : m_stats_tables) { + // Do not execute BACKUP LOCK for stats tables as it's supposed + // that they must be copied on BLOCK_DDL and BLOCK_COMMIT locks. + // Delete stats table object after copy (see process_table_job()) + m_process_table_jobs.push_task( + std::bind(&BackupImpl::process_table_job, this, table_it.second.release(), + true, true, false, std::placeholders::_1)); + } + m_stats_tables.clear(); + return true; +} + +bool BackupImpl::wait_for_finish() { + /* Wait for threads to exit */ + return m_process_table_jobs.wait_for_finish(); +} + +bool BackupImpl::close_log_tables() { + bool result = wait_for_finish(); + for (auto &table_it : m_log_tables) + table_it.second->close(); + return result; +} + +Backup::Backup(const char *datadir_path, ds_ctxt_t *datasink, + std::vector &con_pool, ThreadPool &thread_pool) : + m_backup_impl( + new BackupImpl(datadir_path, datasink, con_pool, + thread_pool)) { } + +Backup::~Backup() { + delete m_backup_impl; +} + +bool Backup::scan( + const std::unordered_set &exclude_tables, + std::unordered_set *out_processed_tables, + bool no_lock, bool collect_log_and_stats) { + return m_backup_impl->scan(exclude_tables, out_processed_tables, no_lock, + collect_log_and_stats); +} + +bool Backup::copy_log_tables(bool finalize) { + return m_backup_impl->copy_log_tables(finalize); +} + +bool Backup::copy_stats_tables() { + return m_backup_impl->copy_stats_tables(); +} + +bool Backup::wait_for_finish() { + return m_backup_impl->wait_for_finish(); +} + +bool Backup::close_log_tables() { + return m_backup_impl->close_log_tables(); +} + +void Backup::set_post_copy_table_hook(const post_copy_table_hook_t &hook) { + m_backup_impl->set_post_copy_table_hook(hook); +} + +} // namespace common_engine diff --git a/extra/mariabackup/common_engine.h b/extra/mariabackup/common_engine.h new file mode 100644 index 00000000000..6f5d8062e50 --- /dev/null +++ b/extra/mariabackup/common_engine.h @@ -0,0 +1,39 @@ +#pragma once +#include "my_global.h" +#include "backup_mysql.h" +#include "datasink.h" +#include "thread_pool.h" +#include "xtrabackup.h" + +#include +#include +#include + +namespace common_engine { + +class BackupImpl; + +class Backup { + public: + Backup(const char *datadir_path, ds_ctxt_t *datasink, + std::vector &con_pool, ThreadPool &thread_pool); + ~Backup(); + Backup (Backup &&other) = delete; + Backup & operator= (Backup &&other) = delete; + Backup(const Backup &) = delete; + Backup & operator= (const Backup &) = delete; + bool scan( + const std::unordered_set &exclude_tables, + std::unordered_set *out_processed_tables, + bool no_lock, bool collect_log_and_stats); + bool copy_log_tables(bool finalize); + bool copy_stats_tables(); + bool wait_for_finish(); + bool close_log_tables(); + void set_post_copy_table_hook(const post_copy_table_hook_t &hook); + private: + BackupImpl *m_backup_impl; +}; + +} // namespace common_engine + diff --git a/extra/mariabackup/datasink.cc b/extra/mariabackup/datasink.cc index a576526d7ff..132ff3fcfb6 100644 --- a/extra/mariabackup/datasink.cc +++ b/extra/mariabackup/datasink.cc @@ -80,11 +80,11 @@ ds_create(const char *root, ds_type_t type) /************************************************************************ Open a datasink file */ ds_file_t * -ds_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *stat) +ds_open(ds_ctxt_t *ctxt, const char *path, const MY_STAT *stat, bool rewrite) { ds_file_t *file; - file = ctxt->datasink->open(ctxt, path, stat); + file = ctxt->datasink->open(ctxt, path, stat, rewrite); if (file != NULL) { file->datasink = ctxt->datasink; } @@ -104,6 +104,30 @@ ds_write(ds_file_t *file, const void *buf, size_t len) return file->datasink->write(file, (const uchar *)buf, len); } +int ds_seek_set(ds_file_t *file, my_off_t offset) { + DBUG_ASSERT(file); + DBUG_ASSERT(file->datasink); + if (file->datasink->seek_set) + return file->datasink->seek_set(file, offset); + return 0; +} + +int ds_rename(ds_ctxt_t *ctxt, const char *old_path, const char *new_path) { + DBUG_ASSERT(ctxt); + DBUG_ASSERT(ctxt->datasink); + if (ctxt->datasink->rename) + return ctxt->datasink->rename(ctxt, old_path, new_path); + return 0; +} + +int ds_remove(ds_ctxt_t *ctxt, const char *path) { + DBUG_ASSERT(ctxt); + DBUG_ASSERT(ctxt->datasink); + if (ctxt->datasink->remove) + return ctxt->datasink->mremove(ctxt, path); + return 0; +} + /************************************************************************ Close a datasink file. @return 0 on success, 1, on error. */ diff --git a/extra/mariabackup/datasink.h b/extra/mariabackup/datasink.h index 57468e0c9c7..98cbe5252ac 100644 --- a/extra/mariabackup/datasink.h +++ b/extra/mariabackup/datasink.h @@ -43,7 +43,8 @@ typedef struct ds_ctxt { */ bool copy_file(const char *src_file_path, const char *dst_file_path, - uint thread_n); + uint thread_n, + bool rewrite = false); bool move_file(const char *src_file_path, const char *dst_file_path, @@ -76,10 +77,15 @@ typedef struct { struct datasink_struct { ds_ctxt_t *(*init)(const char *root); - ds_file_t *(*open)(ds_ctxt_t *ctxt, const char *path, MY_STAT *stat); + ds_file_t *(*open)(ds_ctxt_t *ctxt, const char *path, + const MY_STAT *stat, bool rewrite); int (*write)(ds_file_t *file, const unsigned char *buf, size_t len); + int (*seek_set)(ds_file_t *file, my_off_t offset); int (*close)(ds_file_t *file); int (*remove)(const char *path); + // TODO: consider to return bool from "rename" and "remove" + int (*rename)(ds_ctxt_t *ctxt, const char *old_path, const char *new_path); + int (*mremove)(ds_ctxt_t *ctxt, const char *path); void (*deinit)(ds_ctxt_t *ctxt); }; @@ -106,12 +112,17 @@ ds_ctxt_t *ds_create(const char *root, ds_type_t type); /************************************************************************ Open a datasink file */ -ds_file_t *ds_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *stat); +ds_file_t *ds_open( + ds_ctxt_t *ctxt, const char *path, const MY_STAT *stat, bool rewrite = false); /************************************************************************ Write to a datasink file. @return 0 on success, 1 on error. */ int ds_write(ds_file_t *file, const void *buf, size_t len); +int ds_seek_set(ds_file_t *file, my_off_t offset); + +int ds_rename(ds_ctxt_t *ctxt, const char *old_path, const char *new_path); +int ds_remove(ds_ctxt_t *ctxt, const char *path); /************************************************************************ Close a datasink file. diff --git a/extra/mariabackup/ddl_log.cc b/extra/mariabackup/ddl_log.cc new file mode 100644 index 00000000000..6af34172dcb --- /dev/null +++ b/extra/mariabackup/ddl_log.cc @@ -0,0 +1,553 @@ +#include "ddl_log.h" +#include "common.h" +#include "my_sys.h" +#include "sql_table.h" +#include "backup_copy.h" +#include "xtrabackup.h" +#include +#include +#include +#include + +namespace ddl_log { + +struct Entry { + enum Type { + CREATE, + ALTER, + RENAME, + REPAIR, + OPTIMIZE, + DROP, + TRUNCATE, + CHANGE_INDEX, + BULK_INSERT + }; + Type type; + std::string date; + std::string engine; + bool partitioned; + std::string db; + std::string table; + std::string id; + std::string new_engine; + bool new_partitioned; + std::string new_db; + std::string new_table; + std::string new_id; +}; + +typedef std::vector> entries_t; +typedef std::function)> store_entry_func_t; + +const char *aria_engine_name = "Aria"; +static const char *frm_ext = ".frm"; +static const char *database_keyword = "DATABASE"; + +const std::unordered_map> engine_exts = +{ + {"Aria", {".MAD", ".MAI"}}, + {"MyISAM", {".MYD", ".MYI"}}, + {"MRG_MyISAM", {".MRG"}}, + {"ARCHIVE", {".ARM", ".ARZ"}}, + {"CSV", {".CSM", ".CSV"}} +}; + +static inline bool known_engine(const std::string &engine) { + return engine_exts.count(engine); +} + +// TODO: add error messages +size_t parse(const uchar *buf, size_t buf_size, bool &error_flag, + store_entry_func_t &store_entry_func) { + DBUG_ASSERT(buf); + static constexpr char token_delimiter = '\t'; + static constexpr char line_delimiter = '\n'; + enum { + TOKEN_FIRST = 0, + TOKEN_DATE = TOKEN_FIRST, + TOKEN_TYPE, + TOKEN_ENGINE, + TOKEN_PARTITIONED, + TOKEN_DB, + TOKEN_TABLE, + TOKEN_ID, + TOKEN_MANDATORY = TOKEN_ID, + TOKEN_NEW_ENGINE, + TOKEN_NEW_PARTITIONED, + TOKEN_NEW_DB, + TOKEN_NEW_TABLE, + TOKEN_NEW_ID, + TOKEN_LAST = TOKEN_NEW_ID + }; + const size_t string_offsets[TOKEN_LAST + 1] = { + offsetof(Entry, date), + offsetof(Entry, type), // not a string, be careful + offsetof(Entry, engine), + offsetof(Entry, partitioned), // not a string, be careful + offsetof(Entry, db), + offsetof(Entry, table), + offsetof(Entry, id), + offsetof(Entry, new_engine), + offsetof(Entry, new_partitioned), // not a string, be careful + offsetof(Entry, new_db), + offsetof(Entry, new_table), + offsetof(Entry, new_id) + }; + const std::unordered_map str_to_type = { + {"CREATE", Entry::CREATE}, + {"ALTER", Entry::ALTER}, + {"RENAME", Entry::RENAME}, + // TODO: fix to use uppercase-only + {"repair", Entry::REPAIR}, + {"optimize", Entry::OPTIMIZE}, + {"DROP", Entry::DROP}, + {"TRUNCATE", Entry::TRUNCATE}, + {"CHANGE_INDEX", Entry::CHANGE_INDEX}, + {"BULK_INSERT", Entry::BULK_INSERT} + }; + + const uchar *new_line = buf; + const uchar *token_start = buf; + unsigned token_num = TOKEN_FIRST; + + error_flag = false; + + std::unique_ptr entry(new Entry()); + + for (const uchar *ptr = buf; ptr < buf + buf_size; ++ptr) { + + if (*ptr != token_delimiter && *ptr != line_delimiter) + continue; + + if (token_start != ptr) { + std::string token(token_start, ptr); + + if (token_num == TOKEN_TYPE) { + const auto type_it = str_to_type.find(token); + if (type_it == str_to_type.end()) { + error_flag = true; + goto exit; + } + entry->type = type_it->second; + } + else if (token_num == TOKEN_PARTITIONED) { + entry->partitioned = token[0] - '0'; + } + else if (token_num == TOKEN_NEW_PARTITIONED) { + entry->new_partitioned = token[0] - '0'; + } + else if (token_num <= TOKEN_LAST) { + DBUG_ASSERT(token_num != TOKEN_TYPE); + DBUG_ASSERT(token_num != TOKEN_PARTITIONED); + DBUG_ASSERT(token_num != TOKEN_NEW_PARTITIONED); + reinterpret_cast + (reinterpret_cast(entry.get()) + string_offsets[token_num])-> + assign(std::move(token)); + } + else { + error_flag = true; + goto exit; + } + } + token_start = ptr + 1; + + if (*ptr == line_delimiter) { + if (token_num < TOKEN_MANDATORY) { + error_flag = true; + goto exit; + } + if (!store_entry_func(std::move(entry))) { + error_flag = true; + goto exit; + } + entry.reset(new Entry()); + token_num = TOKEN_FIRST; + new_line = ptr + 1; + } else + ++token_num; + } + +exit: + return new_line - buf; +} + +bool parse(const char *file_path, store_entry_func_t store_entry_func) { + DBUG_ASSERT(file_path); + DBUG_ASSERT(store_entry_func); + File file= -1; + bool result = true; + uchar buf[1024]; + size_t bytes_read = 0; + size_t buf_read_offset = 0; + + if ((file= my_open(file_path, O_RDONLY | O_SHARE | O_NOFOLLOW | O_CLOEXEC, + MYF(MY_WME))) < 0) { + msg("DDL log file %s open failed: %d", file_path, my_errno); + result = false; + goto exit; + } + + while((bytes_read = my_read( + file, &buf[buf_read_offset], sizeof(buf) - buf_read_offset, MY_WME)) > 0) { + if (bytes_read == size_t(-1)) { + msg("DDL log file %s read error: %d", file_path, my_errno); + result = false; + break; + } + bytes_read += buf_read_offset; + bool parse_error_flag = false; + size_t bytes_parsed = parse( + buf, bytes_read, parse_error_flag, store_entry_func); + if (parse_error_flag) { + result = false; + break; + } + size_t rest_size = bytes_read - bytes_parsed; + if (rest_size) + memcpy(buf, buf + bytes_parsed, rest_size); + buf_read_offset = rest_size; + } + +exit: + if (file >= 0) + my_close(file, MYF(MY_WME)); + return result; +}; + + +static +bool process_database( + const char *datadir_path, + ds_ctxt_t *ds, + const Entry &entry, + std::unordered_set &dropped_databases) { + + if (entry.type == Entry::Type::CREATE || + entry.type == Entry::Type::ALTER) { + std::string opt_file(datadir_path); + opt_file.append("/").append(entry.db).append("/db.opt"); + if (!ds->copy_file(opt_file.c_str(), opt_file.c_str(), 0, true)) { + msg("Failed to re-copy %s.", opt_file.c_str()); + return false; + } + if (entry.type == Entry::Type::CREATE) + dropped_databases.erase(entry.db); + return true; + } + + DBUG_ASSERT(entry.type == Entry::Type::DROP); + + std::string db_path(datadir_path); + db_path.append("/").append(entry.db); + const char *dst_path = convert_dst(db_path.c_str()); + if (!ds_remove(ds, dst_path)) { + dropped_databases.insert(entry.db); + return true; + } + return false; +} + +static +std::unique_ptr> + find_table_files( + const char *dir_path, + const std::string &db, + const std::string &table) { + + std::unique_ptr> + result(new std::vector()); + + std::string prefix = convert_tablename_to_filepath(dir_path, db, table); + foreach_file_in_db_dirs(dir_path, [&](const char *file_name)->bool { + if (!strncmp(file_name, prefix.c_str(), prefix.size())) { + DBUG_ASSERT(strlen(file_name) >= prefix.size()); + if (file_name[prefix.size()] == '.' || + !strncmp(file_name + prefix.size(), "#P#", strlen("#P#"))) + result->push_back(std::string(file_name)); + } + return true; + }); + + return result; +} + +static +bool process_remove( + const char *datadir_path, + ds_ctxt_t *ds, + const Entry &entry, + bool remove_frm) { + + if (check_if_skip_table( + std::string(entry.db).append("/").append(entry.table).c_str())) + return true; + + auto ext_it = engine_exts.find(entry.engine); + if (ext_it == engine_exts.end()) + return true; + + std::string file_preffix = convert_tablename_to_filepath(datadir_path, + entry.db, entry.table); + const char *dst_preffix = convert_dst(file_preffix.c_str()); + + for (const char *ext : ext_it->second) { + std::string old_name(dst_preffix); + if (!entry.partitioned) + old_name.append(ext); + else + old_name.append("#P#*"); + if (ds_remove(ds, old_name.c_str())) { + msg("Failed to remove %s.", old_name.c_str()); + return false; + } + } + + if (remove_frm) { + std::string old_frm_name(dst_preffix); + old_frm_name.append(frm_ext); + if (ds_remove(ds, old_frm_name.c_str())) { + msg("Failed to remove %s.", old_frm_name.c_str()); + return false; + } + } + return true; + +} + +static +bool process_recopy( + const char *datadir_path, + ds_ctxt_t *ds, + const Entry &entry, + const tables_t &tables) { + + if (check_if_skip_table( + std::string(entry.db).append("/").append(entry.table).c_str())) + return true; + + const std::string &new_table_id = + entry.new_id.empty() ? entry.id : entry.new_id; + DBUG_ASSERT(!new_table_id.empty()); + const std::string &new_table = + entry.new_table.empty() ? entry.table : entry.new_table; + DBUG_ASSERT(!new_table.empty()); + const std::string &new_db = + entry.new_db.empty() ? entry.db : entry.new_db; + DBUG_ASSERT(!new_db.empty()); + const std::string &new_engine = + entry.new_engine.empty() ? entry.engine : entry.new_engine; + DBUG_ASSERT(!new_engine.empty()); + + if (entry.type != Entry::Type::BULK_INSERT) { + auto table_it = tables.find(table_key(new_db, new_table)); + if (table_it != tables.end() && + table_it->second == new_table_id) + return true; + } + + if (!entry.new_engine.empty() && + entry.engine != entry.new_engine && + !known_engine(entry.new_engine)) { + return process_remove(datadir_path, ds, entry, false); + } + + if ((entry.partitioned || entry.new_partitioned) && + !process_remove(datadir_path, ds, entry, false)) + return false; + + if (entry.partitioned || entry.new_partitioned) { + auto files = find_table_files(datadir_path, new_db, new_table); + if (!files.get()) + return true; + for (const auto &file : *files) { + const char *dst_path = convert_dst(file.c_str()); + if (!ds->copy_file(file.c_str(), dst_path, 0, true)) { + msg("Failed to re-copy %s.", file.c_str()); + return false; + } + } + return true; + } + + auto ext_it = engine_exts.find(new_engine); + if (ext_it == engine_exts.end()) + return false; + + for (const char *ext : ext_it->second) { + std::string file_name = + convert_tablename_to_filepath(datadir_path, new_db, new_table). + append(ext); + const char *dst_path = convert_dst(file_name.c_str()); + if (file_exists(file_name.c_str()) && + !ds->copy_file(file_name.c_str(), dst_path, 0, true)) { + msg("Failed to re-copy %s.", file_name.c_str()); + return false; + } + } + + std::string frm_file = + convert_tablename_to_filepath(datadir_path, new_db, new_table). + append(frm_ext); + const char *frm_dst_path = convert_dst(frm_file.c_str()); + if (file_exists(frm_file.c_str()) && + !ds->copy_file(frm_file.c_str(), frm_dst_path, 0, true)) { + msg("Failed to re-copy %s.", frm_file.c_str()); + return false; + } + + return true; +} + +static +bool process_rename( + const char *datadir_path, + ds_ctxt_t *ds, + const Entry &entry) { + + if (check_if_skip_table( + std::string(entry.db).append("/").append(entry.table).c_str())) + return true; + + DBUG_ASSERT(entry.db != "partition"); + + auto ext_it = engine_exts.find(entry.engine); + if (ext_it == engine_exts.end()) + return false; + + std::string new_preffix = convert_tablename_to_filepath(datadir_path, + entry.new_db, entry.new_table); + const char *dst_path = convert_dst(new_preffix.c_str()); + + std::string old_preffix = convert_tablename_to_filepath(datadir_path, + entry.db, entry.table); + const char *src_path = convert_dst(old_preffix.c_str()); + + for (const char *ext : ext_it->second) { + std::string old_name(src_path); + old_name.append(ext); + std::string new_name(dst_path); + new_name.append(ext); + if (ds_rename(ds, old_name.c_str(), new_name.c_str())) { + msg("Failed to rename %s to %s.", + old_name.c_str(), new_name.c_str()); + return false; + } + } + + std::string new_frm_file = new_preffix + frm_ext; + const char *new_frm_dst = convert_dst(new_frm_file.c_str()); + if (file_exists(new_frm_file.c_str()) && + !ds->copy_file(new_frm_file.c_str(), new_frm_dst, 0, true)) { + msg("Failed to re-copy %s.", new_frm_file.c_str()); + return false; + } + +// TODO: return this code if .frm is copied not under BLOCK_DDL +/* + std::string old_frm_name(src_path); + old_frm_name.append(frm_ext); + std::string new_frm_name(dst_path); + new_frm_name.append(frm_ext); + if (ds_rename(ds, old_frm_name.c_str(), new_frm_name.c_str())) { + msg("Failed to rename %s to %s.", + old_frm_name.c_str(), new_frm_name.c_str()); + return false; + } +*/ + return true; +} + +bool backup( + const char *datadir_path, + ds_ctxt_t *ds, + const tables_t &tables) { + DBUG_ASSERT(datadir_path); + DBUG_ASSERT(ds); + char ddl_log_path[FN_REFLEN]; + fn_format(ddl_log_path, "ddl", datadir_path, ".log", 0); + std::vector> entries; + + std::unordered_set processed_tables; + std::unordered_set dropped_databases; + + bool parsing_result = + parse(ddl_log_path, [&](std::unique_ptr entry)->bool { + + if (entry->engine == database_keyword) + return process_database(datadir_path, ds, *entry, dropped_databases); + + if (!known_engine(entry->engine) && !known_engine(entry->new_engine)) + return true; + + if (entry->type == Entry::Type::CREATE || + (entry->type == Entry::Type::ALTER && + !entry->new_engine.empty() && + entry->engine != entry->new_engine)) { + if (!process_recopy(datadir_path, ds, *entry, tables)) + return false; + processed_tables.insert(table_key(entry->db, entry->table)); + if (entry->type == Entry::Type::ALTER) + processed_tables.insert(table_key(entry->new_db, entry->new_table)); + return true; + } + + if (entry->type == Entry::Type::DROP) { + if (!process_remove(datadir_path, ds, *entry, true)) + return false; + processed_tables.insert(table_key(entry->db, entry->table)); + return true; + } + if (entry->type == Entry::Type::RENAME) { + if (entry->partitioned) { + if (!process_remove(datadir_path, ds, *entry, true)) + return false; + Entry recopy_entry { + entry->type, + {}, + entry->new_engine.empty() ? entry->engine : entry->new_engine, + true, + entry->new_db, + entry->new_table, + entry->new_id, + {}, true, {}, {}, {} + }; + if (!process_recopy(datadir_path, ds, recopy_entry, tables)) + return false; + } + else if (!process_rename(datadir_path, ds, *entry)) + return false; + processed_tables.insert(table_key(entry->db, entry->table)); + processed_tables.insert(table_key(entry->new_db, entry->new_table)); + return true; + } + + entries.push_back(std::move(entry)); + return true; + + }); + + if (!parsing_result) + return false; + + + while (!entries.empty()) { + auto entry = std::move(entries.back()); + entries.pop_back(); + auto tk = table_key( + entry->new_db.empty() ? entry->db : entry->new_db, + entry->new_table.empty() ? entry->table : entry->new_table); + if (dropped_databases.count(entry->db) || + dropped_databases.count(entry->new_db)) + continue; + if (processed_tables.count(tk)) + continue; + processed_tables.insert(std::move(tk)); + if (!process_recopy(datadir_path, ds, *entry, tables)) + return false; + } + + return true; +} + +} // namespace ddl_log diff --git a/extra/mariabackup/ddl_log.h b/extra/mariabackup/ddl_log.h new file mode 100644 index 00000000000..5cac3e5dcfc --- /dev/null +++ b/extra/mariabackup/ddl_log.h @@ -0,0 +1,15 @@ +#pragma once +#include "my_global.h" +#include "datasink.h" +#include "aria_backup_client.h" +#include +#include +#include +#include + +namespace ddl_log { + +typedef std::unordered_map tables_t; +bool backup(const char *datadir_path, ds_ctxt_t *ds, const tables_t &tables); + +} // namespace ddl_log diff --git a/extra/mariabackup/ds_buffer.cc b/extra/mariabackup/ds_buffer.cc index d6a420951cb..bc1d466350a 100644 --- a/extra/mariabackup/ds_buffer.cc +++ b/extra/mariabackup/ds_buffer.cc @@ -44,7 +44,7 @@ typedef struct { static ds_ctxt_t *buffer_init(const char *root); static ds_file_t *buffer_open(ds_ctxt_t *ctxt, const char *path, - MY_STAT *mystat); + const MY_STAT *mystat, bool rewrite); static int buffer_write(ds_file_t *file, const uchar *buf, size_t len); static int buffer_close(ds_file_t *file); static void buffer_deinit(ds_ctxt_t *ctxt); @@ -53,8 +53,11 @@ datasink_t datasink_buffer = { &buffer_init, &buffer_open, &buffer_write, + nullptr, &buffer_close, &dummy_remove, + nullptr, + nullptr, &buffer_deinit }; @@ -84,8 +87,10 @@ buffer_init(const char *root) } static ds_file_t * -buffer_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *mystat) +buffer_open(ds_ctxt_t *ctxt, const char *path, + const MY_STAT *mystat, bool rewrite) { + DBUG_ASSERT(rewrite == false); ds_buffer_ctxt_t *buffer_ctxt; ds_ctxt_t *pipe_ctxt; ds_file_t *dst_file; diff --git a/extra/mariabackup/ds_compress.cc b/extra/mariabackup/ds_compress.cc index f7a9b7a1fbd..0cb52e978db 100644 --- a/extra/mariabackup/ds_compress.cc +++ b/extra/mariabackup/ds_compress.cc @@ -65,7 +65,7 @@ extern ulonglong xtrabackup_compress_chunk_size; static ds_ctxt_t *compress_init(const char *root); static ds_file_t *compress_open(ds_ctxt_t *ctxt, const char *path, - MY_STAT *mystat); + const MY_STAT *mystat, bool rewrite); static int compress_write(ds_file_t *file, const uchar *buf, size_t len); static int compress_close(ds_file_t *file); static void compress_deinit(ds_ctxt_t *ctxt); @@ -74,8 +74,11 @@ datasink_t datasink_compress = { &compress_init, &compress_open, &compress_write, + nullptr, &compress_close, &dummy_remove, + nullptr, + nullptr, &compress_deinit }; @@ -116,8 +119,10 @@ compress_init(const char *root) static ds_file_t * -compress_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *mystat) +compress_open(ds_ctxt_t *ctxt, const char *path, + const MY_STAT *mystat, bool rewrite) { + DBUG_ASSERT(rewrite == false); ds_compress_ctxt_t *comp_ctxt; ds_ctxt_t *dest_ctxt; ds_file_t *dest_file; diff --git a/extra/mariabackup/ds_local.cc b/extra/mariabackup/ds_local.cc index f86612b951a..ff2021fc035 100644 --- a/extra/mariabackup/ds_local.cc +++ b/extra/mariabackup/ds_local.cc @@ -42,8 +42,9 @@ typedef struct { static ds_ctxt_t *local_init(const char *root); static ds_file_t *local_open(ds_ctxt_t *ctxt, const char *path, - MY_STAT *mystat); + const MY_STAT *mystat, bool rewrite); static int local_write(ds_file_t *file, const uchar *buf, size_t len); +static int local_seek_set(ds_file_t *file, my_off_t offset); static int local_close(ds_file_t *file); static void local_deinit(ds_ctxt_t *ctxt); @@ -52,13 +53,20 @@ static int local_remove(const char *path) return unlink(path); } +static int local_rename( + ds_ctxt_t *ctxt, const char *old_path, const char *new_path); +static int local_mremove(ds_ctxt_t *ctxt, const char *path); + extern "C" { datasink_t datasink_local = { &local_init, &local_open, &local_write, + &local_seek_set, &local_close, &local_remove, + &local_rename, + &local_mremove, &local_deinit }; } @@ -89,7 +97,7 @@ local_init(const char *root) static ds_file_t * local_open(ds_ctxt_t *ctxt, const char *path, - MY_STAT *mystat __attribute__((unused))) + const MY_STAT *mystat __attribute__((unused)), bool rewrite) { char fullpath[FN_REFLEN]; char dirpath[FN_REFLEN]; @@ -111,8 +119,10 @@ local_open(ds_ctxt_t *ctxt, const char *path, return NULL; } - fd = my_create(fullpath, 0, O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW, - MYF(MY_WME)); + // TODO: check in Windows and set the corresponding flags on fail + fd = my_create(fullpath, 0, + O_WRONLY | O_BINARY | (rewrite ? O_TRUNC : O_EXCL) | O_NOFOLLOW, + MYF(MY_WME)); if (fd < 0) { return NULL; } @@ -194,8 +204,8 @@ static void init_ibd_data(ds_local_file_t *local_file, const uchar *buf, size_t return; } - auto flags = mach_read_from_4(&buf[FIL_PAGE_DATA + FSP_SPACE_FLAGS]); - auto ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags); + uint32_t flags = mach_read_from_4(&buf[FIL_PAGE_DATA + FSP_SPACE_FLAGS]); + uint32_t ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags); local_file->pagesize= ssize == 0 ? UNIV_PAGE_SIZE_ORIG : ((UNIV_ZIP_SIZE_MIN >> 1) << ssize); local_file->compressed = fil_space_t::full_crc32(flags) ? fil_space_t::is_compressed(flags) @@ -239,6 +249,15 @@ local_write(ds_file_t *file, const uchar *buf, size_t len) return 1; } +static +int +local_seek_set(ds_file_t *file, my_off_t offset) { + ds_local_file_t *local_file= (ds_local_file_t *)file->ptr; + if (my_seek(local_file->fd, offset, SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR) + return 1; + return 0; +} + /* Set EOF at file's current position.*/ static int set_eof(File fd) { @@ -276,3 +295,77 @@ local_deinit(ds_ctxt_t *ctxt) my_free(ctxt->root); my_free(ctxt); } + + +static int local_rename( + ds_ctxt_t *ctxt, const char *old_path, const char *new_path) { + char full_old_path[FN_REFLEN]; + char full_new_path[FN_REFLEN]; + fn_format(full_old_path, old_path, ctxt->root, "", MYF(MY_RELATIVE_PATH)); + fn_format(full_new_path, new_path, ctxt->root, "", MYF(MY_RELATIVE_PATH)); + // Ignore errors as .frm files can me copied separately. + // TODO: return error processing here after the corresponding changes in + // xtrabackup.cc + (void)my_rename(full_old_path, full_new_path, MYF(0)); +// if (my_rename(full_old_path, full_new_path, MYF(0))) { +// msg("Failed to rename file %s to %s", old_path, new_path); +// return 1; +// } + return 0; +} + +// It's ok if destination does not contain the file or folder +static int local_mremove(ds_ctxt_t *ctxt, const char *path) { + char full_path[FN_REFLEN]; + fn_format(full_path, path, ctxt->root, "", MYF(MY_RELATIVE_PATH)); + size_t full_path_len = strlen(full_path); + if (full_path[full_path_len - 1] == '*') { + full_path[full_path_len - 1] = '\0'; + char *preffix = strrchr(full_path, '/'); + const char *full_path_dir = full_path; + size_t preffix_len; + if (preffix) { + preffix_len = (full_path_len - 1) - (preffix - full_path); + *(preffix++) = '\0'; + } + else { + preffix = full_path; + preffix_len = full_path_len - 1; + full_path_dir= IF_WIN(".\\", "./"); + } + if (!preffix_len) + return 0; + MY_DIR *dir= my_dir(full_path_dir, 0); + if (!dir) + return 0; + for (size_t i = 0; i < dir->number_of_files; ++i) { + char full_fpath[FN_REFLEN]; + if (strncmp(dir->dir_entry[i].name, preffix, preffix_len)) + continue; + fn_format(full_fpath, dir->dir_entry[i].name, + full_path_dir, "", MYF(MY_RELATIVE_PATH)); + (void)my_delete(full_fpath, MYF(0)); + } + my_dirend(dir); + } + else { + MY_STAT stat; + if (!my_stat(full_path, &stat, MYF(0))) + return 0; + MY_DIR *dir= my_dir(full_path, 0); + if (!dir) { + // TODO: check for error here if necessary + (void)my_delete(full_path, MYF(0)); + return 0; + } + for (size_t i = 0; i < dir->number_of_files; ++i) { + char full_fpath[FN_REFLEN]; + fn_format(full_fpath, dir->dir_entry[i].name, + full_path, "", MYF(MY_RELATIVE_PATH)); + (void)my_delete(full_fpath, MYF(0)); + } + my_dirend(dir); + (void)my_rmtree(full_path, MYF(0)); + } + return 0; +} diff --git a/extra/mariabackup/ds_stdout.cc b/extra/mariabackup/ds_stdout.cc index a9639ff7739..3fc0873b6ca 100644 --- a/extra/mariabackup/ds_stdout.cc +++ b/extra/mariabackup/ds_stdout.cc @@ -30,7 +30,7 @@ typedef struct { static ds_ctxt_t *stdout_init(const char *root); static ds_file_t *stdout_open(ds_ctxt_t *ctxt, const char *path, - MY_STAT *mystat); + const MY_STAT *mystat, bool rewrite); static int stdout_write(ds_file_t *file, const uchar *buf, size_t len); static int stdout_close(ds_file_t *file); static void stdout_deinit(ds_ctxt_t *ctxt); @@ -39,8 +39,11 @@ datasink_t datasink_stdout = { &stdout_init, &stdout_open, &stdout_write, + nullptr, &stdout_close, &dummy_remove, + nullptr, + nullptr, &stdout_deinit }; @@ -61,8 +64,9 @@ static ds_file_t * stdout_open(ds_ctxt_t *ctxt __attribute__((unused)), const char *path __attribute__((unused)), - MY_STAT *mystat __attribute__((unused))) + const MY_STAT *mystat __attribute__((unused)), bool rewrite) { + DBUG_ASSERT(rewrite == false); ds_stdout_file_t *stdout_file; ds_file_t *file; size_t pathlen; diff --git a/extra/mariabackup/ds_tmpfile.cc b/extra/mariabackup/ds_tmpfile.cc index 80b9d3bb4d0..6bafee25971 100644 --- a/extra/mariabackup/ds_tmpfile.cc +++ b/extra/mariabackup/ds_tmpfile.cc @@ -41,7 +41,7 @@ typedef struct { static ds_ctxt_t *tmpfile_init(const char *root); static ds_file_t *tmpfile_open(ds_ctxt_t *ctxt, const char *path, - MY_STAT *mystat); + const MY_STAT *mystat, bool rewrite); static int tmpfile_write(ds_file_t *file, const uchar *buf, size_t len); static int tmpfile_close(ds_file_t *file); static void tmpfile_deinit(ds_ctxt_t *ctxt); @@ -50,8 +50,11 @@ datasink_t datasink_tmpfile = { &tmpfile_init, &tmpfile_open, &tmpfile_write, + nullptr, &tmpfile_close, &dummy_remove, + nullptr, + nullptr, &tmpfile_deinit }; @@ -80,8 +83,9 @@ tmpfile_init(const char *root) static ds_file_t * tmpfile_open(ds_ctxt_t *ctxt, const char *path, - MY_STAT *mystat) + const MY_STAT *mystat, bool rewrite) { + DBUG_ASSERT(rewrite == false); ds_tmpfile_ctxt_t *tmpfile_ctxt; char tmp_path[FN_REFLEN]; ds_tmp_file_t *tmp_file; diff --git a/extra/mariabackup/ds_xbstream.cc b/extra/mariabackup/ds_xbstream.cc index 3bf8bd086c2..96e0cf7aea3 100644 --- a/extra/mariabackup/ds_xbstream.cc +++ b/extra/mariabackup/ds_xbstream.cc @@ -40,24 +40,31 @@ General streaming interface */ static ds_ctxt_t *xbstream_init(const char *root); static ds_file_t *xbstream_open(ds_ctxt_t *ctxt, const char *path, - MY_STAT *mystat); + const MY_STAT *mystat, bool rewrite); static int xbstream_write(ds_file_t *file, const uchar *buf, size_t len); +static int xbstream_seek_set(ds_file_t *file, my_off_t offset); static int xbstream_close(ds_file_t *file); static void xbstream_deinit(ds_ctxt_t *ctxt); +static int xbstream_rename( + ds_ctxt_t *ctxt, const char *old_path, const char *new_path); +static int xbstream_mremove(ds_ctxt_t *ctxt, const char *path); + datasink_t datasink_xbstream = { &xbstream_init, &xbstream_open, &xbstream_write, + &xbstream_seek_set, &xbstream_close, &dummy_remove, + &xbstream_rename, + &xbstream_mremove, &xbstream_deinit }; static ssize_t -my_xbstream_write_callback(xb_wstream_file_t *f __attribute__((unused)), - void *userdata, const void *buf, size_t len) +my_xbstream_write_callback(void *userdata, const void *buf, size_t len) { ds_stream_ctxt_t *stream_ctxt; @@ -89,7 +96,7 @@ xbstream_init(const char *root __attribute__((unused))) goto err; } - xbstream = xb_stream_write_new(); + xbstream = xb_stream_write_new(my_xbstream_write_callback, stream_ctxt); if (xbstream == NULL) { msg("xb_stream_write_new() failed."); goto err; @@ -108,7 +115,8 @@ err: static ds_file_t * -xbstream_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *mystat) +xbstream_open(ds_ctxt_t *ctxt, const char *path, + const MY_STAT *mystat, bool rewrite) { ds_file_t *file; ds_stream_file_t *stream_file; @@ -144,9 +152,7 @@ xbstream_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *mystat) xbstream = stream_ctxt->xbstream; - xbstream_file = xb_stream_write_open(xbstream, path, mystat, - stream_ctxt, - my_xbstream_write_callback); + xbstream_file = xb_stream_write_open(xbstream, path, mystat, rewrite); if (xbstream_file == NULL) { msg("xb_stream_write_open() failed."); @@ -190,6 +196,45 @@ xbstream_write(ds_file_t *file, const uchar *buf, size_t len) return 0; } +static +int +xbstream_seek_set(ds_file_t *file, my_off_t offset) +{ + ds_stream_file_t *stream_file; + xb_wstream_file_t *xbstream_file; + + + stream_file = (ds_stream_file_t *) file->ptr; + + xbstream_file = stream_file->xbstream_file; + + if (xb_stream_write_seek_set(xbstream_file, offset)) { + msg("xb_stream_write_seek_set() failed."); + return 1; + } + + return 0; +} + +static +int +xbstream_mremove(ds_ctxt_t *ctxt, const char *path) { + ds_stream_ctxt_t *stream_ctxt = + reinterpret_cast(ctxt->ptr); + xb_wstream_t *xbstream = stream_ctxt->xbstream; + return xb_stream_write_remove(xbstream, path); +} + +static +int +xbstream_rename( + ds_ctxt_t *ctxt, const char *old_path, const char *new_path) { + ds_stream_ctxt_t *stream_ctxt = + reinterpret_cast(ctxt->ptr); + xb_wstream_t *xbstream = stream_ctxt->xbstream; + return xb_stream_write_rename(xbstream, old_path, new_path); +} + static int xbstream_close(ds_file_t *file) diff --git a/extra/mariabackup/xb_plugin.cc b/extra/mariabackup/encryption_plugin.cc similarity index 75% rename from extra/mariabackup/xb_plugin.cc rename to extra/mariabackup/encryption_plugin.cc index 7470d376eaa..ab0c51400dd 100644 --- a/extra/mariabackup/xb_plugin.cc +++ b/extra/mariabackup/encryption_plugin.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, 2022, MariaDB Corporation. +/* Copyright (c) 2017, MariaDB Corporation. 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 @@ -17,18 +17,18 @@ #include #include #include -#include +#include #include #include #include #include #include -#include +#include extern struct st_maria_plugin *mysql_optional_plugins[]; extern struct st_maria_plugin *mysql_mandatory_plugins[]; -static void xb_plugin_init(int argc, char **argv); +static void encryption_plugin_init(int argc, char **argv); extern char *xb_plugin_load; extern char *xb_plugin_dir; @@ -42,7 +42,7 @@ const char *QUERY_PLUGIN = " OR (plugin_type = 'DAEMON' AND plugin_name LIKE 'provider\\_%')" " AND plugin_status='ACTIVE'"; -std::string xb_plugin_config; +std::string encryption_plugin_config; static void add_to_plugin_load_list(const char *plugin_def) { @@ -52,16 +52,16 @@ static void add_to_plugin_load_list(const char *plugin_def) static char XTRABACKUP_EXE[] = "xtrabackup"; /* - Read "plugin-load" value from backup-my.cnf during prepare phase. + Read "plugin-load" value (encryption plugin) from backup-my.cnf during + prepare phase. The value is stored during backup phase. */ -static std::string get_plugin_from_cnf(const char *dir) +static std::string get_encryption_plugin_from_cnf() { - std::string path = dir + std::string("/backup-my.cnf"); - FILE *f = fopen(path.c_str(), "r"); + FILE *f = fopen("backup-my.cnf", "r"); if (!f) { - die("Can't open %s for reading", path.c_str()); + die("Can't open backup-my.cnf for reading"); } char line[512]; std::string plugin_load; @@ -72,7 +72,16 @@ static std::string get_plugin_from_cnf(const char *dir) plugin_load = line + 12; // remote \n at the end of string plugin_load.resize(plugin_load.size() - 1); - break; + } + + if (strncmp(line, "innodb_encrypt_tables=", 22) == 0) + { + if (!strncmp(line + 22, "ON", 2) || + !strncmp(line + 22, "1", 1)) + srv_encrypt_tables= 1; + else if (!strncmp(line + 22, "FORCE", 5) || + !strncmp(line + 22, "2", 1)) + srv_encrypt_tables= 2; } } fclose(f); @@ -80,7 +89,7 @@ static std::string get_plugin_from_cnf(const char *dir) } -void xb_plugin_backup_init(MYSQL *mysql) +void encryption_plugin_backup_init(MYSQL *mysql) { MYSQL_RES *result; MYSQL_ROW row; @@ -163,7 +172,18 @@ void xb_plugin_backup_init(MYSQL *mysql) mysql_free_result(result); } - xb_plugin_config = oss.str(); + result = xb_mysql_query(mysql, "select @@innodb_encrypt_tables", true, true); + row = mysql_fetch_row(result); + if (!row); + else if (const char *r= row[0]) + { + if (!strcmp(r, "ON")) srv_encrypt_tables= 1; + else if (!strcmp(r, "FORCE")) srv_encrypt_tables= 2; + oss << "innodb_encrypt_tables=" << r << std::endl; + } + + mysql_free_result(result); + encryption_plugin_config = oss.str(); argc = 0; argv[argc++] = XTRABACKUP_EXE; @@ -175,23 +195,23 @@ void xb_plugin_backup_init(MYSQL *mysql) } argv[argc] = 0; - xb_plugin_init(argc, argv); + encryption_plugin_init(argc, argv); } -const char *xb_plugin_get_config() +const char *encryption_plugin_get_config() { - return xb_plugin_config.c_str(); + return encryption_plugin_config.c_str(); } extern int finalize_encryption_plugin(st_plugin_int *plugin); -void xb_plugin_prepare_init(int argc, char **argv, const char *dir) +void encryption_plugin_prepare_init(int argc, char **argv) { - std::string plugin_load= get_plugin_from_cnf(dir ? dir : "."); + std::string plugin_load= get_encryption_plugin_from_cnf(); if (plugin_load.size()) { - msg("Loading plugins from %s", plugin_load.c_str()); + msg("Loading encryption plugin from %s", plugin_load.c_str()); } else { @@ -211,19 +231,19 @@ void xb_plugin_prepare_init(int argc, char **argv, const char *dir) new_argv[0] = XTRABACKUP_EXE; memcpy(&new_argv[1], argv, argc*sizeof(char *)); - xb_plugin_init(argc+1, new_argv); + encryption_plugin_init(argc+1, new_argv); delete[] new_argv; } -static void xb_plugin_init(int argc, char **argv) +static void encryption_plugin_init(int argc, char **argv) { /* Patch optional and mandatory plugins, we only need to load the one in xb_plugin_load. */ mysql_optional_plugins[0] = mysql_mandatory_plugins[0] = 0; plugin_maturity = MariaDB_PLUGIN_MATURITY_UNKNOWN; /* mariabackup accepts all plugins */ - msg("Loading plugins"); + msg("Loading encryption plugin"); for (int i= 1; i < argc; i++) - msg("\t Plugin parameter : '%s'", argv[i]); + msg("\t Encryption plugin parameter : '%s'", argv[i]); plugin_init(&argc, argv, PLUGIN_INIT_SKIP_PLUGIN_TABLE); } diff --git a/extra/mariabackup/encryption_plugin.h b/extra/mariabackup/encryption_plugin.h new file mode 100644 index 00000000000..16d74790254 --- /dev/null +++ b/extra/mariabackup/encryption_plugin.h @@ -0,0 +1,7 @@ +#include +#include +extern void encryption_plugin_backup_init(MYSQL *mysql); +extern const char* encryption_plugin_get_config(); +extern void encryption_plugin_prepare_init(int argc, char **argv); + +//extern void encryption_plugin_init(int argc, char **argv); diff --git a/extra/mariabackup/fil_cur.cc b/extra/mariabackup/fil_cur.cc index 2932fa6d5a6..be871e4a65f 100644 --- a/extra/mariabackup/fil_cur.cc +++ b/extra/mariabackup/fil_cur.cc @@ -231,12 +231,14 @@ xb_fil_cur_open( / cursor->page_size); cursor->read_filter = read_filter; - cursor->read_filter->init(&cursor->read_filter_ctxt, cursor, - node->space->id); + cursor->read_filter->init(&cursor->read_filter_ctxt, cursor); return(XB_FIL_CUR_SUCCESS); } +/* Stack usage 131224 with clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + static bool page_is_corrupted(const byte *page, ulint page_no, const xb_fil_cur_t *cursor, const fil_space_t *space) @@ -340,6 +342,7 @@ static bool page_is_corrupted(const byte *page, ulint page_no, return buf_page_is_corrupted(true, page, space->flags); } +PRAGMA_REENABLE_CHECK_STACK_FRAME /** Reads and verifies the next block of pages from the source file. Positions the cursor after the last read non-corrupted page. @@ -502,10 +505,6 @@ xb_fil_cur_close( /*=============*/ xb_fil_cur_t *cursor) /*!< in/out: source file cursor */ { - if (cursor->read_filter) { - cursor->read_filter->deinit(&cursor->read_filter_ctxt); - } - aligned_free(cursor->buf); cursor->buf = NULL; diff --git a/extra/mariabackup/fil_cur.h b/extra/mariabackup/fil_cur.h index b7812f6589e..46c8cb03705 100644 --- a/extra/mariabackup/fil_cur.h +++ b/extra/mariabackup/fil_cur.h @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA #include #include "read_filt.h" +#include "mtr0types.h" #include "srv0start.h" #include "srv0srv.h" #include "xtrabackup.h" diff --git a/extra/mariabackup/innobackupex.cc b/extra/mariabackup/innobackupex.cc index 6c9a837b761..60c38546c09 100644 --- a/extra/mariabackup/innobackupex.cc +++ b/extra/mariabackup/innobackupex.cc @@ -78,10 +78,8 @@ my_bool opt_ibx_galera_info = FALSE; my_bool opt_ibx_slave_info = FALSE; my_bool opt_ibx_no_lock = FALSE; my_bool opt_ibx_safe_slave_backup = FALSE; -my_bool opt_ibx_rsync = FALSE; my_bool opt_ibx_force_non_empty_dirs = FALSE; my_bool opt_ibx_noversioncheck = FALSE; -my_bool opt_ibx_no_backup_locks = FALSE; my_bool opt_ibx_decompress = FALSE; char *opt_ibx_incremental_history_name = NULL; @@ -268,8 +266,10 @@ static struct my_option ibx_long_options[] = (uchar *) &opt_ibx_incremental, (uchar *) &opt_ibx_incremental, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"no-lock", OPT_NO_LOCK, "Use this option to disable table lock " - "with \"FLUSH TABLES WITH READ LOCK\". Use it only if ALL your " + {"no-lock", OPT_NO_LOCK, "This option should not be used as " + "mariadb-backup now is using BACKUP LOCKS, which minimizes the " + "lock time. ALTER TABLE can run in parallel with BACKUP LOCKS." + "Use the --no-lock option it only if ALL your " "tables are InnoDB and you DO NOT CARE about the binary log " "position of the backup. This option shouldn't be used if there " "are any DDL statements being executed or if any updates are " @@ -297,15 +297,6 @@ static struct my_option ibx_long_options[] = (uchar *) &opt_ibx_safe_slave_backup, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"rsync", OPT_RSYNC, "Uses the rsync utility to optimize local file " - "transfers. When this option is specified, innobackupex uses rsync " - "to copy all non-InnoDB files instead of spawning a separate cp for " - "each file, which can be much faster for servers with a large number " - "of databases or tables. This option cannot be used together with " - "--stream.", - (uchar *) &opt_ibx_rsync, (uchar *) &opt_ibx_rsync, - 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"force-non-empty-directories", OPT_FORCE_NON_EMPTY_DIRS, "This " "option, when specified, makes --copy-back or --move-back transfer " "files to non-empty directories. Note that no existing files will be " @@ -330,13 +321,9 @@ static struct my_option ibx_long_options[] = (uchar *) &opt_ibx_noversioncheck, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"no-backup-locks", OPT_NO_BACKUP_LOCKS, "This option controls if " - "backup locks should be used instead of FLUSH TABLES WITH READ LOCK " - "on the backup stage. The option has no effect when backup locks are " - "not supported by the server. This option is enabled by default, " - "disable with --no-backup-locks.", - (uchar *) &opt_ibx_no_backup_locks, - (uchar *) &opt_ibx_no_backup_locks, + {"no-backup-locks", OPT_NO_BACKUP_LOCKS, + "Old disabled option which has no effect anymore.", + (uchar *) 0, (uchar*) 0, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"decompress", OPT_DECOMPRESS, "Decompresses all files with the .qp " @@ -402,11 +389,10 @@ static struct my_option ibx_long_options[] = REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"ftwrl-wait-query-type", OPT_LOCK_WAIT_QUERY_TYPE, - "This option specifies which types of queries are allowed to complete " - "before innobackupex will issue the global lock. Default is all.", - (uchar*) &opt_ibx_lock_wait_query_type, - (uchar*) &opt_ibx_lock_wait_query_type, &query_type_typelib, - GET_ENUM, REQUIRED_ARG, QUERY_TYPE_ALL, 0, 0, 0, 0, 0}, + "Old disabled option which has no effect anymore (not needed " + "with BACKUP LOCKS)", + (uchar*) 0, (uchar*) 0, &query_type_typelib, GET_ENUM, + REQUIRED_ARG, QUERY_TYPE_ALL, 0, 0, 0, 0, 0}, {"kill-long-query-type", OPT_KILL_LONG_QUERY_TYPE, "This option specifies which types of queries should be killed to " @@ -447,32 +433,32 @@ static struct my_option ibx_long_options[] = REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"kill-long-queries-timeout", OPT_KILL_LONG_QUERIES_TIMEOUT, - "This option specifies the number of seconds innobackupex waits " - "between starting FLUSH TABLES WITH READ LOCK and killing those " - "queries that block it. Default is 0 seconds, which means " - "innobackupex will not attempt to kill any queries.", - (uchar*) &opt_ibx_kill_long_queries_timeout, - (uchar*) &opt_ibx_kill_long_queries_timeout, 0, GET_UINT, + "Old disabled option which has no effect anymore (not needed " + "with BACKUP LOCKS)", + (uchar*) 0, (uchar*) 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"ftwrl-wait-timeout", OPT_LOCK_WAIT_TIMEOUT, - "This option specifies time in seconds that innobackupex should wait " - "for queries that would block FTWRL before running it. If there are " - "still such queries when the timeout expires, innobackupex terminates " - "with an error. Default is 0, in which case innobackupex does not " - "wait for queries to complete and starts FTWRL immediately.", - (uchar*) &opt_ibx_lock_wait_timeout, - (uchar*) &opt_ibx_lock_wait_timeout, 0, GET_UINT, + "Alias for startup-wait-timeout", + (uchar*) &opt_ibx_lock_wait_timeout, + (uchar*) &opt_ibx_lock_wait_timeout, 0, GET_UINT, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + + {"startup-wait-timeout", OPT_LOCK_WAIT_TIMEOUT, + "This option specifies time in seconds that mariadb-backup should wait for " + "BACKUP STAGE START to complete. BACKUP STAGE START has to wait until all " + "currently running queries using explicite LOCK TABLES has ended. " + "If there are still such queries when the timeout expires, mariadb-backup " + "terminates with an error. Default is 0, in which case mariadb-backup waits " + "indefinitely for BACKUP STAGE START to finish", + (uchar*) &opt_ibx_lock_wait_timeout, + (uchar*) &opt_ibx_lock_wait_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"ftwrl-wait-threshold", OPT_LOCK_WAIT_THRESHOLD, - "This option specifies the query run time threshold which is used by " - "innobackupex to detect long-running queries with a non-zero value " - "of --ftwrl-wait-timeout. FTWRL is not started until such " - "long-running queries exist. This option has no effect if " - "--ftwrl-wait-timeout is 0. Default value is 60 seconds.", - (uchar*) &opt_ibx_lock_wait_threshold, - (uchar*) &opt_ibx_lock_wait_threshold, 0, GET_UINT, + "Old disabled option which has no effect anymore (not needed " + "with BACKUP LOCKS)", + (uchar*) 0, (uchar*) 0, 0, GET_UINT, REQUIRED_ARG, 60, 0, 0, 0, 0, 0}, {"safe-slave-backup-timeout", OPT_SAFE_SLAVE_BACKUP_TIMEOUT, @@ -864,10 +850,8 @@ ibx_init() opt_slave_info = opt_ibx_slave_info; opt_no_lock = opt_ibx_no_lock; opt_safe_slave_backup = opt_ibx_safe_slave_backup; - opt_rsync = opt_ibx_rsync; opt_force_non_empty_dirs = opt_ibx_force_non_empty_dirs; opt_noversioncheck = opt_ibx_noversioncheck; - opt_no_backup_locks = opt_ibx_no_backup_locks; opt_decompress = opt_ibx_decompress; opt_incremental_history_name = opt_ibx_incremental_history_name; diff --git a/extra/mariabackup/read_filt.cc b/extra/mariabackup/read_filt.cc index 589200552a2..c7c0aa555a4 100644 --- a/extra/mariabackup/read_filt.cc +++ b/extra/mariabackup/read_filt.cc @@ -32,29 +32,13 @@ Perform read filter context initialization that is common to all read filters. */ static void -common_init( -/*========*/ +rf_pass_through_init( xb_read_filt_ctxt_t* ctxt, /*!offset = 0; ctxt->data_file_size = cursor->statinfo.st_size; ctxt->buffer_capacity = cursor->buf_size; - ctxt->page_size = cursor->page_size; -} - -/****************************************************************//** -Initialize the pass-through read filter. */ -static -void -rf_pass_through_init( -/*=================*/ - xb_read_filt_ctxt_t* ctxt, /*!offset; *read_batch_len = ctxt->data_file_size - ctxt->offset; - if (*read_batch_len > (ib_int64_t)ctxt->buffer_capacity) { + if (*read_batch_len > (int64_t)ctxt->buffer_capacity) { *read_batch_len = ctxt->buffer_capacity; } ctxt->offset += *read_batch_len; } -/****************************************************************//** -Deinitialize the pass-through read filter. */ -static -void -rf_pass_through_deinit( -/*===================*/ - xb_read_filt_ctxt_t* ctxt __attribute__((unused))) - /*!bitmap_range = xb_page_bitmap_range_init(changed_page_bitmap, - space_id); - ctxt->filter_batch_end = 0; -} - -/****************************************************************//** -Get the next batch of pages for the bitmap read filter. */ -static -void -rf_bitmap_get_next_batch( -/*=====================*/ - xb_read_filt_ctxt_t* ctxt, /*!page_size; - - start_page_id = (ulint)(ctxt->offset / page_size); - - xb_a (ctxt->offset % page_size == 0); - - if (start_page_id == ctxt->filter_batch_end) { - - /* Used up all the previous bitmap range, get some more */ - ulint next_page_id; - - /* Find the next changed page using the bitmap */ - next_page_id = xb_page_bitmap_range_get_next_bit - (ctxt->bitmap_range, TRUE); - - if (next_page_id == ULINT_UNDEFINED) { - *read_batch_len = 0; - return; - } - - ctxt->offset = next_page_id * page_size; - - /* Find the end of the current changed page block by searching - for the next cleared bitmap bit */ - ctxt->filter_batch_end - = xb_page_bitmap_range_get_next_bit(ctxt->bitmap_range, - FALSE); - xb_a(next_page_id < ctxt->filter_batch_end); - } - - *read_batch_start = ctxt->offset; - if (ctxt->filter_batch_end == ULINT_UNDEFINED) { - /* No more cleared bits in the bitmap, need to copy all the - remaining pages. */ - *read_batch_len = ctxt->data_file_size - ctxt->offset; - } else { - *read_batch_len = ctxt->filter_batch_end * page_size - - ctxt->offset; - } - - /* If the page block is larger than the buffer capacity, limit it to - buffer capacity. The subsequent invocations will continue returning - the current block in buffer-sized pieces until ctxt->filter_batch_end - is reached, trigerring the next bitmap query. */ - if (*read_batch_len > (ib_int64_t)ctxt->buffer_capacity) { - *read_batch_len = ctxt->buffer_capacity; - } - - ctxt->offset += *read_batch_len; - xb_a (ctxt->offset % page_size == 0); - xb_a (*read_batch_start % page_size == 0); - xb_a (*read_batch_len % page_size == 0); -} - -/****************************************************************//** -Deinitialize the changed page bitmap-based read filter. */ -static -void -rf_bitmap_deinit( -/*=============*/ - xb_read_filt_ctxt_t* ctxt) /*!bitmap_range); -} - /* The pass-through read filter */ xb_read_filt_t rf_pass_through = { &rf_pass_through_init, &rf_pass_through_get_next_batch, - &rf_pass_through_deinit -}; - -/* The changed page bitmap-based read filter */ -xb_read_filt_t rf_bitmap = { - &rf_bitmap_init, - &rf_bitmap_get_next_batch, - &rf_bitmap_deinit }; diff --git a/extra/mariabackup/read_filt.h b/extra/mariabackup/read_filt.h index 51150705367..caf8ac566e0 100644 --- a/extra/mariabackup/read_filt.h +++ b/extra/mariabackup/read_filt.h @@ -25,42 +25,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA #ifndef XB_READ_FILT_H #define XB_READ_FILT_H -#include "changed_page_bitmap.h" - -typedef uint32_t space_id_t; +#include +#include struct xb_fil_cur_t; /* The read filter context */ struct xb_read_filt_ctxt_t { - ib_int64_t offset; /*!< current file offset */ - ib_int64_t data_file_size; /*!< data file size */ + int64_t offset; /*!< current file offset */ + int64_t data_file_size; /*!< data file size */ size_t buffer_capacity;/*!< read buffer capacity */ - space_id_t space_id; /*!< space id */ - /* The following fields used only in bitmap filter */ - /* Move these to union if any other filters are added in future */ - xb_page_bitmap_range *bitmap_range; /*!< changed page bitmap range - iterator for space_id */ - ulint page_size; /*!< page size */ - ulint filter_batch_end;/*!< the ending page id of the - current changed page block in - the bitmap */ - /** TODO: remove this default constructor */ - xb_read_filt_ctxt_t() : page_size(0) {} }; /* The read filter */ struct xb_read_filt_t { void (*init)(xb_read_filt_ctxt_t* ctxt, - const xb_fil_cur_t* cursor, - ulint space_id); + const xb_fil_cur_t* cursor); void (*get_next_batch)(xb_read_filt_ctxt_t* ctxt, - ib_int64_t* read_batch_start, - ib_int64_t* read_batch_len); - void (*deinit)(xb_read_filt_ctxt_t* ctxt); + int64_t* read_batch_start, + int64_t* read_batch_len); }; extern xb_read_filt_t rf_pass_through; -extern xb_read_filt_t rf_bitmap; #endif diff --git a/extra/mariabackup/thread_pool.cc b/extra/mariabackup/thread_pool.cc new file mode 100644 index 00000000000..e18581f4b24 --- /dev/null +++ b/extra/mariabackup/thread_pool.cc @@ -0,0 +1,50 @@ +#include "thread_pool.h" +#include "common.h" + +bool ThreadPool::start(size_t threads_count) { + if (!m_stopped) + return false; + m_stopped = false; + for (unsigned i = 0; i < threads_count; ++i) + m_threads.emplace_back(&ThreadPool::thread_func, this, i); + return true; +} + +void ThreadPool::stop() { + if (m_stopped) + return; + m_stop = true; + m_cv.notify_all(); + for (auto &t : m_threads) + t.join(); + m_stopped = true; +}; + +void ThreadPool::push(ThreadPool::job_t &&j) { + std::unique_lock lock(m_mutex); + m_jobs.push(j); + lock.unlock(); + m_cv.notify_one(); +} + +void ThreadPool::thread_func(unsigned thread_num) { + if (my_thread_init()) + die("Can't init mysql thread"); + std::unique_lock lock(m_mutex); + while(true) { + if (m_stop) + goto exit; + while (!m_jobs.empty()) { + if (m_stop) + goto exit; + job_t j = std::move(m_jobs.front()); + m_jobs.pop(); + lock.unlock(); + j(thread_num); + lock.lock(); + } + m_cv.wait(lock, [&] { return m_stop || !m_jobs.empty(); }); + } +exit: + my_thread_end(); +} diff --git a/extra/mariabackup/thread_pool.h b/extra/mariabackup/thread_pool.h new file mode 100644 index 00000000000..10ad74c6220 --- /dev/null +++ b/extra/mariabackup/thread_pool.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include "trx0sys.h" + +class ThreadPool { +public: + typedef std::function job_t; + + ThreadPool() { m_stop = false; m_stopped = true; } + ThreadPool (ThreadPool &&other) = delete; + ThreadPool & operator= (ThreadPool &&other) = delete; + ThreadPool(const ThreadPool &) = delete; + ThreadPool & operator= (const ThreadPool &) = delete; + + bool start(size_t threads_count); + void stop(); + void push(job_t &&j); + size_t threads_count() const { return m_threads.size(); } +private: + void thread_func(unsigned thread_num); + std::mutex m_mutex; + std::condition_variable m_cv; + std::queue m_jobs; + std::atomic m_stop; + std::atomic m_stopped; + std::vector m_threads; +}; + +class TasksGroup { +public: + TasksGroup(ThreadPool &thread_pool) : m_thread_pool(thread_pool) { + m_tasks_count = 0; + m_tasks_result = 1; + } + void push_task(ThreadPool::job_t &&j) { + ++m_tasks_count; + m_thread_pool.push(std::forward(j)); + } + void finish_task(int res) { + --m_tasks_count; + m_tasks_result.fetch_and(res); + } + int get_result() const { return m_tasks_result; } + bool is_finished() const { + return !m_tasks_count; + } + bool wait_for_finish() { + while (!is_finished()) + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + return get_result(); + } +private: + ThreadPool &m_thread_pool; + std::atomic m_tasks_count; + std::atomic m_tasks_result; +}; diff --git a/extra/mariabackup/write_filt.cc b/extra/mariabackup/write_filt.cc index 052cea26ef6..13f19ca6b6a 100644 --- a/extra/mariabackup/write_filt.cc +++ b/extra/mariabackup/write_filt.cc @@ -144,6 +144,18 @@ wf_incremental_process(xb_write_filt_ctxt_t *ctxt, ds_file_t *dstfile) return false; } + /* Check whether TRX_SYS page has been changed */ + if (mach_read_from_4(page + FIL_PAGE_SPACE_ID) + == TRX_SYS_SPACE + && mach_read_from_4(page + FIL_PAGE_OFFSET) + == TRX_SYS_PAGE_NO) { + msg(cursor->thread_n, + "--incremental backup is impossible if " + "the server had been restarted with " + "different innodb_undo_tablespaces."); + return false; + } + /* updated page */ if (cp->npages == page_size / 4) { /* flush buffer */ diff --git a/extra/mariabackup/wsrep.cc b/extra/mariabackup/wsrep.cc index c155f511f79..0a2cb8741d1 100644 --- a/extra/mariabackup/wsrep.cc +++ b/extra/mariabackup/wsrep.cc @@ -52,10 +52,12 @@ permission notice: #include /*! Name of file where Galera info is stored on recovery */ -#define XB_GALERA_INFO_FILENAME "xtrabackup_galera_info" #define MB_GALERA_INFO_FILENAME "mariadb_backup_galera_info" #define XB_GALERA_DONOR_INFO_FILENAME "donor_galera_info" +/* backup copy of galera info file as sent by donor */ +#define MB_GALERA_INFO_FILENAME_SST "mariadb_backup_galera_info_SST" + /*********************************************************************** Store Galera checkpoint info in the MB_GALERA_INFO_FILENAME file, if that information is present in the trx system header. Otherwise, do nothing. */ @@ -69,20 +71,45 @@ xb_write_galera_info(bool incremental_prepare) long long seqno; MY_STAT statinfo; - /* Do not overwrite an existing file to be compatible with - servers with older server versions */ - if (!incremental_prepare && - (my_stat(XB_GALERA_INFO_FILENAME, &statinfo, MYF(0)) != NULL || - my_stat(MB_GALERA_INFO_FILENAME, &statinfo, MYF(0)) != NULL)) { + xid.null(); + /* try to read last wsrep XID from innodb rsegs, we will use it + instead of galera info file received from donor + */ + if (!trx_rseg_read_wsrep_checkpoint(xid)) { + /* no worries yet, SST may have brought in galera info file + from some old MariaDB version, which does not support + wsrep XID storing in innodb rsegs + */ return; } - xid.null(); + /* if SST brought in galera info file, copy it as *_SST file + this will not be used, saved just for future reference + */ + if (my_stat(MB_GALERA_INFO_FILENAME, &statinfo, MYF(0))) { + FILE* fp_in = fopen(MB_GALERA_INFO_FILENAME, "r"); + FILE* fp_out = fopen(MB_GALERA_INFO_FILENAME_SST, "w"); - if (!trx_rseg_read_wsrep_checkpoint(xid)) { - - return; + char buf[BUFSIZ] = {'\0'}; + size_t size; + while ((size = fread(buf, 1, BUFSIZ, fp_in))) { + if (fwrite(buf, 1, size, fp_out) != strlen(buf)) { + die( + "could not write to " + MB_GALERA_INFO_FILENAME_SST + ", errno = %d\n", + errno); + } + } + if (!feof(fp_in)) { + die( + MB_GALERA_INFO_FILENAME_SST + " not fully copied\n" + ); + } + fclose(fp_out); + fclose(fp_in); } wsrep_uuid_t uuid; @@ -99,7 +126,6 @@ xb_write_galera_info(bool incremental_prepare) "could not create " MB_GALERA_INFO_FILENAME ", errno = %d\n", errno); - exit(EXIT_FAILURE); } seqno = wsrep_xid_seqno(&xid); diff --git a/extra/mariabackup/xb_plugin.h b/extra/mariabackup/xb_plugin.h deleted file mode 100644 index fea24b6b052..00000000000 --- a/extra/mariabackup/xb_plugin.h +++ /dev/null @@ -1,5 +0,0 @@ -#include -#include -extern void xb_plugin_backup_init(MYSQL *mysql); -extern const char* xb_plugin_get_config(); -extern void xb_plugin_prepare_init(int argc, char **argv, const char *dir); diff --git a/extra/mariabackup/xbstream.cc b/extra/mariabackup/xbstream.cc index 3a3ba55b8b2..5a54caceb72 100644 --- a/extra/mariabackup/xbstream.cc +++ b/extra/mariabackup/xbstream.cc @@ -255,7 +255,7 @@ mode_create(int argc, char **argv) return 1; } - stream = xb_stream_write_new(); + stream = xb_stream_write_new(nullptr, nullptr); if (stream == NULL) { msg("%s: xb_stream_write_new() failed.", my_progname); return 1; @@ -280,7 +280,7 @@ mode_create(int argc, char **argv) goto err; } - file = xb_stream_write_open(stream, filepath, &mystat, NULL, NULL); + file = xb_stream_write_open(stream, filepath, &mystat, false); if (file == NULL) { goto err; } @@ -307,7 +307,8 @@ err: static file_entry_t * -file_entry_new(extract_ctxt_t *ctxt, const char *path, uint pathlen) +file_entry_new(extract_ctxt_t *ctxt, const char *path, uint pathlen, + uchar chunk_flags) { file_entry_t *entry; ds_file_t *file; @@ -324,7 +325,8 @@ file_entry_new(extract_ctxt_t *ctxt, const char *path, uint pathlen) } entry->pathlen = pathlen; - file = ds_open(ctxt->ds_ctxt, path, NULL); + file = ds_open(ctxt->ds_ctxt, path, NULL, + chunk_flags == XB_STREAM_FLAG_REWRITE); if (file == NULL) { msg("%s: failed to create file.", my_progname); @@ -405,10 +407,50 @@ extract_worker_thread_func(void *arg) (uchar *) chunk.path, chunk.pathlen); + if (entry && (chunk.type == XB_CHUNK_TYPE_REMOVE || + chunk.type == XB_CHUNK_TYPE_RENAME)) { + msg("%s: rename and remove chunks can not be applied to opened file: %s", + my_progname, chunk.path); + pthread_mutex_unlock(ctxt->mutex); + break; + } + + if (chunk.type == XB_CHUNK_TYPE_REMOVE) { + if (ds_remove(ctxt->ds_ctxt, chunk.path)) { + msg("%s: error on file removing: %s", my_progname, chunk.path); + pthread_mutex_unlock(ctxt->mutex); + res = XB_STREAM_READ_ERROR; + break; + } + pthread_mutex_unlock(ctxt->mutex); + continue; + } + + if (chunk.type == XB_CHUNK_TYPE_RENAME) { + if (my_hash_search(ctxt->filehash, + reinterpret_cast(chunk.data), chunk.length)) { + msg("%s: rename chunks can not be applied to opened file: %s", + my_progname, reinterpret_cast(chunk.data)); + pthread_mutex_unlock(ctxt->mutex); + break; + } + if (ds_rename(ctxt->ds_ctxt, chunk.path, + reinterpret_cast(chunk.data))) { + msg("%s: error on file renaming: %s to %s", my_progname, + reinterpret_cast(chunk.data), chunk.path); + pthread_mutex_unlock(ctxt->mutex); + res = XB_STREAM_READ_ERROR; + break; + } + pthread_mutex_unlock(ctxt->mutex); + continue; + } + if (entry == NULL) { entry = file_entry_new(ctxt, chunk.path, - chunk.pathlen); + chunk.pathlen, + chunk.flags); if (entry == NULL) { pthread_mutex_unlock(ctxt->mutex); break; @@ -425,6 +467,18 @@ extract_worker_thread_func(void *arg) pthread_mutex_unlock(ctxt->mutex); + if (chunk.type == XB_CHUNK_TYPE_SEEK) { + if (ds_seek_set(entry->file, chunk.offset)) { + msg("%s: my_seek() failed.", my_progname); + pthread_mutex_unlock(&entry->mutex); + res = XB_STREAM_READ_ERROR; + break; + } + entry->offset = chunk.offset; + pthread_mutex_unlock(&entry->mutex); + continue; + } + res = xb_stream_validate_checksum(&chunk); if (res != XB_STREAM_READ_CHUNK) { diff --git a/extra/mariabackup/xbstream.h b/extra/mariabackup/xbstream.h index 1b36ec249b6..c8b2997d402 100644 --- a/extra/mariabackup/xbstream.h +++ b/extra/mariabackup/xbstream.h @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA /* Chunk flags */ /* Chunk can be ignored if unknown version/format */ #define XB_STREAM_FLAG_IGNORABLE 0x01 +#define XB_STREAM_FLAG_REWRITE 0x02 /* Magic + flags + type + path len */ #define CHUNK_HEADER_CONSTANT_LEN ((sizeof(XB_STREAM_CHUNK_MAGIC) - 1) + \ @@ -48,18 +49,21 @@ typedef enum { /************************************************************************ Write interface. */ -typedef ssize_t xb_stream_write_callback(xb_wstream_file_t *file, +typedef ssize_t xb_stream_write_callback( void *userdata, const void *buf, size_t len); -xb_wstream_t *xb_stream_write_new(void); - +xb_wstream_t *xb_stream_write_new( + xb_stream_write_callback *write_callback, void *user_data); xb_wstream_file_t *xb_stream_write_open(xb_wstream_t *stream, const char *path, - MY_STAT *mystat, void *userdata, - xb_stream_write_callback *onwrite); + const MY_STAT *mystat, bool rewrite); int xb_stream_write_data(xb_wstream_file_t *file, const void *buf, size_t len); - +int xb_stream_write_seek_set(xb_wstream_file_t *file, my_off_t offset); +int xb_stream_write_remove(xb_wstream_t *stream, const char *path); +int +xb_stream_write_rename( + xb_wstream_t *stream, const char *old_path, const char *new_path); int xb_stream_write_close(xb_wstream_file_t *file); int xb_stream_write_done(xb_wstream_t *stream); @@ -76,6 +80,9 @@ typedef enum { typedef enum { XB_CHUNK_TYPE_UNKNOWN = '\0', XB_CHUNK_TYPE_PAYLOAD = 'P', + XB_CHUNK_TYPE_RENAME = 'R', + XB_CHUNK_TYPE_REMOVE = 'D', + XB_CHUNK_TYPE_SEEK = 'S', XB_CHUNK_TYPE_EOF = 'E' } xb_chunk_type_t; diff --git a/extra/mariabackup/xbstream_read.cc b/extra/mariabackup/xbstream_read.cc index b54a98157ea..d82176ad8be 100644 --- a/extra/mariabackup/xbstream_read.cc +++ b/extra/mariabackup/xbstream_read.cc @@ -59,6 +59,9 @@ validate_chunk_type(uchar code) { switch ((xb_chunk_type_t) code) { case XB_CHUNK_TYPE_PAYLOAD: + case XB_CHUNK_TYPE_RENAME: + case XB_CHUNK_TYPE_REMOVE: + case XB_CHUNK_TYPE_SEEK: case XB_CHUNK_TYPE_EOF: return (xb_chunk_type_t) code; default: @@ -159,57 +162,91 @@ xb_stream_read_chunk(xb_rstream_t *stream, xb_rstream_chunk_t *chunk) } chunk->path[pathlen] = '\0'; - if (chunk->type == XB_CHUNK_TYPE_EOF) { + if (chunk->type == XB_CHUNK_TYPE_EOF || + chunk->type == XB_CHUNK_TYPE_REMOVE) { return XB_STREAM_READ_CHUNK; } - /* Payload length */ - F_READ(tmpbuf, 16); - ullval = uint8korr(tmpbuf); - if (ullval > (ulonglong) SIZE_T_MAX) { - msg("xb_stream_read_chunk(): chunk length is too large at " - "offset 0x%llx: 0x%llx.", (ulonglong) stream->offset, - ullval); - goto err; - } - chunk->length = (size_t) ullval; - stream->offset += 8; - - /* Payload offset */ - ullval = uint8korr(tmpbuf + 8); - if (ullval > (ulonglong) MY_OFF_T_MAX) { - msg("xb_stream_read_chunk(): chunk offset is too large at " - "offset 0x%llx: 0x%llx.", (ulonglong) stream->offset, - ullval); - goto err; - } - chunk->offset = (my_off_t) ullval; - stream->offset += 8; - - /* Reallocate the buffer if needed */ - if (chunk->length > chunk->buflen) { - chunk->data = my_realloc(PSI_NOT_INSTRUMENTED, chunk->data, chunk->length, - MYF(MY_WME | MY_ALLOW_ZERO_PTR)); - if (chunk->data == NULL) { - msg("xb_stream_read_chunk(): failed to increase buffer " - "to %lu bytes.", (ulong) chunk->length); + if (chunk->type == XB_CHUNK_TYPE_RENAME) { + F_READ(tmpbuf, 4); + size_t new_pathlen = uint4korr(tmpbuf); + if (new_pathlen >= FN_REFLEN) { + msg("xb_stream_read_chunk(): path length (%lu) for new name of 'rename'" + " chunk is too large", (ulong) new_pathlen); goto err; } - chunk->buflen = chunk->length; + chunk->length = new_pathlen; + stream->offset +=4; + } + else if (chunk->type == XB_CHUNK_TYPE_SEEK) { + F_READ(tmpbuf, 8); + chunk->offset = uint8korr(tmpbuf); + stream->offset += 8; + return XB_STREAM_READ_CHUNK; + } + else { + /* Payload length */ + F_READ(tmpbuf, 16); + ullval = uint8korr(tmpbuf); + if (ullval > (ulonglong) SIZE_T_MAX) { + msg("xb_stream_read_chunk(): chunk length is too large at " + "offset 0x%llx: 0x%llx.", (ulonglong) stream->offset, + ullval); + goto err; + } + chunk->length = (size_t) ullval; + stream->offset += 8; + + /* Payload offset */ + ullval = uint8korr(tmpbuf + 8); + if (ullval > (ulonglong) MY_OFF_T_MAX) { + msg("xb_stream_read_chunk(): chunk offset is too large at " + "offset 0x%llx: 0x%llx.", (ulonglong) stream->offset, + ullval); + goto err; + } + chunk->offset = (my_off_t) ullval; + stream->offset += 8; } - /* Checksum */ - F_READ(tmpbuf, 4); - chunk->checksum = uint4korr(tmpbuf); - chunk->checksum_offset = stream->offset; + /* Reallocate the buffer if needed, take into account trailing '\0' for + new file name in the case of XB_CHUNK_TYPE_RENAME */ + if (chunk->length + 1 > chunk->buflen) { + chunk->data = my_realloc(PSI_NOT_INSTRUMENTED, chunk->data, + chunk->length + 1, MYF(MY_WME | MY_ALLOW_ZERO_PTR)); + if (chunk->data == NULL) { + msg("xb_stream_read_chunk(): failed to increase buffer " + "to %lu bytes.", (ulong) chunk->length + 1); + goto err; + } + chunk->buflen = chunk->length + 1; + } - /* Payload */ - if (chunk->length > 0) { + if (chunk->type == XB_CHUNK_TYPE_RENAME) { + if (chunk->length == 0) { + msg("xb_stream_read_chunk(): failed to read new name for file to rename " + ": %s", chunk->path); + goto err; + } F_READ(chunk->data, chunk->length); stream->offset += chunk->length; + reinterpret_cast(chunk->data)[chunk->length] = '\0'; + ++chunk->length; } + else { + /* Checksum */ + F_READ(tmpbuf, 4); + chunk->checksum = uint4korr(tmpbuf); + chunk->checksum_offset = stream->offset; - stream->offset += 4; + /* Payload */ + if (chunk->length > 0) { + F_READ(chunk->data, chunk->length); + stream->offset += chunk->length; + } + + stream->offset += 4; + } return XB_STREAM_READ_CHUNK; diff --git a/extra/mariabackup/xbstream_write.cc b/extra/mariabackup/xbstream_write.cc index 5801e867aac..926e091becb 100644 --- a/extra/mariabackup/xbstream_write.cc +++ b/extra/mariabackup/xbstream_write.cc @@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA #include #include #include +#include #include "common.h" #include "xbstream.h" @@ -29,6 +30,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA struct xb_wstream_struct { pthread_mutex_t mutex; + xb_stream_write_callback *write; + void *user_data; }; struct xb_wstream_file_struct { @@ -39,8 +42,7 @@ struct xb_wstream_file_struct { char *chunk_ptr; size_t chunk_free; my_off_t offset; - void *userdata; - xb_stream_write_callback *write; + bool rewrite; }; static int xb_stream_flush(xb_wstream_file_t *file); @@ -50,7 +52,7 @@ static int xb_stream_write_eof(xb_wstream_file_t *file); static ssize_t -xb_stream_default_write_callback(xb_wstream_file_t *file __attribute__((unused)), +xb_stream_default_write_callback( void *userdata __attribute__((unused)), const void *buf, size_t len) { @@ -60,21 +62,31 @@ xb_stream_default_write_callback(xb_wstream_file_t *file __attribute__((unused)) } xb_wstream_t * -xb_stream_write_new(void) +xb_stream_write_new( + xb_stream_write_callback *write_callback, void *user_data) { xb_wstream_t *stream; stream = (xb_wstream_t *) my_malloc(PSI_NOT_INSTRUMENTED, sizeof(xb_wstream_t), MYF(MY_FAE)); pthread_mutex_init(&stream->mutex, NULL); + if (write_callback) { +#ifdef _WIN32 + setmode(fileno(stdout), _O_BINARY); +#endif + stream->write = write_callback; + stream->user_data = user_data; + } + else { + stream->write = xb_stream_default_write_callback; + stream->user_data = user_data; + } return stream;; } xb_wstream_file_t * xb_stream_write_open(xb_wstream_t *stream, const char *path, - MY_STAT *mystat __attribute__((unused)), - void *userdata, - xb_stream_write_callback *onwrite) + const MY_STAT *mystat __attribute__((unused)), bool rewrite) { xb_wstream_file_t *file; size_t path_len; @@ -109,16 +121,7 @@ xb_stream_write_open(xb_wstream_t *stream, const char *path, file->offset = 0; file->chunk_ptr = file->chunk; file->chunk_free = XB_STREAM_MIN_CHUNK_SIZE; - if (onwrite) { -#ifdef _WIN32 - setmode(fileno(stdout), _O_BINARY); -#endif - file->userdata = userdata; - file->write = onwrite; - } else { - file->userdata = NULL; - file->write = xb_stream_default_write_callback; - } + file->rewrite = rewrite; return file; } @@ -202,7 +205,8 @@ xb_stream_write_chunk(xb_wstream_file_t *file, const void *buf, size_t len) memcpy(ptr, XB_STREAM_CHUNK_MAGIC, sizeof(XB_STREAM_CHUNK_MAGIC) - 1); ptr += sizeof(XB_STREAM_CHUNK_MAGIC) - 1; - *ptr++ = 0; /* Chunk flags */ + *ptr++ = + file->rewrite ? XB_STREAM_FLAG_REWRITE : 0; /* Chunk flags */ *ptr++ = (uchar) XB_CHUNK_TYPE_PAYLOAD; /* Chunk type */ @@ -227,11 +231,11 @@ xb_stream_write_chunk(xb_wstream_file_t *file, const void *buf, size_t len) xb_ad(ptr <= tmpbuf + sizeof(tmpbuf)); - if (file->write(file, file->userdata, tmpbuf, ptr-tmpbuf) == -1) + if (stream->write(stream->user_data, tmpbuf, ptr-tmpbuf) == -1) goto err; - if (file->write(file, file->userdata, buf, len) == -1) /* Payload */ + if (stream->write(stream->user_data, buf, len) == -1) /* Payload */ goto err; file->offset+= len; @@ -247,6 +251,38 @@ err: return 1; } +int xb_stream_write_seek_set(xb_wstream_file_t *file, my_off_t offset) +{ + /* Chunk magic + flags + chunk type + path_len + path + offset */ + uchar tmpbuf[sizeof(XB_STREAM_CHUNK_MAGIC) - 1 + 1 + 1 + 4 + + FN_REFLEN + 8]; + int error = 0; + xb_wstream_t *stream = file->stream; + uchar *ptr = tmpbuf; + /* Chunk magic */ + memcpy(ptr, XB_STREAM_CHUNK_MAGIC, sizeof(XB_STREAM_CHUNK_MAGIC) - 1); + ptr += sizeof(XB_STREAM_CHUNK_MAGIC) - 1; + *ptr++ = 0; /* Chunk flags */ + *ptr++ = (uchar) XB_CHUNK_TYPE_SEEK; /* Chunk type */ + int4store(ptr, file->path_len); /* Path length */ + ptr += 4; + memcpy(ptr, file->path, file->path_len); /* Path */ + ptr += file->path_len; + int8store(ptr, static_cast(offset)); /* Offset */ + ptr += 8; + if (xb_stream_flush(file)) + return 1; + pthread_mutex_lock(&stream->mutex); + if (stream->write(stream->user_data, tmpbuf, ptr-tmpbuf) == -1) + error = 1; + if (!error) + file->offset = offset; + pthread_mutex_unlock(&stream->mutex); + if (xb_stream_flush(file)) + return 1; + return error; +} + static int xb_stream_write_eof(xb_wstream_file_t *file) @@ -278,7 +314,7 @@ xb_stream_write_eof(xb_wstream_file_t *file) xb_ad(ptr <= tmpbuf + sizeof(tmpbuf)); - if (file->write(file, file->userdata, tmpbuf, + if (stream->write(stream->user_data, tmpbuf, (ulonglong) (ptr - tmpbuf)) == -1) goto err; @@ -291,3 +327,77 @@ err: return 1; } + + +int +xb_stream_write_remove(xb_wstream_t *stream, const char *path) { + /* Chunk magic + flags + chunk type + path_len + path */ + uchar tmpbuf[sizeof(XB_STREAM_CHUNK_MAGIC) - 1 + 1 + 1 + 4 + FN_REFLEN]; + uchar *ptr = tmpbuf; + /* Chunk magic */ + memcpy(ptr, XB_STREAM_CHUNK_MAGIC, sizeof(XB_STREAM_CHUNK_MAGIC) - 1); + ptr += sizeof(XB_STREAM_CHUNK_MAGIC) - 1; + + *ptr++ = 0; /* Chunk flags */ + + *ptr++ = (uchar) XB_CHUNK_TYPE_REMOVE; /* Chunk type */ + size_t path_len = strlen(path); + int4store(ptr, path_len); /* Path length */ + ptr += 4; + + memcpy(ptr, path, path_len); /* Path */ + ptr += path_len; + + xb_ad(ptr <= tmpbuf + sizeof(tmpbuf)); + + pthread_mutex_lock(&stream->mutex); + + ssize_t result = stream->write(stream->user_data, tmpbuf, + (ulonglong) (ptr - tmpbuf)); + + pthread_mutex_unlock(&stream->mutex); + + return result < 0; + +} + +int +xb_stream_write_rename( + xb_wstream_t *stream, const char *old_path, const char *new_path) { + /* Chunk magic + flags + chunk type + path_len + path + path_len + path*/ + uchar tmpbuf[sizeof(XB_STREAM_CHUNK_MAGIC) - 1 + 1 + 1 + + 4 + FN_REFLEN + 4 + FN_REFLEN]; + uchar *ptr = tmpbuf; + /* Chunk magic */ + memcpy(ptr, XB_STREAM_CHUNK_MAGIC, sizeof(XB_STREAM_CHUNK_MAGIC) - 1); + ptr += sizeof(XB_STREAM_CHUNK_MAGIC) - 1; + + *ptr++ = 0; /* Chunk flags */ + + *ptr++ = (uchar) XB_CHUNK_TYPE_RENAME; /* Chunk type */ + size_t path_len = strlen(old_path); + int4store(ptr, path_len); /* Path length */ + ptr += 4; + + memcpy(ptr, old_path, path_len); /* Path */ + ptr += path_len; + + path_len = strlen(new_path); + int4store(ptr, path_len); /* Path length */ + ptr += 4; + + memcpy(ptr, new_path, path_len); /* Path */ + ptr += path_len; + + xb_ad(ptr <= tmpbuf + sizeof(tmpbuf)); + + pthread_mutex_lock(&stream->mutex); + + ssize_t result = stream->write(stream->user_data, tmpbuf, + (ulonglong) (ptr - tmpbuf)); + + pthread_mutex_unlock(&stream->mutex); + + return result < 0; +} + diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 1482c5f3507..c4cb0fa3cb2 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -4,7 +4,7 @@ MariaBackup: hot backup tool for InnoDB Originally Created 3/3/2009 Yasufumi Kinoshita Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko, Yasufumi Kinoshita, Ignacio Nin and Baron Schwartz. -(c) 2017, 2022, MariaDB Corporation. +(c) 2017, 2024, MariaDB Corporation. Portions written by Marko Mäkelä. This program is free software; you can redistribute it and/or modify @@ -54,7 +54,6 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA #include #include -#include #include #ifdef __linux__ @@ -70,6 +69,7 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA # include #endif +#include "aria_backup_client.h" #include #include @@ -82,6 +82,7 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA #include #include #include "ha_innodb.h" +#include "fts0types.h" #include #include @@ -97,23 +98,26 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA #include "xb_regex.h" #include "fil_cur.h" #include "write_filt.h" -#include "xtrabackup.h" #include "ds_buffer.h" #include "ds_tmpfile.h" #include "xbstream.h" -#include "changed_page_bitmap.h" #include "read_filt.h" #include "backup_wsrep.h" #include "innobackupex.h" #include "backup_mysql.h" #include "backup_copy.h" #include "backup_mysql.h" -#include "xb_plugin.h" +#include "encryption_plugin.h" #include #include #include #include #include +#include +#include "ddl_log.h" +#include "common_engine.h" +#include "lex_string.h" +#include "sql_table.h" #include "backup_debug.h" #define MB_CORRUPTED_PAGES_FILE "innodb_corrupted_pages" @@ -126,6 +130,9 @@ int sd_notifyf() { return 0; } int sys_var_init(); +extern const char* fts_common_tables[]; +extern const fts_index_selector_t fts_index_selector[]; + /* === xtrabackup specific options === */ #define DEFAULT_TARGET_DIR "./mariadb_backup_files/" char xtrabackup_real_target_dir[FN_REFLEN] = DEFAULT_TARGET_DIR; @@ -140,8 +147,8 @@ my_bool xtrabackup_decrypt_decompress; my_bool xtrabackup_print_param; my_bool xtrabackup_mysqld_args; my_bool xtrabackup_help; - my_bool xtrabackup_export; +my_bool ignored_option; longlong xtrabackup_use_memory; @@ -155,7 +162,6 @@ char *xtrabackup_incremental; lsn_t incremental_lsn; lsn_t incremental_to_lsn; lsn_t incremental_last_lsn; -xb_page_bitmap *changed_page_bitmap; char *xtrabackup_incremental_basedir; /* for --backup */ char *xtrabackup_extra_lsndir; /* for --backup with --extra-lsndir */ @@ -195,10 +201,12 @@ struct xb_filter_entry_t{ xb_filter_entry_t *name_hash; }; +lsn_t checkpoint_lsn_start; +lsn_t checkpoint_no_start; /** whether log_copying_thread() is active; protected by recv_sys.mutex */ static bool log_copying_running; -int xtrabackup_parallel; +uint xtrabackup_parallel; char *xtrabackup_stream_str = NULL; xb_stream_fmt_t xtrabackup_stream_fmt = XB_STREAM_FMT_NONE; @@ -254,7 +262,7 @@ recv_sys.mutex. */ static std::set fail_undo_ids; longlong innobase_page_size = (1LL << 14); /* 16KB */ -char* innobase_buffer_pool_filename = NULL; +char *innobase_buffer_pool_filename = NULL; /* The default values for the following char* start-up parameters are determined in innobase_init below: */ @@ -360,10 +368,8 @@ my_bool opt_galera_info = FALSE; my_bool opt_slave_info = FALSE; my_bool opt_no_lock = FALSE; my_bool opt_safe_slave_backup = FALSE; -my_bool opt_rsync = FALSE; my_bool opt_force_non_empty_dirs = FALSE; my_bool opt_noversioncheck = FALSE; -my_bool opt_no_backup_locks = FALSE; my_bool opt_decompress = FALSE; my_bool opt_remove_original; my_bool opt_log_innodb_page_corruption; @@ -373,8 +379,8 @@ static my_bool opt_check_privileges; extern const char *innodb_checksum_algorithm_names[]; extern TYPELIB innodb_checksum_algorithm_typelib; -extern const char *innodb_flush_method_names[]; extern TYPELIB innodb_flush_method_typelib; +extern TYPELIB innodb_doublewrite_typelib; /** Ignored option */ static ulong innodb_flush_method; @@ -423,6 +429,8 @@ pthread_cond_t scanned_lsn_cond; /** Store the deferred tablespace name during --backup */ static std::set defer_space_names; +typedef decltype(fil_space_t::id) space_id_t; + typedef std::map space_id_to_name_t; struct ddl_tracker_t { @@ -697,8 +705,190 @@ typedef void (*process_single_tablespace_func_t)(const char *dirname, uint32_t defer_space_id); static dberr_t enumerate_ibd_files(process_single_tablespace_func_t callback); +const char *convert_dst(const char *dst) { + return + (xtrabackup_copy_back || xtrabackup_move_back) ? + dst : trim_dotslash(dst); +} + +std::string convert_tablename_to_filepath( + const char *data_dir_path, const std::string &db, const std::string &table) { + char dbbuff[FN_REFLEN]; + char tbbuff[FN_REFLEN]; + (void)tablename_to_filename(db.c_str(), dbbuff, sizeof(dbbuff)); + (void)tablename_to_filename(table.c_str(), tbbuff, sizeof(tbbuff)); + std::string result(data_dir_path); + result.append(1, FN_LIBCHAR).append(dbbuff). + append(1, FN_LIBCHAR).append(tbbuff); + return result; +} + +std::tuple +convert_filepath_to_tablename(const char *filepath) { + char db_name_orig[FN_REFLEN]; + char table_name_orig[FN_REFLEN]; + parse_db_table_from_file_path(filepath, db_name_orig, table_name_orig); + if (!db_name_orig[0] || !table_name_orig[0]) + return std::make_tuple("", "", ""); + char db_name_conv[FN_REFLEN]; + char table_name_conv[FN_REFLEN]; + filename_to_tablename(db_name_orig, db_name_conv, sizeof(db_name_conv)); + filename_to_tablename( + table_name_orig, table_name_conv, sizeof(table_name_conv)); + if (!db_name_conv[0] || !table_name_conv[0]) + return std::make_tuple("", "", ""); + return std::make_tuple(db_name_conv, table_name_conv, + std::string(db_name_orig).append("/").append(table_name_orig)); +} + +std::string get_table_version_from_image(const std::vector &frm_image) { + DBUG_ASSERT(frm_image.size() >= 64); + + if (!strncmp((char*) frm_image.data(), "TYPE=VIEW\n", 10)) + return {}; + + if (!is_binary_frm_header(frm_image.data())) + return {}; + + /* Length of the MariaDB extra2 segment in the form file. */ + uint len = uint2korr(frm_image.data() + 4); + const uchar *extra2= frm_image.data() + 64; + + if (*extra2 == '/') // old frm had '/' there + return {}; + + const uchar *e2end= extra2 + len; + while (extra2 + 3 <= e2end) + { + uchar type= *extra2++; + size_t length= *extra2++; + if (!length) + { + if (extra2 + 2 >= e2end) + return {}; + length= uint2korr(extra2); + extra2+= 2; + if (length < 256) + return {}; + } + if (extra2 + length > e2end) + return {}; + if (type == EXTRA2_TABLEDEF_VERSION) { + char buff[MY_UUID_STRING_LENGTH]; + my_uuid2str(extra2, buff, 1); + return std::string(buff, buff + MY_UUID_STRING_LENGTH); + } + extra2+= length; + } + + return {}; +} + +std::pair + get_table_engine_from_image(const std::vector &frm_image) { + + DBUG_ASSERT(frm_image.size() >= 64); + + if (!strncmp((char*) frm_image.data(), "TYPE=VIEW\n", 10)) + return std::make_pair(false, DB_TYPE_UNKNOWN); + + if (!is_binary_frm_header(frm_image.data())) + return std::make_pair(false, DB_TYPE_UNKNOWN); + + legacy_db_type dbt = (legacy_db_type)frm_image[3]; + + if (dbt >= DB_TYPE_FIRST_DYNAMIC) + return std::make_pair(false, DB_TYPE_UNKNOWN); + + if (dbt != DB_TYPE_PARTITION_DB) + return std::make_pair(false, dbt); + + dbt = (legacy_db_type)frm_image[61]; + return std::make_pair(true, + dbt < DB_TYPE_FIRST_DYNAMIC ? dbt : DB_TYPE_UNKNOWN); +} + +std::vector read_frm_image(File file) { + std::vector frm_image; + MY_STAT state; + + if (mysql_file_fstat(file, &state, MYF(MY_WME))) + return frm_image; + + frm_image.resize((size_t)state.st_size, 0); + + if (mysql_file_read( + file, frm_image.data(), (size_t)state.st_size, MYF(MY_NABP))) + frm_image.clear(); + + return frm_image; +} + +std::string read_table_version_id(File file) { + auto frm_image = read_frm_image(file); + if (frm_image.empty()) + return {}; + return get_table_version_from_image(frm_image); +} + +bool is_log_table(const char *dbname, const char *tablename) { + DBUG_ASSERT(dbname); + DBUG_ASSERT(tablename); + + LEX_CSTRING lex_db; + LEX_CSTRING lex_table; + lex_db.str = dbname; + lex_db.length = strlen(dbname); + lex_table.str = tablename; + lex_table.length = strlen(tablename); + + if (!lex_string_eq(&MYSQL_SCHEMA_NAME, &lex_db)) + return false; + + if (lex_string_eq(&GENERAL_LOG_NAME, &lex_table)) + return true; + + if (lex_string_eq(&SLOW_LOG_NAME, &lex_table)) + return true; + + return false; +} + +bool is_stats_table(const char *dbname, const char *tablename) { + DBUG_ASSERT(dbname); + DBUG_ASSERT(tablename); + + LEX_CSTRING lex_db; + LEX_CSTRING lex_table; + lex_db.str = dbname; + lex_db.length = strlen(dbname); + lex_table.str = tablename; + lex_table.length = strlen(tablename); + + if (!lex_string_eq(&MYSQL_SCHEMA_NAME, &lex_db)) + return false; + + CHARSET_INFO *ci= system_charset_info; + + return (lex_table.length > 4 && + /* one of mysql.*_stat tables, but not mysql.innodb* tables*/ + ((my_tolower(ci, lex_table.str[lex_table.length-5]) == 's' && + my_tolower(ci, lex_table.str[lex_table.length-4]) == 't' && + my_tolower(ci, lex_table.str[lex_table.length-3]) == 'a' && + my_tolower(ci, lex_table.str[lex_table.length-2]) == 't' && + my_tolower(ci, lex_table.str[lex_table.length-1]) == 's') && + !(my_tolower(ci, lex_table.str[0]) == 'i' && + my_tolower(ci, lex_table.str[1]) == 'n' && + my_tolower(ci, lex_table.str[2]) == 'n' && + my_tolower(ci, lex_table.str[3]) == 'o'))); +} + /* ======== Datafiles iterator ======== */ struct datafiles_iter_t { + datafiles_iter_t() : space(fil_system.space_list.end()), node(nullptr), started(FALSE) { + } + ~datafiles_iter_t() { + } space_list_t::iterator space = fil_system.space_list.end(); fil_node_t *node = nullptr; bool started = false; @@ -778,8 +968,6 @@ static void *dbug_execute_in_new_connection(void *arg) return nullptr; } -static pthread_t dbug_alter_thread; - /* Execute query from a new connection, in own thread. @@ -790,8 +978,9 @@ Execute query from a new connection, in own thread. otherwise query should return error. @param expected_errno - if not 0, and query finished with error, expected mysql_errno() +@return created thread id */ -static void dbug_start_query_thread( +static pthread_t dbug_start_query_thread( const char *query, const char *wait_state, int expected_err, @@ -803,12 +992,14 @@ static void dbug_start_query_thread( par->expect_err = expected_err; par->expect_errno = expected_errno; par->con = xb_mysql_connect(); - - mysql_thread_create(0, &dbug_alter_thread, nullptr, + if (mysql_set_server_option(par->con, MYSQL_OPTION_MULTI_STATEMENTS_ON)) + die("Can't set multistatement option for query: %s", query); + pthread_t result_thread; + mysql_thread_create(0, &result_thread, nullptr, dbug_execute_in_new_connection, par); if (!wait_state) - return; + return result_thread; char q[256]; snprintf(q, sizeof(q), @@ -830,7 +1021,11 @@ static void dbug_start_query_thread( end: msg("query '%s' on connection %lu reached state '%s'", query, mysql_thread_id(par->con), wait_state); + return result_thread; } + +static pthread_t dbug_alter_thread; +static pthread_t dbug_emulate_ddl_on_intermediate_table_thread; #endif void mdl_lock_all() @@ -953,6 +1148,31 @@ static void backup_file_op(uint32_t space_id, int type, } } +static bool check_if_fts_table(const char *file_name) { + const char *table_name_start = strrchr(file_name, '/'); + if (table_name_start) + ++table_name_start; + else + table_name_start = file_name; + + if (!starts_with(table_name_start,"FTS_")) + return false; + + const char *table_name_end = strrchr(table_name_start, '.'); + if (!table_name_end) + table_name_end = table_name_start + strlen(table_name_start); + ptrdiff_t table_name_len = table_name_end - table_name_end; + + for (const char **suffix = fts_common_tables; *suffix; ++suffix) + if (!strncmp(table_name_start, *suffix, table_name_len)) + return true; + for (size_t i = 0; fts_index_selector[i].suffix; ++i) + if (!strncmp(table_name_start, fts_index_selector[i].suffix, + table_name_len)) + return true; + + return false; +} /* This callback is called if DDL operation is detected, @@ -986,8 +1206,9 @@ static void backup_file_op_fail(uint32_t space_id, int type, break; case FILE_DELETE: fail = !check_if_skip_table( - filename_to_spacename(name, len).c_str()); - msg("DDL tracking : delete %u \"%.*s\"", space_id, int(len), name); + filename_to_spacename(name, len).c_str()) + && !check_if_fts_table(reinterpret_cast(name)); + msg("DDL tracking : delete %u \"%.*s\"", space_id, int(len), name); break; default: ut_ad(0); @@ -1115,6 +1336,7 @@ enum options_xtrabackup OPT_INNODB_DATA_FILE_BUFFERING, OPT_INNODB_DATA_FILE_WRITE_THROUGH, OPT_INNODB_LOG_FILE_SIZE, + OPT_INNODB_LOG_FILES_IN_GROUP, OPT_INNODB_OPEN_FILES, OPT_XTRA_DEBUG_SYNC, OPT_INNODB_CHECKSUM_ALGORITHM, @@ -1132,9 +1354,9 @@ enum options_xtrabackup OPT_NO_LOCK, OPT_SAFE_SLAVE_BACKUP, OPT_RSYNC, + OPT_NO_BACKUP_LOCKS, OPT_FORCE_NON_EMPTY_DIRS, OPT_NO_VERSION_CHECK, - OPT_NO_BACKUP_LOCKS, OPT_DECOMPRESS, OPT_INCREMENTAL_HISTORY_NAME, OPT_INCREMENTAL_HISTORY_UUID, @@ -1346,8 +1568,10 @@ struct my_option xb_client_options[]= { 0, 0, 0, 0, 0, 0}, {"no-lock", OPT_NO_LOCK, - "Use this option to disable table lock " - "with \"FLUSH TABLES WITH READ LOCK\". Use it only if ALL your " + "This option should not be used as " + "mariadb-backup now is using BACKUP LOCKS, which minimizes the " + "lock time. ALTER TABLE can run in parallel with BACKUP LOCKS." + "Use the --no-lock option it only if ALL your " "tables are InnoDB and you DO NOT CARE about the binary log " "position of the backup. This option shouldn't be used if there " "are any DDL statements being executed or if any updates are " @@ -1376,14 +1600,12 @@ struct my_option xb_client_options[]= { GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"rsync", OPT_RSYNC, - "Uses the rsync utility to optimize local file " - "transfers. When this option is specified, " XB_TOOL_NAME " uses rsync " - "to copy all non-InnoDB files instead of spawning a separate cp for " - "each file, which can be much faster for servers with a large number " - "of databases or tables. This option cannot be used together with " - "--stream.", - (uchar *) &opt_rsync, (uchar *) &opt_rsync, 0, GET_BOOL, NO_ARG, 0, 0, 0, - 0, 0, 0}, + "Obsolete depricated option", + &ignored_option, &ignored_option, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + + {"no-backup-locks", OPT_NO_BACKUP_LOCKS, + "Obsolete depricated option", + &ignored_option, &ignored_option, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"force-non-empty-directories", OPT_FORCE_NON_EMPTY_DIRS, "This " @@ -1401,15 +1623,6 @@ struct my_option xb_client_options[]= { (uchar *) &opt_noversioncheck, (uchar *) &opt_noversioncheck, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"no-backup-locks", OPT_NO_BACKUP_LOCKS, - "This option controls if " - "backup locks should be used instead of FLUSH TABLES WITH READ LOCK " - "on the backup stage. The option has no effect when backup locks are " - "not supported by the server. This option is enabled by default, " - "disable with --no-backup-locks.", - (uchar *) &opt_no_backup_locks, (uchar *) &opt_no_backup_locks, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"decompress", OPT_DECOMPRESS, "Decompresses all files with the .qp " "extension in a backup previously made with the --compress option. " @@ -1486,11 +1699,10 @@ struct my_option xb_client_options[]= { (uchar *) &opt_remove_original, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"ftwrl-wait-query-type", OPT_LOCK_WAIT_QUERY_TYPE, - "This option specifies which types of queries are allowed to complete " - "before " XB_TOOL_NAME " will issue the global lock. Default is all.", - (uchar *) &opt_lock_wait_query_type, (uchar *) &opt_lock_wait_query_type, - &query_type_typelib, GET_ENUM, REQUIRED_ARG, QUERY_TYPE_ALL, 0, 0, 0, 0, - 0}, + "Old disabled option which has no effect anymore (not needed " + "with BACKUP LOCKS)", + (uchar*) 0, (uchar*) 0, &query_type_typelib, GET_ENUM, + REQUIRED_ARG, QUERY_TYPE_ALL, 0, 0, 0, 0, 0}, {"kill-long-query-type", OPT_KILL_LONG_QUERY_TYPE, "This option specifies which types of queries should be killed to " @@ -1507,32 +1719,31 @@ struct my_option xb_client_options[]= { NULL, NULL, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"kill-long-queries-timeout", OPT_KILL_LONG_QUERIES_TIMEOUT, - "This option specifies the number of seconds " XB_TOOL_NAME " waits " - "between starting FLUSH TABLES WITH READ LOCK and killing those " - "queries that block it. Default is 0 seconds, which means " - XB_TOOL_NAME " will not attempt to kill any queries.", - (uchar *) &opt_kill_long_queries_timeout, - (uchar *) &opt_kill_long_queries_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, + "Old disabled option which has no effect anymore (not needed " + "with BACKUP LOCKS)", + (uchar*) 0, (uchar*) 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"ftwrl-wait-timeout", OPT_LOCK_WAIT_TIMEOUT, - "This option specifies time in seconds that " XB_TOOL_NAME " should wait " - "for queries that would block FTWRL before running it. If there are " - "still such queries when the timeout expires, " XB_TOOL_NAME " terminates " - "with an error. Default is 0, in which case " XB_TOOL_NAME " does not " - "wait for queries to complete and starts FTWRL immediately.", - (uchar *) &opt_lock_wait_timeout, (uchar *) &opt_lock_wait_timeout, 0, - GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + "Alias for startup-wait-timeout", + (uchar*) &opt_lock_wait_timeout, (uchar*) &opt_lock_wait_timeout, + 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + + {"startup-wait-timeout", OPT_LOCK_WAIT_TIMEOUT, + "This option specifies time in seconds that mariadb-backup should wait for " + "BACKUP STAGE START to complete. BACKUP STAGE START has to wait until all " + "currently running queries using explicite LOCK TABLES has ended. " + "If there are still such queries when the timeout expires, mariadb-backup " + "terminates with an error. Default is 0, in which case mariadb-backup waits " + "indefinitely for BACKUP STAGE START to finish", + (uchar*) &opt_lock_wait_timeout, (uchar*) &opt_lock_wait_timeout, + 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"ftwrl-wait-threshold", OPT_LOCK_WAIT_THRESHOLD, - "This option specifies the query run time threshold which is used by " - XB_TOOL_NAME " to detect long-running queries with a non-zero value " - "of --ftwrl-wait-timeout. FTWRL is not started until such " - "long-running queries exist. This option has no effect if " - "--ftwrl-wait-timeout is 0. Default value is 60 seconds.", - (uchar *) &opt_lock_wait_threshold, (uchar *) &opt_lock_wait_threshold, 0, - GET_UINT, REQUIRED_ARG, 60, 0, 0, 0, 0, 0}, - + "Old disabled option which has no effect anymore (not needed " + "with BACKUP LOCKS)", + (uchar*) 0, (uchar*) 0, 0, GET_UINT, + REQUIRED_ARG, 60, 0, 0, 0, 0, 0}, {"safe-slave-backup-timeout", OPT_SAFE_SLAVE_BACKUP_TIMEOUT, "How many seconds --safe-slave-backup should wait for " @@ -1598,7 +1809,7 @@ struct my_option xb_server_options[] = {"parallel", OPT_XTRA_PARALLEL, "Number of threads to use for parallel datafiles transfer. " "The default value is 1.", - (G_PTR*) &xtrabackup_parallel, (G_PTR*) &xtrabackup_parallel, 0, GET_INT, + (G_PTR*) &xtrabackup_parallel, (G_PTR*) &xtrabackup_parallel, 0, GET_UINT, REQUIRED_ARG, 1, 1, INT_MAX, 0, 0, 0}, {"extended_validation", OPT_XTRA_EXTENDED_VALIDATION, @@ -1647,8 +1858,8 @@ struct my_option xb_server_options[] = &innobase_data_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_doublewrite", OPT_INNODB_DOUBLEWRITE, "Enable InnoDB doublewrite buffer during --prepare.", - (G_PTR*) &srv_use_doublewrite_buf, - (G_PTR*) &srv_use_doublewrite_buf, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + (G_PTR*) &buf_dblwr.use, (G_PTR*) &buf_dblwr.use, + &innodb_doublewrite_typelib, GET_ENUM, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_io_capacity", OPT_INNODB_IO_CAPACITY, "Number of IOPs the server can do. Tunes the background IO rate", (G_PTR*) &srv_io_capacity, (G_PTR*) &srv_io_capacity, @@ -1680,8 +1891,8 @@ struct my_option xb_server_options[] = {"innodb_log_buffer_size", OPT_INNODB_LOG_BUFFER_SIZE, "Redo log buffer size in bytes.", (G_PTR*) &log_sys.buf_size, (G_PTR*) &log_sys.buf_size, 0, - IF_WIN(GET_ULL,GET_ULONG), REQUIRED_ARG, 2U << 20, - 2U << 20, SIZE_T_MAX, 0, 4096, 0}, + GET_UINT, REQUIRED_ARG, 2U << 20, + 2U << 20, log_sys.buf_size_max, 0, 4096, 0}, #if defined __linux__ || defined _WIN32 {"innodb_log_file_buffering", OPT_INNODB_LOG_FILE_BUFFERING, "Whether the file system cache for ib_logfile0 is enabled during --backup", @@ -1767,17 +1978,17 @@ struct my_option xb_server_options[] = 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"plugin-dir", OPT_PLUGIN_DIR, - "Server plugin directory. Used to load plugins during 'prepare' phase." - "Has no effect in the 'backup' phase (plugin directory during backup is the same as server's)", - &xb_plugin_dir, &xb_plugin_dir, - 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + "Server plugin directory. Used to load plugins during 'prepare' phase." + "Has no effect in the 'backup' phase (plugin directory during backup is the same as server's)", + &xb_plugin_dir, &xb_plugin_dir, + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, {"aria_log_dir_path", OPT_ARIA_LOG_DIR_PATH, "Path to individual files and their sizes.", &aria_log_dir_path, &aria_log_dir_path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"open_files_limit", OPT_OPEN_FILES_LIMIT, "the maximum number of file " + {"open_files_limit", 0, "the maximum number of file " "descriptors to reserve with setrlimit().", (G_PTR*) &xb_open_files_limit, (G_PTR*) &xb_open_files_limit, 0, GET_ULONG, REQUIRED_ARG, 0, 0, UINT_MAX, 0, 1, 0}, @@ -1898,7 +2109,7 @@ static int prepare_export() IF_WIN("\"","") "\"%s\" --mysqld \"%s\"" " --defaults-extra-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=." " --innodb --innodb-fast-shutdown=0 --loose-partition" - " --innodb-buffer-pool-size=%llu" + " --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu" " --console --skip-log-error --skip-log-bin --bootstrap %s< " BOOTSTRAP_FILENAME IF_WIN("\"",""), mariabackup_exe, @@ -1912,7 +2123,7 @@ static int prepare_export() IF_WIN("\"","") "\"%s\" --mysqld" " --defaults-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=." " --innodb --innodb-fast-shutdown=0 --loose-partition" - " --innodb-buffer-pool-size=%llu" + " --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu" " --console --log-error= --skip-log-bin --bootstrap %s< " BOOTSTRAP_FILENAME IF_WIN("\"",""), mariabackup_exe, @@ -1961,7 +2172,8 @@ static void usage(void) puts("Open source backup tool for InnoDB and XtraDB\n\ \n\ Copyright (C) 2009-2015 Percona LLC and/or its affiliates.\n\ -Portions Copyright (C) 2000, 2011, MySQL AB & Innobase Oy. All Rights Reserved.\n\ +Portions Copyright (C) 2000, 2011, MySQL AB & Innobase Oy.\n\ +Portions Copyright (C) 2017-2023 MariaDB Corporation / MariaDB Plc.\n\ \n\ This program is free software; you can redistribute it and/or\n\ modify it under the terms of the GNU General Public License\n\ @@ -2129,6 +2341,11 @@ xb_get_one_option(const struct my_option *opt, } } break; + case OPT_RSYNC: + case OPT_NO_BACKUP_LOCKS: + if (my_handle_options_init_variables) + fprintf(stderr, "Obsolete option: %s. Ignored\n", opt->name); + break; #define MYSQL_CLIENT #include "sslopt-case.h" #undef MYSQL_CLIENT @@ -2418,7 +2635,12 @@ static bool innodb_init() os_file_delete_if_exists_func(ib_logfile0.c_str(), nullptr); os_file_t file= os_file_create_func(ib_logfile0.c_str(), OS_FILE_CREATE, OS_FILE_NORMAL, - OS_DATA_FILE_NO_O_DIRECT, false, &ret); +#if defined _WIN32 || defined O_DIRECT + OS_DATA_FILE_NO_O_DIRECT, +#else + OS_DATA_FILE, +#endif + false, &ret); if (!ret) { invalid_log: @@ -3050,12 +3272,7 @@ static my_bool xtrabackup_copy_datafile(ds_ctxt *ds_data, goto skip; } - if (!changed_page_bitmap) { - read_filter = &rf_pass_through; - } - else { - read_filter = &rf_bitmap; - } + read_filter = &rf_pass_through; res = xb_fil_cur_open(&cursor, read_filter, node, thread_n, ULLONG_MAX); if (res == XB_FIL_CUR_SKIP) { @@ -3379,50 +3596,22 @@ To use this facility, you need to 3. start mariabackup with --dbug=+d,debug_mariabackup_events */ void dbug_mariabackup_event(const char *event, - const fil_space_t::name_type key) + const fil_space_t::name_type key, + bool need_lock) { + static std::mutex dbug_mariabackup_event_mutex; char *sql = dbug_mariabackup_get_val(event, key); if (sql && *sql) { msg("dbug_mariabackup_event : executing '%s'", sql); - xb_mysql_query(mysql_connection, sql, false, true); - } + if (need_lock) { + std::lock_guard lock(dbug_mariabackup_event_mutex); + xb_mysql_query(mysql_connection, sql, false, true); + } else + xb_mysql_query(mysql_connection, sql, false, true); + } } #endif // DBUG_OFF -/** Datafiles copying thread.*/ -static void data_copy_thread_func(data_thread_ctxt_t *ctxt) /* thread context */ -{ - uint num = ctxt->num; - fil_node_t* node; - ut_ad(ctxt->corrupted_pages); - - /* - Initialize mysys thread-specific memory so we can - use mysys functions in this thread. - */ - my_thread_init(); - - while ((node = datafiles_iter_next(ctxt->it)) != NULL) { - DBUG_MARIABACKUP_EVENT("before_copy", node->space->name()); - DBUG_EXECUTE_FOR_KEY("wait_innodb_redo_before_copy", - node->space->name(), - backup_wait_for_lsn(get_current_lsn(mysql_connection));); - /* copy the datafile */ - if (xtrabackup_copy_datafile(ctxt->datasinks->m_data, - ctxt->datasinks->m_meta, node, num, NULL, - xtrabackup_incremental ? wf_incremental : wf_write_through, - *ctxt->corrupted_pages)) - die("failed to copy datafile."); - - DBUG_MARIABACKUP_EVENT("after_copy", node->space->name()); - } - - pthread_mutex_lock(ctxt->count_mutex); - (*ctxt->count)--; - pthread_mutex_unlock(ctxt->count_mutex); - - my_thread_end(); -} /************************************************************************ Initialize the appropriate datasink(s). Both local backups and streaming in the @@ -3577,6 +3766,11 @@ static void xb_load_single_table_tablespace(const char *dirname, } if (file->open_read_only(true) != DB_SUCCESS) { + // Ignore FTS tables, as they can be removed for intermediate tables, + // this code must be executed under stronger or equal to BLOCK_DDL lock, + // so there must not be errors for non-intermediate FTS tables. + if (check_if_fts_table(filname)) + return; die("Can't open datafile %s", name); } @@ -4582,7 +4776,6 @@ bool Backup_datasinks::backup_low() if (failed_ids.size() > 0) { return false; } - if (!xtrabackup_incremental) { safe_strcpy(metadata_type, sizeof(metadata_type), "full-backuped"); @@ -4621,16 +4814,441 @@ bool Backup_datasinks::backup_low() return true; } +class InnodbDataCopier { +public: + InnodbDataCopier(Backup_datasinks &backup_datasinks, + CorruptedPages &corrupted_pages, + ThreadPool &thread_pool) : + m_backup_datasinks(backup_datasinks), + m_corrupted_pages(corrupted_pages), + m_tasks(thread_pool) {} + + ~InnodbDataCopier() { + DBUG_ASSERT(m_tasks.is_finished()); + } + + bool start() { + DBUG_ASSERT(m_tasks.is_finished()); + m_tasks.push_task( + std::bind(&InnodbDataCopier::scan_job, this, std::placeholders::_1)); + return true; + } + + bool wait_for_finish() { + return m_tasks.wait_for_finish(); + } + +private: + void scan_job(unsigned thread_num) { + datafiles_iter_t it; + fil_node_t* node; + while ((node = datafiles_iter_next(&it)) != nullptr) { + m_tasks.push_task( + std::bind(&InnodbDataCopier::copy_job, this, node, + std::placeholders::_1)); + } + m_tasks.finish_task(1); + } + + void copy_job(fil_node_t *node, unsigned thread_num) { + DBUG_ASSERT(node); + // TODO: this came from the old code, where it was not thread-safe + // too, use separate mysql connection per thread here + DBUG_MARIABACKUP_EVENT("before_copy", node->space->name()); + DBUG_EXECUTE_FOR_KEY("wait_innodb_redo_before_copy", + node->space->name(), + backup_wait_for_lsn( + get_current_lsn(mysql_connection));); + /* copy the datafile */ + if(xtrabackup_copy_datafile(m_backup_datasinks.m_data, + m_backup_datasinks.m_meta, + node, thread_num, NULL, + xtrabackup_incremental + ? wf_incremental : wf_write_through, + m_corrupted_pages)) + die("mariabackup: Error: failed to copy datafile."); + // TODO: this came from the old code, where it was not thread-safe + // too, use separate mysql connection per thread here + DBUG_MARIABACKUP_EVENT("after_copy", node->space->name()); + m_tasks.finish_task(1); + } + + Backup_datasinks &m_backup_datasinks; + CorruptedPages &m_corrupted_pages; + TasksGroup m_tasks; +}; + + +class BackupStages { + + public: + + BackupStages(ds_ctxt_t *ds_data) : + m_bs_con(nullptr), + m_aria_backup(fil_path_to_mysql_datadir, + aria_log_dir_path, + ds_data, m_con_pool, m_thread_pool), + m_common_backup(fil_path_to_mysql_datadir, ds_data, m_con_pool, + m_thread_pool) {} + + ~BackupStages() { destroy(); } + + bool init() { + if ((m_bs_con = xb_mysql_connect()) == nullptr) + return false; + + while(m_con_pool.size() < xtrabackup_parallel) { + MYSQL *con = xb_mysql_connect(); + if (con == nullptr) + return false; + m_con_pool.push_back(con); + } + + if (!m_thread_pool.start(xtrabackup_parallel)) + return false; + if (!m_aria_backup.init()) + return false; + m_aria_backup.set_post_copy_table_hook( + std::bind(&BackupStages::store_table_version, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + m_common_backup.set_post_copy_table_hook( + std::bind(&BackupStages::store_table_version, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + return true; + } + + void destroy() { + m_thread_pool.stop(); + while (!m_con_pool.empty()) { + MYSQL *con = m_con_pool.back(); + m_con_pool.pop_back(); + mysql_close(con); + } + if (m_bs_con) + mysql_close(m_bs_con); + m_bs_con = nullptr; + } + + bool stage_start(Backup_datasinks &backup_datasinks, + CorruptedPages &corrupted_pages) { + msg("BACKUP STAGE START"); + if (!opt_no_lock) { + if (opt_safe_slave_backup) { + if (!wait_for_safe_slave(mysql_connection)) { + return(false); + } + } + + history_lock_time = time(NULL); + + if (!lock_for_backup_stage_start(m_bs_con)) { + msg("Error on BACKUP STAGE START query execution"); + return(false); + } + } + + InnodbDataCopier innodb_data_copier(backup_datasinks, + corrupted_pages, + m_thread_pool); + // Start InnoDB data files copy in background + if (!innodb_data_copier.start()) { + msg("Error on starting InnoDB data files backup"); + return false; + } + // Start online non-stats-log Aria tables copying in background + if (!m_aria_backup.start(opt_no_lock)) { + msg("Error on starting Aria data files backup"); + innodb_data_copier.wait_for_finish(); + return false; + } + + // Wait for all innodb data files copy finish + if(!innodb_data_copier.wait_for_finish()) { + msg("InnoDB data files backup process is finished with error"); + return false; + } + // Wait for online non-stats-log Aria tables copy finish + if (!m_aria_backup.wait_for_finish()) { + msg("Aria data files backup process is finished with error"); + return false; + } + + DBUG_MARIABACKUP_EVENT_LOCK("after_aria_background", {}); + + return true; + } + + bool stage_flush() { + msg("BACKUP STAGE FLUSH"); + if (!opt_no_lock && !lock_for_backup_stage_flush(m_bs_con)) { + msg("Error on BACKUP STAGE FLUSH query execution"); + return false; + } + auto tables_in_use = get_tables_in_use(mysql_connection); + // Copy non-stats-log non-in-use tables of non-InnoDB-Aria-RocksDB engines + // in background + if (!m_common_backup.scan(tables_in_use, + &m_copied_common_tables, opt_no_lock, true)) { + msg("Error on scan data directory for common engines"); + return false; + } + // Copy Aria offline non-stats-log non-in-use tables in background + if (!m_aria_backup.copy_offline_tables(&tables_in_use, opt_no_lock, + false)) { + msg("Error on start Aria tables backup"); + return false; + } + + if (!m_aria_backup.copy_log_tail()) { + msg("Error on Aria log tail copy"); + return false; + }; + + // Wait for Aria tables copy finish + if (!m_aria_backup.wait_for_finish()) { + msg("Aria data files backup process is finished with error"); + return false; + } + // Wait for non-InnoDB-Aria-RocksDB engines copy finish + if (!m_common_backup.wait_for_finish()) { + msg("Data files backup process is finished with error"); + return false; + } + + DBUG_EXECUTE_IF("emulate_ddl_on_intermediate_table", + dbug_emulate_ddl_on_intermediate_table_thread = + dbug_start_query_thread( + "SET debug_sync='copy_data_between_tables_after_set_backup_lock " + "SIGNAL copy_started';" + "SET debug_sync='copy_data_between_tables_before_reset_backup_lock " + "SIGNAL before_backup_lock_reset WAIT_FOR backup_lock_reset';" + "SET debug_sync='alter_table_after_temp_table_drop " + "SIGNAL temp_table_dropped';" + "SET SESSION lock_wait_timeout = 1;" + "ALTER TABLE test.t1 ADD COLUMN col1_copy INT, ALGORITHM = COPY;", + NULL, 0, 0); + xb_mysql_query(mysql_connection, + "SET debug_sync='now WAIT_FOR copy_started'", false, true); + ); + + return true; + } + + bool stage_block_ddl(Backup_datasinks &backup_datasinks, + CorruptedPages &corrupted_pages) { + if (!opt_no_lock) { + if (!lock_for_backup_stage_block_ddl(m_bs_con)) { + msg("BACKUP STAGE BLOCK_DDL"); + return false; + } + if (have_galera_enabled) + { + xb_mysql_query(mysql_connection, "SET SESSION wsrep_sync_wait=0", false); + } + } + + ulonglong server_lsn_after_lock = get_current_lsn(mysql_connection); + + // Copy the rest of non-stats-lognon-InnoDB-Aria-RocksDB tables + // Do not execute BACKUP LOCK under BLOCK_DDL stage + if (!m_common_backup.scan(m_copied_common_tables, &m_copied_common_tables, + true, false)) { + msg("Error on scan data directory for common engines"); + return false; + } + // Copy log tables tail + if (!m_common_backup.copy_log_tables(false)) { + msg("Error on copy system tables"); + return false; + } + + // Copy the rest of non-stats Aria tables in background + if (!m_aria_backup.copy_offline_tables(nullptr, true, false)) { + msg("Error on start Aria tables backup"); + return false; + } + + // Copy .frm, .trn and other files + if (!backup_files(backup_datasinks.m_data, + fil_path_to_mysql_datadir)) { + msg("Backup files error"); + return false; + } + + msg("Waiting for log copy thread to read lsn %llu", + server_lsn_after_lock); + backup_wait_for_lsn(server_lsn_after_lock); + corrupted_pages.backup_fix_ddl(backup_datasinks.m_data, + backup_datasinks.m_meta); + + if (!m_aria_backup.copy_log_tail()) { + msg("Error on Aria log tail copy"); + return false; + } + + // Wait for Aria tables copy finish + if (!m_aria_backup.wait_for_finish()) { + msg("Aria data files backup process is finished with error"); + return false; + } + // Wait for non-InnoDB-Aria-RocksDB engines copy finish + if (!m_common_backup.wait_for_finish()) { + msg("Data files backup process is finished with error"); + return false; + } + + ddl_log::backup(fil_path_to_mysql_datadir, + backup_datasinks.m_data, m_tables); + + DBUG_MARIABACKUP_EVENT_LOCK("after_stage_block_ddl", {}); + + return true; + } + + bool stage_block_commit(Backup_datasinks &backup_datasinks) { + msg("BACKUP STAGE BLOCK_COMMIT"); + if (!opt_no_lock && !lock_for_backup_stage_commit(m_bs_con)) { + msg("Error on BACKUP STAGE BLOCK_COMMIT query execution"); + return false; + } + + // Copy log tables tail + if (!m_common_backup.copy_log_tables(true)) { + msg("Error on copy log tables"); + return false; + } + + // Copy stats tables + if (!m_common_backup.copy_stats_tables()) { + msg("Error on copy stats tables"); + return false; + } + + // Copy system Aria files + if (!m_aria_backup.finalize()) { + msg("Error on finalize Aria tables backup"); + return false; + } + + if (!m_common_backup.wait_for_finish()) { + msg("Error on finish common engines backup"); + return false; + } + + if (!m_common_backup.close_log_tables()) { + msg("Error on close log tables"); + return false; + } + + if (!backup_files_from_datadir(backup_datasinks.m_data, + fil_path_to_mysql_datadir, + "aws-kms-key")) { + msg("Error on root data dir files backup"); + return false; + } + + if (has_rocksdb_plugin()) { + rocksdb_create_checkpoint(); + } + + // There is no need to stop slave thread before coping non-Innodb data when + // --no-lock option is used because --no-lock option requires that no DDL or + // DML to non-transaction tables can occur. + if (opt_no_lock) { + if (opt_safe_slave_backup) { + if (!wait_for_safe_slave(mysql_connection)) { + return(false); + } + } + } + + if (opt_slave_info) { + if (!write_slave_info(backup_datasinks.m_data, + mysql_connection)) { + return(false); + } + } + + /* The only reason why Galera/binlog info is written before + wait_for_ibbackup_log_copy_finish() is that after that call the xtrabackup + binary will start streamig a temporary copy of REDO log to stdout and + thus, any streaming from innobackupex would interfere. The only way to + avoid that is to have a single process, i.e. merge innobackupex and + xtrabackup. */ + if (opt_galera_info) { + if (!write_galera_info(backup_datasinks.m_data, + mysql_connection)) { + return(false); + } + } + + bool with_binlogs = opt_binlog_info == BINLOG_INFO_ON; + + if (with_binlogs || opt_galera_info) { + if (!write_binlog_info(backup_datasinks.m_data, + mysql_connection)) { + return(false); + } + } + + if (!opt_no_lock) { + msg("Executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS..."); + xb_mysql_query(mysql_connection, + "FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS", false); + } + + return backup_datasinks.backup_low(); + } + + bool stage_end(Backup_datasinks &backup_datasinks) { + msg("BACKUP STAGE END"); + /* release all locks */ + if (!opt_no_lock) { + unlock_all(m_bs_con); + history_lock_time = 0; + } else { + history_lock_time = time(NULL) - history_lock_time; + } + backup_release(); + DBUG_EXECUTE_IF("check_mdl_lock_works", + pthread_join(dbug_alter_thread, nullptr); + ); + + DBUG_EXECUTE_IF("emulate_ddl_on_intermediate_table", + pthread_join( + dbug_emulate_ddl_on_intermediate_table_thread, + nullptr); + ); + + backup_finish(backup_datasinks.m_data); + return true; + } + + void store_table_version( + std::string db, std::string table, std::string table_version) { + auto tk = table_key(db, table); + std::lock_guard lock(m_tables_mutex); + m_tables[std::move(tk)] = std::move(table_version); + } + + private: + Backup_datasinks *backup_datasinks; + MYSQL *m_bs_con; + ThreadPool m_thread_pool; + std::vector m_con_pool; + std::mutex m_tables_mutex; + ddl_log::tables_t m_tables; + aria::Backup m_aria_backup; + common_engine::Backup m_common_backup; + std::unordered_set m_copied_common_tables; +}; + /** Implement --backup @return whether the operation succeeded */ static bool xtrabackup_backup_func() { MY_STAT stat_info; - uint i; - uint count; - pthread_mutex_t count_mutex; CorruptedPages corrupted_pages; - data_thread_ctxt_t *data_threads; Backup_datasinks backup_datasinks; pthread_cond_init(&scanned_lsn_cond, NULL); @@ -4646,7 +5264,7 @@ static bool xtrabackup_backup_func() return(false); } msg("cd to %s", mysql_real_data_home); - xb_plugin_backup_init(mysql_connection); + encryption_plugin_backup_init(mysql_connection); msg("open files limit requested %lu, set to %lu", xb_open_files_limit, xb_set_max_open_files(xb_open_files_limit)); @@ -4687,22 +5305,6 @@ fail: return(false); } - if (srv_buf_pool_size >= 1000 * 1024 * 1024) { - /* Here we still have srv_pool_size counted - in kilobytes (in 4.0 this was in bytes) - srv_boot() converts the value to - pages; if buffer pool is less than 1000 MB, - assume fewer threads. */ - srv_max_n_threads = 50000; - - } else if (srv_buf_pool_size >= 8 * 1024 * 1024) { - - srv_max_n_threads = 10000; - } else { - srv_max_n_threads = 1000; /* saves several MB of memory, - especially in 64-bit - computers */ - } srv_thread_pool_init(); /* Reset the system variables in the recovery module. */ trx_pool_init(); @@ -4722,9 +5324,10 @@ fail: } /* get current checkpoint_lsn */ { + log_sys.latch.wr_lock(SRW_LOCK_CALL); mysql_mutex_lock(&recv_sys.mutex); - dberr_t err = recv_sys.find_checkpoint(); + log_sys.latch.wr_unlock(); if (err != DB_SUCCESS) { msg("Error: cannot read redo log header"); @@ -4820,11 +5423,6 @@ fail: std::thread(log_copying_thread).detach(); - /* FLUSH CHANGED_PAGE_BITMAPS call */ - if (!flush_changed_page_bitmaps()) { - goto fail; - } - ut_a(xtrabackup_parallel > 0); if (xtrabackup_parallel > 1) { @@ -4836,71 +5434,36 @@ fail: mdl_lock_all(); DBUG_EXECUTE_IF("check_mdl_lock_works", - dbug_start_query_thread("ALTER TABLE test.t ADD COLUMN mdl_lock_column int", + dbug_alter_thread = + dbug_start_query_thread("ALTER TABLE test.t ADD COLUMN mdl_lock_column int", "Waiting for table metadata lock", 0, 0);); } - datafiles_iter_t it; + BackupStages stages(backup_datasinks.m_data); - /* Create data copying threads */ - data_threads = (data_thread_ctxt_t *) - malloc(sizeof(data_thread_ctxt_t) * xtrabackup_parallel); - count = xtrabackup_parallel; - pthread_mutex_init(&count_mutex, NULL); - - for (i = 0; i < (uint) xtrabackup_parallel; i++) { - data_threads[i].it = ⁢ - data_threads[i].num = i+1; - data_threads[i].count = &count; - data_threads[i].count_mutex = &count_mutex; - data_threads[i].corrupted_pages = &corrupted_pages; - data_threads[i].datasinks= &backup_datasinks; - std::thread(data_copy_thread_func, data_threads + i).detach(); - } - - /* Wait for threads to exit */ - while (1) { - std::this_thread::sleep_for(std::chrono::seconds(1)); - pthread_mutex_lock(&count_mutex); - bool stop = count == 0; - pthread_mutex_unlock(&count_mutex); - if (stop) { - break; - } - } - - pthread_mutex_destroy(&count_mutex); - free(data_threads); - - DBUG_ASSERT(backup_datasinks.m_data); - DBUG_ASSERT(backup_datasinks.m_meta); - bool ok = backup_start(backup_datasinks.m_data, - backup_datasinks.m_meta, corrupted_pages); - - if (ok) { - ok = backup_datasinks.backup_low(); - - backup_release(); - - DBUG_EXECUTE_IF("check_mdl_lock_works", - pthread_join(dbug_alter_thread, nullptr);); - - if (ok) { - backup_finish(backup_datasinks.m_data); - } - } - - if (opt_log_innodb_page_corruption) - ok = corrupted_pages.print_to_file(backup_datasinks.m_data, - MB_CORRUPTED_PAGES_FILE); - - if (!ok) { + if (!stages.init()) + goto fail; + + if (!stages.stage_start(backup_datasinks, corrupted_pages)) + goto fail; + + if (!stages.stage_flush()) + goto fail; + + if (!stages.stage_block_ddl(backup_datasinks, corrupted_pages)) + goto fail; + + if (!stages.stage_block_commit(backup_datasinks)) + goto fail; + + if (!stages.stage_end(backup_datasinks)) + goto fail; + + if (opt_log_innodb_page_corruption + && !corrupted_pages.print_to_file(backup_datasinks.m_data, + MB_CORRUPTED_PAGES_FILE)) goto fail; - } - if (changed_page_bitmap) { - xb_page_bitmap_deinit(changed_page_bitmap); - } backup_datasinks.destroy(); msg("Redo log (from LSN " LSN_PF " to " LSN_PF ") was copied.", @@ -4962,6 +5525,12 @@ void CorruptedPages::backup_fix_ddl(ds_ctxt *ds_data, ds_ctxt *ds_meta) DBUG_MARIABACKUP_EVENT("backup_fix_ddl", {}); + DBUG_EXECUTE_IF("emulate_ddl_on_intermediate_table", + xb_mysql_query(mysql_connection, + "SET debug_sync='now SIGNAL backup_lock_reset " + "WAIT_FOR temp_table_dropped'", false, true); + ); + for (space_id_to_name_t::iterator iter = ddl_tracker.tables_in_backup.begin(); iter != ddl_tracker.tables_in_backup.end(); iter++) { @@ -5106,6 +5675,7 @@ void CorruptedPages::backup_fix_ddl(ds_ctxt *ds_data, ds_ctxt *ds_meta) } } + /* ================= prepare ================= */ /*********************************************************************** @@ -5592,7 +6162,7 @@ std::string change_extension(std::string filename, std::string new_ext) { } -static void rename_file(const char *from,const char *to) { +void rename_file(const char *from,const char *to) { msg("Renaming %s to %s\n", from, to); if (my_rename(from, to, MY_WME)) { die("Can't rename %s to %s errno %d", from, to, errno); @@ -5614,7 +6184,7 @@ typedef ibool (*handle_datadir_entry_func_t)( void* arg); /*! /dev/null 2>&1") == 0)); - if (!have_rsync) - { - msg("Error: rsync executable not found, cannot run backup with --rsync\n"); - return false; - } - } - n_mixed_options = 0; if (opt_decompress) { @@ -6511,6 +7067,7 @@ xb_init() if (opt_check_privileges && !check_all_privileges()) { return(false); } + history_start_time = time(NULL); } diff --git a/extra/mariabackup/xtrabackup.h b/extra/mariabackup/xtrabackup.h index d091c4744ab..38d7e5fdd03 100644 --- a/extra/mariabackup/xtrabackup.h +++ b/extra/mariabackup/xtrabackup.h @@ -24,8 +24,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA #include #include "datasink.h" #include "xbstream.h" -#include "changed_page_bitmap.h" +#include "fil0fil.h" #include +#include "handler.h" + +#include +#include +#include +#include + #define XB_TOOL_NAME "mariadb-backup" #define XB_HISTORY_TABLE "mysql.mariadb_backup_history" @@ -84,8 +91,6 @@ extern my_bool xb_backup_rocksdb; extern uint opt_protocol; -extern xb_page_bitmap *changed_page_bitmap; - extern char *xtrabackup_incremental; extern my_bool xtrabackup_incremental_force_scan; @@ -112,7 +117,7 @@ extern my_bool xtrabackup_decrypt_decompress; extern char *innobase_data_file_path; extern longlong innobase_page_size; -extern int xtrabackup_parallel; +extern uint xtrabackup_parallel; extern my_bool xb_close_files; extern const char *xtrabackup_compress_alg; @@ -131,7 +136,6 @@ extern my_bool opt_galera_info; extern my_bool opt_slave_info; extern my_bool opt_no_lock; extern my_bool opt_safe_slave_backup; -extern my_bool opt_rsync; extern my_bool opt_force_non_empty_dirs; extern my_bool opt_noversioncheck; extern my_bool opt_no_backup_locks; @@ -288,15 +292,40 @@ fil_file_readdir_next_file( os_file_stat_t* info); /*!< in/out: buffer where the info is returned */ -#ifndef DBUG_OFF -#include -extern void dbug_mariabackup_event(const char *event, - const fil_space_t::name_type key); +const char *convert_dst(const char *dst); -#define DBUG_MARIABACKUP_EVENT(A, B) \ - DBUG_EXECUTE_IF("mariabackup_events", dbug_mariabackup_event(A, B);) -#else -#define DBUG_MARIABACKUP_EVENT(A, B) /* empty */ -#endif // DBUG_OFF +std::string get_table_version_from_image(const std::vector &frm_image); +std::pair + get_table_engine_from_image(const std::vector &frm_image); +std::string read_table_version_id(File file); +std::string convert_tablename_to_filepath( + const char *data_dir_path, const std::string &db, const std::string &table); + +std::tuple +convert_filepath_to_tablename(const char *filepath); + +typedef std::string table_key_t; + +inline table_key_t table_key(const std::string &db, const std::string &table) { + return std::string(db).append(".").append(table); +}; + +inline table_key_t table_key(const char *db, const char *table) { + return std::string(db).append(".").append(table); +}; + +typedef std::function + post_copy_table_hook_t; + +my_bool +check_if_skip_table( +/******************/ + const char* name); /*!< in: path to the table */ + +bool is_log_table(const char *dbname, const char *tablename); +bool is_stats_table(const char *dbname, const char *tablename); + +extern my_bool xtrabackup_copy_back; +extern my_bool xtrabackup_move_back; #endif /* XB_XTRABACKUP_H */ diff --git a/extra/wolfssl/CMakeLists.txt b/extra/wolfssl/CMakeLists.txt index 271e76b8c45..e3f8da21f76 100644 --- a/extra/wolfssl/CMakeLists.txt +++ b/extra/wolfssl/CMakeLists.txt @@ -1,86 +1,57 @@ IF(MSVC_INTEL) PROJECT(wolfssl C ASM_MASM) ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64") - PROJECT(wolfssl C ASM) + PROJECT(wolfssl C ASM) ELSE() PROJECT(wolfssl C) ENDIF() IF(CMAKE_SIZEOF_VOID_P MATCHES 8) -IF(MSVC_INTEL) +IF(MSVC_INTEL AND NOT (CMAKE_C_COMPILER_ID MATCHES Clang)) SET(WOLFSSL_INTELASM ON) - SET(WOLFSSL_X86_64_BUILD 1) SET(HAVE_INTEL_RDSEED 1) SET(HAVE_INTEL_RDRAND 1) -ELSEIF(CMAKE_ASM_COMPILER_ID MATCHES "Clang" AND CMAKE_VERSION VERSION_LESS 3.16) - - # WolfSSL 5.5.4 bug workaround below does not work, due to some CMake bug ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64") - SET(WOLFSSL_X86_64_BUILD 1) IF(CMAKE_C_COMPILER_ID MATCHES GNU AND CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9) MESSAGE_ONCE(NO_INTEL_ASSEMBLY "Disable Intel assembly for WolfSSL - compiler is too old") + ELSEIF(WITH_MSAN) + MESSAGE_ONCE(MSAN_CANT_HANDLE_IT "Disable Intel assembly for WolfSSL - MSAN can't handle it") ELSE() - IF(WITH_MSAN) - MESSAGE_ONCE(MSAN_CANT_HANDLE_IT - "Disable Intel assembly for WolfSSL - MSAN can't handle it") - ELSE() - MY_CHECK_C_COMPILER_FLAG(-maes) - MY_CHECK_C_COMPILER_FLAG(-msse4) - MY_CHECK_C_COMPILER_FLAG(-mpclmul) - IF(have_C__maes AND have_C__msse4 AND have_C__mpclmul) - SET(WOLFSSL_INTELASM ON) + MY_CHECK_C_COMPILER_FLAG(-maes) + MY_CHECK_C_COMPILER_FLAG(-msse4) + MY_CHECK_C_COMPILER_FLAG(-mpclmul) + IF(have_C__maes AND have_C__msse4 AND have_C__mpclmul) + SET(WOLFSSL_INTELASM ON) + MY_CHECK_C_COMPILER_FLAG(-mrdrnd) + MY_CHECK_C_COMPILER_FLAG(-mrdseed) + IF(have_C__mrdrnd) + SET(HAVE_INTEL_RDRAND ON) + ENDIF() + IF(have_C__mrdseed) + SET(HAVE_INTEL_RDSEED ON) ENDIF() - ENDIF() - MY_CHECK_C_COMPILER_FLAG(-mrdrnd) - MY_CHECK_C_COMPILER_FLAG(-mrdseed) - IF(have_C__mrdrnd) - SET(HAVE_INTEL_RDRAND ON) - ENDIF() - IF(have_C__mrdseed) - SET(HAVE_INTEL_RDSEED ON) ENDIF() ENDIF() ENDIF() ENDIF() SET(WOLFSSL_SRCDIR ${CMAKE_CURRENT_SOURCE_DIR}/wolfssl/src) -ADD_DEFINITIONS(${SSL_DEFINES}) - -SET(WOLFSSL_SOURCES - ${WOLFSSL_SRCDIR}/crl.c - ${WOLFSSL_SRCDIR}/internal.c - ${WOLFSSL_SRCDIR}/keys.c - ${WOLFSSL_SRCDIR}/tls.c - ${WOLFSSL_SRCDIR}/wolfio.c - ${WOLFSSL_SRCDIR}/ocsp.c - ${WOLFSSL_SRCDIR}/ssl.c - ${WOLFSSL_SRCDIR}/tls13.c) - -ADD_DEFINITIONS(-DWOLFSSL_LIB -DBUILDING_WOLFSSL) - -INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/wolfssl) -IF(MSVC) - # size_t to long truncation warning - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -wd4267 -wd4334 -wd4028 -wd4244") -ENDIF() - -ADD_CONVENIENCE_LIBRARY(wolfssl ${WOLFSSL_SOURCES}) - -# Workaround linker crash with older Ubuntu binutils -# e.g aborting at ../../bfd/merge.c line 873 in _bfd_merged_section_offset -IF(CMAKE_SYSTEM_NAME MATCHES "Linux") - STRING(REPLACE "-g " "-g1 " CMAKE_C_FLAGS_RELWITHDEBINFO - ${CMAKE_C_FLAGS_RELWITHDEBINFO}) - STRING(REPLACE "-g " "-g1 " CMAKE_C_FLAGS_DEBUG - ${CMAKE_C_FLAGS_DEBUG}) - STRING(REPLACE "-ggdb3 " " " CMAKE_C_FLAGS_RELWITHDEBINFO - ${CMAKE_C_FLAGS_RELWITHDEBINFO}) - STRING(REPLACE "-ggdb3 " " " CMAKE_C_FLAGS_DEBUG - ${CMAKE_C_FLAGS_DEBUG}) -ENDIF() - SET(WOLFCRYPT_SRCDIR ${CMAKE_CURRENT_SOURCE_DIR}/wolfssl/wolfcrypt/src) -SET(WOLFCRYPT_SOURCES +ADD_DEFINITIONS(${SSL_DEFINES}) +ADD_DEFINITIONS(-DWOLFSSL_LIB -DBUILDING_WOLFSSL) +ADD_DEFINITIONS(-DWOLFSSL_SP_4096) +INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/wolfssl) +INCLUDE_DIRECTORIES(${SSL_INCLUDE_DIRS}) + +add_library(wolfssl STATIC +${WOLFSSL_SRCDIR}/crl.c +${WOLFSSL_SRCDIR}/internal.c +${WOLFSSL_SRCDIR}/keys.c +${WOLFSSL_SRCDIR}/tls.c +${WOLFSSL_SRCDIR}/wolfio.c +${WOLFSSL_SRCDIR}/ocsp.c +${WOLFSSL_SRCDIR}/ssl.c +${WOLFSSL_SRCDIR}/tls13.c ${WOLFCRYPT_SRCDIR}/aes.c ${WOLFCRYPT_SRCDIR}/arc4.c ${WOLFCRYPT_SRCDIR}/asn.c @@ -110,69 +81,56 @@ ${WOLFCRYPT_SRCDIR}/wc_encrypt.c ${WOLFCRYPT_SRCDIR}/hash.c ${WOLFCRYPT_SRCDIR}/wolfmath.c ${WOLFCRYPT_SRCDIR}/kdf.c +${WOLFCRYPT_SRCDIR}/sp_int.c +${WOLFCRYPT_SRCDIR}/sp_c32.c +${WOLFCRYPT_SRCDIR}/sp_c64.c ) -# Use fastmath large number math library. -IF(NOT (MSVC AND CMAKE_C_COMPILER_ID MATCHES Clang)) - # Can't use clang-cl with WOLFSSL_FASTMATH - # due to https://bugs.llvm.org/show_bug.cgi?id=25305 - SET(WOLFSSL_FASTMATH 1) -ENDIF() - -IF(WOLFSSL_FASTMATH) - SET(USE_FAST_MATH 1) - SET(TFM_TIMING_RESISTANT 1) - # FP_MAX_BITS is set high solely to satisfy ssl_8k_key.test - # WolfSSL will use more stack space with it - SET(FP_MAX_BITS 16384) - SET(WOLFCRYPT_SOURCES ${WOLFCRYPT_SOURCES} ${WOLFCRYPT_SRCDIR}/tfm.c) - IF((CMAKE_SIZEOF_VOID_P MATCHES 4) AND (CMAKE_SYSTEM_PROCESSOR MATCHES "86") - AND (NOT MSVC)) - # Workaround https://github.com/wolfSSL/wolfssl/issues/4245 - # On 32bit Intel, to satisfy inline assembly's wish for free registers - # 1. use -fomit-frame-pointer - # 2. With GCC 4, additionally use -fno-PIC, which works on x86 - # (modern GCC has PIC optimizations, that make it unnecessary) - # The following assumes GCC or Clang - SET(TFM_COMPILE_FLAGS "-fomit-frame-pointer") - IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "5") - SET(TFM_COMPILE_FLAGS "${TFM_COMPILE_FLAGS} -fno-PIC") - ENDIF() - SET_SOURCE_FILES_PROPERTIES(${WOLFCRYPT_SRCDIR}/tfm.c - PROPERTIES COMPILE_FLAGS ${TFM_COMPILE_FLAGS}) - ENDIF() -ELSE() - SET(WOLFSSL_SP_MATH_ALL 1) - SET(WOLFCRYPT_SOURCES ${WOLFCRYPT_SOURCES} ${WOLFCRYPT_SRCDIR}/sp_int.c) -ENDIF() - -IF(WOLFSSL_X86_64_BUILD) - LIST(APPEND WOLFCRYPT_SOURCES ${WOLFCRYPT_SRCDIR}/cpuid.c) - IF(MSVC) - SET(WOLFSSL_AESNI 1) - LIST(APPEND WOLFCRYPT_SOURCES - ${WOLFCRYPT_SRCDIR}/aes_asm.asm - ${WOLFCRYPT_SRCDIR}/aes_gcm_asm.asm) - IF(CMAKE_C_COMPILER_ID MATCHES Clang) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -msse4.2 -mpclmul -mrdrnd -mrdseed") - ENDIF() - ELSEIF(WOLFSSL_INTELASM) - SET(WOLFSSL_AESNI 1) - SET(USE_INTEL_SPEEDUP 1) - LIST(APPEND WOLFCRYPT_SOURCES +# Optimizations, assembly +if(WOLFSSL_INTELASM) + set(WOLFSSL_X86_64_BUILD 1) + set(WOLFSSL_SP_X86_64 1) + set(WOLFSSL_SP_X86_64_ASM 1) + set(WOLFSSL_AESNI 1) + target_sources(wolfssl PRIVATE + ${WOLFCRYPT_SRCDIR}/cpuid.c + ${WOLFCRYPT_SRCDIR}/sp_x86_64.c + ) + if(MSVC_INTEL) + target_sources(wolfssl PRIVATE + ${WOLFCRYPT_SRCDIR}/aes_asm.asm + ${WOLFCRYPT_SRCDIR}/aes_gcm_asm.asm + ${WOLFCRYPT_SRCDIR}/sp_x86_64_asm.asm + ) + target_compile_options(wolfssl PRIVATE + $<$:-maes -msse4.2 -mpclmul -mrdrnd -mrdseed> + $<$:/Zi> + ) + else() + set(USE_INTEL_SPEEDUP 1) + target_sources(wolfssl PRIVATE ${WOLFCRYPT_SRCDIR}/aes_asm.S ${WOLFCRYPT_SRCDIR}/aes_gcm_asm.S ${WOLFCRYPT_SRCDIR}/chacha_asm.S ${WOLFCRYPT_SRCDIR}/poly1305_asm.S ${WOLFCRYPT_SRCDIR}/sha512_asm.S - ${WOLFCRYPT_SRCDIR}/sha256_asm.S) - ADD_DEFINITIONS(-maes -msse4.2 -mpclmul) - # WolfSSL 5.5.4 bug - user_settings.h not included into aes_asm.S - SET_PROPERTY(SOURCE ${WOLFCRYPT_SRCDIR}/aes_asm.S APPEND PROPERTY COMPILE_OPTIONS "-DWOLFSSL_X86_64_BUILD") - ENDIF() -ENDIF() + ${WOLFCRYPT_SRCDIR}/sha256_asm.S + ${WOLFCRYPT_SRCDIR}/sp_x86_64_asm.S + ) + target_compile_options(wolfssl PRIVATE -maes -msse4.2 -mpclmul) + # Workaround 5.5.4 bug (user_settings.h not included into aes_asm.S) + set_property(SOURCE ${WOLFCRYPT_SRCDIR}/aes_asm.S APPEND PROPERTY COMPILE_OPTIONS "-DWOLFSSL_X86_64_BUILD") + endif() +endif() + +# Silence some warnings +if(MSVC) + # truncation warnings + target_compile_options(wolfssl PRIVATE $<$:/wd4244>) + if(CMAKE_C_COMPILER_ID MATCHES Clang) + target_compile_options(wolfssl PRIVATE $<$:-Wno-incompatible-function-pointer-types>) + endif() +endif() CONFIGURE_FILE(user_settings.h.in user_settings.h) -INCLUDE_DIRECTORIES(${SSL_INCLUDE_DIRS}) -ADD_CONVENIENCE_LIBRARY(wolfcrypt ${WOLFCRYPT_SOURCES}) diff --git a/extra/wolfssl/user_settings.h.in b/extra/wolfssl/user_settings.h.in index 8f37b3be0a9..62f8c5f700e 100644 --- a/extra/wolfssl/user_settings.h.in +++ b/extra/wolfssl/user_settings.h.in @@ -21,6 +21,7 @@ #define HAVE_AESGCM #define HAVE_CHACHA #define HAVE_POLY1305 +#define HAVE_THREAD_LS #define WOLFSSL_AES_COUNTER #define NO_WOLFSSL_STUB #define OPENSSL_ALL @@ -53,20 +54,19 @@ #define NO_RABBIT #define NO_RC4 -/* - FP_MAX_BITS is set high solely to satisfy ssl_8k_key.test - WolfSSL will use more stack space with it, with fastmath -*/ -#cmakedefine FP_MAX_BITS 16384 #define RSA_MAX_SIZE 8192 +#define WOLFSSL_SP_MATH_ALL +#define WOLFSSL_HAVE_SP_RSA +#ifndef WOLFSSL_SP_4096 +#define WOLFSSL_SP_4096 +#endif + #cmakedefine WOLFSSL_AESNI -#cmakedefine USE_FAST_MATH -#cmakedefine TFM_TIMING_RESISTANT #cmakedefine HAVE_INTEL_RDSEED #cmakedefine HAVE_INTEL_RDRAND #cmakedefine USE_INTEL_SPEEDUP -#cmakedefine USE_FAST_MATH #cmakedefine WOLFSSL_X86_64_BUILD -#cmakedefine WOLFSSL_SP_MATH_ALL +#cmakedefine WOLFSSL_SP_X86_64 +#cmakedefine WOLFSSL_SP_X86_64_ASM #endif /* WOLFSSL_USER_SETTINGS_H */ diff --git a/extra/wolfssl/wolfssl b/extra/wolfssl/wolfssl index 66596ad9e1d..8970ff4c340 160000 --- a/extra/wolfssl/wolfssl +++ b/extra/wolfssl/wolfssl @@ -1 +1 @@ -Subproject commit 66596ad9e1d7efa8479656872cf09c9c1870a02e +Subproject commit 8970ff4c34034dbb3594943d11f8c9d4c5512bd5 diff --git a/include/my_attribute.h b/include/my_attribute.h index c8e980702b6..25d21d5e787 100644 --- a/include/my_attribute.h +++ b/include/my_attribute.h @@ -70,5 +70,19 @@ # endif /* GNUC >= 3.1 */ #endif +/* Define pragmas to disable warnings for stack frame checking */ +#if defined(__clang__) +#define PRAGMA_DISABLE_CHECK_STACK_FRAME \ +_Pragma("clang diagnostic push") \ +_Pragma("clang diagnostic ignored \"-Wframe-larger-than=\"") + +#define PRAGMA_REENABLE_CHECK_STACK_FRAME \ +_Pragma("clang diagnostic pop") + +#else +#define PRAGMA_DISABLE_CHECK_STACK_FRAME +#define PRAGMA_REENABLE_CHECK_STACK_FRAME #endif + +#endif /* _my_attribute_h */ diff --git a/include/my_base.h b/include/my_base.h index a8014f819b4..b214ad045f3 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -49,6 +49,7 @@ #define HA_OPEN_MERGE_TABLE 2048U #define HA_OPEN_FOR_CREATE 4096U #define HA_OPEN_FOR_DROP (1U << 13) /* Open part of drop */ +#define HA_OPEN_GLOBAL_TMP_TABLE (1U << 14) /* TMP table used by repliction */ /* Allow opening even if table is incompatible as this is for ALTER TABLE which @@ -377,6 +378,12 @@ enum ha_base_keytype { #define HA_CREATE_INTERNAL_TABLE 256U #define HA_PRESERVE_INSERT_ORDER 512U #define HA_CREATE_NO_ROLLBACK 1024U +/* + A temporary table that can be used by different threads, eg. replication + threads. This flag ensure that memory is not allocated with THREAD_SPECIFIC, + as we do for other temporary tables. +*/ +#define HA_CREATE_GLOBAL_TMP_TABLE 2048U /* Flags used by start_bulk_insert */ diff --git a/include/my_bitmap.h b/include/my_bitmap.h index f88a6fe8d9d..d54670653f3 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -22,14 +22,15 @@ #include #include -typedef uint32 my_bitmap_map; +typedef ulonglong my_bitmap_map; typedef struct st_bitmap { my_bitmap_map *bitmap; my_bitmap_map *last_word_ptr; - my_bitmap_map last_word_mask; + my_bitmap_map last_bit_mask; uint32 n_bits; /* number of bits occupied by the above */ + my_bool bitmap_allocated; } MY_BITMAP; #ifdef __cplusplus @@ -39,7 +40,7 @@ extern "C" { /* Reset memory. Faster then doing a full bzero */ #define my_bitmap_clear(A) ((A)->bitmap= 0) -extern void create_last_word_mask(MY_BITMAP *map); +extern void create_last_bit_mask(MY_BITMAP *map); extern my_bool my_bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits); extern my_bool bitmap_is_clear_all(const MY_BITMAP *map); extern my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size); @@ -53,12 +54,12 @@ extern my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit); extern my_bool bitmap_fast_test_and_clear(MY_BITMAP *map, uint bitmap_bit); extern my_bool bitmap_union_is_set_all(const MY_BITMAP *map1, const MY_BITMAP *map2); -extern my_bool bitmap_exists_intersection(const MY_BITMAP **bitmap_array, +extern my_bool bitmap_exists_intersection(MY_BITMAP **bitmap_array, uint bitmap_count, uint start_bit, uint end_bit); extern uint bitmap_set_next(MY_BITMAP *map); -extern uint bitmap_get_first(const MY_BITMAP *map); +extern uint bitmap_get_first_clear(const MY_BITMAP *map); extern uint bitmap_get_first_set(const MY_BITMAP *map); extern uint bitmap_bits_set(const MY_BITMAP *map); extern uint bitmap_get_next_set(const MY_BITMAP *map, uint bitmap_bit); @@ -71,54 +72,70 @@ extern void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2); extern void bitmap_xor(MY_BITMAP *map, const MY_BITMAP *map2); extern void bitmap_invert(MY_BITMAP *map); extern void bitmap_copy(MY_BITMAP *map, const MY_BITMAP *map2); +/* Functions to export/import bitmaps to an architecture independent format */ +extern void bitmap_export(uchar *to, MY_BITMAP *map); +extern void bitmap_import(MY_BITMAP *map, uchar *from); + +#define my_bitmap_map_bytes sizeof(my_bitmap_map) +#define my_bitmap_map_bits (my_bitmap_map_bytes*8) +/* Size in bytes to store 'bits' number of bits */ +#define bitmap_buffer_size(bits) (MY_ALIGN((bits), my_bitmap_map_bits)/8) +#define my_bitmap_buffer_size(map) bitmap_buffer_size((map)->n_bits) +#define no_bytes_in_export_map(map) (((map)->n_bits + 7)/8) +#define no_words_in_map(map) (((map)->n_bits + (my_bitmap_map_bits-1))/my_bitmap_map_bits) /* Fast, not thread safe, bitmap functions */ -#define bitmap_buffer_size(bits) (((bits)+31)/32)*4 -#define no_bytes_in_map(map) (((map)->n_bits + 7)/8) -#define no_words_in_map(map) (((map)->n_bits + 31)/32) -#define bytes_word_aligned(bytes) (4*((bytes + 3)/4)) -/* The following functions must be compatible with create_last_word_mask()! */ +/* The following functions must be compatible with create_last_bit_mask()! */ static inline void bitmap_set_bit(MY_BITMAP *map,uint bit) { - uchar *b= (uchar*) map->bitmap + bit / 8; DBUG_ASSERT(bit < map->n_bits); - *b= (uchar) (*b | 1U << (bit & 7)); + map->bitmap[bit/my_bitmap_map_bits]|= + (1ULL << (bit & (my_bitmap_map_bits-1))); } static inline void bitmap_flip_bit(MY_BITMAP *map,uint bit) { - uchar *b= (uchar*) map->bitmap + bit / 8; DBUG_ASSERT(bit < map->n_bits); - *b= (uchar) (*b ^ 1U << (bit & 7)); + map->bitmap[bit/my_bitmap_map_bits]^= + (1ULL << (bit & (my_bitmap_map_bits-1))); } static inline void bitmap_clear_bit(MY_BITMAP *map,uint bit) { - uchar *b= (uchar*) map->bitmap + bit / 8; DBUG_ASSERT(bit < map->n_bits); - *b= (uchar) (*b & ~(1U << (bit & 7))); + map->bitmap[bit/my_bitmap_map_bits]&= + ~(1ULL << (bit & (my_bitmap_map_bits-1))); } static inline uint bitmap_is_set(const MY_BITMAP *map,uint bit) { - const uchar *b= (const uchar*) map->bitmap + bit / 8; DBUG_ASSERT(bit < map->n_bits); - return !!(*b & (1U << (bit & 7))); + return (!!(map->bitmap[bit/my_bitmap_map_bits] & + (1ULL << (bit & (my_bitmap_map_bits-1))))); } +/* Return true if bitmaps are equal */ static inline my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2) { - if (memcmp(map1->bitmap, map2->bitmap, 4*(no_words_in_map(map1)-1)) != 0) - return FALSE; - return ((*map1->last_word_ptr | map1->last_word_mask) == - (*map2->last_word_ptr | map2->last_word_mask)); + DBUG_ASSERT(map1->n_bits == map2->n_bits); + return (memcmp(map1->bitmap, map2->bitmap, + my_bitmap_buffer_size(map1)) == 0); } #define bitmap_clear_all(MAP) \ - { memset((MAP)->bitmap, 0, 4*no_words_in_map((MAP))); } -#define bitmap_set_all(MAP) \ - (memset((MAP)->bitmap, 0xFF, 4*no_words_in_map((MAP)))) + { memset((MAP)->bitmap, 0, my_bitmap_buffer_size(MAP)); } + +static inline void +bitmap_set_all(const MY_BITMAP *map) +{ + if (map->n_bits) + { + memset(map->bitmap, 0xFF, my_bitmap_map_bytes * (no_words_in_map(map)-1)); + DBUG_ASSERT(map->bitmap + no_words_in_map(map)-1 == map->last_word_ptr); + *map->last_word_ptr= ~map->last_bit_mask; + } +} #ifdef __cplusplus } diff --git a/include/my_global.h b/include/my_global.h index 952e65c9728..e6cbb933401 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -974,6 +974,7 @@ typedef struct st_mysql_lex_string LEX_STRING; #define SOCKET_ECONNRESET WSAECONNRESET #define SOCKET_ENFILE ENFILE #define SOCKET_EMFILE EMFILE +#define SOCKET_CLOSED EIO #else /* Unix */ #define socket_errno errno #define closesocket(A) close(A) @@ -983,6 +984,7 @@ typedef struct st_mysql_lex_string LEX_STRING; #define SOCKET_EADDRINUSE EADDRINUSE #define SOCKET_ETIMEDOUT ETIMEDOUT #define SOCKET_ECONNRESET ECONNRESET +#define SOCKET_CLOSED EIO #define SOCKET_ENFILE ENFILE #define SOCKET_EMFILE EMFILE #endif diff --git a/include/my_rdtsc.h b/include/my_rdtsc.h index 8b9b0046bc0..21e44847d9a 100644 --- a/include/my_rdtsc.h +++ b/include/my_rdtsc.h @@ -111,7 +111,7 @@ C_MODE_START On AARCH64, we use the generic timer base register. We override clang implementation for aarch64 as it access a PMU register which is not guaranteed to be active. - On RISC-V, we use the rdcycle instruction to read from mcycle register. + On RISC-V, we use the rdtime instruction to read from mtime register. Sadly, we have nothing for the Digital Alpha, MIPS, Motorola m68k, HP PA-RISC or other non-mainstream (or obsolete) processors. @@ -211,15 +211,15 @@ static inline ulonglong my_timer_cycles(void) } #elif defined(__riscv) #define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_RISCV - /* Use RDCYCLE (and RDCYCLEH on riscv32) */ + /* Use RDTIME (and RDTIMEH on riscv32) */ { # if __riscv_xlen == 32 ulong result_lo, result_hi0, result_hi1; /* Implemented in assembly because Clang insisted on branching. */ __asm __volatile__( - "rdcycleh %0\n" - "rdcycle %1\n" - "rdcycleh %2\n" + "rdtimeh %0\n" + "rdtime %1\n" + "rdtimeh %2\n" "sub %0, %0, %2\n" "seqz %0, %0\n" "sub %0, zero, %0\n" @@ -228,7 +228,7 @@ static inline ulonglong my_timer_cycles(void) return (static_cast(result_hi1) << 32) | result_lo; # else ulonglong result; - __asm __volatile__("rdcycle %0" : "=r"(result)); + __asm __volatile__("rdtime %0" : "=r"(result)); return result; } # endif diff --git a/include/my_sys.h b/include/my_sys.h index af509c7df45..f0ed1160f98 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -154,7 +154,7 @@ char *guess_malloc_library(); void sf_report_leaked_memory(my_thread_id id); int sf_sanity(); extern my_thread_id (*sf_malloc_dbug_id)(void); -#define SAFEMALLOC_REPORT_MEMORY(X) sf_report_leaked_memory(X) +#define SAFEMALLOC_REPORT_MEMORY(X) if (!sf_leaking_memory) sf_report_leaked_memory(X) #else #define SAFEMALLOC_REPORT_MEMORY(X) do {} while(0) #endif @@ -665,6 +665,7 @@ extern size_t my_fwrite(FILE *stream,const uchar *Buffer,size_t Count, myf MyFlags); extern my_off_t my_fseek(FILE *stream,my_off_t pos,int whence,myf MyFlags); extern my_off_t my_ftell(FILE *stream,myf MyFlags); +extern void (*my_sleep_for_space)(unsigned int seconds); /* implemented in my_memmem.c */ extern void *my_memmem(const void *haystack, size_t haystacklen, diff --git a/include/mysql/service_print_check_msg.h b/include/mysql/service_print_check_msg.h new file mode 100644 index 00000000000..c2c7cf0a381 --- /dev/null +++ b/include/mysql/service_print_check_msg.h @@ -0,0 +1,44 @@ +/* Copyright (c) 2019, MariaDB Corporation. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ + +#pragma once + +/** + @file include/mysql/service_print_check_msg.h + This service provides functions to write messages for check or repair +*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct print_check_msg_service_st { + void (*print_check_msg)(MYSQL_THD, const char *db_name, const char *table_name, + const char *op, const char *msg_type, const char *message, + my_bool print_to_log); +} *print_check_msg_service; + +#ifdef MYSQL_DYNAMIC_PLUGIN +# define print_check_msg_context(_THD) print_check_msg_service->print_check_msg +#else +extern void print_check_msg(MYSQL_THD, const char *db_name, const char *table_name, + const char *op, const char *msg_type, const char *message, + my_bool print_to_log); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/include/mysql_com.h b/include/mysql_com.h index 0d50981ecd5..a56c3f48bd4 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -457,6 +457,7 @@ typedef struct st_net { my_bool thread_specific_malloc; unsigned char compress; my_bool pkt_nr_can_be_reset; + my_bool using_proxy_protocol; /* Pointer to query object in query cache, do not equal NULL (0) for queries in cache that have not stored its results yet diff --git a/include/service_versions.h b/include/service_versions.h index 8c3f7fc6f15..5fcff1e6482 100644 --- a/include/service_versions.h +++ b/include/service_versions.h @@ -44,6 +44,7 @@ #define VERSION_wsrep 0x0500 #define VERSION_json 0x0100 #define VERSION_thd_mdl 0x0100 +#define VERSION_print_check_msg 0x0100 #define VERSION_sql_service 0x0102 #define VERSION_provider_bzip2 0x0100 diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h index 586440bad11..38bb89b6915 100644 --- a/include/sslopt-longopts.h +++ b/include/sslopt-longopts.h @@ -19,13 +19,12 @@ #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) - {"ssl", OPT_SSL_SSL, + {"ssl", 0, "Enable SSL for connection (automatically enabled with other flags).", &opt_use_ssl, &opt_use_ssl, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, {"ssl-ca", OPT_SSL_CA, "CA file in PEM format (check OpenSSL docs, implies --ssl).", - &opt_ssl_ca, &opt_ssl_ca, 0, GET_STR, REQUIRED_ARG, - 0, 0, 0, 0, 0, 0}, + &opt_ssl_ca, &opt_ssl_ca, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"ssl-capath", OPT_SSL_CAPATH, "CA directory (check OpenSSL docs, implies --ssl).", &opt_ssl_capath, &opt_ssl_capath, 0, GET_STR, REQUIRED_ARG, @@ -57,7 +56,7 @@ {"ssl-fplist", OPT_SSL_FPLIST, "File with accepted server certificate " "fingerprints, one per line (implies --ssl).", &opt_ssl_fplist, &opt_ssl_fplist, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"ssl-verify-server-cert", OPT_SSL_VERIFY_SERVER_CERT, + {"ssl-verify-server-cert", 0, "Verify server's certificate to prevent man-in-the-middle attacks", &opt_ssl_verify_server_cert, &opt_ssl_verify_server_cert, 0, GET_BOOL, OPT_ARG, 2, 0, 0, 0, 0, 0}, diff --git a/include/violite.h b/include/violite.h index b823e62b2e1..f1e5c95a648 100644 --- a/include/violite.h +++ b/include/violite.h @@ -41,6 +41,13 @@ enum enum_vio_type VIO_TYPE_SSL /* see also vio_type_names[] */ }; + +enum enum_vio_state +{ + VIO_STATE_NOT_INITIALIZED, VIO_STATE_ACTIVE, VIO_STATE_SHUTDOWN, + VIO_STATE_CLOSED +}; + #define FIRST_VIO_TYPE VIO_CLOSED #define LAST_VIO_TYPE VIO_TYPE_SSL @@ -244,6 +251,7 @@ struct st_vio struct sockaddr_storage local; /* Local internet address */ struct sockaddr_storage remote; /* Remote internet address */ enum enum_vio_type type; /* Type of connection */ + enum enum_vio_state state; /* State of the connection */ const char *desc; /* String description */ char *read_buffer; /* buffer for vio_read_buff */ char *read_pos; /* start of unfetched data in the diff --git a/libmariadb b/libmariadb index 1e2968ade73..d9a50aceac6 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 1e2968ade732d320e074e89c3e9d39a4a57cd70c +Subproject commit d9a50aceac6496215f8fdadc07658d923bb41afd diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index c981e96f771..12bcc7ce1aa 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -25,7 +25,7 @@ ${CMAKE_SOURCE_DIR}/tpool ${CMAKE_BINARY_DIR}/sql ${PCRE_INCLUDE_DIRS} ${LIBFMT_INCLUDE_DIR} -${ZLIB_INCLUDE_DIR} +${ZLIB_INCLUDE_DIRS} ${SSL_INCLUDE_DIRS} ${SSL_INTERNAL_INCLUDE_DIRS} ) @@ -185,7 +185,7 @@ ENDIF() SET(LIBS dbug strings mysys mysys_ssl pcre2-8 vio - ${ZLIB_LIBRARY} ${SSL_LIBRARIES} + ${ZLIB_LIBRARIES} ${SSL_LIBRARIES} ${LIBWRAP} ${LIBCRYPT} ${CMAKE_DL_LIBS} ${EMBEDDED_PLUGIN_LIBS} sql_embedded diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h index 2262706217e..345c3ebd2d5 100644 --- a/libmysqld/embedded_priv.h +++ b/libmysqld/embedded_priv.h @@ -23,6 +23,8 @@ void init_embedded_mysql(MYSQL *mysql, ulong client_flag); void *create_embedded_thd(ulong client_flag); int check_embedded_connection(MYSQL *mysql, const char *db); void free_old_query(MYSQL *mysql); +THD *embedded_get_current_thd(); +void embedded_set_current_thd(THD *thd); extern MYSQL_METHODS embedded_methods; /* This one is used by embedded library to gather returning data */ diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 0be844fbd20..cf958c4e9a0 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -111,7 +111,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, MYSQL_STMT *stmt) { my_bool result= 1; - THD *thd=(THD *) mysql->thd; + THD *thd=(THD *) mysql->thd, *old_current_thd= current_thd; NET *net= &mysql->net; my_bool stmt_skip= stmt ? stmt->state != MYSQL_STMT_INIT_DONE : FALSE; @@ -122,6 +122,8 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, else { free_embedded_thd(mysql); + if (old_current_thd == thd) + old_current_thd= 0; thd= 0; } } @@ -179,6 +181,8 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, end: thd->reset_globals(); + if (old_current_thd) + old_current_thd->store_globals(); return result; } @@ -265,6 +269,7 @@ static my_bool emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) mysql->server_status|= SERVER_STATUS_IN_TRANS; stmt->fields= mysql->fields; + free_root(&stmt->mem_root, MYF(0)); stmt->mem_root= res->alloc; mysql->fields= NULL; my_free(res); @@ -374,6 +379,7 @@ int emb_read_binary_rows(MYSQL_STMT *stmt) set_stmt_errmsg(stmt, &stmt->mysql->net); return 1; } + free_root(&stmt->result.alloc, MYF(0)); stmt->result= *data; my_free(data); set_stmt_errmsg(stmt, &stmt->mysql->net); @@ -432,12 +438,15 @@ int emb_unbuffered_fetch(MYSQL *mysql, char **row) static void free_embedded_thd(MYSQL *mysql) { - THD *thd= (THD*)mysql->thd; + THD *thd= (THD*)mysql->thd, *org_current_thd= current_thd; server_threads.erase(thd); thd->clear_data_list(); thd->store_globals(); delete thd; - set_current_thd(nullptr); + if (thd == org_current_thd) + set_current_thd(nullptr); + else + set_current_thd(org_current_thd); mysql->thd=0; } @@ -727,6 +736,17 @@ void *create_embedded_thd(ulong client_flag) } +THD *embedded_get_current_thd() +{ + return current_thd; +} + +void embedded_set_current_thd(THD *thd) +{ + set_current_thd(thd); +} + + #ifdef NO_EMBEDDED_ACCESS_CHECKS static void emb_transfer_connect_attrs(MYSQL *mysql) diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index 14cca6e073f..444c1cfbca3 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -78,7 +78,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, uint port, const char *unix_socket,ulong client_flag) { char name_buff[USERNAME_LENGTH]; - + THD *org_current_thd= embedded_get_current_thd(); DBUG_ENTER("mysql_real_connect"); DBUG_PRINT("enter",("host: %s db: %s user: %s (libmysqld)", host ? host : "(Null)", @@ -200,6 +200,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, } } } + embedded_set_current_thd(org_current_thd); DBUG_PRINT("exit",("Mysql handler: %p", mysql)); DBUG_RETURN(mysql); @@ -216,6 +217,7 @@ error: mysql_close(mysql); mysql->free_me=free_me; } + embedded_set_current_thd(org_current_thd); DBUG_RETURN(0); } diff --git a/libservices/CMakeLists.txt b/libservices/CMakeLists.txt index 8c559cb07f5..37c24646791 100644 --- a/libservices/CMakeLists.txt +++ b/libservices/CMakeLists.txt @@ -25,6 +25,7 @@ SET(MYSQLSERVICES_SOURCES my_crypt_service.c my_md5_service.c my_print_error_service.c + print_check_msg_service.c my_sha1_service.c my_sha2_service.c my_snprintf_service.c diff --git a/libservices/print_check_msg_service.c b/libservices/print_check_msg_service.c new file mode 100644 index 00000000000..12f7bc51118 --- /dev/null +++ b/libservices/print_check_msg_service.c @@ -0,0 +1,18 @@ +/* Copyright (c) 2024, MariaDB Plc + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +SERVICE_VERSION print_check_msg_context= (void*) VERSION_print_check_msg; diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index ae308a00392..4c71ccbf048 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -25,7 +25,7 @@ IF(NOT WITHOUT_SERVER) INSTALL_MANPAGES(Server wsrep_sst_rsync.1 wsrep_sst_common.1 wsrep_sst_mariabackup.1 wsrep_sst_mysqldump.1 wsrep_sst_rsync_wan.1 galera_recovery.1 - galera_new_cluster.1) + galera_new_cluster.1 wsrep_sst_backup.1) ENDIF() ENDIF() INSTALL_MANPAGES(Client diff --git a/man/my_print_defaults.1 b/man/my_print_defaults.1 index d519d89ea67..38f2c0a8fe1 100644 --- a/man/my_print_defaults.1 +++ b/man/my_print_defaults.1 @@ -1,6 +1,6 @@ '\" t .\" -.TH "\fBMY_PRINT_DEFAULTS\fR" "1" "15 May 2020" "MariaDB 10.11" "MariaDB Database System" +.TH "\fBMY_PRINT_DEFAULTS\fR" "1" "18 December 2023" "MariaDB 10.11" "MariaDB Database System" .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -146,6 +146,22 @@ In addition to the groups named on the command line, read groups that have the g .sp -1 .IP \(bu 2.3 .\} +.\" my_print_defaults: --mariadbd option +.\" mariadbd option: my_print_defaults +\fB\-\-mariadbd\fR +.sp +Read the same set of groups that the mariadbd binary does. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} + .\" my_print_defaults: --mysqld option .\" mysqld option: my_print_defaults \fB\-\-mysqld\fR diff --git a/man/wsrep_sst_backup.1 b/man/wsrep_sst_backup.1 new file mode 100644 index 00000000000..d7b145575cc --- /dev/null +++ b/man/wsrep_sst_backup.1 @@ -0,0 +1,16 @@ +'\" t +.\" +.TH "\FBWSREP_SST_BACKUP\FR" "1" "22 May 2022" "MariaDB 10\&.3" "MariaDB Database System" +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH NAME +wsrep_sst_backup \- backup helper script for the MariaDB Galera Cluster +.SH DESCRIPTION +Use: See source code of script\. +.PP +For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ diff --git a/mysql-test/collections/buildbot_suites.bat b/mysql-test/collections/buildbot_suites.bat index 0198b036149..86a2c08f17f 100644 --- a/mysql-test/collections/buildbot_suites.bat +++ b/mysql-test/collections/buildbot_suites.bat @@ -1,5 +1,5 @@ if "%MTR_PARALLEL%"=="" set MTR_PARALLEL=%NUMBER_OF_PROCESSORS% -perl mysql-test-run.pl --verbose-restart --force --suite-timeout=120 --max-test-fail=10 --retry=3 --suite=^ +perl mysql-test-run.pl --force --suite-timeout=120 --max-test-fail=10 --retry=3 --suite=^ vcol,gcol,period,perfschema,^ main,^ innodb,^ diff --git a/mysql-test/dgcov.pl b/mysql-test/dgcov.pl index db3ce429bac..152b2f32072 100755 --- a/mysql-test/dgcov.pl +++ b/mysql-test/dgcov.pl @@ -112,8 +112,7 @@ sub print_gcov_for_diff { $acc.=sprintf '%9s:%5s:%s', '', $lnum, $' if /^ /; ++$printme, $acc.=sprintf '%9s:%5s:%s', gcov_prefix($fcov->{$lnum}), $lnum, $' if /^\+/; die "$_^^^ dying", unless /^[- +]/; - ++$lnum; - --$cnt; + ++$lnum, --$cnt unless /^-/; } print $acc if $printme; close PIPE or die "command '$cmd' failed: $!: $?"; diff --git a/mysql-test/include/aria_log_control_load.inc b/mysql-test/include/aria_log_control_load.inc new file mode 100644 index 00000000000..34db3aeb4f5 --- /dev/null +++ b/mysql-test/include/aria_log_control_load.inc @@ -0,0 +1,11 @@ +# +# This file loads aria_log_control file into a user variable @aria_log_control. +# Set $ARIA_DATADIR before including this file +# + +--disable_query_log +--copy_file $ARIA_DATADIR/aria_log_control $MYSQLTEST_VARDIR/aria_log_control_tmp +--chmod 0777 $MYSQLTEST_VARDIR/aria_log_control_tmp +--eval SET @aria_log_control=(SELECT LOAD_FILE('$MYSQLTEST_VARDIR/aria_log_control_tmp')) +--remove_file $MYSQLTEST_VARDIR/aria_log_control_tmp +--enable_query_log diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test index eea0aca6e84..25990c1a9e3 100644 --- a/mysql-test/include/check-testcase.test +++ b/mysql-test/include/check-testcase.test @@ -32,7 +32,6 @@ if ($tmp) --echo Relay_Master_Log_File # --echo Slave_IO_Running No --echo Slave_SQL_Running No - --echo Replicate_Rewrite_DB # --echo Replicate_Do_DB # --echo Replicate_Ignore_DB # --echo Replicate_Do_Table # @@ -74,13 +73,22 @@ if ($tmp) --echo Slave_DDL_Groups # --echo Slave_Non_Transactional_Groups # --echo Slave_Transactional_Groups # + --echo Replicate_Rewrite_DB # } if (!$tmp) { # Note: after WL#5177, fields 13-18 shall not be filtered-out. - --replace_column 4 # 5 # 6 # 7 # 8 # 9 # 10 # 13 # 14 # 15 # 16 # 17 # 18 # 19 # 23 # 24 # 25 # 26 # 27 # 41 # 42 # 43 # 45 # 52 # 53 # 54 # + --replace_column 4 # 5 # 6 # 7 # 8 # 9 # 10 # 13 # 14 # 15 # 16 # 17 # 18 # 22 # 23 # 24 # 25 # 26 # 40 # 41 # 42 # 44 # 51 # 52 # 53 # 54 # query_vertical SHOW SLAVE STATUS; } +# +# Note, we must never, _ever_, add extra rows to this output of SHOW SLAVE +# STATUS, except at the very end, as this breaks backwards compatibility +# with applications or scripts that parse the output. This also means that +# we cannot add _any_ new rows in a GA version if a different row was +# already added in a later MariaDB version, as this would make it impossible +# to merge the change up while preserving the order of rows. +# # # Ensure that we don't get warnings from mysql.proc (used by check_mysqld) diff --git a/mysql-test/include/commit.inc b/mysql-test/include/commit.inc index c696613dab3..132fdcff7bd 100644 --- a/mysql-test/include/commit.inc +++ b/mysql-test/include/commit.inc @@ -613,13 +613,17 @@ call p_verify_status_increment(2, 0, 2, 0); drop table t2; set sql_mode=no_engine_substitution; create temporary table t2 (a int); -call p_verify_status_increment(1, 0, 0, 0); +# One commit for the create temporary table, and two for committing the +# read of the stored procedure from Aria table (creating temporary table +# clears the sp cache). +call p_verify_status_increment(3, 0, 2, 0); set sql_mode=default; --echo # 19. A function changes temp-trans-table. --echo # select f1(); ---echo # Two commits because a binary log record is written -call p_verify_status_increment(2, 0, 1, 0); +--echo # Two commits because a binary log record is written, and another two +--echo # as the function f1() is reloaded after creating temporary table. +call p_verify_status_increment(4, 0, 3, 0); commit; call p_verify_status_increment(2, 0, 1, 0); @@ -672,9 +676,11 @@ call p_verify_status_increment(2, 0, 1, 0); --echo # 25. DDL: DROP TEMPORARY TABLE, does not start a transaction --echo # drop temporary table t2; -call p_verify_status_increment(1, 0, 1, 0); +# Dropping temporary table clears SP caches, so get another two commit +# increments from loading the p_verify_status_increment procedure. +call p_verify_status_increment(3, 0, 2, 0); commit; -call p_verify_status_increment(1, 0, 1, 0); +call p_verify_status_increment(1, 0, 0, 0); --echo # 26. Verify that SET AUTOCOMMIT issues an implicit commit --echo # @@ -721,7 +727,9 @@ call p_verify_status_increment(1, 0, 1, 0); create table t2 (a int); call p_verify_status_increment(0, 0, 0, 0); do (select f1() from t1 where a=2); -call p_verify_status_increment(2, 2, 2, 2); +# Again extra 2 commit increments from re-loading function f1 after +# dropping temporary table. +call p_verify_status_increment(4, 2, 4, 2); commit; call p_verify_status_increment(2, 2, 2, 2); diff --git a/mysql-test/include/crash_mysqld.inc b/mysql-test/include/crash_mysqld.inc index 4190d24d801..89bc8ced416 100644 --- a/mysql-test/include/crash_mysqld.inc +++ b/mysql-test/include/crash_mysqld.inc @@ -4,7 +4,7 @@ --source include/not_embedded.inc # Write file to make mysql-test-run.pl expect crash and restart ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Setup the mysqld to crash at shutdown SET debug_dbug="d,crash_shutdown"; diff --git a/mysql-test/include/deadlock.inc b/mysql-test/include/deadlock.inc index abf217aea75..362d456e3f2 100644 --- a/mysql-test/include/deadlock.inc +++ b/mysql-test/include/deadlock.inc @@ -103,7 +103,6 @@ connection con2; # The following query should hang because con1 is locking the record update t2 set a=2 where b = 0; -select * from t2; --send update t1 set x=2 where id = 0; --sleep 2 diff --git a/mysql-test/include/default_mysqld.cnf b/mysql-test/include/default_mysqld.cnf index 89d0d779627..06a4ff15086 100644 --- a/mysql-test/include/default_mysqld.cnf +++ b/mysql-test/include/default_mysqld.cnf @@ -71,7 +71,7 @@ loose-performance-schema-hosts-size=100 loose-performance-schema-users-size=100 loose-performance-schema-max-mutex-instances=5000 loose-performance-schema-max-rwlock-instances=5000 -loose-performance-schema-max-cond-instances=1000 +loose-performance-schema-max-cond-instances=1500 loose-performance-schema-max-file-instances=10000 loose-performance-schema-max-socket-instances=1000 loose-performance-schema-max-table-instances=500 @@ -91,7 +91,7 @@ loose-performance-schema-events-statements-history-size=10 loose-performance-schema-events-statements-history-long-size=1000 loose-performance-schema-events-transactions-history-size=10 loose-performance-schema-events-transactions-history-long-size=1000 -loose-performance-schema-max-thread-instances=200 +loose-performance-schema-max-thread-instances=400 loose-performance-schema-session-connect-attrs-size=2048 loose-performance-schema-max-metadata-locks=10000 diff --git a/mysql-test/include/expect_crash.inc b/mysql-test/include/expect_crash.inc index b4bd9828a08..56abc88ae24 100644 --- a/mysql-test/include/expect_crash.inc +++ b/mysql-test/include/expect_crash.inc @@ -2,4 +2,4 @@ --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect # There should be a debug crash after using this .inc file ---exec echo "wait" > $_expect_file_name +--write_line wait $_expect_file_name diff --git a/mysql-test/include/galera_cluster.inc b/mysql-test/include/galera_cluster.inc index 48b5bc631db..12708bfcc5f 100644 --- a/mysql-test/include/galera_cluster.inc +++ b/mysql-test/include/galera_cluster.inc @@ -13,10 +13,8 @@ if (!$galera_cluster_size) } --source include/galera_init.inc ---source include/have_innodb.inc --source include/galera_wait_ready.inc - --let $_galera_node= $galera_cluster_size while ($_galera_node != 1) diff --git a/mysql-test/include/have_innodb.combinations b/mysql-test/include/have_innodb.combinations deleted file mode 100644 index f1131c448f3..00000000000 --- a/mysql-test/include/have_innodb.combinations +++ /dev/null @@ -1,39 +0,0 @@ -[innodb_plugin] -ignore-builtin-innodb -plugin-load-add=$HA_INNODB_SO -innodb -innodb-cmpmem -innodb-cmp-per-index -innodb-trx -innodb-locks -innodb-lock-waits -innodb-buffer-pool-stats -innodb-buffer-page -innodb-buffer-page-lru -innodb-sys-columns -innodb-sys-fields -innodb-sys-foreign -innodb-sys-foreign-cols -innodb-sys-indexes -innodb-sys-tables -innodb-sys-virtual -innodb-metrics - -[innodb] -innodb -innodb-cmpmem -innodb-cmp-per-index -innodb-trx -innodb-locks -innodb-lock-waits -innodb-metrics -innodb-buffer-pool-stats -innodb-buffer-page -innodb-buffer-page-lru -innodb-sys-columns -innodb-sys-fields -innodb-sys-foreign -innodb-sys-foreign-cols -innodb-sys-indexes -innodb-sys-tables -innodb-sys-virtual diff --git a/mysql-test/include/have_innodb.inc b/mysql-test/include/have_innodb.inc index 8c9cdb54363..1e853d186b1 100644 --- a/mysql-test/include/have_innodb.inc +++ b/mysql-test/include/have_innodb.inc @@ -3,6 +3,11 @@ # will be skipped unless innodb is enabled # --disable_query_log +if (`select version() like '%debug%'`) +{ +SET STATEMENT sql_log_bin=0 FOR +call mtr.add_suppression("InnoDB: Trying to delete tablespace.*pending operations"); +} if (`select count(*) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like 'MSAN%'`) { SET STATEMENT sql_log_bin=0 FOR diff --git a/mysql-test/include/have_innodb.opt b/mysql-test/include/have_innodb.opt new file mode 100644 index 00000000000..0a6d4d9c819 --- /dev/null +++ b/mysql-test/include/have_innodb.opt @@ -0,0 +1,17 @@ +--innodb +--innodb-cmpmem +--innodb-cmp-per-index +--innodb-trx +--innodb-locks +--innodb-lock-waits +--innodb-metrics +--innodb-buffer-pool-stats +--innodb-buffer-page +--innodb-buffer-page-lru +--innodb-sys-columns +--innodb-sys-fields +--innodb-sys-foreign +--innodb-sys-foreign-cols +--innodb-sys-indexes +--innodb-sys-tables +--innodb-sys-virtual diff --git a/mysql-test/include/have_wsrep_enabled.inc b/mysql-test/include/have_wsrep_enabled.inc index 7eb8b4372cf..33ff58b93ab 100644 --- a/mysql-test/include/have_wsrep_enabled.inc +++ b/mysql-test/include/have_wsrep_enabled.inc @@ -1,8 +1,6 @@ # To be used in a test which requires wsrep plugin to be ACTIVE and enabled # (i.e. wsrep_on=ON). It includes have_wsrep.inc. ---source include/have_innodb.inc - if (`SELECT COUNT(*)=0 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME = 'wsrep_on' AND VARIABLE_VALUE='ON'`) { --skip Test requires wsrep_on=ON diff --git a/mysql-test/include/innodb_rollback_on_timeout.inc b/mysql-test/include/innodb_rollback_on_timeout.inc index 274bbe12566..d41e1f1ec9f 100644 --- a/mysql-test/include/innodb_rollback_on_timeout.inc +++ b/mysql-test/include/innodb_rollback_on_timeout.inc @@ -1,4 +1,3 @@ ---source include/have_innodb.inc # # Bug #24200: Provide backwards compatibility mode for 4.x "rollback on # transaction timeout" @@ -22,7 +21,6 @@ select * from t1; connection con1; begin work; insert into t1 values (5); -select * from t1; # Lock wait timeout set to 2 seconds in -master.opt; this # statement will time out; in 5.0.13+, it will not roll back transaction. --error ER_LOCK_WAIT_TIMEOUT diff --git a/mysql-test/include/kill_and_restart_mysqld.inc b/mysql-test/include/kill_and_restart_mysqld.inc index b67fb7350b4..50b28bcd494 100644 --- a/mysql-test/include/kill_and_restart_mysqld.inc +++ b/mysql-test/include/kill_and_restart_mysqld.inc @@ -7,7 +7,7 @@ if (!$restart_parameters) --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect --echo # Kill and $restart_parameters ---exec echo "$restart_parameters" > $_expect_file_name +--write_line "$restart_parameters" $_expect_file_name --shutdown_server 0 --source include/wait_until_disconnected.inc --enable_reconnect diff --git a/mysql-test/include/kill_galera.inc b/mysql-test/include/kill_galera.inc index aba672d8a89..887e21f5f79 100644 --- a/mysql-test/include/kill_galera.inc +++ b/mysql-test/include/kill_galera.inc @@ -3,7 +3,7 @@ # Write file to make mysql-test-run.pl expect the crash, but don't start it --let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')` --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect ---exec echo "wait" > $_expect_file_name +--write_line wait $_expect_file_name # Kill the connected server --disable_reconnect diff --git a/mysql-test/include/kill_mysqld.inc b/mysql-test/include/kill_mysqld.inc index 01ee7f82bdc..a41af2d74a6 100644 --- a/mysql-test/include/kill_mysqld.inc +++ b/mysql-test/include/kill_mysqld.inc @@ -2,6 +2,6 @@ --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect --echo # Kill the server ---exec echo "wait" > $_expect_file_name +--write_line wait $_expect_file_name --shutdown_server 0 --source include/wait_until_disconnected.inc diff --git a/mysql-test/include/rpl_change_topology.inc b/mysql-test/include/rpl_change_topology.inc index eb8a6795615..299277a42df 100644 --- a/mysql-test/include/rpl_change_topology.inc +++ b/mysql-test/include/rpl_change_topology.inc @@ -96,10 +96,11 @@ # Remove whitespace from $rpl_topology --let $rpl_topology= `SELECT REPLACE('$rpl_topology', ' ', '')` +--source include/slow_environ.inc + --let $include_filename= rpl_change_topology.inc [new topology=$rpl_topology] --source include/begin_include_file.inc - if ($rpl_debug) { --echo ---- Check input ---- @@ -235,11 +236,11 @@ if (!$rpl_skip_change_master) } if ($rpl_master_log_file) { - eval CHANGE MASTER TO MASTER_HOST = '127.0.0.1', MASTER_PORT = $_rpl_port, MASTER_USER = 'root', MASTER_LOG_FILE = '$_rpl_master_log_file'$_rpl_master_log_pos, MASTER_CONNECT_RETRY = 1, MASTER_SSL_VERIFY_SERVER_CERT=0, MASTER_USE_GTID=NO; + eval CHANGE MASTER TO MASTER_HOST = '127.0.0.1', MASTER_PORT = $_rpl_port, MASTER_USER = 'root', MASTER_LOG_FILE = '$_rpl_master_log_file'$_rpl_master_log_pos, MASTER_CONNECT_RETRY = 1$_timeout_adjustmen, MASTER_SSL_VERIFY_SERVER_CERT=0, MASTER_USE_GTID=NO; } if (!$rpl_master_log_file) { - eval CHANGE MASTER TO MASTER_HOST = '127.0.0.1', MASTER_PORT = $_rpl_port, MASTER_USER = 'root', MASTER_CONNECT_RETRY=1, MASTER_SSL_VERIFY_SERVER_CERT=0; + eval CHANGE MASTER TO MASTER_HOST = '127.0.0.1', MASTER_PORT = $_rpl_port, MASTER_USER = 'root', MASTER_CONNECT_RETRY=1$_timeout_adjustment, MASTER_SSL_VERIFY_SERVER_CERT=0; } } if ($_rpl_master == '') diff --git a/mysql-test/include/rpl_clone_slave_using_mariadb-backup.inc b/mysql-test/include/rpl_clone_slave_using_mariadb-backup.inc new file mode 100644 index 00000000000..5961e3cc096 --- /dev/null +++ b/mysql-test/include/rpl_clone_slave_using_mariadb-backup.inc @@ -0,0 +1,298 @@ +if ($cnf == "galera2_to_mariadb") +{ + --let MASTER_MYPORT= $NODE_MYPORT_1 + --connect master, 127.0.0.1, root, , test, $NODE_MYPORT_1 + --connect slave, 127.0.0.1, root, , test, $NODE_MYPORT_3 + --disable_query_log + --replace_result $MASTER_MYPORT ### + --eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$MASTER_MYPORT, MASTER_USE_GTID=NO, MASTER_SSL_VERIFY_SERVER_CERT=0; + --enable_query_log + START SLAVE; + --source include/wait_for_slave_to_start.inc + + --let XTRABACKUP_BACKUP_OPTIONS=--no-defaults --user=root --host='127.0.0.1' --port=$NODE_MYPORT_3 --loose-disable-ssl-verify-server-cert --loose-ssl-cert=$MYSQL_TEST_DIR/std_data/server-cert.pem --loose-ssl-key=$MYSQL_TEST_DIR/std_data/server-key.pem --loose-ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem + + --let XTRABACKUP_COPY_BACK_OPTIONS=--no-defaults +} + +if ($cnf == "mariadb_to_mariadb") +{ + --let XTRABACKUP_BACKUP_OPTIONS=--defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group-suffix=.2 + --let XTRABACKUP_COPY_BACK_OPTIONS=--defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group-suffix=.2 +} + +--connection master +--let $MYSQLD_DATADIR_MASTER= `select @@datadir` +--connection slave +--let $MYSQLD_DATADIR_SLAVE= `select @@datadir` + +# This test covers the filename:pos based synchronization +# between the master and the slave. +# If we ever need to test a GTID based synchronization, +# it should be done in a separate test. + + +--echo ############################################################## +--echo ### Initial block with some transactions + +--echo ### Slave: Make sure replication is not using GTID +--connection slave +--let $value= query_get_value(SHOW SLAVE STATUS, "Using_Gtid", 1) +--echo # Using_Gtid=$value + +--echo ### Master: Create and populate t1 +--connection master +CREATE TABLE t1(a TEXT) ENGINE=InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#00:stmt#00 - slave run#0, before backup'); +INSERT INTO t1 VALUES ('tr#00:stmt#01 - slave run#0, before backup'); +INSERT INTO t1 VALUES ('tr#00:stmt#02 - slave run#0, before backup'); +COMMIT; +--sync_slave_with_master + + + +--echo ############################################################## +--echo ### Run the last transaction before mariadb-backup --backup +--echo ### Remember SHOW MASTER STATUS and @@gtid_binlog_pos +--echo ### before and after the transaction. + +--echo ### Master: Rember MASTER STATUS and @@gtid_binlog_pos before tr#01 +--connection master +--let $master_before_tr01_show_master_status_file=query_get_value(SHOW MASTER STATUS, File, 1) +--let $master_before_tr01_show_master_status_position=query_get_value(SHOW MASTER STATUS, Position, 1) +--let $master_before_tr01_gtid_binlog_pos=`SELECT @@global.gtid_binlog_pos` + +--echo ### Slave: Remember MASTER STATUS and @@gtid_binlog_pos before tr#01 +--connection slave +--let $slave_before_tr01_show_master_status_file=query_get_value(SHOW MASTER STATUS, File, 1) +--let $slave_before_tr01_show_master_status_position=query_get_value(SHOW MASTER STATUS, Position, 1) +--let $slave_before_tr01_gtid_binlog_pos=`SELECT @@global.gtid_binlog_pos` + +--echo ### Master: Run the actual last transaction before the backup +--connection master +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#01:stmt#00 - slave run#0, before backup'); +INSERT INTO t1 VALUES ('tr#01:stmt#01 - slave run#0, before backup'); +INSERT INTO t1 VALUES ('tr#01:stmt#02 - slave run#0, before backup'); +COMMIT; +--sync_slave_with_master + +--echo ### Master: Remember MASTER STATUS and @@gtid_binlog_pos after tr#01 +--connection master +--let $master_after_tr01_show_master_status_file=query_get_value(SHOW MASTER STATUS, File, 1) +--let $master_after_tr01_show_master_status_position=query_get_value(SHOW MASTER STATUS, Position, 1) +--let $master_after_tr01_gtid_binlog_pos=`SELECT @@global.gtid_binlog_pos` + +--echo ### Slave: Remember MASTER STATUS and @@gtid_binlog_pos after tr#01 +--connection slave +--let $slave_after_tr01_show_master_status_file=query_get_value(SHOW MASTER STATUS, File, 1) +--let $slave_after_tr01_show_master_status_position=query_get_value(SHOW MASTER STATUS, Position, 1) +--let $slave_after_tr01_gtid_binlog_pos=`SELECT @@global.gtid_binlog_pos` + + +--echo ############################################################## +--echo ### Running `mariadb-backup --backup,--prepare` and checking +--echo ### that mariadb_backup_slave_info and mariadb_backup_binlog_info are OK + +--echo ### Slave: Create a backup +--let $backup_slave=$MYSQLTEST_VARDIR/tmp/backup-slave +--disable_result_log +--exec $XTRABACKUP $XTRABACKUP_BACKUP_OPTIONS --slave-info --backup --target-dir=$backup_slave +--enable_result_log + +--echo ### Slave: Prepare the backup +--exec $XTRABACKUP --prepare --target-dir=$backup_slave + +--echo ### Slave: xtrabackup files: +--echo ############################ mariadb_backup_slave_info +--replace_result $master_after_tr01_show_master_status_file master_after_tr01_show_master_status_file $master_after_tr01_show_master_status_position master_after_tr01_show_master_status_position +--cat_file $backup_slave/mariadb_backup_slave_info +--echo ############################ mariadb_backup_binlog_info +--replace_result $slave_after_tr01_show_master_status_file slave_after_tr01_show_master_status_file $slave_after_tr01_show_master_status_position slave_after_tr01_show_master_status_position $slave_after_tr01_gtid_binlog_pos slave_after_tr01_gtid_binlog_pos +--cat_file $backup_slave/mariadb_backup_binlog_info +--echo ############################ + + +--echo ############################################################## +--echo ### Run more transactions after the backup: +--echo ### - while the slave is still running, then +--echo ### - while the slave is shut down + +--echo ### Master: Run another transaction while the slave is still running +--connection master +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup'); +INSERT INTO t1 VALUES ('tr#02:stmt#01 - slave run#0, after backup'); +INSERT INTO t1 VALUES ('tr#02:stmt@02 - slave run#0, after backup'); +COMMIT; +--sync_slave_with_master + +--echo ### Master: Remember MASTER STATUS and @@gtid_binlog_pos after tr#02 +--connection master +--let $master_after_tr02_show_master_status_file=query_get_value(SHOW MASTER STATUS, File, 1) +--let $master_after_tr02_show_master_status_position=query_get_value(SHOW MASTER STATUS, Position, 1) +--let $master_after_tr02_gtid_binlog_pos=`SELECT @@global.gtid_binlog_pos` + +--echo ### Slave: Remember MASTER STATUS and @@gtid_binlog_pos after tr#02 +--connection slave +--let $slave_after_tr02_show_master_status_file=query_get_value(SHOW MASTER STATUS, File, 1) +--let $slave_after_tr02_show_master_status_position=query_get_value(SHOW MASTER STATUS, Position, 1) +--let $slave_after_tr02_gtid_binlog_pos=`SELECT @@global.gtid_binlog_pos` + + +--echo ### Master: Checking SHOW BINLOG EVENTS + +--connection master +--vertical_results +### The BEGIN event +--replace_column 4 # 5 # +--replace_result $master_after_tr01_show_master_status_file master_after_tr01_show_master_status_file $master_after_tr01_show_master_status_position master_after_tr01_show_master_status_position $master_after_tr02_gtid_binlog_pos master_after_tr02_gtid_binlog_pos +--eval SHOW BINLOG EVENTS IN '$master_after_tr01_show_master_status_file' FROM $master_after_tr01_show_master_status_position LIMIT 0,1 +### The INSERT event +--replace_column 2 # 4 # 5 # +--replace_result $master_after_tr01_show_master_status_file master_after_tr01_show_master_status_file $master_after_tr01_show_master_status_position master_after_tr01_show_master_status_position +# Hide the difference between row and stmt binary logging +--replace_regex /use `test`; // /(Query|Annotate_rows)/Query_or_Annotate_rows/ +--eval SHOW BINLOG EVENTS IN '$master_after_tr01_show_master_status_file' FROM $master_after_tr01_show_master_status_position LIMIT 1,1 +--horizontal_results + +--echo ### Slave: Checking SHOW BINLOG EVENTS +--connection slave +--vertical_results +### The BEGIN event +--replace_column 2 # 5 # +--replace_result $slave_after_tr01_show_master_status_file slave_after_tr01_show_master_status_file $slave_after_tr01_show_master_status_position slave_after_tr01_show_master_status_position $slave_after_tr02_gtid_binlog_pos slave_after_tr02_gtid_binlog_pos +--eval SHOW BINLOG EVENTS IN '$slave_after_tr01_show_master_status_file' FROM $slave_after_tr01_show_master_status_position LIMIT 0,1 +### The INSERT event +--replace_column 2 # 4 # 5 # +--replace_result $slave_after_tr01_show_master_status_file slave_after_tr01_show_master_status_file $slave_after_tr01_show_master_status_position slave_after_tr01_show_master_status_position $slave_after_tr02_gtid_binlog_pos slave_after_tr02_gtid_binlog_pos +# Hide the difference between row and stmt binary logging +--replace_regex /use `test`; // /(Query|Annotate_rows)/Query_or_Annotate_rows/ +--eval SHOW BINLOG EVENTS IN '$slave_after_tr01_show_master_status_file' FROM $slave_after_tr01_show_master_status_position LIMIT 1,1 +--horizontal_results + +--echo ### Slave: Stop replication +--connection slave +STOP SLAVE; +--source include/wait_for_slave_to_stop.inc +RESET SLAVE; + +--echo ### Slave: Shutdown the server + +if ($cnf == "mariadb_to_mariadb") +{ + --let $rpl_server_number= 2 + --source include/rpl_stop_server.inc +} + +if ($cnf == "galera2_to_mariadb") +{ + --connection slave + --source $MYSQL_TEST_DIR/include/shutdown_mysqld.inc +} + +--echo ### Master: Run a transaction while the slave is shut down +--connection master +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#03:stmt#00 - after slave run#0, slave is shut down, after backup'); +INSERT INTO t1 VALUES ('tr#03:stmt#01 - after slave run#0, slave is shut down, after backup'); +INSERT INTO t1 VALUES ('tr#03:stmt#02 - after slave run#0, slave is shut down, after backup'); +COMMIT; + + +--echo ############################################################## +--echo ### Emulate starting a new virgin slave + +--echo ### Slave: Remove the data directory +--rmdir $MYSQLD_DATADIR_SLAVE + +--echo ### Slave: Copy back the backup +--exec $XTRABACKUP $XTRABACKUP_COPY_BACK_OPTIONS --copy-back --datadir=$MYSQLD_DATADIR_SLAVE --target-dir=$backup_slave + +--echo ### Slave: Restart the server +if ($cnf == "mariadb_to_mariadb") +{ + --let $rpl_server_number= 2 + --source include/rpl_start_server.inc + --source include/wait_until_connected_again.inc +} + +if ($cnf == "galera2_to_mariadb") +{ + --connection slave + --source $MYSQL_TEST_DIR/include/start_mysqld.inc +} + +--echo ### Slave: Display the restored data before START SLAVE +--connection slave +SELECT * FROM t1 ORDER BY a; + +--echo ### Slave: Execute the CHANGE MASTER statement to set up the host and port +--replace_result $MASTER_MYPORT ### +--eval CHANGE MASTER '' TO MASTER_USER='root', MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_CONNECT_RETRY=1, MASTER_SSL_VERIFY_SERVER_CERT=0 + +--echo ### Slave: Execute the CHANGE MASTER statement from mariadb_backup_slave_info +--replace_result $master_after_tr01_show_master_status_file master_after_tr01_show_master_status_file $master_after_tr01_show_master_status_position master_after_tr01_show_master_status_position +--source $backup_slave/mariadb_backup_slave_info + +--echo ### Slave: Execute START SLAVE +--source include/start_slave.inc + +--echo ### Master: Wait for the slave to apply all master events +--connection master +--sync_slave_with_master slave + +--echo ### Slave: Make sure replication is not using GTID after the slave restart +--connection slave +--let $value= query_get_value(SHOW SLAVE STATUS, "Using_Gtid", 1) +--echo # Using_Gtid=$value + +--echo ### Slave: Display the restored data after START SLAVE +--connection slave +SELECT * FROM t1 ORDER BY a; + + +--echo ############################################################## +--echo ### Continue master transactions, check the new slave replicates well. + +--echo ### Master: Run a transaction after restarting replication +--connection master +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#04:stmt#00 - slave run#1'); +INSERT INTO t1 VALUES ('tr#04:stmt#01 - slave run#1'); +INSERT INTO t1 VALUES ('tr#04:stmt#02 - slave run#1'); +COMMIT; +--sync_slave_with_master + +--echo ### Slave: Display the restored data + new transactions +--connection slave +SELECT * FROM t1 ORDER BY a; + + +--echo ############################################################## +--echo ### Cleanup + +--echo ### Removing the backup directory +--rmdir $backup_slave + +--connection master +DROP TABLE t1; +--sync_slave_with_master + +if ($cnf == "mariadb_to_mariadb") +{ + --source include/rpl_end.inc +} + +if ($cnf == "galera2_to_mariadb") +{ + STOP SLAVE; + --source include/wait_for_slave_to_stop.inc + RESET SLAVE ALL; + + --connection master + set global wsrep_on=OFF; + RESET MASTER; + set global wsrep_on=ON; +} diff --git a/mysql-test/include/rpl_start_server.inc b/mysql-test/include/rpl_start_server.inc index 932fc9da7ef..0479dbbd8ac 100644 --- a/mysql-test/include/rpl_start_server.inc +++ b/mysql-test/include/rpl_start_server.inc @@ -49,7 +49,7 @@ if ($rpl_server_parameters) --source include/rpl_connection.inc # Write file to make mysql-test-run.pl start up the server again ---exec echo "$_rpl_start_server_command" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect +--write_line "$_rpl_start_server_command" $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect if (!$rpl_server_error) { diff --git a/mysql-test/include/rpl_stop_server.inc b/mysql-test/include/rpl_stop_server.inc index 470e86a139d..1e4a64cca25 100644 --- a/mysql-test/include/rpl_stop_server.inc +++ b/mysql-test/include/rpl_stop_server.inc @@ -44,7 +44,7 @@ if ($rpl_debug) # Write file to make mysql-test-run.pl expect the "crash", but don't start # it until it's told to ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect # Send shutdown to the connected server and give # it 60 seconds (of mysqltest's default) to die before zapping it diff --git a/mysql-test/include/search_pattern_in_file.inc b/mysql-test/include/search_pattern_in_file.inc index 3105f7f9077..ab3c95fce3c 100644 --- a/mysql-test/include/search_pattern_in_file.inc +++ b/mysql-test/include/search_pattern_in_file.inc @@ -9,9 +9,6 @@ # # The environment variables SEARCH_FILE and SEARCH_PATTERN must be set # before sourcing this routine. -# SEARCH_TYPE can also be set to either NULL(default) or _gm_ -# NULL is equivalent of using m/SEARCH_PATTERN/gs -# _gm_ is equivalent of using m/SEARCH_RANGE/gm # # Optionally, SEARCH_RANGE can be set to the max number of bytes of the file # to search. If negative, it will search that many bytes at the end of the @@ -25,6 +22,7 @@ # Supported formats: # - (default) : "FOUND n /pattern/ in FILE " or "NOT FOUND ..." # - "matches" : Each match is printed, on a separate line +# - "count" : "FOUND n matches in FILE" or "NOT FOUND ..." (omit pattern) # # In case of # - SEARCH_FILE and/or SEARCH_PATTERN is not set @@ -38,7 +36,7 @@ # let SEARCH_FILE= $error_log; # # Stop the server # let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; -# --exec echo "wait" > $restart_file +# --write_line wait $restart_file # --shutdown_server # --source include/wait_until_disconnected.inc # @@ -51,15 +49,12 @@ # Created: 2011-11-11 mleich # ---error 0,1 perl; use strict; die "SEARCH_FILE not set" unless $ENV{SEARCH_FILE}; my @search_files= glob($ENV{SEARCH_FILE}); my $search_pattern= $ENV{SEARCH_PATTERN} or die "SEARCH_PATTERN not set"; my $search_range= $ENV{SEARCH_RANGE}; - my $silent= $ENV{SEARCH_SILENT}; - my $search_result= 0; my $content; foreach my $search_file (@search_files) { open(FILE, '<', $search_file) || die("Can't open file $search_file: $!"); @@ -83,48 +78,23 @@ perl; close(FILE); $content.= $file_content; } - my @matches; - if (not defined($ENV{SEARCH_TYPE})) - { - @matches=($content =~ /$search_pattern/gs); - } - elsif($ENV{SEARCH_TYPE} == "_gm_") - { - @matches=($content =~ /$search_pattern/gm); - } - my $res; - if (@matches) - { - $res="FOUND " . scalar(@matches); - $search_result= 1; - } - else - { - $res= "NOT FOUND"; - } + my @matches= ($content =~ /$search_pattern/gs); + my $res=@matches ? "FOUND " . scalar(@matches) : "NOT FOUND"; + $ENV{SEARCH_FILE} =~ s{^.*?([^/\\]+)$}{$1}; - if (!$silent || $search_result) - { - if ($ENV{SEARCH_OUTPUT} eq "matches") - { - foreach (@matches) - { - print $_ . "\n"; - } - } - else - { - print "$res /$search_pattern/ in $ENV{SEARCH_FILE}\n"; + if ($ENV{SEARCH_OUTPUT} eq "matches") { + foreach (@matches) { + print $_ . "\n"; } } - die "$ENV{SEARCH_ABORT}\n" - if $ENV{SEARCH_ABORT} && $res =~ /^$ENV{SEARCH_ABORT}/; - exit($search_result != 1); + elsif ($ENV{SEARCH_OUTPUT} eq "count") + { + print "$res matches in $ENV{SEARCH_FILE}\n"; + } + elsif ($ENV{SEARCH_ABORT} and $res =~ /^$ENV{SEARCH_ABORT}/) { + die "$res /$search_pattern/ in $ENV{SEARCH_FILE}\n"; + } else { + print "$res /$search_pattern/ in $ENV{SEARCH_FILE}\n"; + } EOF - -let $SEARCH_RESULT= 1; # Found pattern -if ($errno) -{ - let $SEARCH_RESULT= 0; # Did not find pattern -} diff --git a/mysql-test/include/shutdown_mysqld.inc b/mysql-test/include/shutdown_mysqld.inc index fc2972560c3..1684d81970a 100644 --- a/mysql-test/include/shutdown_mysqld.inc +++ b/mysql-test/include/shutdown_mysqld.inc @@ -24,18 +24,15 @@ if ($rpl_inited) # Write file to make mysql-test-run.pl expect the "crash", but don't start it --let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')` --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect ---exec echo "wait" > $_expect_file_name +--write_line wait $_expect_file_name # Avoid warnings from connection threads that does not have time to exit --disable_query_log set @@global.log_warnings=0; --enable_query_log ---let $server_shutdown_timeout= 60 -if ($VALGRIND_TEST) -{ - --let $server_shutdown_timeout= 300 -} +--source include/slow_environ.inc +--let $server_shutdown_timeout= 60$_timeout_adjustment if ($shutdown_timeout) { diff --git a/mysql-test/include/slow_environ.inc b/mysql-test/include/slow_environ.inc new file mode 100644 index 00000000000..761147fd288 --- /dev/null +++ b/mysql-test/include/slow_environ.inc @@ -0,0 +1,9 @@ +if (!$slow_environ_check) +{ + let $_timeout_adjustment=; + if (`select $VALGRIND_TEST + count(*) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like '%SAN%'`) + { + let $_timeout_adjustment=0; + } + let $slow_environ_check=1; +} diff --git a/mysql-test/include/start_mysqld.inc b/mysql-test/include/start_mysqld.inc index 6e448cb2efd..91b06997d6e 100644 --- a/mysql-test/include/start_mysqld.inc +++ b/mysql-test/include/start_mysqld.inc @@ -21,7 +21,7 @@ if ($restart_bindir) if ($restart_parameters) { - --exec echo "$restart_cmd: $restart_parameters" > $_expect_file_name + --write_line "$restart_cmd: $restart_parameters" $_expect_file_name if (!$restart_noprint) { --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MYSQLTEST_VARDIR MYSQLTEST_VARDIR @@ -34,7 +34,7 @@ if ($restart_parameters) } if (!$restart_parameters) { - --exec echo "$restart_cmd" > $_expect_file_name + --write_line "$restart_cmd" $_expect_file_name if ($restart_noprint < 2) { --exec echo "# $restart_cmd" diff --git a/mysql-test/include/stop_slave_io.inc b/mysql-test/include/stop_slave_io.inc index ddc83782311..a9d97f2f8a1 100644 --- a/mysql-test/include/stop_slave_io.inc +++ b/mysql-test/include/stop_slave_io.inc @@ -34,8 +34,17 @@ if (!$rpl_debug) --disable_query_log } - +let $_enable_warnings=0; +if ($rpl_allow_error) { + if ($ENABLED_WARNINGS) { + let $_enable_warnings=1; + disable_warnings; + } +} STOP SLAVE IO_THREAD; +if ($_enable_warnings) { + enable_warnings; +} --source include/wait_for_slave_io_to_stop.inc diff --git a/mysql-test/include/sync_slave_sql_with_io.inc b/mysql-test/include/sync_slave_sql_with_io.inc index 9efede9a61f..c16d28edbb9 100644 --- a/mysql-test/include/sync_slave_sql_with_io.inc +++ b/mysql-test/include/sync_slave_sql_with_io.inc @@ -25,11 +25,8 @@ let $_slave_timeout= $slave_timeout; if (!$_slave_timeout) { - let $_slave_timeout= 300; - if ($VALGRIND_TEST) - { - let $_slave_timeout= 1500; - } + source include/slow_environ.inc; + let $_slave_timeout= 300$_timeout_adjustment; } --let $_master_log_file= query_get_value(SHOW SLAVE STATUS, Master_Log_File, 1) diff --git a/mysql-test/include/sync_with_master_gtid.inc b/mysql-test/include/sync_with_master_gtid.inc index 777711b979c..0ca2c90784e 100644 --- a/mysql-test/include/sync_with_master_gtid.inc +++ b/mysql-test/include/sync_with_master_gtid.inc @@ -33,11 +33,8 @@ let $_slave_timeout= $slave_timeout; if (!$_slave_timeout) { - let $_slave_timeout= 120; - if ($VALGRIND_TEST) - { - let $_slave_timeout= 1200; - } + source include/slow_environ.inc; + let $_slave_timeout= 120$_timeout_adjustment; } --let $_result= `SELECT master_gtid_wait('$master_pos', $_slave_timeout)` diff --git a/mysql-test/include/wait_for_pattern_in_file.inc b/mysql-test/include/wait_for_pattern_in_file.inc index 52226acd2da..a551761012f 100644 --- a/mysql-test/include/wait_for_pattern_in_file.inc +++ b/mysql-test/include/wait_for_pattern_in_file.inc @@ -25,23 +25,23 @@ if (!$_timeout) } let $_timeout_counter=`SELECT $_timeout * 10`; -let SEARCH_SILENT=1; - +let SEARCH_ABORT=NOT FOUND; let $_continue= 1; +disable_abort_on_error; while ($_continue) { source include/search_pattern_in_file.inc; - if ($SEARCH_RESULT) + if (!$errno) { # Found match let $_continue= 0; } - if (!$SEARCH_RESULT) + if ($errno) { dec $_timeout_counter; if ($_timeout_counter == 1) { - let $SEARCH_SILENT= 0; + enable_abort_on_error; } if (!$_timeout_counter) { @@ -49,8 +49,7 @@ while ($_continue) } } } - -let SEARCH_SILENT=0; +enable_abort_on_error; --source include/end_include_file.inc --let $keep_include_silent=$wait_save_keep_include_silent diff --git a/mysql-test/include/wait_for_slave_param.inc b/mysql-test/include/wait_for_slave_param.inc index ed81c55963f..6802cd41203 100644 --- a/mysql-test/include/wait_for_slave_param.inc +++ b/mysql-test/include/wait_for_slave_param.inc @@ -49,11 +49,8 @@ let $_slave_timeout= $slave_timeout; if (!$_slave_timeout) { - let $_slave_timeout= 300; - if ($VALGRIND_TEST) - { - let $_slave_timeout= 1500; - } + source include/slow_environ.inc; + let $_slave_timeout= 300$_timeout_adjustment; } let $_slave_param_comparison= $slave_param_comparison; diff --git a/mysql-test/include/wait_until_connected_again.inc b/mysql-test/include/wait_until_connected_again.inc index deb6ca13e8b..2b20c780b69 100644 --- a/mysql-test/include/wait_until_connected_again.inc +++ b/mysql-test/include/wait_until_connected_again.inc @@ -11,7 +11,7 @@ let $counter= 5000; let $mysql_errno= 9999; while ($mysql_errno) { - --error 0,ER_ACCESS_DENIED_ERROR,ER_SERVER_SHUTDOWN,ER_CONNECTION_KILLED,ER_LOCK_WAIT_TIMEOUT,2002,2006,2013,HA_ERR_NO_ENCRYPTION + --error 0,ER_ACCESS_DENIED_ERROR,ER_SERVER_SHUTDOWN,ER_CONNECTION_KILLED,ER_LOCK_WAIT_TIMEOUT,2002,2006,2013,HA_ERR_NO_ENCRYPTION,2026 select 1; dec $counter; diff --git a/mysql-test/lib/My/Debugger.pm b/mysql-test/lib/My/Debugger.pm index b068698e340..2ab8a3520c8 100644 --- a/mysql-test/lib/My/Debugger.pm +++ b/mysql-test/lib/My/Debugger.pm @@ -263,6 +263,7 @@ sub pre_setup() { $::opt_suite_timeout= 24 * 60; # in minutes $::opt_shutdown_timeout= ($interactive ? 24 * 60 : 3) * 60; # in seconds $::opt_start_timeout= $::opt_shutdown_timeout; # in seconds + $::opt_debug_sync_timeout= 3000; # in seconds } } diff --git a/mysql-test/lib/My/Platform.pm b/mysql-test/lib/My/Platform.pm index 2b32ef87b81..f33875e14aa 100644 --- a/mysql-test/lib/My/Platform.pm +++ b/mysql-test/lib/My/Platform.pm @@ -23,7 +23,7 @@ use File::Path; use Carp; use base qw(Exporter); -our @EXPORT= qw(IS_CYGWIN IS_MSYS IS_WINDOWS IS_WIN32PERL IS_AIX +our @EXPORT= qw(IS_CYGWIN IS_MSYS IS_WINDOWS IS_WIN32PERL IS_AIX IS_MAC native_path posix_path mixed_path check_socket_path_length process_alive open_for_append); @@ -70,6 +70,14 @@ BEGIN { } } +BEGIN { + if ($^O eq "darwin") { + eval 'sub IS_MAC { 1 }'; + } + else { + eval 'sub IS_MAC { 0 }'; + } +} # # native_path diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 97c48c19112..0c3c45f3b18 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -87,12 +87,16 @@ sub flush_out { $out_line = ""; } +use if $^O eq "MSWin32", "threads::shared"; +my $flush_lock :shared; + # Print to stdout sub print_out { if(IS_WIN32PERL) { $out_line .= $_[0]; # Flush buffered output on new lines. if (rindex($_[0], "\n") != -1) { + lock($flush_lock); flush_out(); } } else { diff --git a/mysql-test/main/alter_table.result b/mysql-test/main/alter_table.result index 2db89f77434..9b2fe43a945 100644 --- a/mysql-test/main/alter_table.result +++ b/mysql-test/main/alter_table.result @@ -3098,6 +3098,14 @@ CREATE TEMPORARY TABLE t2 LIKE t1; DROP TEMPORARY TABLE t2; DROP TABLE t1; # +# MDEV-33313 Incorrect error message for "ALTER TABLE ... DROP CONSTRAINT ..., DROP col, DROP col" +# +create table t2(id int primary key) engine=innodb; +create table t1(id int primary key, t2_id int, constraint t1_fk_t2_id foreign key(t2_id) references t2(id)) engine=innodb; +alter table t1 drop constraint t1_fk_t2_id, drop t2_id, drop t2_id; +ERROR 42000: Can't DROP COLUMN `t2_id`; check that it exists +drop table t1, t2; +# # End of 10.6 tests # # diff --git a/mysql-test/main/alter_table.test b/mysql-test/main/alter_table.test index d37abb0b801..48175f493eb 100644 --- a/mysql-test/main/alter_table.test +++ b/mysql-test/main/alter_table.test @@ -2398,6 +2398,15 @@ CREATE TEMPORARY TABLE t2 LIKE t1; DROP TEMPORARY TABLE t2; DROP TABLE t1; +--echo # +--echo # MDEV-33313 Incorrect error message for "ALTER TABLE ... DROP CONSTRAINT ..., DROP col, DROP col" +--echo # +create table t2(id int primary key) engine=innodb; +create table t1(id int primary key, t2_id int, constraint t1_fk_t2_id foreign key(t2_id) references t2(id)) engine=innodb; +--error ER_CANT_DROP_FIELD_OR_KEY +alter table t1 drop constraint t1_fk_t2_id, drop t2_id, drop t2_id; +drop table t1, t2; + --echo # --echo # End of 10.6 tests --echo # diff --git a/mysql-test/main/alter_table_online.result b/mysql-test/main/alter_table_online.result index 7928222a428..fb5f2abf984 100644 --- a/mysql-test/main/alter_table_online.result +++ b/mysql-test/main/alter_table_online.result @@ -238,3 +238,26 @@ ERROR 0A000: LOCK=NONE is not supported. Reason: Function or expression 'NEXTVAL drop table t2; drop table t1; drop sequence s; +# +# MDEV-33348 ALTER TABLE lock waiting stages are indistinguishable +# +connect con2, localhost, root; +create table t1 (a int); +insert t1 values (5); +start transaction; +select * from t1; +a +5 +connection default; +alter table t1 add b int NULL, algorithm= copy, lock= none; +connection con2; +set @con= $con; +select stage, state, info from information_schema.processlist where id = @con; +stage 4 +state Waiting for table metadata lock +info alter table t1 add b int NULL, algorithm= copy, lock= none +rollback; +connection default; +drop table t1; +disconnect con2; +# End of 11.2 tests diff --git a/mysql-test/main/alter_table_online.test b/mysql-test/main/alter_table_online.test index 35e01054890..4d8f831186f 100644 --- a/mysql-test/main/alter_table_online.test +++ b/mysql-test/main/alter_table_online.test @@ -246,3 +246,40 @@ alter table t2 modify b int not null default (nextval(s)), lock=none; drop table t2; drop table t1; drop sequence s; + +--echo # +--echo # MDEV-33348 ALTER TABLE lock waiting stages are indistinguishable +--echo # +--disable_view_protocol +--connect con2, localhost, root + +create table t1 (a int); +insert t1 values (5); + +start transaction; +select * from t1; + +--connection default +--let $con= `select connection_id()` +send alter table t1 add b int NULL, algorithm= copy, lock= none; + +--connection con2 +evalp set @con= $con; + +let $wait_condition= select stage = 4 and progress = 100 + and state= "Waiting for table metadata lock" + from information_schema.processlist where id = @con; +--source include/wait_condition.inc + +query_vertical select stage, state, info from information_schema.processlist where id = @con; + +rollback; + +--connection default +reap; + +drop table t1; +--disconnect con2 +--enable_view_protocol + +--echo # End of 11.2 tests diff --git a/mysql-test/main/alter_table_online_debug.result b/mysql-test/main/alter_table_online_debug.result index f94c785864b..37fadcd8840 100644 --- a/mysql-test/main/alter_table_online_debug.result +++ b/mysql-test/main/alter_table_online_debug.result @@ -412,29 +412,29 @@ update t1 set b= 666 where a = 6; set debug_sync= 'now SIGNAL start_replication'; # First signal is for log description event. set debug_sync= 'now WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; -stage progress -3 53.390 +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +stage progress examined_rows +3 53.390 0 set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; -stage progress -3 63.559 +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +stage progress examined_rows +3 63.559 1 set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; -stage progress -3 71.610 +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +stage progress examined_rows +3 71.610 2 set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; -stage progress -3 81.780 +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +stage progress examined_rows +3 81.780 3 set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; -stage progress -3 89.831 +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +stage progress examined_rows +3 89.831 4 set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; -stage progress -3 100.000 +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +stage progress examined_rows +3 100.000 5 set debug_sync= 'now SIGNAL proceed WAIT_FOR locking'; begin; update t1 set b= 222 where a = 2; @@ -442,17 +442,17 @@ update t1 set b= 333 where a = 3; update t1 set b= 444 where a = 4; commit; set debug_sync= 'now SIGNAL end WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; -stage progress -4 33.333 +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +stage progress examined_rows +4 33.333 6 set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; -stage progress -4 66.667 +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +stage progress examined_rows +4 66.667 7 set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; -stage progress -4 100.000 +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +stage progress examined_rows +4 100.000 8 set debug_sync= 'now SIGNAL proceed'; connection default; select * from t1; @@ -1787,6 +1787,48 @@ a d 0 qwe 0 qwe drop table t; +# +# MDEV-32803 Assertion `total == 0' failed in Event_log::write_cache_raw +# +create or replace table t1 (a int) engine=aria; +insert t1 values (5); +set debug_sync= 'alter_table_copy_end SIGNAL ended WAIT_FOR end'; +alter table t1 add b int NULL, algorithm= copy, lock= none; +connection con2; +set debug_sync= 'now WAIT_FOR ended'; +begin; +insert into t1 values (123); +insert into t1 values (456), (789); +commit; +set debug_sync= 'now SIGNAL end'; +connection default; +select * from t1; +a b +5 NULL +123 NULL +456 NULL +789 NULL +drop table t1; +# MDEV-32614 LeakSanitizer errors in copy_data_between_tables +create table t (a int, b int) engine=aria; +insert into t select seq, seq from seq_1_to_5; +backup stage start; +connect con_lock,localhost,root,,; +set lock_wait_timeout= 1; +set debug_sync='copy_data_between_tables_before_reset_backup_lock signal backup wait_for continue'; +alter table t add index (b), algorithm=copy, lock=none; +connection default; +set debug_sync='now wait_for backup'; +backup stage block_commit; +set debug_sync='now signal continue'; +connection con_lock; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +disconnect con_lock; +connection default; +backup stage end; +alter table t add index (a), algorithm=copy, lock=none; +connection default; +drop table t; set global default_storage_engine= MyISAM; disconnect con1; disconnect con2; diff --git a/mysql-test/main/alter_table_online_debug.test b/mysql-test/main/alter_table_online_debug.test index cf0062da269..64b73157a2f 100644 --- a/mysql-test/main/alter_table_online_debug.test +++ b/mysql-test/main/alter_table_online_debug.test @@ -510,22 +510,22 @@ eval set @con= $con; --echo # First signal is for log description event. set debug_sync= 'now WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; set debug_sync= 'now SIGNAL proceed WAIT_FOR locking'; begin; @@ -537,13 +537,13 @@ update t1 set b= 444 where a = 4; commit; set debug_sync= 'now SIGNAL end WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; -select stage, progress from INFORMATION_SCHEMA.PROCESSLIST where id = @con; +select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; set debug_sync= 'now SIGNAL proceed'; --connection default @@ -2041,6 +2041,63 @@ select * from t; drop table t; +--echo # +--echo # MDEV-32803 Assertion `total == 0' failed in Event_log::write_cache_raw +--echo # + +create or replace table t1 (a int) engine=aria; +insert t1 values (5); +set debug_sync= 'alter_table_copy_end SIGNAL ended WAIT_FOR end'; + +send alter table t1 add b int NULL, algorithm= copy, lock= none; + +--connection con2 +set debug_sync= 'now WAIT_FOR ended'; +begin; +insert into t1 values (123); +insert into t1 values (456), (789); +commit; +set debug_sync= 'now SIGNAL end'; + +--connection default +--reap +select * from t1; + +drop table t1; + + +--echo # MDEV-32614 LeakSanitizer errors in copy_data_between_tables +create table t (a int, b int) engine=aria; +insert into t select seq, seq from seq_1_to_5; +backup stage start; + +--connect (con_lock,localhost,root,,) +set lock_wait_timeout= 1; + +set debug_sync='copy_data_between_tables_before_reset_backup_lock signal backup wait_for continue'; +send alter table t add index (b), algorithm=copy, lock=none; + +--connection default + +set debug_sync='now wait_for backup'; + +backup stage block_commit; + +set debug_sync='now signal continue'; + +--connection con_lock +--error ER_LOCK_WAIT_TIMEOUT +--reap +--disconnect con_lock + +--connection default +backup stage end; +alter table t add index (a), algorithm=copy, lock=none; + +--connection default +drop table t; + + eval set global default_storage_engine= $default_storage_engine; --disconnect con1 diff --git a/mysql-test/main/bootstrap.test b/mysql-test/main/bootstrap.test index 76d5ed008a6..68fbc00181d 100644 --- a/mysql-test/main/bootstrap.test +++ b/mysql-test/main/bootstrap.test @@ -74,7 +74,7 @@ SELECT 'bug' as '' FROM INFORMATION_SCHEMA.ENGINES WHERE engine='innodb' --echo # MDEV-13063 Server crashes in intern_plugin_lock or assertion `plugin_ptr->ref_count == 1' fails in plugin_init --echo # --error 1 ---exec $MYSQLD_BOOTSTRAP_CMD --myisam_recover_options=NONE +--exec $MYSQLD_BOOTSTRAP_CMD --myisam_recover_options=NONE 2>/dev/null --echo # --echo # MDEV-19349 mysql_install_db: segfault at tmp_file_prefix check diff --git a/mysql-test/main/column_compression_parts.result b/mysql-test/main/column_compression_parts.result index fa12217ce22..5f5539b723c 100644 --- a/mysql-test/main/column_compression_parts.result +++ b/mysql-test/main/column_compression_parts.result @@ -12,7 +12,6 @@ INSERT INTO t1 VALUES (1,REPEAT('a',100)),(2,REPEAT('v',200)),(3,REPEAT('r',300) INSERT INTO t1 VALUES (5,REPEAT('k',500)),(6,'April'),(7,7),(8,""),(9,"M"),(10,DEFAULT); ALTER TABLE t1 ANALYZE PARTITION p1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK ALTER TABLE t1 CHECK PARTITION p2; Table Op Msg_type Msg_text diff --git a/mysql-test/main/commit_1innodb.result b/mysql-test/main/commit_1innodb.result index d090844cb74..973be9fde0d 100644 --- a/mysql-test/main/commit_1innodb.result +++ b/mysql-test/main/commit_1innodb.result @@ -634,7 +634,7 @@ SUCCESS drop table t2; set sql_mode=no_engine_substitution; create temporary table t2 (a int); -call p_verify_status_increment(1, 0, 0, 0); +call p_verify_status_increment(3, 0, 2, 0); SUCCESS set sql_mode=default; @@ -643,8 +643,9 @@ set sql_mode=default; select f1(); f1() 2 -# Two commits because a binary log record is written -call p_verify_status_increment(2, 0, 1, 0); +# Two commits because a binary log record is written, and another two +# as the function f1() is reloaded after creating temporary table. +call p_verify_status_increment(4, 0, 3, 0); SUCCESS commit; @@ -715,11 +716,11 @@ SUCCESS # 25. DDL: DROP TEMPORARY TABLE, does not start a transaction # drop temporary table t2; -call p_verify_status_increment(1, 0, 1, 0); +call p_verify_status_increment(3, 0, 2, 0); SUCCESS commit; -call p_verify_status_increment(1, 0, 1, 0); +call p_verify_status_increment(1, 0, 0, 0); SUCCESS # 26. Verify that SET AUTOCOMMIT issues an implicit commit @@ -801,7 +802,7 @@ call p_verify_status_increment(0, 0, 0, 0); SUCCESS do (select f1() from t1 where a=2); -call p_verify_status_increment(2, 2, 2, 2); +call p_verify_status_increment(4, 2, 4, 2); SUCCESS commit; diff --git a/mysql-test/main/constraints.result b/mysql-test/main/constraints.result index 143c22321ab..d2a19040083 100644 --- a/mysql-test/main/constraints.result +++ b/mysql-test/main/constraints.result @@ -235,3 +235,16 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop procedure sp; drop table t1; +# +# MDEV-33768: Memory leak found in the test main.constraints run with --ps-protocol against a server built with the option -DWITH_PROTECT_STATEMENT_MEMROOT +# This test case was added by reviewer's request. +# +PREPARE stmt FROM 'CREATE TABLE t1 (a INT)'; +EXECUTE stmt; +DROP TABLE t1; +EXECUTE stmt; +EXECUTE stmt; +ERROR 42S01: Table 't1' already exists +# Clean up +DROP TABLE t1; +DEALLOCATE PREPARE stmt; diff --git a/mysql-test/main/constraints.test b/mysql-test/main/constraints.test index 5c673f9be81..83f3394d6f6 100644 --- a/mysql-test/main/constraints.test +++ b/mysql-test/main/constraints.test @@ -189,3 +189,18 @@ call sp; show create table t1; drop procedure sp; drop table t1; + +--echo # +--echo # MDEV-33768: Memory leak found in the test main.constraints run with --ps-protocol against a server built with the option -DWITH_PROTECT_STATEMENT_MEMROOT +--echo # This test case was added by reviewer's request. +--echo # +PREPARE stmt FROM 'CREATE TABLE t1 (a INT)'; +EXECUTE stmt; +DROP TABLE t1; +EXECUTE stmt; +--error ER_TABLE_EXISTS_ERROR +EXECUTE stmt; + +--echo # Clean up +DROP TABLE t1; +DEALLOCATE PREPARE stmt; diff --git a/mysql-test/main/crash_commit_before.test b/mysql-test/main/crash_commit_before.test index 93b96de6e53..30b59ce4480 100644 --- a/mysql-test/main/crash_commit_before.test +++ b/mysql-test/main/crash_commit_before.test @@ -17,7 +17,7 @@ insert into t1 values(9); SET GLOBAL debug_dbug="d,crash_commit_before"; # Write file to make mysql-test-run.pl expect crash and restart ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Run the crashing query --error 2013 diff --git a/mysql-test/main/create.result b/mysql-test/main/create.result index b57c898c384..d7f4eb274ea 100644 --- a/mysql-test/main/create.result +++ b/mysql-test/main/create.result @@ -1805,7 +1805,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `color` char(32) GENERATED ALWAYS AS (column_get(`dynamic_cols`,1 as char charset latin1)) STORED, - `cl` char(32) GENERATED ALWAYS AS (column_get(column_add(column_create(1,'blue' AS char charset latin1 ),2,'ttt'),`i` as char charset latin1)) STORED, + `cl` char(32) GENERATED ALWAYS AS (column_get(column_add(column_create(1,'blue' AS char charset latin1 collate latin1_swedish_ci ),2,'ttt'),`i` as char charset latin1)) STORED, `item_name` varchar(32) NOT NULL, `i` int(11) DEFAULT NULL, `dynamic_cols` blob DEFAULT NULL, diff --git a/mysql-test/main/ctype_collate.result b/mysql-test/main/ctype_collate.result index 8624cff4eef..9f2eca8e726 100644 --- a/mysql-test/main/ctype_collate.result +++ b/mysql-test/main/ctype_collate.result @@ -780,3 +780,27 @@ string # # End of 10.2 tests # +# +# MDEV-33318 ORDER BY COLLATE improperly applied to non-character columns +# +set names utf8; +create table t1 (ts datetime); +insert t1 values ('2024-01-26 21:37:54'), ('2024-01-26 21:37:54'), +('2024-01-26 21:37:54'), ('2024-01-26 21:37:54'), +('2024-01-26 21:37:58'), ('2024-01-26 21:37:58'), +('2024-01-26 21:37:58'), ('2024-01-26 21:38:02'), +('2024-01-26 21:38:02'), ('2024-01-26 21:38:02'); +select * from t1 order by ts collate utf8_bin; +ts +2024-01-26 21:37:54 +2024-01-26 21:37:54 +2024-01-26 21:37:54 +2024-01-26 21:37:54 +2024-01-26 21:37:58 +2024-01-26 21:37:58 +2024-01-26 21:37:58 +2024-01-26 21:38:02 +2024-01-26 21:38:02 +2024-01-26 21:38:02 +drop table t1; +# End of 10.6 tests diff --git a/mysql-test/main/ctype_collate.test b/mysql-test/main/ctype_collate.test index 2366b130e7c..96ad216dd20 100644 --- a/mysql-test/main/ctype_collate.test +++ b/mysql-test/main/ctype_collate.test @@ -357,3 +357,18 @@ SELECT COLUMN_GET(COLUMN_CREATE(0, 'string'),0 AS CHAR CHARACTER SET latin1 COLL --echo # --echo # End of 10.2 tests --echo # + +--echo # +--echo # MDEV-33318 ORDER BY COLLATE improperly applied to non-character columns +--echo # +set names utf8; +create table t1 (ts datetime); +insert t1 values ('2024-01-26 21:37:54'), ('2024-01-26 21:37:54'), + ('2024-01-26 21:37:54'), ('2024-01-26 21:37:54'), + ('2024-01-26 21:37:58'), ('2024-01-26 21:37:58'), + ('2024-01-26 21:37:58'), ('2024-01-26 21:38:02'), + ('2024-01-26 21:38:02'), ('2024-01-26 21:38:02'); +select * from t1 order by ts collate utf8_bin; +drop table t1; + +--echo # End of 10.6 tests diff --git a/mysql-test/main/ctype_ucs.result b/mysql-test/main/ctype_ucs.result index 99d8209d32e..88838245ac4 100644 --- a/mysql-test/main/ctype_ucs.result +++ b/mysql-test/main/ctype_ucs.result @@ -6517,5 +6517,25 @@ SELECT 1 COLLATE latin1_swedish_ci; ERROR 42000: COLLATION 'latin1_swedish_ci' is not valid for CHARACTER SET 'ucs2' SET NAMES utf8; # +# MDEV-33772 Bad SEPARATOR value in GROUP_CONCAT on character set conversion +# +SET NAMES utf8mb3, @@collation_connection=ucs2_general_ci; +CREATE TABLE t1 (c VARCHAR(10)) CHARACTER SET ucs2; +INSERT INTO t1 VALUES ('a'),('A'); +CREATE OR REPLACE VIEW v1 AS +SELECT COUNT(*) AS cnt, GROUP_CONCAT(c) AS c1 FROM t1 GROUP BY c; +SELECT * FROM v1; +cnt c1 +2 a,A +SELECT HEX(c1) FROM v1; +HEX(c1) +0061002C0041 +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select count(0) AS `cnt`,group_concat(`t1`.`c` separator ',') AS `c1` from `t1` group by `t1`.`c` utf8mb3 ucs2_general_ci +DROP VIEW v1; +DROP TABLE t1; +SET NAMES utf8mb3; +# # End of 10.5 tests # diff --git a/mysql-test/main/ctype_ucs.test b/mysql-test/main/ctype_ucs.test index 993f9be5c54..93ddcb86964 100644 --- a/mysql-test/main/ctype_ucs.test +++ b/mysql-test/main/ctype_ucs.test @@ -1193,6 +1193,23 @@ SELECT HEX(1 COLLATE ucs2_bin); SELECT 1 COLLATE latin1_swedish_ci; SET NAMES utf8; +--echo # +--echo # MDEV-33772 Bad SEPARATOR value in GROUP_CONCAT on character set conversion +--echo # + +SET NAMES utf8mb3, @@collation_connection=ucs2_general_ci; +CREATE TABLE t1 (c VARCHAR(10)) CHARACTER SET ucs2; +INSERT INTO t1 VALUES ('a'),('A'); +CREATE OR REPLACE VIEW v1 AS + SELECT COUNT(*) AS cnt, GROUP_CONCAT(c) AS c1 FROM t1 GROUP BY c; +SELECT * FROM v1; +SELECT HEX(c1) FROM v1; +SHOW CREATE VIEW v1; +DROP VIEW v1; +DROP TABLE t1; +SET NAMES utf8mb3; + + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/ddl_i18n_koi8r.result b/mysql-test/main/ddl_i18n_koi8r.result index f588374a26f..bc4ef5ca644 100644 --- a/mysql-test/main/ddl_i18n_koi8r.result +++ b/mysql-test/main/ddl_i18n_koi8r.result @@ -719,6 +719,7 @@ ca cb utf8mb3_general_ci utf8mb3_general_ci ---> Dump of mysqltest1 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET cp866 COLLATE cp866_general_ci */; @@ -795,6 +796,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ; ---> Dumping mysqltest1 to ddl_i18n_koi8r.sp.mysqltest1.sql ---> Dump of mysqltest2 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER SET cp866 COLLATE cp866_general_ci */; @@ -1723,6 +1725,7 @@ koi8r_general_ci utf8mb3_general_ci koi8r_general_ci koi8r_general_ci utf8mb3_ge DELETE FROM mysqltest2.log| ---> Dump of mysqltest1 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET cp866 COLLATE cp866_general_ci */; @@ -1805,6 +1808,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ; ---> Dumping mysqltest1 to ddl_i18n_koi8r.triggers.mysqltest1.sql ---> Dump of mysqltest2 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER SET cp866 COLLATE cp866_general_ci */; @@ -2491,6 +2495,7 @@ COLLATION( ' END ONE TIME 1970-01-02 00:00:00 NULL NULL NULL NULL DISABLED PRESERVE CREATED LAST_ALTERED NULL 1 koi8r koi8r_general_ci utf8mb3_unicode_ci ---> Dump of mysqltest1 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET cp866 COLLATE cp866_general_ci */; @@ -2558,6 +2563,7 @@ DELIMITER ; ---> Dumping mysqltest1 to ddl_i18n_koi8r.events.mysqltest1.sql ---> Dump of mysqltest2 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER SET cp866 COLLATE cp866_general_ci */; diff --git a/mysql-test/main/ddl_i18n_utf8.result b/mysql-test/main/ddl_i18n_utf8.result index cb57bc5e9df..9561c914302 100644 --- a/mysql-test/main/ddl_i18n_utf8.result +++ b/mysql-test/main/ddl_i18n_utf8.result @@ -719,6 +719,7 @@ ca cb utf8mb3_general_ci utf8mb3_general_ci ---> Dump of mysqltest1 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET cp866 COLLATE cp866_general_ci */; @@ -795,6 +796,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ; ---> Dumping mysqltest1 to ddl_i18n_utf8sp.mysqltest1.sql ---> Dump of mysqltest2 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER SET cp866 COLLATE cp866_general_ci */; @@ -1723,6 +1725,7 @@ utf8mb3_general_ci utf8mb3_general_ci koi8r_general_ci utf8mb3_general_ci utf8mb DELETE FROM mysqltest2.log| ---> Dump of mysqltest1 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET cp866 COLLATE cp866_general_ci */; @@ -1805,6 +1808,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET cp866 COLLATE cp866_general_ci ; ---> Dumping mysqltest1 to ddl_i18n_utf8triggers.mysqltest1.sql ---> Dump of mysqltest2 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER SET cp866 COLLATE cp866_general_ci */; @@ -2491,6 +2495,7 @@ COLLATION( 'текст') AS c4, END ONE TIME 1970-01-02 00:00:00 NULL NULL NULL NULL DISABLED PRESERVE CREATED LAST_ALTERED NULL 1 utf8mb3 utf8mb3_general_ci utf8mb3_unicode_ci ---> Dump of mysqltest1 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET cp866 COLLATE cp866_general_ci */; @@ -2558,6 +2563,7 @@ DELIMITER ; ---> Dumping mysqltest1 to ddl_i18n_utf8events.mysqltest1.sql ---> Dump of mysqltest2 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER SET cp866 COLLATE cp866_general_ci */; diff --git a/mysql-test/main/deadlock_innodb.result b/mysql-test/main/deadlock_innodb.result index 09958bf0413..9236f21c22b 100644 --- a/mysql-test/main/deadlock_innodb.result +++ b/mysql-test/main/deadlock_innodb.result @@ -89,11 +89,6 @@ id x 300 300 connection con2; update t2 set a=2 where b = 0; -select * from t2; -b a -0 2 -1 20 -2 30 update t1 set x=2 where id = 0; connection con1; update t1 set x=1 where id = 0; diff --git a/mysql-test/main/delete_innodb.result b/mysql-test/main/delete_innodb.result index 662c0c558ea..c171e8d0fe0 100644 --- a/mysql-test/main/delete_innodb.result +++ b/mysql-test/main/delete_innodb.result @@ -69,4 +69,518 @@ c1 5 6 DROP TABLE t1, t2; +# +# MDEV-33533: multi-delete using rowid filter +# +set @save_default_storage_engine=@@default_storage_engine; +set default_storage_engine=InnoDB; +CREATE DATABASE dbt3_s001; +use dbt3_s001; +create index i_n_name on nation(n_name); +analyze table +nation, lineitem, customer, orders, part, supplier, partsupp, region +persistent for all; +Table Op Msg_type Msg_text +dbt3_s001.nation analyze status Engine-independent statistics collected +dbt3_s001.nation analyze status OK +dbt3_s001.lineitem analyze status Engine-independent statistics collected +dbt3_s001.lineitem analyze status OK +dbt3_s001.customer analyze status Engine-independent statistics collected +dbt3_s001.customer analyze status OK +dbt3_s001.orders analyze status Engine-independent statistics collected +dbt3_s001.orders analyze status OK +dbt3_s001.part analyze status Engine-independent statistics collected +dbt3_s001.part analyze status OK +dbt3_s001.supplier analyze status Engine-independent statistics collected +dbt3_s001.supplier analyze status OK +dbt3_s001.partsupp analyze status Engine-independent statistics collected +dbt3_s001.partsupp analyze status OK +dbt3_s001.region analyze status Engine-independent statistics collected +dbt3_s001.region analyze status OK +explain +select o_orderkey, o_totalprice from orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE nation ref PRIMARY,i_n_name i_n_name 26 const 1 Using where; Using index +1 SIMPLE customer ref PRIMARY,i_c_nationkey i_c_nationkey 5 dbt3_s001.nation.n_nationkey 6 Using index +1 SIMPLE orders ref|filter i_o_orderdate,i_o_custkey i_o_custkey|i_o_orderdate 5|4 dbt3_s001.customer.c_custkey 15 (8%) Using where; Using rowid filter +explain format=json +select o_orderkey, o_totalprice from orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "nation", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_n_name"], + "key": "i_n_name", + "key_length": "26", + "used_key_parts": ["n_name"], + "ref": ["const"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "nation.n_name = 'PERU'", + "using_index": true + } + }, + { + "table": { + "table_name": "customer", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_c_nationkey"], + "key": "i_c_nationkey", + "key_length": "5", + "used_key_parts": ["c_nationkey"], + "ref": ["dbt3_s001.nation.n_nationkey"], + "loops": 1, + "rows": 6, + "cost": "COST_REPLACED", + "filtered": 100, + "using_index": true + } + }, + { + "table": { + "table_name": "orders", + "access_type": "ref", + "possible_keys": ["i_o_orderdate", "i_o_custkey"], + "key": "i_o_custkey", + "key_length": "5", + "used_key_parts": ["o_custkey"], + "ref": ["dbt3_s001.customer.c_custkey"], + "rowid_filter": { + "range": { + "key": "i_o_orderdate", + "used_key_parts": ["o_orderDATE"] + }, + "rows": 119, + "selectivity_pct": 7.933333333 + }, + "loops": 6, + "rows": 15, + "cost": "COST_REPLACED", + "filtered": 7.933333397, + "attached_condition": "orders.o_orderDATE between '1992-01-01' and '1992-06-30'" + } + } + ] + } +} +select o_orderkey, o_totalprice from orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +o_orderkey o_totalprice +1729 12137.76 +2880 145761.99 +3142 16030.15 +5095 184583.99 +5121 150334.57 +5382 138423.03 +644 201268.06 +737 12984.85 +create table t as +select orders.* from orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +explain +delete from orders using orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE nation ref PRIMARY,i_n_name i_n_name 26 const 1 Using where; Using index +1 SIMPLE customer ref PRIMARY,i_c_nationkey i_c_nationkey 5 dbt3_s001.nation.n_nationkey 6 Using index +1 SIMPLE orders ref|filter i_o_orderdate,i_o_custkey i_o_custkey|i_o_orderdate 5|4 dbt3_s001.customer.c_custkey 15 (8%) Using where; Using rowid filter +explain format=json +delete from orders using orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "nation", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_n_name"], + "key": "i_n_name", + "key_length": "26", + "used_key_parts": ["n_name"], + "ref": ["const"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "nation.n_name = 'PERU'", + "using_index": true + } + }, + { + "table": { + "table_name": "customer", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_c_nationkey"], + "key": "i_c_nationkey", + "key_length": "5", + "used_key_parts": ["c_nationkey"], + "ref": ["dbt3_s001.nation.n_nationkey"], + "loops": 1, + "rows": 6, + "cost": "COST_REPLACED", + "filtered": 100, + "using_index": true + } + }, + { + "table": { + "table_name": "orders", + "access_type": "ref", + "possible_keys": ["i_o_orderdate", "i_o_custkey"], + "key": "i_o_custkey", + "key_length": "5", + "used_key_parts": ["o_custkey"], + "ref": ["dbt3_s001.customer.c_custkey"], + "rowid_filter": { + "range": { + "key": "i_o_orderdate", + "used_key_parts": ["o_orderDATE"] + }, + "rows": 119, + "selectivity_pct": 7.933333333 + }, + "loops": 6, + "rows": 15, + "cost": "COST_REPLACED", + "filtered": 7.933333397, + "attached_condition": "orders.o_orderDATE between '1992-01-01' and '1992-06-30'" + } + } + ] + } +} +delete from orders using orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +select o_orderkey, o_totalprice from orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +o_orderkey o_totalprice +insert into orders select * from t; +select o_orderkey, o_totalprice from orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +o_orderkey o_totalprice +1729 12137.76 +2880 145761.99 +3142 16030.15 +5095 184583.99 +5121 150334.57 +5382 138423.03 +644 201268.06 +737 12984.85 +prepare stmt from " +delete from orders using orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +"; +execute stmt; +select o_orderkey, o_totalprice from orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +o_orderkey o_totalprice +insert into orders select * from t; +select o_orderkey, o_totalprice from orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +o_orderkey o_totalprice +1729 12137.76 +2880 145761.99 +3142 16030.15 +5095 184583.99 +5121 150334.57 +5382 138423.03 +644 201268.06 +737 12984.85 +execute stmt; +select o_orderkey, o_totalprice from orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +o_orderkey o_totalprice +insert into orders select * from t; +select o_orderkey, o_totalprice from orders, customer, nation where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and +c_nationkey = n_nationkey and +n_name='PERU'; +o_orderkey o_totalprice +1729 12137.76 +2880 145761.99 +3142 16030.15 +5095 184583.99 +5121 150334.57 +5382 138423.03 +644 201268.06 +737 12984.85 +deallocate prepare stmt; +drop table t; +explain +select o_orderkey, o_totalprice from orders where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey in (select c_custkey from customer +where c_nationkey in (select n_nationkey from nation +where n_name='PERU')); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY nation ref PRIMARY,i_n_name i_n_name 26 const 1 Using where; Using index +1 PRIMARY customer ref PRIMARY,i_c_nationkey i_c_nationkey 5 dbt3_s001.nation.n_nationkey 6 Using index +1 PRIMARY orders ref|filter i_o_orderdate,i_o_custkey i_o_custkey|i_o_orderdate 5|4 dbt3_s001.customer.c_custkey 15 (8%) Using where; Using rowid filter +explain format=json +select o_orderkey, o_totalprice from orders where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey in (select c_custkey from customer +where c_nationkey in (select n_nationkey from nation +where n_name='PERU')); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "nation", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_n_name"], + "key": "i_n_name", + "key_length": "26", + "used_key_parts": ["n_name"], + "ref": ["const"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "nation.n_name = 'PERU'", + "using_index": true + } + }, + { + "table": { + "table_name": "customer", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_c_nationkey"], + "key": "i_c_nationkey", + "key_length": "5", + "used_key_parts": ["c_nationkey"], + "ref": ["dbt3_s001.nation.n_nationkey"], + "loops": 1, + "rows": 6, + "cost": "COST_REPLACED", + "filtered": 100, + "using_index": true + } + }, + { + "table": { + "table_name": "orders", + "access_type": "ref", + "possible_keys": ["i_o_orderdate", "i_o_custkey"], + "key": "i_o_custkey", + "key_length": "5", + "used_key_parts": ["o_custkey"], + "ref": ["dbt3_s001.customer.c_custkey"], + "rowid_filter": { + "range": { + "key": "i_o_orderdate", + "used_key_parts": ["o_orderDATE"] + }, + "rows": 119, + "selectivity_pct": 7.933333333 + }, + "loops": 6, + "rows": 15, + "cost": "COST_REPLACED", + "filtered": 7.933333397, + "attached_condition": "orders.o_orderDATE between '1992-01-01' and '1992-06-30'" + } + } + ] + } +} +select o_orderkey, o_totalprice from orders where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey in (select c_custkey from customer +where c_nationkey in (select n_nationkey from nation +where n_name='PERU')); +o_orderkey o_totalprice +1729 12137.76 +2880 145761.99 +3142 16030.15 +5095 184583.99 +5121 150334.57 +5382 138423.03 +644 201268.06 +737 12984.85 +create table t as +select * from orders where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey in (select c_custkey from customer +where c_nationkey in (select n_nationkey from nation +where n_name='PERU')); +explain +delete from orders where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey in (select c_custkey from customer +where c_nationkey in (select n_nationkey from nation +where n_name='PERU')); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY nation ref PRIMARY,i_n_name i_n_name 26 const 1 Using where; Using index +1 PRIMARY customer ref PRIMARY,i_c_nationkey i_c_nationkey 5 dbt3_s001.nation.n_nationkey 6 Using index +1 PRIMARY orders ref|filter i_o_orderdate,i_o_custkey i_o_custkey|i_o_orderdate 5|4 dbt3_s001.customer.c_custkey 15 (8%) Using where; Using rowid filter +explain format=json +delete from orders where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey in (select c_custkey from customer +where c_nationkey in (select n_nationkey from nation +where n_name='PERU')); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "nation", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_n_name"], + "key": "i_n_name", + "key_length": "26", + "used_key_parts": ["n_name"], + "ref": ["const"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "nation.n_name = 'PERU'", + "using_index": true + } + }, + { + "table": { + "table_name": "customer", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_c_nationkey"], + "key": "i_c_nationkey", + "key_length": "5", + "used_key_parts": ["c_nationkey"], + "ref": ["dbt3_s001.nation.n_nationkey"], + "loops": 1, + "rows": 6, + "cost": "COST_REPLACED", + "filtered": 100, + "using_index": true + } + }, + { + "table": { + "table_name": "orders", + "access_type": "ref", + "possible_keys": ["i_o_orderdate", "i_o_custkey"], + "key": "i_o_custkey", + "key_length": "5", + "used_key_parts": ["o_custkey"], + "ref": ["dbt3_s001.customer.c_custkey"], + "rowid_filter": { + "range": { + "key": "i_o_orderdate", + "used_key_parts": ["o_orderDATE"] + }, + "rows": 119, + "selectivity_pct": 7.933333333 + }, + "loops": 6, + "rows": 15, + "cost": "COST_REPLACED", + "filtered": 7.933333397, + "attached_condition": "orders.o_orderDATE between '1992-01-01' and '1992-06-30'" + } + } + ] + } +} +delete from orders where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey in (select c_custkey from customer +where c_nationkey in (select n_nationkey from nation +where n_name='PERU')); +select o_orderkey, o_totalprice from orders where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey in (select c_custkey from customer +where c_nationkey in (select n_nationkey from nation +where n_name='PERU')); +o_orderkey o_totalprice +insert into orders select * from t; +select o_orderkey, o_totalprice from orders where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey in (select c_custkey from customer +where c_nationkey in (select n_nationkey from nation +where n_name='PERU')); +o_orderkey o_totalprice +1729 12137.76 +2880 145761.99 +3142 16030.15 +5095 184583.99 +5121 150334.57 +5382 138423.03 +644 201268.06 +737 12984.85 +drop table t; +DROP DATABASE dbt3_s001; +set default_storage_engine=@save_default_storage_engine; +# +# Additional tests of first table and rowid filter +# +CREATE DATABASE dbt3_s001; +use dbt3_s001; +set @save_default_storage_engine=@@default_storage_engine; +set default_storage_engine=InnoDB; +CREATE INDEX i_l_quantity ON lineitem(l_quantity); +CREATE INDEX i_o_totalprice ON orders(o_totalprice); +ANALYZE TABLE lineitem, orders; +Table Op Msg_type Msg_text +dbt3_s001.lineitem analyze status Engine-independent statistics collected +dbt3_s001.lineitem analyze status OK +dbt3_s001.orders analyze status Engine-independent statistics collected +dbt3_s001.orders analyze status OK +set optimizer_use_condition_selectivity=2; +create table second(s_receiptDATE date, filler char(100), key(s_receiptDATE)) ; +insert into second select date_add(l_receiptDATE, interval 1 day), 'helllo' from lineitem ; +select count(*) from lineitem, second WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND l_quantity > 47 and second.s_receiptDATE = date_add(l_receiptDATE, interval 1 day); +count(*) +114 +# lineitem should be first and with "Using rowid filter" +explain delete lineitem FROM lineitem, second WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND l_quantity > 47 and second.s_receiptDATE = date_add(l_receiptDATE, interval 1 day); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE lineitem range|filter i_l_shipdate,i_l_quantity i_l_quantity|i_l_shipdate 9|4 NULL 349 (8%) Using where; Using rowid filter +1 SIMPLE second ref s_receiptDATE s_receiptDATE 4 func 1 Using where; Using index +delete lineitem FROM lineitem, second WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND l_quantity > 47 and second.s_receiptDATE = date_add(l_receiptDATE, interval 1 day); +# Should be 0 +select count(*) from lineitem, second WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND l_quantity > 47 and second.s_receiptDATE = date_add(l_receiptDATE, interval 1 day); +count(*) +0 +drop database dbt3_s001; +set default_storage_engine=@save_default_storage_engine; End of 11.1 tests diff --git a/mysql-test/main/delete_innodb.test b/mysql-test/main/delete_innodb.test index e29cf3fa922..86c32732ad9 100644 --- a/mysql-test/main/delete_innodb.test +++ b/mysql-test/main/delete_innodb.test @@ -49,4 +49,175 @@ analyze DELETE FROM t1 WHERE c1 IN (select c2 from t2) ORDER BY c1 limit 1; select * from t1; DROP TABLE t1, t2; + +--echo # +--echo # MDEV-33533: multi-delete using rowid filter +--echo # + +set @save_default_storage_engine=@@default_storage_engine; +set default_storage_engine=InnoDB; + +CREATE DATABASE dbt3_s001; + +use dbt3_s001; + +--disable_query_log +--disable_result_log +--disable_warnings +--source include/dbt3_s001.inc +--enable_warnings +--enable_result_log +--enable_query_log + +create index i_n_name on nation(n_name); +analyze table + nation, lineitem, customer, orders, part, supplier, partsupp, region +persistent for all; + +let $c1= + o_orderDATE between '1992-01-01' and '1992-06-30' and + o_custkey = c_custkey and + c_nationkey = n_nationkey and + n_name='PERU'; + +eval +explain +select o_orderkey, o_totalprice from orders, customer, nation where $c1; +--source include/explain-no-costs.inc +eval +explain format=json +select o_orderkey, o_totalprice from orders, customer, nation where $c1; +--sorted_result +eval +select o_orderkey, o_totalprice from orders, customer, nation where $c1; +eval +create table t as +select orders.* from orders, customer, nation where $c1; + +eval +explain +delete from orders using orders, customer, nation where $c1; +--source include/explain-no-costs.inc +eval +explain format=json +delete from orders using orders, customer, nation where $c1; +eval +delete from orders using orders, customer, nation where $c1; +eval +select o_orderkey, o_totalprice from orders, customer, nation where $c1; + +insert into orders select * from t; +--sorted_result +eval +select o_orderkey, o_totalprice from orders, customer, nation where $c1; + +eval +prepare stmt from " +delete from orders using orders, customer, nation where $c1; +"; + +execute stmt; +--sorted_result +eval +select o_orderkey, o_totalprice from orders, customer, nation where $c1; +insert into orders select * from t; +--sorted_result +eval +select o_orderkey, o_totalprice from orders, customer, nation where $c1; + +execute stmt; +--sorted_result +eval +select o_orderkey, o_totalprice from orders, customer, nation where $c1; +insert into orders select * from t; +--sorted_result +eval +select o_orderkey, o_totalprice from orders, customer, nation where $c1; + +deallocate prepare stmt; + +drop table t; + +let $c1= + o_orderDATE between '1992-01-01' and '1992-06-30' and + o_custkey in (select c_custkey from customer + where c_nationkey in (select n_nationkey from nation + where n_name='PERU')); + +eval +explain +select o_orderkey, o_totalprice from orders where $c1; +--source include/explain-no-costs.inc +eval +explain format=json +select o_orderkey, o_totalprice from orders where $c1; +--sorted_result +eval +select o_orderkey, o_totalprice from orders where $c1; +eval +create table t as +select * from orders where $c1; + +eval +explain +delete from orders where $c1; +--source include/explain-no-costs.inc +eval +explain format=json +delete from orders where $c1; +eval +delete from orders where $c1; +eval +select o_orderkey, o_totalprice from orders where $c1; + +insert into orders select * from t; +--sorted_result +eval +select o_orderkey, o_totalprice from orders where $c1; +drop table t; + +DROP DATABASE dbt3_s001; + +set default_storage_engine=@save_default_storage_engine; + +--echo # +--echo # Additional tests of first table and rowid filter +--echo # + +CREATE DATABASE dbt3_s001; + +use dbt3_s001; + +set @save_default_storage_engine=@@default_storage_engine; +set default_storage_engine=InnoDB; + +--disable_query_log +--disable_result_log +--disable_warnings +--source include/dbt3_s001.inc +--enable_warnings +--enable_result_log +--enable_query_log + +CREATE INDEX i_l_quantity ON lineitem(l_quantity); +CREATE INDEX i_o_totalprice ON orders(o_totalprice); +ANALYZE TABLE lineitem, orders; +set optimizer_use_condition_selectivity=2; +create table second(s_receiptDATE date, filler char(100), key(s_receiptDATE)) ; +insert into second select date_add(l_receiptDATE, interval 1 day), 'helllo' from lineitem ; + +select count(*) from lineitem, second WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND l_quantity > 47 and second.s_receiptDATE = date_add(l_receiptDATE, interval 1 day); + +--echo # lineitem should be first and with "Using rowid filter" +explain delete lineitem FROM lineitem, second WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND l_quantity > 47 and second.s_receiptDATE = date_add(l_receiptDATE, interval 1 day); + +delete lineitem FROM lineitem, second WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND l_quantity > 47 and second.s_receiptDATE = date_add(l_receiptDATE, interval 1 day); + +--echo # Should be 0 +select count(*) from lineitem, second WHERE l_shipdate BETWEEN '1997-01-01' AND '1997-06-30' AND l_quantity > 47 and second.s_receiptDATE = date_add(l_receiptDATE, interval 1 day); + +drop database dbt3_s001; +set default_storage_engine=@save_default_storage_engine; + + --echo End of 11.1 tests diff --git a/mysql-test/main/derived_split_innodb.result b/mysql-test/main/derived_split_innodb.result index 2fbb6da2d03..90b980bb4e0 100644 --- a/mysql-test/main/derived_split_innodb.result +++ b/mysql-test/main/derived_split_innodb.result @@ -906,5 +906,61 @@ SELECT * FROM t1 WHERE t1.a IN (SELECT b FROM (SELECT t2.b FROM t2 WHERE NOT EXISTS (SELECT 1 FROM t3) GROUP BY b) sq); a DROP TABLE t1, t2, t3; +# +# MDEV-23878: Wrong result with semi-join and splittable derived table +# +CREATE TABLE t1 ( +groupId int, +id int unsigned, +PRIMARY KEY (groupId, id) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES +(8,1),(8,2),(8,3),(8,4),(8,5),(8,6),(8,7),(8,8),(8,9),(8,10), +(8,11),(8,12),(8,13),(8,14),(8,15),(8,16),(8,17),(8,18),(8,19); +set statement in_predicate_conversion_threshold=2 for SELECT COUNT(*) AS cnt FROM t1 +JOIN +( +SELECT groupId, id +FROM t1 +WHERE id IN (1,2,3,4,5,6) +GROUP BY groupId, id +) AS t2 +USING (groupId, id) +WHERE id IN (1,2,3,4,5,6,7,8); +cnt +6 +set statement in_predicate_conversion_threshold=2 for EXPLAIN SELECT COUNT(*) AS cnt FROM t1 +JOIN +( +SELECT groupId, id +FROM t1 +WHERE id IN (1,2,3,4,5,6) +GROUP BY groupId, id +) AS t2 +USING (groupId, id) +WHERE id IN (1,2,3,4,5,6,7,8); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 19 +1 PRIMARY ref key0 key0 8 test.t1.groupId,test.t1.id 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t1.id 1 Using where +5 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used +3 LATERAL DERIVED t1 eq_ref PRIMARY PRIMARY 8 test.t1.groupId,test.t1.id 1 +3 LATERAL DERIVED eq_ref distinct_key distinct_key 4 test.t1.id 1 Using where +7 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used +set statement optimizer_switch='split_materialized=off, loosescan=off' for +set statement in_predicate_conversion_threshold=2 for +SELECT COUNT(*) AS cnt FROM t1 +JOIN +( +SELECT groupId, id +FROM t1 +WHERE id IN (1,2,3,4,5,6) +GROUP BY groupId, id +) AS t2 +USING (groupId, id) +WHERE id IN (1,2,3,4,5,6,7,8); +cnt +6 +DROP TABLE t1; # End of 10.4 tests SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/main/derived_split_innodb.test b/mysql-test/main/derived_split_innodb.test index acd7674786a..f0498834254 100644 --- a/mysql-test/main/derived_split_innodb.test +++ b/mysql-test/main/derived_split_innodb.test @@ -517,6 +517,48 @@ SELECT * FROM t1 WHERE t1.a IN (SELECT b FROM DROP TABLE t1, t2, t3; +--echo # +--echo # MDEV-23878: Wrong result with semi-join and splittable derived table +--echo # + +CREATE TABLE t1 ( + groupId int, + id int unsigned, + PRIMARY KEY (groupId, id) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO t1 VALUES + (8,1),(8,2),(8,3),(8,4),(8,5),(8,6),(8,7),(8,8),(8,9),(8,10), + (8,11),(8,12),(8,13),(8,14),(8,15),(8,16),(8,17),(8,18),(8,19); + +let $query= +SELECT COUNT(*) AS cnt FROM t1 +JOIN +( + SELECT groupId, id + FROM t1 + WHERE id IN (1,2,3,4,5,6) + GROUP BY groupId, id +) AS t2 +USING (groupId, id) +WHERE id IN (1,2,3,4,5,6,7,8); + +let $tvc_conversion_threshold = + set statement in_predicate_conversion_threshold=2 for; + +eval $tvc_conversion_threshold $query; +eval $tvc_conversion_threshold EXPLAIN $query; + +let $no_split_materialized_loosescan= + set statement optimizer_switch='split_materialized=off, loosescan=off' for; + +# Correct result with split materializied optimization disabled +eval $no_split_materialized_loosescan + $tvc_conversion_threshold + $query; + +DROP TABLE t1; + --echo # End of 10.4 tests SET GLOBAL innodb_stats_persistent=@save_innodb_stats_persistent; diff --git a/mysql-test/main/derived_view.result b/mysql-test/main/derived_view.result index 130516cc950..5ceb04cb75d 100644 --- a/mysql-test/main/derived_view.result +++ b/mysql-test/main/derived_view.result @@ -4354,8 +4354,74 @@ a drop table t1, t2; drop view v1; drop procedure aproc; +# +# MDEV-31305: Aggregation over materialized derived table +# +CREATE VIEW v AS +SELECT seq1.seq AS dim1, seq2.seq AS dim2, seq3.seq AS dim3, +FLOOR(RAND(13) * 5) AS p +FROM seq_100_to_105 seq1 +JOIN seq_10_to_15 seq2 +JOIN seq_1_to_5 seq3; +SELECT v.*, SUM(p) from v; +dim1 dim2 dim3 p SUM(p) +100 10 1 2 371 +SELECT d.*, SUM(p) +FROM ( +SELECT seq1.seq AS dim1, seq2.seq AS dim2, seq3.seq AS dim3, +FLOOR(RAND(13) * 5) AS p +FROM seq_100_to_105 seq1 +JOIN seq_10_to_15 seq2 +JOIN seq_1_to_5 seq3 +) d; +dim1 dim2 dim3 p SUM(p) +100 10 1 2 371 +WITH demo AS +( +SELECT seq1.seq AS dim1, seq2.seq AS dim2, seq3.seq AS dim3, +FLOOR(RAND(13) * 5) AS p +FROM seq_100_to_105 seq1 +JOIN seq_10_to_15 seq2 +JOIN seq_1_to_5 seq3 +) +SELECT d.*, SUM(p) FROM demo d; +dim1 dim2 dim3 p SUM(p) +100 10 1 2 371 +DROP VIEW v; # End of 10.4 tests # +# MDEV-31277: 2-nd execution of PS to select from materialized view +# specified as left join whose inner table is mergeable +# derived containing a constant column +# +create table t1 ( +Election int(10) unsigned NOT NULL +) engine=MyISAM; +insert into t1 (Election) values (1), (4); +create table t2 ( +VoteID int(10), +ElectionID int(10), +UserID int(10) +); +insert into t2 (ElectionID, UserID) values (2, 30), (3, 30); +create view v1 as select * from t1 +left join ( select 'Y' AS Voted, ElectionID from t2 ) AS T +on T.ElectionID = t1.Election +limit 9; +prepare stmt1 from "select * from v1"; +execute stmt1; +Election Voted ElectionID +1 NULL NULL +4 NULL NULL +execute stmt1; +Election Voted ElectionID +1 NULL NULL +4 NULL NULL +deallocate prepare stmt1; +drop view v1; +drop table t1, t2; +# End of 10.5 tests +# # MDEV-31143: view with ORDER BY used in query with rownum() in WHERE # create table t1 (id int primary key); diff --git a/mysql-test/main/derived_view.test b/mysql-test/main/derived_view.test index a7b09e7b02c..1cfc0cbfa30 100644 --- a/mysql-test/main/derived_view.test +++ b/mysql-test/main/derived_view.test @@ -2803,8 +2803,80 @@ drop table t1, t2; drop view v1; drop procedure aproc; +--echo # +--echo # MDEV-31305: Aggregation over materialized derived table +--echo # + +--source include/have_sequence.inc + +CREATE VIEW v AS + SELECT seq1.seq AS dim1, seq2.seq AS dim2, seq3.seq AS dim3, + FLOOR(RAND(13) * 5) AS p + FROM seq_100_to_105 seq1 + JOIN seq_10_to_15 seq2 + JOIN seq_1_to_5 seq3; + +SELECT v.*, SUM(p) from v; + +SELECT d.*, SUM(p) + FROM ( + SELECT seq1.seq AS dim1, seq2.seq AS dim2, seq3.seq AS dim3, + FLOOR(RAND(13) * 5) AS p + FROM seq_100_to_105 seq1 + JOIN seq_10_to_15 seq2 + JOIN seq_1_to_5 seq3 +) d; + +WITH demo AS +( + SELECT seq1.seq AS dim1, seq2.seq AS dim2, seq3.seq AS dim3, + FLOOR(RAND(13) * 5) AS p + FROM seq_100_to_105 seq1 + JOIN seq_10_to_15 seq2 + JOIN seq_1_to_5 seq3 +) +SELECT d.*, SUM(p) FROM demo d; + +DROP VIEW v; + --echo # End of 10.4 tests +--echo # +--echo # MDEV-31277: 2-nd execution of PS to select from materialized view +--echo # specified as left join whose inner table is mergeable +--echo # derived containing a constant column +--echo # + +create table t1 ( + Election int(10) unsigned NOT NULL +) engine=MyISAM; + +insert into t1 (Election) values (1), (4); + +create table t2 ( + VoteID int(10), + ElectionID int(10), + UserID int(10) +); + +insert into t2 (ElectionID, UserID) values (2, 30), (3, 30); +create view v1 as select * from t1 + left join ( select 'Y' AS Voted, ElectionID from t2 ) AS T + on T.ElectionID = t1.Election +limit 9; + +prepare stmt1 from "select * from v1"; + +execute stmt1; +execute stmt1; + +deallocate prepare stmt1; + +drop view v1; +drop table t1, t2; + +--echo # End of 10.5 tests + --echo # --echo # MDEV-31143: view with ORDER BY used in query with rownum() in WHERE --echo # diff --git a/mysql-test/main/distinct_notembedded.result b/mysql-test/main/distinct_notembedded.result new file mode 100644 index 00000000000..df81fe1c228 --- /dev/null +++ b/mysql-test/main/distinct_notembedded.result @@ -0,0 +1,322 @@ +# +# MDEV-30660 COUNT DISTINCT seems unnecessarily slow when run on a PK +# +set @save_optimizer_trace = @@optimizer_trace; +SET optimizer_trace='enabled=on'; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT NOT NULL); +INSERT INTO t1 VALUES (1,1), (2,1), (3,1); +# Optimization is applied (aggregator=simple): +SELECT COUNT(DISTINCT a) FROM t1; +COUNT(DISTINCT a) +3 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct t1.a)", + "aggregator_type": "simple" + } +] +SELECT AVG(DISTINCT a), SUM(DISTINCT b) FROM t1; +AVG(DISTINCT a) SUM(DISTINCT b) +2.0000 1 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "avg(distinct t1.a)", + "aggregator_type": "simple" + }, + { + "function": "sum(distinct t1.b)", + "aggregator_type": "distinct" + } +] +# Only `a` is unique but it's enough to eliminate DISTINCT: +SELECT COUNT(DISTINCT b, a) FROM t1; +COUNT(DISTINCT b, a) +3 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct t1.b,t1.a)", + "aggregator_type": "simple" + } +] +SELECT COUNT(DISTINCT a, a + b) FROM t1; +COUNT(DISTINCT a, a + b) +3 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct t1.a,t1.a + t1.b)", + "aggregator_type": "simple" + } +] +SELECT SUM(DISTINCT a), AVG(DISTINCT a), COUNT(DISTINCT a) FROM t1 WHERE a > 1; +SUM(DISTINCT a) AVG(DISTINCT a) COUNT(DISTINCT a) +5 2.5000 2 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "sum(distinct t1.a)", + "aggregator_type": "simple" + }, + { + "function": "avg(distinct t1.a)", + "aggregator_type": "simple" + }, + { + "function": "count(distinct t1.a)", + "aggregator_type": "simple" + } +] +# Optimization is not applied 'cause function argument is not a field +# (aggregator=distinct): +SELECT SUM(DISTINCT a + b) FROM t1; +SUM(DISTINCT a + b) +9 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "sum(distinct t1.a + t1.b)", + "aggregator_type": "distinct" + } +] +SELECT COUNT(DISTINCT b) FROM t1; +COUNT(DISTINCT b) +1 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct t1.b)", + "aggregator_type": "distinct" + } +] +SELECT AVG(DISTINCT b / a) FROM t1; +AVG(DISTINCT b / a) +0.61110000 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "avg(distinct t1.b / t1.a)", + "aggregator_type": "distinct" + } +] +EXPLAIN SELECT COUNT(DISTINCT (SELECT a)) FROM t1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 index NULL PRIMARY 4 NULL 3 Using index +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct (/* select#2 */ select t1.a))", + "aggregator_type": "distinct" + } +] +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (1), (2); +# Optimization is not applied 'cause there is more than one table +SELECT COUNT(DISTINCT t1.a) FROM t1, t2; +COUNT(DISTINCT t1.a) +3 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct t1.a)", + "aggregator_type": "distinct" + } +] +SELECT AVG(DISTINCT t1.a) FROM t1, t2; +AVG(DISTINCT t1.a) +2.0000 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "avg(distinct t1.a)", + "aggregator_type": "distinct" + } +] +# Const tables, optimization is applied +SELECT COUNT(DISTINCT a) FROM t1, (SELECT 1) AS t2; +COUNT(DISTINCT a) +3 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct t1.a)", + "aggregator_type": "simple" + } +] +SELECT AVG(DISTINCT t1.a) FROM (SELECT 1 AS a) AS t2, t1, (SELECT 2 AS a) AS t3; +AVG(DISTINCT t1.a) +2.0000 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "avg(distinct t1.a)", + "aggregator_type": "simple" + } +] +SELECT COUNT(DISTINCT a) FROM t1, (SELECT 1 UNION SELECT 2) AS t2; +COUNT(DISTINCT a) +3 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct t1.a)", + "aggregator_type": "distinct" + } +] +# Unique index on two columns +CREATE TABLE t3 (a INT NOT NULL, b INT NOT NULL); +INSERT INTO t3 VALUES (1,1), (1,2), (1,3), (2,1), (2,2), (3,1), (3,2); +CREATE UNIQUE INDEX t3_a_b ON t3 (a, b); +# Optimization is applied: +SELECT COUNT(DISTINCT a, b) FROM t3; +COUNT(DISTINCT a, b) +7 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct t3.a,t3.b)", + "aggregator_type": "simple" + } +] +SELECT COUNT(DISTINCT b, a) FROM t3; +COUNT(DISTINCT b, a) +7 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct t3.b,t3.a)", + "aggregator_type": "simple" + } +] +SELECT COUNT(DISTINCT b, a) FROM t3 WHERE a < 3; +COUNT(DISTINCT b, a) +5 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct t3.b,t3.a)", + "aggregator_type": "simple" + } +] +# Optimization is applied to one of the functions: +SELECT COUNT(DISTINCT b), SUM(DISTINCT a), SUM(DISTINCT a + b) FROM t3 GROUP BY a; +COUNT(DISTINCT b) SUM(DISTINCT a) SUM(DISTINCT a + b) +3 1 9 +2 2 7 +2 3 9 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct t3.b)", + "aggregator_type": "simple" + }, + { + "function": "sum(distinct t3.a)", + "aggregator_type": "distinct" + }, + { + "function": "sum(distinct t3.a + t3.b)", + "aggregator_type": "distinct" + } +] +# Can't apply optimization 'cause GROUP BY argument is not a field: +SELECT COUNT(DISTINCT b) FROM t3 GROUP BY a+b; +COUNT(DISTINCT b) +1 +2 +3 +1 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct t3.b)", + "aggregator_type": "distinct" + } +] +# Test merged view +CREATE VIEW v1 AS SELECT * FROM t1; +# Optimization is applied +SELECT COUNT(DISTINCT a, b) FROM v1; +COUNT(DISTINCT a, b) +3 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "count(distinct t1.a,t1.b)", + "aggregator_type": "simple" + } +] +# GROUP_CONCAT implements non-standard distinct aggregator +SELECT GROUP_CONCAT(b) FROM t1; +GROUP_CONCAT(b) +1,1,1 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "group_concat(t1.b separator ',')", + "aggregator_type": "simple" + } +] +SELECT GROUP_CONCAT(DISTINCT b) FROM t1; +GROUP_CONCAT(DISTINCT b) +1 +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.prepare_sum_aggregators')) AS JS +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +JS +[ + { + "function": "group_concat(distinct t1.b separator ',')", + "aggregator_type": "distinct" + } +] +DROP TABLE t1, t2, t3; +DROP VIEW v1; +SET optimizer_trace = @save_optimizer_trace; +# +# end of 10.5 tests +# diff --git a/mysql-test/main/distinct_notembedded.test b/mysql-test/main/distinct_notembedded.test new file mode 100644 index 00000000000..9ef2f45913c --- /dev/null +++ b/mysql-test/main/distinct_notembedded.test @@ -0,0 +1,109 @@ +# Embedded doesn't have optimizer trace: +--source include/not_embedded.inc +--source include/have_sequence.inc + +--echo # +--echo # MDEV-30660 COUNT DISTINCT seems unnecessarily slow when run on a PK +--echo # + +set @save_optimizer_trace = @@optimizer_trace; +SET optimizer_trace='enabled=on'; +let $trace= +SELECT JSON_DETAILED(JSON_EXTRACT(trace, '\$**.prepare_sum_aggregators')) AS JS + FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; + +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT NOT NULL); +INSERT INTO t1 VALUES (1,1), (2,1), (3,1); + +--echo # Optimization is applied (aggregator=simple): +SELECT COUNT(DISTINCT a) FROM t1; +eval $trace; + +SELECT AVG(DISTINCT a), SUM(DISTINCT b) FROM t1; +eval $trace; + +--echo # Only `a` is unique but it's enough to eliminate DISTINCT: +SELECT COUNT(DISTINCT b, a) FROM t1; +eval $trace; + +SELECT COUNT(DISTINCT a, a + b) FROM t1; +eval $trace; + +SELECT SUM(DISTINCT a), AVG(DISTINCT a), COUNT(DISTINCT a) FROM t1 WHERE a > 1; +eval $trace; + +--echo # Optimization is not applied 'cause function argument is not a field +--echo # (aggregator=distinct): +SELECT SUM(DISTINCT a + b) FROM t1; +eval $trace; + +SELECT COUNT(DISTINCT b) FROM t1; +eval $trace; + +SELECT AVG(DISTINCT b / a) FROM t1; +eval $trace; + +EXPLAIN SELECT COUNT(DISTINCT (SELECT a)) FROM t1; +eval $trace; + +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (1), (2); + +--echo # Optimization is not applied 'cause there is more than one table +SELECT COUNT(DISTINCT t1.a) FROM t1, t2; +eval $trace; + +SELECT AVG(DISTINCT t1.a) FROM t1, t2; +eval $trace; + +--echo # Const tables, optimization is applied +SELECT COUNT(DISTINCT a) FROM t1, (SELECT 1) AS t2; +eval $trace; + +SELECT AVG(DISTINCT t1.a) FROM (SELECT 1 AS a) AS t2, t1, (SELECT 2 AS a) AS t3; +eval $trace; + +SELECT COUNT(DISTINCT a) FROM t1, (SELECT 1 UNION SELECT 2) AS t2; +eval $trace; + +--echo # Unique index on two columns +CREATE TABLE t3 (a INT NOT NULL, b INT NOT NULL); +INSERT INTO t3 VALUES (1,1), (1,2), (1,3), (2,1), (2,2), (3,1), (3,2); +CREATE UNIQUE INDEX t3_a_b ON t3 (a, b); +--echo # Optimization is applied: +SELECT COUNT(DISTINCT a, b) FROM t3; +eval $trace; + +SELECT COUNT(DISTINCT b, a) FROM t3; +eval $trace; + +SELECT COUNT(DISTINCT b, a) FROM t3 WHERE a < 3; +eval $trace; + +--echo # Optimization is applied to one of the functions: +SELECT COUNT(DISTINCT b), SUM(DISTINCT a), SUM(DISTINCT a + b) FROM t3 GROUP BY a; +eval $trace; + +--echo # Can't apply optimization 'cause GROUP BY argument is not a field: +SELECT COUNT(DISTINCT b) FROM t3 GROUP BY a+b; +eval $trace; + +--echo # Test merged view +CREATE VIEW v1 AS SELECT * FROM t1; +--echo # Optimization is applied +SELECT COUNT(DISTINCT a, b) FROM v1; +eval $trace; + +--echo # GROUP_CONCAT implements non-standard distinct aggregator +SELECT GROUP_CONCAT(b) FROM t1; +eval $trace; + +SELECT GROUP_CONCAT(DISTINCT b) FROM t1; +eval $trace; + +DROP TABLE t1, t2, t3; +DROP VIEW v1; +SET optimizer_trace = @save_optimizer_trace; +--echo # +--echo # end of 10.5 tests +--echo # diff --git a/mysql-test/main/dyncol.result b/mysql-test/main/dyncol.result index 88cec1c50f0..64ce60b4e45 100644 --- a/mysql-test/main/dyncol.result +++ b/mysql-test/main/dyncol.result @@ -150,7 +150,7 @@ select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8, id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select hex(column_create(1,'afaf' AS char charset utf8mb3 ,2,1212 AS unsigned int,3,1212 AS int,4,12.12 AS double,4 + 1,12.12 AS decimal,6,'2011-04-05' AS date,7,'- 0:45:49.000001' AS time,8,'2011-04-05 0:45:49.000001' AS datetime)) AS `ex` +Note 1003 select hex(column_create(1,'afaf' AS char charset utf8mb3 collate utf8mb3_general_ci ,2,1212 AS unsigned int,3,1212 AS int,4,12.12 AS double,4 + 1,12.12 AS decimal,6,'2011-04-05' AS date,7,'- 0:45:49.000001' AS time,8,'2011-04-05 0:45:49.000001' AS datetime)) AS `ex` select hex(column_create(1, 0.0 AS decimal)); hex(column_create(1, 0.0 AS decimal)) 000100010004 @@ -354,7 +354,7 @@ select column_get(column_create(1, "1212" AS char charset utf8), 1 as char chars id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select column_get(column_create(1,'1212' AS char charset utf8mb3 ),1 as char charset utf8mb3) AS `ex` +Note 1003 select column_get(column_create(1,'1212' AS char charset utf8mb3 collate utf8mb3_general_ci ),1 as char charset utf8mb3) AS `ex` select column_get(column_create(1, 1212 AS unsigned int), 1 as char charset utf8) as ex; ex 1212 @@ -414,7 +414,7 @@ select column_get(column_create(1, "1212" AS char charset utf8), 1 as char chars id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select column_get(column_create(1,'1212' AS char charset utf8mb3 ),1 as char charset binary) AS `ex` +Note 1003 select column_get(column_create(1,'1212' AS char charset utf8mb3 collate utf8mb3_general_ci ),1 as char charset binary) AS `ex` # # column get real # @@ -1882,7 +1882,7 @@ drop table t1; create view v1 as select column_get(column_add(column_create(1 , 'blue' as char), 2, 'ttt'), 1 as char); show create view v1; View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select column_get(column_add(column_create(1,'blue' AS char charset utf8mb3 ),2,'ttt'),1 as char charset utf8mb3) AS `Name_exp_1` utf8mb3 utf8mb3_general_ci +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select column_get(column_add(column_create(1,'blue' AS char charset utf8mb3 collate utf8mb3_general_ci ),2,'ttt'),1 as char charset utf8mb3) AS `Name_exp_1` utf8mb3 utf8mb3_general_ci select * from v1; Name_exp_1 blue @@ -1949,3 +1949,23 @@ ex # # End of 10.4 tests # +# +# Start of 10.5 tests +# +# +# Start of 10.5 tests +# +# +# MDEV-33788 HEX(COLUMN_CREATE(.. AS CHAR ...)) fails with --view-protocol +# +SELECT hex(column_create(1,'a' AS CHAR CHARACTER SET utf8mb3 COLLATE utf8mb3_bin)) AS ex; +ex +0001000100035361 +SELECT hex(column_add(column_create( +1, 'a' AS CHAR CHARACTER SET utf8mb3 COLLATE utf8mb3_bin), +2, 'b' AS CHAR CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci)) AS ex; +ex +00020001000302001353612162 +# +# Start of 10.5 tests +# diff --git a/mysql-test/main/dyncol.test b/mysql-test/main/dyncol.test index 8b3164217d1..1343025d5c5 100644 --- a/mysql-test/main/dyncol.test +++ b/mysql-test/main/dyncol.test @@ -1000,3 +1000,24 @@ SELECT HEX(COLUMN_ADD(COLUMN_CREATE(1,10),2,NULL,1,NULL)) as ex; --echo # --echo # End of 10.4 tests --echo # + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-33788 HEX(COLUMN_CREATE(.. AS CHAR ...)) fails with --view-protocol +--echo # + +SELECT hex(column_create(1,'a' AS CHAR CHARACTER SET utf8mb3 COLLATE utf8mb3_bin)) AS ex; +SELECT hex(column_add(column_create( + 1, 'a' AS CHAR CHARACTER SET utf8mb3 COLLATE utf8mb3_bin), + 2, 'b' AS CHAR CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci)) AS ex; + +--echo # +--echo # Start of 10.5 tests +--echo # diff --git a/mysql-test/main/empty_server_name-8224.test b/mysql-test/main/empty_server_name-8224.test index 5c5140be2e0..31760713bc8 100644 --- a/mysql-test/main/empty_server_name-8224.test +++ b/mysql-test/main/empty_server_name-8224.test @@ -3,10 +3,10 @@ # --source include/not_embedded.inc create server '' foreign data wrapper w2 options (host '127.0.0.1'); ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -- enable_reconnect -- source include/wait_until_connected_again.inc diff --git a/mysql-test/main/empty_string_literal.result b/mysql-test/main/empty_string_literal.result index 732e8e6d557..447bad8a75a 100644 --- a/mysql-test/main/empty_string_literal.result +++ b/mysql-test/main/empty_string_literal.result @@ -64,7 +64,7 @@ SET sql_mode=@mode; # Test litteral concat # SELECT 'a' 'b'; -a +ab ab SELECT 'a' ''; a @@ -76,13 +76,13 @@ SELECT '' ''; NULL NULL SELECT '' 'b' 'c'; -b +bc bc SELECT '' '' 'c'; c c SELECT 'a' '' 'c'; -a +ac ac SELECT 'a' '' ''; a @@ -208,3 +208,23 @@ t1 CREATE TABLE `t1` ( KEY `a` (`a`,`b`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; +set sql_mode= default; +# +# MDEV-33460 select '123' 'x'; unexpected result +# +SELECT ''; + + +SELECT '' 'b' 'c'; +bc +bc +SELECT '' '' 'c'; +c +c +SELECT 'a' '' 'c'; +ac +ac +SELECT 'a' '' ''; +a +a +# End of 10.5 test diff --git a/mysql-test/main/empty_string_literal.test b/mysql-test/main/empty_string_literal.test index 9174a7714a2..e3ae009445b 100644 --- a/mysql-test/main/empty_string_literal.test +++ b/mysql-test/main/empty_string_literal.test @@ -25,3 +25,18 @@ flush tables; update t1 set a = 2; show create table t1; drop table t1; +set sql_mode= default; + +--echo # +--echo # MDEV-33460 select '123' 'x'; unexpected result +--echo # + +--disable_view_protocol +SELECT ''; +--enable_view_protocol +SELECT '' 'b' 'c'; +SELECT '' '' 'c'; +SELECT 'a' '' 'c'; +SELECT 'a' '' ''; + +--echo # End of 10.5 test diff --git a/mysql-test/main/func_encrypt_nossl.result b/mysql-test/main/func_encrypt_nossl.result index ad068153e53..274db05fd8c 100644 --- a/mysql-test/main/func_encrypt_nossl.result +++ b/mysql-test/main/func_encrypt_nossl.result @@ -3,56 +3,56 @@ des_encrypt("test", 'akeystr') NULL Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select des_encrypt("test", 1); des_encrypt("test", 1) NULL Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select des_encrypt("test", 9); des_encrypt("test", 9) NULL Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select des_encrypt("test", 100); des_encrypt("test", 100) NULL Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select des_encrypt("test", NULL); des_encrypt("test", NULL) NULL Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select des_encrypt(NULL, NULL); des_encrypt(NULL, NULL) NULL Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select des_decrypt("test", 'anotherkeystr'); des_decrypt("test", 'anotherkeystr') NULL Warnings: Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select des_decrypt(1, 1); des_decrypt(1, 1) NULL Warnings: Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select des_decrypt(des_encrypt("test", 'thekey')); des_decrypt(des_encrypt("test", 'thekey')) NULL Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select hex(des_encrypt("hello")),des_decrypt(des_encrypt("hello")); hex(des_encrypt("hello")) des_decrypt(des_encrypt("hello")) NULL NULL @@ -60,22 +60,22 @@ Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release Warning 1287 'des_encrypt' is deprecated and will be removed in a future release Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select des_decrypt(des_encrypt("hello",4)); des_decrypt(des_encrypt("hello",4)) NULL Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select des_decrypt(des_encrypt("hello",'test'),'test'); des_decrypt(des_encrypt("hello",'test'),'test') NULL Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select hex(des_encrypt("hello")),hex(des_encrypt("hello",5)),hex(des_encrypt("hello",'default_password')); hex(des_encrypt("hello")) hex(des_encrypt("hello",5)) hex(des_encrypt("hello",'default_password')) NULL NULL NULL @@ -83,28 +83,28 @@ Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release Warning 1287 'des_encrypt' is deprecated and will be removed in a future release Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working +Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select des_decrypt(des_encrypt("hello"),'default_password'); des_decrypt(des_encrypt("hello"),'default_password') NULL Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select des_decrypt(des_encrypt("hello",4),'password4'); des_decrypt(des_encrypt("hello",4),'password4') NULL Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working SET @a=des_decrypt(des_encrypt("hello")); Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working flush des_key_file; select @a = des_decrypt(des_encrypt("hello")); @a = des_decrypt(des_encrypt("hello")) @@ -121,11 +121,11 @@ NULL Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working select hex(des_decrypt(des_encrypt("hello","hidden"))); hex(des_decrypt(des_encrypt("hello","hidden"))) NULL Warnings: Warning 1287 'des_encrypt' is deprecated and will be removed in a future release Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with '--with-ssl' to have it working +Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working diff --git a/mysql-test/main/func_extract.result b/mysql-test/main/func_extract.result index bebb8c717f6..dc71f6ae27a 100644 --- a/mysql-test/main/func_extract.result +++ b/mysql-test/main/func_extract.result @@ -590,3 +590,885 @@ Warning 1292 Truncated incorrect time value: '01:02:03/' Warning 1292 Truncated incorrect time value: '01:02:03/' Warning 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '01:02:03/' DROP TABLE t1; +# +# Start of 10.5 tests +# +# +# MDEV-33496 Out of range error in AVG(YEAR(datetime)) due to a wrong data type +# +CREATE FUNCTION select01() RETURNS TEXT RETURN 'SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?'; +CREATE FUNCTION select02() RETURNS TEXT RETURN 'SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)'; +CREATE TABLE t1 (a DATETIME(6)); +INSERT INTO t1 VALUES ('2001-12-31 10:20:30.999999'); +CREATE FUNCTION params(expr TEXT, count INT) RETURNS TEXT +BEGIN +RETURN CONCAT(expr, REPEAT(CONCAT(', ', expr), count-1)); +END; +$$ +CREATE PROCEDURE show_drop() +BEGIN +SELECT TABLE_NAME, COLUMN_TYPE, COLUMN_NAME +FROM INFORMATION_SCHEMA.COLUMNS +WHERE TABLE_SCHEMA='test' + AND TABLE_NAME IN ('t1e_nm','t2e_nm','t1f_nm','t2f_nm', +'t1e_ps','t1f_ps','t2e_ps','t2f_ps') +ORDER BY LEFT(TABLE_NAME, 2), ORDINAL_POSITION, TABLE_NAME; +FOR rec IN (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_SCHEMA='test' + AND TABLE_NAME IN ('t1e_nm','t2e_nm','t1f_nm','t2f_nm', +'t1e_ps','t1f_ps','t2e_ps','t2f_ps')) +DO +EXECUTE IMMEDIATE CONCAT('DROP TABLE ', rec.TABLE_NAME); +END FOR; +END; +$$ +CREATE PROCEDURE p1(unit VARCHAR(32)) +BEGIN +DECLARE do_extract BOOL DEFAULT unit NOT IN('DAYOFYEAR'); +DECLARE query01 TEXT DEFAULT +CONCAT('CREATE TABLE t2 AS ', select01(), ' FROM t1'); +DECLARE query02 TEXT DEFAULT +CONCAT('CREATE TABLE t2 AS ', select02(), ' FROM t1'); +IF (do_extract) +THEN +EXECUTE IMMEDIATE REPLACE(REPLACE(query01,'t2','t1e_nm'),'?', CONCAT('EXTRACT(',unit,' FROM a)')); +EXECUTE IMMEDIATE REPLACE(REPLACE(query02,'t2','t2e_nm'),'?', CONCAT('EXTRACT(',unit,' FROM a)')); +END IF; +EXECUTE IMMEDIATE REPLACE(REPLACE(query01,'t2','t1f_nm'),'?', CONCAT(unit,'(a)')); +EXECUTE IMMEDIATE REPLACE(REPLACE(query02,'t2','t2f_nm'),'?', CONCAT(unit,'(a)')); +END; +$$ + + +# EXTRACT(YEAR FROM expr) and YEAR(expr) are equivalent +CALL p1('YEAR'); +EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(YEAR FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), YEAR(TIMESTAMP'2001-12-13 10:20:30.999999'); +CALL show_drop; +TABLE_NAME COLUMN_TYPE COLUMN_NAME +t1e_nm int(5) EXTRACT(YEAR FROM a) +t1e_ps int(5) ? +t1f_nm int(5) YEAR(a) +t1f_ps int(5) ? +t1e_nm int(4) unsigned CAST(EXTRACT(YEAR FROM a) AS UNSIGNED) +t1e_ps int(4) unsigned CAST(? AS UNSIGNED) +t1f_nm int(4) unsigned CAST(YEAR(a) AS UNSIGNED) +t1f_ps int(4) unsigned CAST(? AS UNSIGNED) +t1e_nm int(5) CAST(EXTRACT(YEAR FROM a) AS SIGNED) +t1e_ps int(5) CAST(? AS SIGNED) +t1f_nm int(5) CAST(YEAR(a) AS SIGNED) +t1f_ps int(5) CAST(? AS SIGNED) +t1e_nm int(5) ABS(EXTRACT(YEAR FROM a)) +t1e_ps int(5) ABS(?) +t1f_nm int(5) ABS(YEAR(a)) +t1f_ps int(5) ABS(?) +t1e_nm int(5) ROUND(EXTRACT(YEAR FROM a)) +t1e_ps int(5) ROUND(?) +t1f_nm int(5) ROUND(YEAR(a)) +t1f_ps int(5) ROUND(?) +t1e_nm int(5) -EXTRACT(YEAR FROM a) +t1e_ps int(5) -? +t1f_nm int(5) -YEAR(a) +t1f_ps int(5) -? +t1e_nm int(6) ROUND(EXTRACT(YEAR FROM a),-1) +t1e_ps int(6) ROUND(?,-1) +t1f_nm int(6) ROUND(YEAR(a),-1) +t1f_ps int(6) ROUND(?,-1) +t1e_nm int(6) EXTRACT(YEAR FROM a)+0 +t1e_ps int(6) ?+0 +t1f_nm int(6) YEAR(a)+0 +t1f_ps int(6) ?+0 +t1e_nm decimal(6,1) EXTRACT(YEAR FROM a)+0.0 +t1e_ps decimal(6,1) ?+0.0 +t1f_nm decimal(6,1) YEAR(a)+0.0 +t1f_ps decimal(6,1) ?+0.0 +t1e_nm varchar(4) CONCAT(EXTRACT(YEAR FROM a)) +t1e_ps varchar(4) CONCAT(?) +t1f_nm varchar(4) CONCAT(YEAR(a)) +t1f_ps varchar(4) CONCAT(?) +t1e_nm int(5) LEAST(EXTRACT(YEAR FROM a),EXTRACT(YEAR FROM a)) +t1e_ps int(5) LEAST(?,?) +t1f_nm int(5) LEAST(YEAR(a),YEAR(a)) +t1f_ps int(5) LEAST(?,?) +t1e_nm int(5) COALESCE(EXTRACT(YEAR FROM a)) +t1e_ps int(5) COALESCE(?) +t1f_nm int(5) COALESCE(YEAR(a)) +t1f_ps int(5) COALESCE(?) +t1e_nm int(5) COALESCE(EXTRACT(YEAR FROM a),CAST(1 AS SIGNED)) +t1e_ps int(5) COALESCE(?,CAST(1 AS SIGNED)) +t1f_nm int(5) COALESCE(YEAR(a),CAST(1 AS SIGNED)) +t1f_ps int(5) COALESCE(?,CAST(1 AS SIGNED)) +t1e_nm decimal(4,0) COALESCE(EXTRACT(YEAR FROM a),CAST(1 AS UNSIGNED)) +t1e_ps decimal(4,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1f_nm decimal(4,0) COALESCE(YEAR(a),CAST(1 AS UNSIGNED)) +t1f_ps decimal(4,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1e_nm int(5) @a:=EXTRACT(YEAR FROM a) +t1e_ps int(5) @a:=? +t1f_nm int(5) @a:=YEAR(a) +t1f_ps int(5) @a:=? +t2e_nm decimal(8,4) AVG(EXTRACT(YEAR FROM a)) +t2e_ps decimal(8,4) AVG(?) +t2f_nm decimal(8,4) AVG(YEAR(a)) +t2f_ps decimal(8,4) AVG(?) +t2e_nm bigint(5) MIN(EXTRACT(YEAR FROM a)) +t2e_ps bigint(5) MIN(?) +t2f_nm bigint(5) MIN(YEAR(a)) +t2f_ps bigint(5) MIN(?) +t2e_nm bigint(5) MAX(EXTRACT(YEAR FROM a)) +t2e_ps bigint(5) MAX(?) +t2f_nm bigint(5) MAX(YEAR(a)) +t2f_ps bigint(5) MAX(?) +t2e_nm mediumtext GROUP_CONCAT(EXTRACT(YEAR FROM a)) +t2e_ps mediumtext GROUP_CONCAT(?) +t2f_nm mediumtext GROUP_CONCAT(YEAR(a)) +t2f_ps mediumtext GROUP_CONCAT(?) + + +# EXTRACT(QUARTER FROM expr) and QUARTER(expr) are equavalent +CALL p1('QUARTER'); +EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(QUARTER FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'), QUARTER(TIMESTAMP'2001-12-13 10:20:30.999999'); +CALL show_drop; +TABLE_NAME COLUMN_TYPE COLUMN_NAME +t1e_nm int(2) EXTRACT(QUARTER FROM a) +t1e_ps int(2) ? +t1f_nm int(2) QUARTER(a) +t1f_ps int(2) ? +t1e_nm int(1) unsigned CAST(EXTRACT(QUARTER FROM a) AS UNSIGNED) +t1e_ps int(1) unsigned CAST(? AS UNSIGNED) +t1f_nm int(1) unsigned CAST(QUARTER(a) AS UNSIGNED) +t1f_ps int(1) unsigned CAST(? AS UNSIGNED) +t1e_nm int(2) CAST(EXTRACT(QUARTER FROM a) AS SIGNED) +t1e_ps int(2) CAST(? AS SIGNED) +t1f_nm int(2) CAST(QUARTER(a) AS SIGNED) +t1f_ps int(2) CAST(? AS SIGNED) +t1e_nm int(2) ABS(EXTRACT(QUARTER FROM a)) +t1e_ps int(2) ABS(?) +t1f_nm int(2) ABS(QUARTER(a)) +t1f_ps int(2) ABS(?) +t1e_nm int(2) ROUND(EXTRACT(QUARTER FROM a)) +t1e_ps int(2) ROUND(?) +t1f_nm int(2) ROUND(QUARTER(a)) +t1f_ps int(2) ROUND(?) +t1e_nm int(2) -EXTRACT(QUARTER FROM a) +t1e_ps int(2) -? +t1f_nm int(2) -QUARTER(a) +t1f_ps int(2) -? +t1e_nm int(3) ROUND(EXTRACT(QUARTER FROM a),-1) +t1e_ps int(3) ROUND(?,-1) +t1f_nm int(3) ROUND(QUARTER(a),-1) +t1f_ps int(3) ROUND(?,-1) +t1e_nm int(3) EXTRACT(QUARTER FROM a)+0 +t1e_ps int(3) ?+0 +t1f_nm int(3) QUARTER(a)+0 +t1f_ps int(3) ?+0 +t1e_nm decimal(3,1) EXTRACT(QUARTER FROM a)+0.0 +t1e_ps decimal(3,1) ?+0.0 +t1f_nm decimal(3,1) QUARTER(a)+0.0 +t1f_ps decimal(3,1) ?+0.0 +t1e_nm varchar(1) CONCAT(EXTRACT(QUARTER FROM a)) +t1e_ps varchar(1) CONCAT(?) +t1f_nm varchar(1) CONCAT(QUARTER(a)) +t1f_ps varchar(1) CONCAT(?) +t1e_nm int(2) LEAST(EXTRACT(QUARTER FROM a),EXTRACT(QUARTER FROM a)) +t1e_ps int(2) LEAST(?,?) +t1f_nm int(2) LEAST(QUARTER(a),QUARTER(a)) +t1f_ps int(2) LEAST(?,?) +t1e_nm int(2) COALESCE(EXTRACT(QUARTER FROM a)) +t1e_ps int(2) COALESCE(?) +t1f_nm int(2) COALESCE(QUARTER(a)) +t1f_ps int(2) COALESCE(?) +t1e_nm int(2) COALESCE(EXTRACT(QUARTER FROM a),CAST(1 AS SIGNED)) +t1e_ps int(2) COALESCE(?,CAST(1 AS SIGNED)) +t1f_nm int(2) COALESCE(QUARTER(a),CAST(1 AS SIGNED)) +t1f_ps int(2) COALESCE(?,CAST(1 AS SIGNED)) +t1e_nm decimal(1,0) COALESCE(EXTRACT(QUARTER FROM a),CAST(1 AS UNSIGNED)) +t1e_ps decimal(1,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1f_nm decimal(1,0) COALESCE(QUARTER(a),CAST(1 AS UNSIGNED)) +t1f_ps decimal(1,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1e_nm int(2) @a:=EXTRACT(QUARTER FROM a) +t1e_ps int(2) @a:=? +t1f_nm int(2) @a:=QUARTER(a) +t1f_ps int(2) @a:=? +t2e_nm decimal(5,4) AVG(EXTRACT(QUARTER FROM a)) +t2e_ps decimal(5,4) AVG(?) +t2f_nm decimal(5,4) AVG(QUARTER(a)) +t2f_ps decimal(5,4) AVG(?) +t2e_nm bigint(2) MIN(EXTRACT(QUARTER FROM a)) +t2e_ps bigint(2) MIN(?) +t2f_nm bigint(2) MIN(QUARTER(a)) +t2f_ps bigint(2) MIN(?) +t2e_nm bigint(2) MAX(EXTRACT(QUARTER FROM a)) +t2e_ps bigint(2) MAX(?) +t2f_nm bigint(2) MAX(QUARTER(a)) +t2f_ps bigint(2) MAX(?) +t2e_nm mediumtext GROUP_CONCAT(EXTRACT(QUARTER FROM a)) +t2e_ps mediumtext GROUP_CONCAT(?) +t2f_nm mediumtext GROUP_CONCAT(QUARTER(a)) +t2f_ps mediumtext GROUP_CONCAT(?) + + +# EXTRACT(MONTH FROM expr) and MONTH(expr) are equavalent +CALL p1('MONTH'); +EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MONTH FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'), MONTH(TIMESTAMP'2001-12-13 10:20:30.999999'); +CALL show_drop; +TABLE_NAME COLUMN_TYPE COLUMN_NAME +t1e_nm int(3) EXTRACT(MONTH FROM a) +t1e_ps int(3) ? +t1f_nm int(3) MONTH(a) +t1f_ps int(3) ? +t1e_nm int(2) unsigned CAST(EXTRACT(MONTH FROM a) AS UNSIGNED) +t1e_ps int(2) unsigned CAST(? AS UNSIGNED) +t1f_nm int(2) unsigned CAST(MONTH(a) AS UNSIGNED) +t1f_ps int(2) unsigned CAST(? AS UNSIGNED) +t1e_nm int(3) CAST(EXTRACT(MONTH FROM a) AS SIGNED) +t1e_ps int(3) CAST(? AS SIGNED) +t1f_nm int(3) CAST(MONTH(a) AS SIGNED) +t1f_ps int(3) CAST(? AS SIGNED) +t1e_nm int(3) ABS(EXTRACT(MONTH FROM a)) +t1e_ps int(3) ABS(?) +t1f_nm int(3) ABS(MONTH(a)) +t1f_ps int(3) ABS(?) +t1e_nm int(3) ROUND(EXTRACT(MONTH FROM a)) +t1e_ps int(3) ROUND(?) +t1f_nm int(3) ROUND(MONTH(a)) +t1f_ps int(3) ROUND(?) +t1e_nm int(3) -EXTRACT(MONTH FROM a) +t1e_ps int(3) -? +t1f_nm int(3) -MONTH(a) +t1f_ps int(3) -? +t1e_nm int(4) ROUND(EXTRACT(MONTH FROM a),-1) +t1e_ps int(4) ROUND(?,-1) +t1f_nm int(4) ROUND(MONTH(a),-1) +t1f_ps int(4) ROUND(?,-1) +t1e_nm int(4) EXTRACT(MONTH FROM a)+0 +t1e_ps int(4) ?+0 +t1f_nm int(4) MONTH(a)+0 +t1f_ps int(4) ?+0 +t1e_nm decimal(4,1) EXTRACT(MONTH FROM a)+0.0 +t1e_ps decimal(4,1) ?+0.0 +t1f_nm decimal(4,1) MONTH(a)+0.0 +t1f_ps decimal(4,1) ?+0.0 +t1e_nm varchar(2) CONCAT(EXTRACT(MONTH FROM a)) +t1e_ps varchar(2) CONCAT(?) +t1f_nm varchar(2) CONCAT(MONTH(a)) +t1f_ps varchar(2) CONCAT(?) +t1e_nm int(3) LEAST(EXTRACT(MONTH FROM a),EXTRACT(MONTH FROM a)) +t1e_ps int(3) LEAST(?,?) +t1f_nm int(3) LEAST(MONTH(a),MONTH(a)) +t1f_ps int(3) LEAST(?,?) +t1e_nm int(3) COALESCE(EXTRACT(MONTH FROM a)) +t1e_ps int(3) COALESCE(?) +t1f_nm int(3) COALESCE(MONTH(a)) +t1f_ps int(3) COALESCE(?) +t1e_nm int(3) COALESCE(EXTRACT(MONTH FROM a),CAST(1 AS SIGNED)) +t1e_ps int(3) COALESCE(?,CAST(1 AS SIGNED)) +t1f_nm int(3) COALESCE(MONTH(a),CAST(1 AS SIGNED)) +t1f_ps int(3) COALESCE(?,CAST(1 AS SIGNED)) +t1e_nm decimal(2,0) COALESCE(EXTRACT(MONTH FROM a),CAST(1 AS UNSIGNED)) +t1e_ps decimal(2,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1f_nm decimal(2,0) COALESCE(MONTH(a),CAST(1 AS UNSIGNED)) +t1f_ps decimal(2,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1e_nm int(3) @a:=EXTRACT(MONTH FROM a) +t1e_ps int(3) @a:=? +t1f_nm int(3) @a:=MONTH(a) +t1f_ps int(3) @a:=? +t2e_nm decimal(6,4) AVG(EXTRACT(MONTH FROM a)) +t2e_ps decimal(6,4) AVG(?) +t2f_nm decimal(6,4) AVG(MONTH(a)) +t2f_ps decimal(6,4) AVG(?) +t2e_nm bigint(3) MIN(EXTRACT(MONTH FROM a)) +t2e_ps bigint(3) MIN(?) +t2f_nm bigint(3) MIN(MONTH(a)) +t2f_ps bigint(3) MIN(?) +t2e_nm bigint(3) MAX(EXTRACT(MONTH FROM a)) +t2e_ps bigint(3) MAX(?) +t2f_nm bigint(3) MAX(MONTH(a)) +t2f_ps bigint(3) MAX(?) +t2e_nm mediumtext GROUP_CONCAT(EXTRACT(MONTH FROM a)) +t2e_ps mediumtext GROUP_CONCAT(?) +t2f_nm mediumtext GROUP_CONCAT(MONTH(a)) +t2f_ps mediumtext GROUP_CONCAT(?) + + +# EXTRACT(WEEK FROM expr) and WEEK(expr) are equavalent +CALL p1('WEEK'); +EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(WEEK FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'), WEEK(TIMESTAMP'2001-12-13 10:20:30.999999'); +CALL show_drop; +TABLE_NAME COLUMN_TYPE COLUMN_NAME +t1e_nm int(3) EXTRACT(WEEK FROM a) +t1e_ps int(3) ? +t1f_nm int(3) WEEK(a) +t1f_ps int(3) ? +t1e_nm int(2) unsigned CAST(EXTRACT(WEEK FROM a) AS UNSIGNED) +t1e_ps int(2) unsigned CAST(? AS UNSIGNED) +t1f_nm int(2) unsigned CAST(WEEK(a) AS UNSIGNED) +t1f_ps int(2) unsigned CAST(? AS UNSIGNED) +t1e_nm int(3) CAST(EXTRACT(WEEK FROM a) AS SIGNED) +t1e_ps int(3) CAST(? AS SIGNED) +t1f_nm int(3) CAST(WEEK(a) AS SIGNED) +t1f_ps int(3) CAST(? AS SIGNED) +t1e_nm int(3) ABS(EXTRACT(WEEK FROM a)) +t1e_ps int(3) ABS(?) +t1f_nm int(3) ABS(WEEK(a)) +t1f_ps int(3) ABS(?) +t1e_nm int(3) ROUND(EXTRACT(WEEK FROM a)) +t1e_ps int(3) ROUND(?) +t1f_nm int(3) ROUND(WEEK(a)) +t1f_ps int(3) ROUND(?) +t1e_nm int(3) -EXTRACT(WEEK FROM a) +t1e_ps int(3) -? +t1f_nm int(3) -WEEK(a) +t1f_ps int(3) -? +t1e_nm int(4) ROUND(EXTRACT(WEEK FROM a),-1) +t1e_ps int(4) ROUND(?,-1) +t1f_nm int(4) ROUND(WEEK(a),-1) +t1f_ps int(4) ROUND(?,-1) +t1e_nm int(4) EXTRACT(WEEK FROM a)+0 +t1e_ps int(4) ?+0 +t1f_nm int(4) WEEK(a)+0 +t1f_ps int(4) ?+0 +t1e_nm decimal(4,1) EXTRACT(WEEK FROM a)+0.0 +t1e_ps decimal(4,1) ?+0.0 +t1f_nm decimal(4,1) WEEK(a)+0.0 +t1f_ps decimal(4,1) ?+0.0 +t1e_nm varchar(2) CONCAT(EXTRACT(WEEK FROM a)) +t1e_ps varchar(2) CONCAT(?) +t1f_nm varchar(2) CONCAT(WEEK(a)) +t1f_ps varchar(2) CONCAT(?) +t1e_nm int(3) LEAST(EXTRACT(WEEK FROM a),EXTRACT(WEEK FROM a)) +t1e_ps int(3) LEAST(?,?) +t1f_nm int(3) LEAST(WEEK(a),WEEK(a)) +t1f_ps int(3) LEAST(?,?) +t1e_nm int(3) COALESCE(EXTRACT(WEEK FROM a)) +t1e_ps int(3) COALESCE(?) +t1f_nm int(3) COALESCE(WEEK(a)) +t1f_ps int(3) COALESCE(?) +t1e_nm int(3) COALESCE(EXTRACT(WEEK FROM a),CAST(1 AS SIGNED)) +t1e_ps int(3) COALESCE(?,CAST(1 AS SIGNED)) +t1f_nm int(3) COALESCE(WEEK(a),CAST(1 AS SIGNED)) +t1f_ps int(3) COALESCE(?,CAST(1 AS SIGNED)) +t1e_nm decimal(2,0) COALESCE(EXTRACT(WEEK FROM a),CAST(1 AS UNSIGNED)) +t1e_ps decimal(2,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1f_nm decimal(2,0) COALESCE(WEEK(a),CAST(1 AS UNSIGNED)) +t1f_ps decimal(2,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1e_nm int(3) @a:=EXTRACT(WEEK FROM a) +t1e_ps int(3) @a:=? +t1f_nm int(3) @a:=WEEK(a) +t1f_ps int(3) @a:=? +t2e_nm decimal(6,4) AVG(EXTRACT(WEEK FROM a)) +t2e_ps decimal(6,4) AVG(?) +t2f_nm decimal(6,4) AVG(WEEK(a)) +t2f_ps decimal(6,4) AVG(?) +t2e_nm bigint(3) MIN(EXTRACT(WEEK FROM a)) +t2e_ps bigint(3) MIN(?) +t2f_nm bigint(3) MIN(WEEK(a)) +t2f_ps bigint(3) MIN(?) +t2e_nm bigint(3) MAX(EXTRACT(WEEK FROM a)) +t2e_ps bigint(3) MAX(?) +t2f_nm bigint(3) MAX(WEEK(a)) +t2f_ps bigint(3) MAX(?) +t2e_nm mediumtext GROUP_CONCAT(EXTRACT(WEEK FROM a)) +t2e_ps mediumtext GROUP_CONCAT(?) +t2f_nm mediumtext GROUP_CONCAT(WEEK(a)) +t2f_ps mediumtext GROUP_CONCAT(?) + + +# EXTRACT(DAY FROM expr) returns hours/24 and includes the sign for TIME +# DAY(expr) returns the DD part of CAST(expr AS DATETIME) +CALL p1('DAY'); +EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(DAY FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'), DAY(TIMESTAMP'2001-12-13 10:20:30.999999'); +CALL show_drop; +TABLE_NAME COLUMN_TYPE COLUMN_NAME +t1e_nm int(3) EXTRACT(DAY FROM a) +t1e_ps int(3) ? +t1f_nm int(3) DAY(a) +t1f_ps int(3) ? +t1e_nm bigint(20) unsigned CAST(EXTRACT(DAY FROM a) AS UNSIGNED) +t1e_ps bigint(20) unsigned CAST(? AS UNSIGNED) +t1f_nm int(2) unsigned CAST(DAY(a) AS UNSIGNED) +t1f_ps int(2) unsigned CAST(? AS UNSIGNED) +t1e_nm int(3) CAST(EXTRACT(DAY FROM a) AS SIGNED) +t1e_ps int(3) CAST(? AS SIGNED) +t1f_nm int(3) CAST(DAY(a) AS SIGNED) +t1f_ps int(3) CAST(? AS SIGNED) +t1e_nm int(3) ABS(EXTRACT(DAY FROM a)) +t1e_ps int(3) ABS(?) +t1f_nm int(3) ABS(DAY(a)) +t1f_ps int(3) ABS(?) +t1e_nm int(3) ROUND(EXTRACT(DAY FROM a)) +t1e_ps int(3) ROUND(?) +t1f_nm int(3) ROUND(DAY(a)) +t1f_ps int(3) ROUND(?) +t1e_nm int(4) -EXTRACT(DAY FROM a) +t1e_ps int(4) -? +t1f_nm int(3) -DAY(a) +t1f_ps int(3) -? +t1e_nm int(4) ROUND(EXTRACT(DAY FROM a),-1) +t1e_ps int(4) ROUND(?,-1) +t1f_nm int(4) ROUND(DAY(a),-1) +t1f_ps int(4) ROUND(?,-1) +t1e_nm int(4) EXTRACT(DAY FROM a)+0 +t1e_ps int(4) ?+0 +t1f_nm int(4) DAY(a)+0 +t1f_ps int(4) ?+0 +t1e_nm decimal(4,1) EXTRACT(DAY FROM a)+0.0 +t1e_ps decimal(4,1) ?+0.0 +t1f_nm decimal(4,1) DAY(a)+0.0 +t1f_ps decimal(4,1) ?+0.0 +t1e_nm varchar(3) CONCAT(EXTRACT(DAY FROM a)) +t1e_ps varchar(3) CONCAT(?) +t1f_nm varchar(2) CONCAT(DAY(a)) +t1f_ps varchar(2) CONCAT(?) +t1e_nm int(3) LEAST(EXTRACT(DAY FROM a),EXTRACT(DAY FROM a)) +t1e_ps int(3) LEAST(?,?) +t1f_nm int(3) LEAST(DAY(a),DAY(a)) +t1f_ps int(3) LEAST(?,?) +t1e_nm int(3) COALESCE(EXTRACT(DAY FROM a)) +t1e_ps int(3) COALESCE(?) +t1f_nm int(3) COALESCE(DAY(a)) +t1f_ps int(3) COALESCE(?) +t1e_nm int(3) COALESCE(EXTRACT(DAY FROM a),CAST(1 AS SIGNED)) +t1e_ps int(3) COALESCE(?,CAST(1 AS SIGNED)) +t1f_nm int(3) COALESCE(DAY(a),CAST(1 AS SIGNED)) +t1f_ps int(3) COALESCE(?,CAST(1 AS SIGNED)) +t1e_nm decimal(2,0) COALESCE(EXTRACT(DAY FROM a),CAST(1 AS UNSIGNED)) +t1e_ps decimal(2,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1f_nm decimal(2,0) COALESCE(DAY(a),CAST(1 AS UNSIGNED)) +t1f_ps decimal(2,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1e_nm int(3) @a:=EXTRACT(DAY FROM a) +t1e_ps int(3) @a:=? +t1f_nm int(3) @a:=DAY(a) +t1f_ps int(3) @a:=? +t2e_nm decimal(6,4) AVG(EXTRACT(DAY FROM a)) +t2e_ps decimal(6,4) AVG(?) +t2f_nm decimal(6,4) AVG(DAY(a)) +t2f_ps decimal(6,4) AVG(?) +t2e_nm bigint(3) MIN(EXTRACT(DAY FROM a)) +t2e_ps bigint(3) MIN(?) +t2f_nm bigint(3) MIN(DAY(a)) +t2f_ps bigint(3) MIN(?) +t2e_nm bigint(3) MAX(EXTRACT(DAY FROM a)) +t2e_ps bigint(3) MAX(?) +t2f_nm bigint(3) MAX(DAY(a)) +t2f_ps bigint(3) MAX(?) +t2e_nm mediumtext GROUP_CONCAT(EXTRACT(DAY FROM a)) +t2e_ps mediumtext GROUP_CONCAT(?) +t2f_nm mediumtext GROUP_CONCAT(DAY(a)) +t2f_ps mediumtext GROUP_CONCAT(?) + + +# EXTRACT(HOUR FROM expr) returns hours%24 and includes the sign for TIME +# HOUR(expr) returns the hh part of CAST(expr AS DATETIME) +CALL p1('HOUR'); +EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(HOUR FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'), HOUR(TIMESTAMP'2001-12-13 10:20:30.999999'); +CALL show_drop; +TABLE_NAME COLUMN_TYPE COLUMN_NAME +t1e_nm int(3) EXTRACT(HOUR FROM a) +t1e_ps int(3) ? +t1f_nm int(3) HOUR(a) +t1f_ps int(3) ? +t1e_nm bigint(20) unsigned CAST(EXTRACT(HOUR FROM a) AS UNSIGNED) +t1e_ps bigint(20) unsigned CAST(? AS UNSIGNED) +t1f_nm int(2) unsigned CAST(HOUR(a) AS UNSIGNED) +t1f_ps int(2) unsigned CAST(? AS UNSIGNED) +t1e_nm int(3) CAST(EXTRACT(HOUR FROM a) AS SIGNED) +t1e_ps int(3) CAST(? AS SIGNED) +t1f_nm int(3) CAST(HOUR(a) AS SIGNED) +t1f_ps int(3) CAST(? AS SIGNED) +t1e_nm int(3) ABS(EXTRACT(HOUR FROM a)) +t1e_ps int(3) ABS(?) +t1f_nm int(3) ABS(HOUR(a)) +t1f_ps int(3) ABS(?) +t1e_nm int(3) ROUND(EXTRACT(HOUR FROM a)) +t1e_ps int(3) ROUND(?) +t1f_nm int(3) ROUND(HOUR(a)) +t1f_ps int(3) ROUND(?) +t1e_nm int(4) -EXTRACT(HOUR FROM a) +t1e_ps int(4) -? +t1f_nm int(3) -HOUR(a) +t1f_ps int(3) -? +t1e_nm int(4) ROUND(EXTRACT(HOUR FROM a),-1) +t1e_ps int(4) ROUND(?,-1) +t1f_nm int(4) ROUND(HOUR(a),-1) +t1f_ps int(4) ROUND(?,-1) +t1e_nm int(4) EXTRACT(HOUR FROM a)+0 +t1e_ps int(4) ?+0 +t1f_nm int(4) HOUR(a)+0 +t1f_ps int(4) ?+0 +t1e_nm decimal(4,1) EXTRACT(HOUR FROM a)+0.0 +t1e_ps decimal(4,1) ?+0.0 +t1f_nm decimal(4,1) HOUR(a)+0.0 +t1f_ps decimal(4,1) ?+0.0 +t1e_nm varchar(3) CONCAT(EXTRACT(HOUR FROM a)) +t1e_ps varchar(3) CONCAT(?) +t1f_nm varchar(2) CONCAT(HOUR(a)) +t1f_ps varchar(2) CONCAT(?) +t1e_nm int(3) LEAST(EXTRACT(HOUR FROM a),EXTRACT(HOUR FROM a)) +t1e_ps int(3) LEAST(?,?) +t1f_nm int(3) LEAST(HOUR(a),HOUR(a)) +t1f_ps int(3) LEAST(?,?) +t1e_nm int(3) COALESCE(EXTRACT(HOUR FROM a)) +t1e_ps int(3) COALESCE(?) +t1f_nm int(3) COALESCE(HOUR(a)) +t1f_ps int(3) COALESCE(?) +t1e_nm int(3) COALESCE(EXTRACT(HOUR FROM a),CAST(1 AS SIGNED)) +t1e_ps int(3) COALESCE(?,CAST(1 AS SIGNED)) +t1f_nm int(3) COALESCE(HOUR(a),CAST(1 AS SIGNED)) +t1f_ps int(3) COALESCE(?,CAST(1 AS SIGNED)) +t1e_nm decimal(2,0) COALESCE(EXTRACT(HOUR FROM a),CAST(1 AS UNSIGNED)) +t1e_ps decimal(2,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1f_nm decimal(2,0) COALESCE(HOUR(a),CAST(1 AS UNSIGNED)) +t1f_ps decimal(2,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1e_nm int(3) @a:=EXTRACT(HOUR FROM a) +t1e_ps int(3) @a:=? +t1f_nm int(3) @a:=HOUR(a) +t1f_ps int(3) @a:=? +t2e_nm decimal(6,4) AVG(EXTRACT(HOUR FROM a)) +t2e_ps decimal(6,4) AVG(?) +t2f_nm decimal(6,4) AVG(HOUR(a)) +t2f_ps decimal(6,4) AVG(?) +t2e_nm bigint(3) MIN(EXTRACT(HOUR FROM a)) +t2e_ps bigint(3) MIN(?) +t2f_nm bigint(3) MIN(HOUR(a)) +t2f_ps bigint(3) MIN(?) +t2e_nm bigint(3) MAX(EXTRACT(HOUR FROM a)) +t2e_ps bigint(3) MAX(?) +t2f_nm bigint(3) MAX(HOUR(a)) +t2f_ps bigint(3) MAX(?) +t2e_nm mediumtext GROUP_CONCAT(EXTRACT(HOUR FROM a)) +t2e_ps mediumtext GROUP_CONCAT(?) +t2f_nm mediumtext GROUP_CONCAT(HOUR(a)) +t2f_ps mediumtext GROUP_CONCAT(?) + + +# EXTRACT(MINUTE FROM expr) includes the sign for TIME +# MINUTE(expr) returns the absolute value +CALL p1('MINUTE'); +EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MINUTE FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'), MINUTE(TIMESTAMP'2001-12-13 10:20:30.999999'); +CALL show_drop; +TABLE_NAME COLUMN_TYPE COLUMN_NAME +t1e_nm int(3) EXTRACT(MINUTE FROM a) +t1e_ps int(3) ? +t1f_nm int(3) MINUTE(a) +t1f_ps int(3) ? +t1e_nm bigint(20) unsigned CAST(EXTRACT(MINUTE FROM a) AS UNSIGNED) +t1e_ps bigint(20) unsigned CAST(? AS UNSIGNED) +t1f_nm int(2) unsigned CAST(MINUTE(a) AS UNSIGNED) +t1f_ps int(2) unsigned CAST(? AS UNSIGNED) +t1e_nm int(3) CAST(EXTRACT(MINUTE FROM a) AS SIGNED) +t1e_ps int(3) CAST(? AS SIGNED) +t1f_nm int(3) CAST(MINUTE(a) AS SIGNED) +t1f_ps int(3) CAST(? AS SIGNED) +t1e_nm int(3) ABS(EXTRACT(MINUTE FROM a)) +t1e_ps int(3) ABS(?) +t1f_nm int(3) ABS(MINUTE(a)) +t1f_ps int(3) ABS(?) +t1e_nm int(3) ROUND(EXTRACT(MINUTE FROM a)) +t1e_ps int(3) ROUND(?) +t1f_nm int(3) ROUND(MINUTE(a)) +t1f_ps int(3) ROUND(?) +t1e_nm int(4) -EXTRACT(MINUTE FROM a) +t1e_ps int(4) -? +t1f_nm int(3) -MINUTE(a) +t1f_ps int(3) -? +t1e_nm int(4) ROUND(EXTRACT(MINUTE FROM a),-1) +t1e_ps int(4) ROUND(?,-1) +t1f_nm int(4) ROUND(MINUTE(a),-1) +t1f_ps int(4) ROUND(?,-1) +t1e_nm int(4) EXTRACT(MINUTE FROM a)+0 +t1e_ps int(4) ?+0 +t1f_nm int(4) MINUTE(a)+0 +t1f_ps int(4) ?+0 +t1e_nm decimal(4,1) EXTRACT(MINUTE FROM a)+0.0 +t1e_ps decimal(4,1) ?+0.0 +t1f_nm decimal(4,1) MINUTE(a)+0.0 +t1f_ps decimal(4,1) ?+0.0 +t1e_nm varchar(3) CONCAT(EXTRACT(MINUTE FROM a)) +t1e_ps varchar(3) CONCAT(?) +t1f_nm varchar(2) CONCAT(MINUTE(a)) +t1f_ps varchar(2) CONCAT(?) +t1e_nm int(3) LEAST(EXTRACT(MINUTE FROM a),EXTRACT(MINUTE FROM a)) +t1e_ps int(3) LEAST(?,?) +t1f_nm int(3) LEAST(MINUTE(a),MINUTE(a)) +t1f_ps int(3) LEAST(?,?) +t1e_nm int(3) COALESCE(EXTRACT(MINUTE FROM a)) +t1e_ps int(3) COALESCE(?) +t1f_nm int(3) COALESCE(MINUTE(a)) +t1f_ps int(3) COALESCE(?) +t1e_nm int(3) COALESCE(EXTRACT(MINUTE FROM a),CAST(1 AS SIGNED)) +t1e_ps int(3) COALESCE(?,CAST(1 AS SIGNED)) +t1f_nm int(3) COALESCE(MINUTE(a),CAST(1 AS SIGNED)) +t1f_ps int(3) COALESCE(?,CAST(1 AS SIGNED)) +t1e_nm decimal(2,0) COALESCE(EXTRACT(MINUTE FROM a),CAST(1 AS UNSIGNED)) +t1e_ps decimal(2,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1f_nm decimal(2,0) COALESCE(MINUTE(a),CAST(1 AS UNSIGNED)) +t1f_ps decimal(2,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1e_nm int(3) @a:=EXTRACT(MINUTE FROM a) +t1e_ps int(3) @a:=? +t1f_nm int(3) @a:=MINUTE(a) +t1f_ps int(3) @a:=? +t2e_nm decimal(6,4) AVG(EXTRACT(MINUTE FROM a)) +t2e_ps decimal(6,4) AVG(?) +t2f_nm decimal(6,4) AVG(MINUTE(a)) +t2f_ps decimal(6,4) AVG(?) +t2e_nm bigint(3) MIN(EXTRACT(MINUTE FROM a)) +t2e_ps bigint(3) MIN(?) +t2f_nm bigint(3) MIN(MINUTE(a)) +t2f_ps bigint(3) MIN(?) +t2e_nm bigint(3) MAX(EXTRACT(MINUTE FROM a)) +t2e_ps bigint(3) MAX(?) +t2f_nm bigint(3) MAX(MINUTE(a)) +t2f_ps bigint(3) MAX(?) +t2e_nm mediumtext GROUP_CONCAT(EXTRACT(MINUTE FROM a)) +t2e_ps mediumtext GROUP_CONCAT(?) +t2f_nm mediumtext GROUP_CONCAT(MINUTE(a)) +t2f_ps mediumtext GROUP_CONCAT(?) + + +# EXTRACT(SECONDS FROM expr) includes the sign for TIME +# SECONDS(expr) returns the absolute value +CALL p1('SECOND'); +EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(SECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), SECOND(TIMESTAMP'2001-12-13 10:20:30.999999'); +CALL show_drop; +TABLE_NAME COLUMN_TYPE COLUMN_NAME +t1e_nm int(3) EXTRACT(SECOND FROM a) +t1e_ps int(3) ? +t1f_nm int(3) SECOND(a) +t1f_ps int(3) ? +t1e_nm bigint(20) unsigned CAST(EXTRACT(SECOND FROM a) AS UNSIGNED) +t1e_ps bigint(20) unsigned CAST(? AS UNSIGNED) +t1f_nm int(2) unsigned CAST(SECOND(a) AS UNSIGNED) +t1f_ps int(2) unsigned CAST(? AS UNSIGNED) +t1e_nm int(3) CAST(EXTRACT(SECOND FROM a) AS SIGNED) +t1e_ps int(3) CAST(? AS SIGNED) +t1f_nm int(3) CAST(SECOND(a) AS SIGNED) +t1f_ps int(3) CAST(? AS SIGNED) +t1e_nm int(3) ABS(EXTRACT(SECOND FROM a)) +t1e_ps int(3) ABS(?) +t1f_nm int(3) ABS(SECOND(a)) +t1f_ps int(3) ABS(?) +t1e_nm int(3) ROUND(EXTRACT(SECOND FROM a)) +t1e_ps int(3) ROUND(?) +t1f_nm int(3) ROUND(SECOND(a)) +t1f_ps int(3) ROUND(?) +t1e_nm int(4) -EXTRACT(SECOND FROM a) +t1e_ps int(4) -? +t1f_nm int(3) -SECOND(a) +t1f_ps int(3) -? +t1e_nm int(4) ROUND(EXTRACT(SECOND FROM a),-1) +t1e_ps int(4) ROUND(?,-1) +t1f_nm int(4) ROUND(SECOND(a),-1) +t1f_ps int(4) ROUND(?,-1) +t1e_nm int(4) EXTRACT(SECOND FROM a)+0 +t1e_ps int(4) ?+0 +t1f_nm int(4) SECOND(a)+0 +t1f_ps int(4) ?+0 +t1e_nm decimal(4,1) EXTRACT(SECOND FROM a)+0.0 +t1e_ps decimal(4,1) ?+0.0 +t1f_nm decimal(4,1) SECOND(a)+0.0 +t1f_ps decimal(4,1) ?+0.0 +t1e_nm varchar(3) CONCAT(EXTRACT(SECOND FROM a)) +t1e_ps varchar(3) CONCAT(?) +t1f_nm varchar(2) CONCAT(SECOND(a)) +t1f_ps varchar(2) CONCAT(?) +t1e_nm int(3) LEAST(EXTRACT(SECOND FROM a),EXTRACT(SECOND FROM a)) +t1e_ps int(3) LEAST(?,?) +t1f_nm int(3) LEAST(SECOND(a),SECOND(a)) +t1f_ps int(3) LEAST(?,?) +t1e_nm int(3) COALESCE(EXTRACT(SECOND FROM a)) +t1e_ps int(3) COALESCE(?) +t1f_nm int(3) COALESCE(SECOND(a)) +t1f_ps int(3) COALESCE(?) +t1e_nm int(3) COALESCE(EXTRACT(SECOND FROM a),CAST(1 AS SIGNED)) +t1e_ps int(3) COALESCE(?,CAST(1 AS SIGNED)) +t1f_nm int(3) COALESCE(SECOND(a),CAST(1 AS SIGNED)) +t1f_ps int(3) COALESCE(?,CAST(1 AS SIGNED)) +t1e_nm decimal(2,0) COALESCE(EXTRACT(SECOND FROM a),CAST(1 AS UNSIGNED)) +t1e_ps decimal(2,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1f_nm decimal(2,0) COALESCE(SECOND(a),CAST(1 AS UNSIGNED)) +t1f_ps decimal(2,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1e_nm int(3) @a:=EXTRACT(SECOND FROM a) +t1e_ps int(3) @a:=? +t1f_nm int(3) @a:=SECOND(a) +t1f_ps int(3) @a:=? +t2e_nm decimal(6,4) AVG(EXTRACT(SECOND FROM a)) +t2e_ps decimal(6,4) AVG(?) +t2f_nm decimal(6,4) AVG(SECOND(a)) +t2f_ps decimal(6,4) AVG(?) +t2e_nm bigint(3) MIN(EXTRACT(SECOND FROM a)) +t2e_ps bigint(3) MIN(?) +t2f_nm bigint(3) MIN(SECOND(a)) +t2f_ps bigint(3) MIN(?) +t2e_nm bigint(3) MAX(EXTRACT(SECOND FROM a)) +t2e_ps bigint(3) MAX(?) +t2f_nm bigint(3) MAX(SECOND(a)) +t2f_ps bigint(3) MAX(?) +t2e_nm mediumtext GROUP_CONCAT(EXTRACT(SECOND FROM a)) +t2e_ps mediumtext GROUP_CONCAT(?) +t2f_nm mediumtext GROUP_CONCAT(SECOND(a)) +t2f_ps mediumtext GROUP_CONCAT(?) + + +# EXTRACT(MICROSECONDS FROM expr) includes the sign for TIME +# MICROSECONDS(expr) returns the absolute value +CALL p1('MICROSECOND'); +EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'), EXTRACT(MICROSECOND FROM TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'), MICROSECOND(TIMESTAMP'2001-12-13 10:20:30.999999'); +CALL show_drop; +TABLE_NAME COLUMN_TYPE COLUMN_NAME +t1e_nm int(7) EXTRACT(MICROSECOND FROM a) +t1e_ps int(7) ? +t1f_nm int(7) MICROSECOND(a) +t1f_ps int(7) ? +t1e_nm bigint(20) unsigned CAST(EXTRACT(MICROSECOND FROM a) AS UNSIGNED) +t1e_ps bigint(20) unsigned CAST(? AS UNSIGNED) +t1f_nm int(6) unsigned CAST(MICROSECOND(a) AS UNSIGNED) +t1f_ps int(6) unsigned CAST(? AS UNSIGNED) +t1e_nm int(7) CAST(EXTRACT(MICROSECOND FROM a) AS SIGNED) +t1e_ps int(7) CAST(? AS SIGNED) +t1f_nm int(7) CAST(MICROSECOND(a) AS SIGNED) +t1f_ps int(7) CAST(? AS SIGNED) +t1e_nm int(7) ABS(EXTRACT(MICROSECOND FROM a)) +t1e_ps int(7) ABS(?) +t1f_nm int(7) ABS(MICROSECOND(a)) +t1f_ps int(7) ABS(?) +t1e_nm int(7) ROUND(EXTRACT(MICROSECOND FROM a)) +t1e_ps int(7) ROUND(?) +t1f_nm int(7) ROUND(MICROSECOND(a)) +t1f_ps int(7) ROUND(?) +t1e_nm int(8) -EXTRACT(MICROSECOND FROM a) +t1e_ps int(8) -? +t1f_nm int(7) -MICROSECOND(a) +t1f_ps int(7) -? +t1e_nm int(8) ROUND(EXTRACT(MICROSECOND FROM a),-1) +t1e_ps int(8) ROUND(?,-1) +t1f_nm int(8) ROUND(MICROSECOND(a),-1) +t1f_ps int(8) ROUND(?,-1) +t1e_nm int(8) EXTRACT(MICROSECOND FROM a)+0 +t1e_ps int(8) ?+0 +t1f_nm int(8) MICROSECOND(a)+0 +t1f_ps int(8) ?+0 +t1e_nm decimal(8,1) EXTRACT(MICROSECOND FROM a)+0.0 +t1e_ps decimal(8,1) ?+0.0 +t1f_nm decimal(8,1) MICROSECOND(a)+0.0 +t1f_ps decimal(8,1) ?+0.0 +t1e_nm varchar(7) CONCAT(EXTRACT(MICROSECOND FROM a)) +t1e_ps varchar(7) CONCAT(?) +t1f_nm varchar(6) CONCAT(MICROSECOND(a)) +t1f_ps varchar(6) CONCAT(?) +t1e_nm int(7) LEAST(EXTRACT(MICROSECOND FROM a),EXTRACT(MICROSECOND FROM a)) +t1e_ps int(7) LEAST(?,?) +t1f_nm int(7) LEAST(MICROSECOND(a),MICROSECOND(a)) +t1f_ps int(7) LEAST(?,?) +t1e_nm int(7) COALESCE(EXTRACT(MICROSECOND FROM a)) +t1e_ps int(7) COALESCE(?) +t1f_nm int(7) COALESCE(MICROSECOND(a)) +t1f_ps int(7) COALESCE(?) +t1e_nm int(7) COALESCE(EXTRACT(MICROSECOND FROM a),CAST(1 AS SIGNED)) +t1e_ps int(7) COALESCE(?,CAST(1 AS SIGNED)) +t1f_nm int(7) COALESCE(MICROSECOND(a),CAST(1 AS SIGNED)) +t1f_ps int(7) COALESCE(?,CAST(1 AS SIGNED)) +t1e_nm decimal(6,0) COALESCE(EXTRACT(MICROSECOND FROM a),CAST(1 AS UNSIGNED)) +t1e_ps decimal(6,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1f_nm decimal(6,0) COALESCE(MICROSECOND(a),CAST(1 AS UNSIGNED)) +t1f_ps decimal(6,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1e_nm int(7) @a:=EXTRACT(MICROSECOND FROM a) +t1e_ps int(7) @a:=? +t1f_nm int(7) @a:=MICROSECOND(a) +t1f_ps int(7) @a:=? +t2e_nm decimal(10,4) AVG(EXTRACT(MICROSECOND FROM a)) +t2e_ps decimal(10,4) AVG(?) +t2f_nm decimal(10,4) AVG(MICROSECOND(a)) +t2f_ps decimal(10,4) AVG(?) +t2e_nm bigint(7) MIN(EXTRACT(MICROSECOND FROM a)) +t2e_ps bigint(7) MIN(?) +t2f_nm bigint(7) MIN(MICROSECOND(a)) +t2f_ps bigint(7) MIN(?) +t2e_nm bigint(7) MAX(EXTRACT(MICROSECOND FROM a)) +t2e_ps bigint(7) MAX(?) +t2f_nm bigint(7) MAX(MICROSECOND(a)) +t2f_ps bigint(7) MAX(?) +t2e_nm mediumtext GROUP_CONCAT(EXTRACT(MICROSECOND FROM a)) +t2e_ps mediumtext GROUP_CONCAT(?) +t2f_nm mediumtext GROUP_CONCAT(MICROSECOND(a)) +t2f_ps mediumtext GROUP_CONCAT(?) + + +# DAYOFYEAR +CALL p1('DAYOFYEAR'); +EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?' USING DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'); +EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?)' USING DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'), DAYOFYEAR(TIMESTAMP'2001-12-13 10:20:30.999999'); +CALL show_drop; +TABLE_NAME COLUMN_TYPE COLUMN_NAME +t1f_nm int(4) DAYOFYEAR(a) +t1f_ps int(4) ? +t1f_nm int(3) unsigned CAST(DAYOFYEAR(a) AS UNSIGNED) +t1f_ps int(3) unsigned CAST(? AS UNSIGNED) +t1f_nm int(4) CAST(DAYOFYEAR(a) AS SIGNED) +t1f_ps int(4) CAST(? AS SIGNED) +t1f_nm int(4) ABS(DAYOFYEAR(a)) +t1f_ps int(4) ABS(?) +t1f_nm int(4) ROUND(DAYOFYEAR(a)) +t1f_ps int(4) ROUND(?) +t1f_nm int(4) -DAYOFYEAR(a) +t1f_ps int(4) -? +t1f_nm int(5) ROUND(DAYOFYEAR(a),-1) +t1f_ps int(5) ROUND(?,-1) +t1f_nm int(5) DAYOFYEAR(a)+0 +t1f_ps int(5) ?+0 +t1f_nm decimal(5,1) DAYOFYEAR(a)+0.0 +t1f_ps decimal(5,1) ?+0.0 +t1f_nm varchar(3) CONCAT(DAYOFYEAR(a)) +t1f_ps varchar(3) CONCAT(?) +t1f_nm int(4) LEAST(DAYOFYEAR(a),DAYOFYEAR(a)) +t1f_ps int(4) LEAST(?,?) +t1f_nm int(4) COALESCE(DAYOFYEAR(a)) +t1f_ps int(4) COALESCE(?) +t1f_nm int(4) COALESCE(DAYOFYEAR(a),CAST(1 AS SIGNED)) +t1f_ps int(4) COALESCE(?,CAST(1 AS SIGNED)) +t1f_nm decimal(3,0) COALESCE(DAYOFYEAR(a),CAST(1 AS UNSIGNED)) +t1f_ps decimal(3,0) COALESCE(?,CAST(1 AS UNSIGNED)) +t1f_nm int(4) @a:=DAYOFYEAR(a) +t1f_ps int(4) @a:=? +t2f_nm decimal(7,4) AVG(DAYOFYEAR(a)) +t2f_ps decimal(7,4) AVG(?) +t2f_nm bigint(4) MIN(DAYOFYEAR(a)) +t2f_ps bigint(4) MIN(?) +t2f_nm bigint(4) MAX(DAYOFYEAR(a)) +t2f_ps bigint(4) MAX(?) +t2f_nm mediumtext GROUP_CONCAT(DAYOFYEAR(a)) +t2f_ps mediumtext GROUP_CONCAT(?) +DROP TABLE t1; +DROP PROCEDURE p1; +DROP PROCEDURE show_drop; +DROP FUNCTION params; +DROP FUNCTION select01; +DROP FUNCTION select02; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/func_extract.test b/mysql-test/main/func_extract.test index 97920f1872f..dd808443f58 100644 --- a/mysql-test/main/func_extract.test +++ b/mysql-test/main/func_extract.test @@ -263,3 +263,254 @@ SELECT FROM t1; DROP TABLE t1; --enable_view_protocol + + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-33496 Out of range error in AVG(YEAR(datetime)) due to a wrong data type +--echo # + +let select01=SELECT ?, CAST(? AS UNSIGNED), CAST(? AS SIGNED), ABS(?), ROUND(?), -?, ROUND(?,-1), ?+0, ?+0.0, CONCAT(?), LEAST(?,?), COALESCE(?), COALESCE(?,CAST(1 AS SIGNED)), COALESCE(?,CAST(1 AS UNSIGNED)), @a:=?; +let pcount01=16; +let select02=SELECT AVG(?), MIN(?), MAX(?), GROUP_CONCAT(?); +let pcount02=4; +let ts=TIMESTAMP'2001-12-13 10:20:30.999999'; + +eval CREATE FUNCTION select01() RETURNS TEXT RETURN '$select01'; +eval CREATE FUNCTION select02() RETURNS TEXT RETURN '$select02'; + +CREATE TABLE t1 (a DATETIME(6)); +INSERT INTO t1 VALUES ('2001-12-31 10:20:30.999999'); + +DELIMITER $$; +CREATE FUNCTION params(expr TEXT, count INT) RETURNS TEXT +BEGIN + RETURN CONCAT(expr, REPEAT(CONCAT(', ', expr), count-1)); +END; +$$ +CREATE PROCEDURE show_drop() +BEGIN + SELECT TABLE_NAME, COLUMN_TYPE, COLUMN_NAME + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_SCHEMA='test' + AND TABLE_NAME IN ('t1e_nm','t2e_nm','t1f_nm','t2f_nm', + 't1e_ps','t1f_ps','t2e_ps','t2f_ps') + ORDER BY LEFT(TABLE_NAME, 2), ORDINAL_POSITION, TABLE_NAME; + + FOR rec IN (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_SCHEMA='test' + AND TABLE_NAME IN ('t1e_nm','t2e_nm','t1f_nm','t2f_nm', + 't1e_ps','t1f_ps','t2e_ps','t2f_ps')) + DO + EXECUTE IMMEDIATE CONCAT('DROP TABLE ', rec.TABLE_NAME); + END FOR; +END; +$$ +CREATE PROCEDURE p1(unit VARCHAR(32)) +BEGIN + DECLARE do_extract BOOL DEFAULT unit NOT IN('DAYOFYEAR'); + + DECLARE query01 TEXT DEFAULT + CONCAT('CREATE TABLE t2 AS ', select01(), ' FROM t1'); + + DECLARE query02 TEXT DEFAULT + CONCAT('CREATE TABLE t2 AS ', select02(), ' FROM t1'); + + IF (do_extract) + THEN + EXECUTE IMMEDIATE REPLACE(REPLACE(query01,'t2','t1e_nm'),'?', CONCAT('EXTRACT(',unit,' FROM a)')); + EXECUTE IMMEDIATE REPLACE(REPLACE(query02,'t2','t2e_nm'),'?', CONCAT('EXTRACT(',unit,' FROM a)')); + END IF; + EXECUTE IMMEDIATE REPLACE(REPLACE(query01,'t2','t1f_nm'),'?', CONCAT(unit,'(a)')); + EXECUTE IMMEDIATE REPLACE(REPLACE(query02,'t2','t2f_nm'),'?', CONCAT(unit,'(a)')); +END; +$$ +DELIMITER ;$$ + + +--echo +--echo +--echo # EXTRACT(YEAR FROM expr) and YEAR(expr) are equivalent + +CALL p1('YEAR'); +let extr=EXTRACT(YEAR FROM $ts); +let func=YEAR($ts); +let extr01=`SELECT params("$extr", $pcount01) AS p`; +let func01=`SELECT params("$func", $pcount01) AS p`; +let extr02=`SELECT params("$extr", $pcount02) AS p`; +let func02=`SELECT params("$func", $pcount02) AS p`; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS $select01' USING $extr01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS $select01' USING $func01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS $select02' USING $extr02; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS $select02' USING $func02; +CALL show_drop; + + +--echo +--echo +--echo # EXTRACT(QUARTER FROM expr) and QUARTER(expr) are equavalent + +CALL p1('QUARTER'); +let extr=EXTRACT(QUARTER FROM $ts); +let func=QUARTER($ts); +let extr01=`SELECT params("$extr", $pcount01) AS p`; +let func01=`SELECT params("$func", $pcount01) AS p`; +let extr02=`SELECT params("$extr", $pcount02) AS p`; +let func02=`SELECT params("$func", $pcount02) AS p`; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS $select01' USING $extr01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS $select01' USING $func01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS $select02' USING $extr02; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS $select02' USING $func02; +CALL show_drop; + +--echo +--echo +--echo # EXTRACT(MONTH FROM expr) and MONTH(expr) are equavalent + +CALL p1('MONTH'); +let extr=EXTRACT(MONTH FROM $ts); +let func=MONTH($ts); +let extr01=`SELECT params("$extr", $pcount01) AS p`; +let func01=`SELECT params("$func", $pcount01) AS p`; +let extr02=`SELECT params("$extr", $pcount02) AS p`; +let func02=`SELECT params("$func", $pcount02) AS p`; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS $select01' USING $extr01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS $select01' USING $func01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS $select02' USING $extr02; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS $select02' USING $func02; +CALL show_drop; + +--echo +--echo +--echo # EXTRACT(WEEK FROM expr) and WEEK(expr) are equavalent + +CALL p1('WEEK'); +let extr=EXTRACT(WEEK FROM $ts); +let func=WEEK($ts); +let extr01=`SELECT params("$extr", $pcount01) AS p`; +let func01=`SELECT params("$func", $pcount01) AS p`; +let extr02=`SELECT params("$extr", $pcount02) AS p`; +let func02=`SELECT params("$func", $pcount02) AS p`; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS $select01' USING $extr01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS $select01' USING $func01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS $select02' USING $extr02; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS $select02' USING $func02; +CALL show_drop; + +--echo +--echo +--echo # EXTRACT(DAY FROM expr) returns hours/24 and includes the sign for TIME +--echo # DAY(expr) returns the DD part of CAST(expr AS DATETIME) + +CALL p1('DAY'); +let extr=EXTRACT(DAY FROM $ts); +let func=DAY($ts); +let extr01=`SELECT params("$extr", $pcount01) AS p`; +let func01=`SELECT params("$func", $pcount01) AS p`; +let extr02=`SELECT params("$extr", $pcount02) AS p`; +let func02=`SELECT params("$func", $pcount02) AS p`; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS $select01' USING $extr01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS $select01' USING $func01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS $select02' USING $extr02; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS $select02' USING $func02; +CALL show_drop; + +--echo +--echo +--echo # EXTRACT(HOUR FROM expr) returns hours%24 and includes the sign for TIME +--echo # HOUR(expr) returns the hh part of CAST(expr AS DATETIME) + +CALL p1('HOUR'); +let extr=EXTRACT(HOUR FROM $ts); +let func=HOUR($ts); +let extr01=`SELECT params("$extr", $pcount01) AS p`; +let func01=`SELECT params("$func", $pcount01) AS p`; +let extr02=`SELECT params("$extr", $pcount02) AS p`; +let func02=`SELECT params("$func", $pcount02) AS p`; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS $select01' USING $extr01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS $select01' USING $func01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS $select02' USING $extr02; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS $select02' USING $func02; +CALL show_drop; + +--echo +--echo +--echo # EXTRACT(MINUTE FROM expr) includes the sign for TIME +--echo # MINUTE(expr) returns the absolute value + +CALL p1('MINUTE'); +let extr=EXTRACT(MINUTE FROM $ts); +let func=MINUTE($ts); +let extr01=`SELECT params("$extr", $pcount01) AS p`; +let func01=`SELECT params("$func", $pcount01) AS p`; +let extr02=`SELECT params("$extr", $pcount02) AS p`; +let func02=`SELECT params("$func", $pcount02) AS p`; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS $select01' USING $extr01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS $select01' USING $func01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS $select02' USING $extr02; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS $select02' USING $func02; +CALL show_drop; + +--echo +--echo +--echo # EXTRACT(SECONDS FROM expr) includes the sign for TIME +--echo # SECONDS(expr) returns the absolute value + +CALL p1('SECOND'); +let extr=EXTRACT(SECOND FROM $ts); +let func=SECOND($ts); +let extr01=`SELECT params("$extr", $pcount01) AS p`; +let func01=`SELECT params("$func", $pcount01) AS p`; +let extr02=`SELECT params("$extr", $pcount02) AS p`; +let func02=`SELECT params("$func", $pcount02) AS p`; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS $select01' USING $extr01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS $select01' USING $func01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS $select02' USING $extr02; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS $select02' USING $func02; +CALL show_drop; + +--echo +--echo +--echo # EXTRACT(MICROSECONDS FROM expr) includes the sign for TIME +--echo # MICROSECONDS(expr) returns the absolute value + +CALL p1('MICROSECOND'); +let extr=EXTRACT(MICROSECOND FROM $ts); +let func=MICROSECOND($ts); +let extr01=`SELECT params("$extr", $pcount01) AS p`; +let func01=`SELECT params("$func", $pcount01) AS p`; +let extr02=`SELECT params("$extr", $pcount02) AS p`; +let func02=`SELECT params("$func", $pcount02) AS p`; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1e_ps AS $select01' USING $extr01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS $select01' USING $func01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2e_ps AS $select02' USING $extr02; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS $select02' USING $func02; +CALL show_drop; + +--echo +--echo +--echo # DAYOFYEAR + +CALL p1('DAYOFYEAR'); +let func=DAYOFYEAR($ts); +let func01=`SELECT params("$func", $pcount01) AS p`; +let func02=`SELECT params("$func", $pcount02) AS p`; +eval EXECUTE IMMEDIATE 'CREATE TABLE t1f_ps AS $select01' USING $func01; +eval EXECUTE IMMEDIATE 'CREATE TABLE t2f_ps AS $select02' USING $func02; +CALL show_drop; + + +DROP TABLE t1; +DROP PROCEDURE p1; +DROP PROCEDURE show_drop; +DROP FUNCTION params; + +DROP FUNCTION select01; +DROP FUNCTION select02; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/main/func_gconcat.result b/mysql-test/main/func_gconcat.result index fea25124941..f817a1176ea 100644 --- a/mysql-test/main/func_gconcat.result +++ b/mysql-test/main/func_gconcat.result @@ -1443,3 +1443,98 @@ drop table t1; # # End of 10.3 tests # +# +# MDEV-31276: Execution of PS from grouping query with join +# and GROUP_CONCAT set function +# +create table t1 (a int, b varchar(20)) engine=myisam; +create table t2 (a int, c varchar(20)) engine=myisam; +insert into t1 values (1,"aaaaaaaaaa"),(2,"bbbbbbbbbb"); +insert into t2 values (1,"cccccccccc"),(2,"dddddddddd"); +insert into t2 values (1,"eeeeeee"),(2,"fffffff"); +set group_concat_max_len=5; +select count(*), group_concat(t1.b,t2.c) +from t1 join t2 on t1.a=t2.a group by t1.a; +count(*) group_concat(t1.b,t2.c) +2 aaaaa +2 bbbbb +Warnings: +Warning 1260 Row 1 was cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() +explain select count(*), group_concat(t1.b,t2.c) +from t1 join t2 on t1.a=t2.a group by t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join) +prepare stmt from "select count(*), group_concat(t1.b,t2.c) +from t1 join t2 on t1.a=t2.a group by t1.a"; +execute stmt; +count(*) group_concat(t1.b,t2.c) +2 aaaaa +2 bbbbb +Warnings: +Warning 1260 Row 1 was cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() +execute stmt; +count(*) group_concat(t1.b,t2.c) +2 aaaaa +2 bbbbb +Warnings: +Warning 1260 Row 1 was cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() +deallocate prepare stmt; +set join_cache_level=0; +select count(*), group_concat(t1.b,t2.c) +from t1 join t2 on t1.a=t2.a group by t1.a; +count(*) group_concat(t1.b,t2.c) +2 aaaaa +2 bbbbb +Warnings: +Warning 1260 Row 1 was cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() +explain select count(*), group_concat(t1.b,t2.c) +from t1 join t2 on t1.a=t2.a group by t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using filesort +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using where +prepare stmt from "select count(*), group_concat(t1.b,t2.c) +from t1 join t2 on t1.a=t2.a group by t1.a"; +execute stmt; +count(*) group_concat(t1.b,t2.c) +2 aaaaa +2 bbbbb +Warnings: +Warning 1260 Row 1 was cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() +execute stmt; +count(*) group_concat(t1.b,t2.c) +2 aaaaa +2 bbbbb +Warnings: +Warning 1260 Row 1 was cut by GROUP_CONCAT() +Warning 1260 Row 2 was cut by GROUP_CONCAT() +deallocate prepare stmt; +set join_cache_level=default; +set group_concat_max_len=default; +drop table t1,t2; +# +# MDEV-33772 Bad SEPARATOR value in GROUP_CONCAT on character set conversion +# +SET NAMES utf8, @@collation_connection=latin1_swedish_ci; +CREATE TABLE t1 (c VARCHAR(10)) CHARACTER SET latin1; +INSERT INTO t1 VALUES ('a'),('A'); +CREATE OR REPLACE VIEW v1 AS +SELECT GROUP_CONCAT(c SEPARATOR 'ß') AS c1 FROM t1 GROUP BY c; +SELECT * FROM v1; +c1 +aßA +SELECT HEX(c1) FROM v1; +HEX(c1) +61DF41 +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select group_concat(`t1`.`c` separator 'ß') AS `c1` from `t1` group by `t1`.`c` utf8mb3 latin1_swedish_ci +DROP VIEW v1; +DROP TABLE t1; +SET NAMES latin1; +# End of 10.5 tests diff --git a/mysql-test/main/func_gconcat.test b/mysql-test/main/func_gconcat.test index cc5236a18be..c9787ce4471 100644 --- a/mysql-test/main/func_gconcat.test +++ b/mysql-test/main/func_gconcat.test @@ -1066,3 +1066,59 @@ drop table t1; --echo # --echo # End of 10.3 tests --echo # + +--echo # +--echo # MDEV-31276: Execution of PS from grouping query with join +--echo # and GROUP_CONCAT set function +--echo # + +create table t1 (a int, b varchar(20)) engine=myisam; +create table t2 (a int, c varchar(20)) engine=myisam; +insert into t1 values (1,"aaaaaaaaaa"),(2,"bbbbbbbbbb"); +insert into t2 values (1,"cccccccccc"),(2,"dddddddddd"); +insert into t2 values (1,"eeeeeee"),(2,"fffffff"); + +let $q= +select count(*), group_concat(t1.b,t2.c) + from t1 join t2 on t1.a=t2.a group by t1.a; + +set group_concat_max_len=5; + +eval $q; +eval explain $q; +eval prepare stmt from "$q"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +set join_cache_level=0; + +eval $q; +eval explain $q; +eval prepare stmt from "$q"; +execute stmt; +execute stmt; +deallocate prepare stmt; + +set join_cache_level=default; +set group_concat_max_len=default; + +drop table t1,t2; + +--echo # +--echo # MDEV-33772 Bad SEPARATOR value in GROUP_CONCAT on character set conversion +--echo # + +SET NAMES utf8, @@collation_connection=latin1_swedish_ci; +CREATE TABLE t1 (c VARCHAR(10)) CHARACTER SET latin1; +INSERT INTO t1 VALUES ('a'),('A'); +CREATE OR REPLACE VIEW v1 AS + SELECT GROUP_CONCAT(c SEPARATOR 'ß') AS c1 FROM t1 GROUP BY c; +SELECT * FROM v1; +SELECT HEX(c1) FROM v1; +SHOW CREATE VIEW v1; +DROP VIEW v1; +DROP TABLE t1; +SET NAMES latin1; + +--echo # End of 10.5 tests diff --git a/mysql-test/main/func_hybrid_type.result b/mysql-test/main/func_hybrid_type.result index a1adde0b993..1773f05ab24 100644 --- a/mysql-test/main/func_hybrid_type.result +++ b/mysql-test/main/func_hybrid_type.result @@ -4317,5 +4317,30 @@ ERROR HY000: Illegal parameter data types bigint unsigned and row for operation SELECT @@max_allowed_packet=ROW(1,1); ERROR HY000: Illegal parameter data types bigint unsigned and row for operation '=' # +# MDEV-21034 GREATEST() and LEAST() malfunction for NULL +# +SELECT 5 AS c1 FROM dual WHERE GREATEST(1, NULL); +c1 +SELECT 5 AS c1 FROM dual WHERE LEAST(1, NULL); +c1 +CREATE TABLE t0 (c0 INT); +INSERT INTO t0 VALUES (1); +SELECT * FROM t0 WHERE GREATEST(c0, NULL); +c0 +SELECT * FROM t0 WHERE LEAST(c0, NULL); +c0 +DROP TABLE t0; +SELECT 5 AS c1 FROM dual WHERE GREATEST(1e0, NULL); +c1 +SELECT 5 AS c1 FROM dual WHERE LEAST(1e0, NULL); +c1 +CREATE TABLE t0 (c0 DOUBLE); +INSERT INTO t0 VALUES (1); +SELECT * FROM t0 WHERE GREATEST(c0, NULL); +c0 +SELECT * FROM t0 WHERE LEAST(c0, NULL); +c0 +DROP TABLE t0; +# # End of 10.5 tests # diff --git a/mysql-test/main/func_hybrid_type.test b/mysql-test/main/func_hybrid_type.test index 508cdcfb668..2ebfb3cfdf1 100644 --- a/mysql-test/main/func_hybrid_type.test +++ b/mysql-test/main/func_hybrid_type.test @@ -1115,6 +1115,29 @@ SELECT 0x20+ROW(1,1); --error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION SELECT @@max_allowed_packet=ROW(1,1); +--echo # +--echo # MDEV-21034 GREATEST() and LEAST() malfunction for NULL +--echo # + +SELECT 5 AS c1 FROM dual WHERE GREATEST(1, NULL); +SELECT 5 AS c1 FROM dual WHERE LEAST(1, NULL); + +CREATE TABLE t0 (c0 INT); +INSERT INTO t0 VALUES (1); +SELECT * FROM t0 WHERE GREATEST(c0, NULL); +SELECT * FROM t0 WHERE LEAST(c0, NULL); +DROP TABLE t0; + +SELECT 5 AS c1 FROM dual WHERE GREATEST(1e0, NULL); +SELECT 5 AS c1 FROM dual WHERE LEAST(1e0, NULL); + +CREATE TABLE t0 (c0 DOUBLE); +INSERT INTO t0 VALUES (1); +SELECT * FROM t0 WHERE GREATEST(c0, NULL); +SELECT * FROM t0 WHERE LEAST(c0, NULL); +DROP TABLE t0; + + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/func_in.result b/mysql-test/main/func_in.result index b3865babca2..1ddb5257314 100644 --- a/mysql-test/main/func_in.result +++ b/mysql-test/main/func_in.result @@ -971,6 +971,84 @@ c1 9223372036854775808 drop table `a`; # +# MDEV-18319 BIGINT UNSIGNED Performance issue +# +CREATE OR REPLACE TABLE t1 ( +id bigint(20) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY +); +FOR i IN 0..255 +DO +INSERT INTO t1 VALUES (); +END FOR +$$ +SELECT MIN(id), MAX(id), COUNT(*) FROM t1; +MIN(id) MAX(id) COUNT(*) +1 256 256 +EXPLAIN SELECT id FROM t1 WHERE id IN (1,2); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL 2 Using where; Using index +EXPLAIN SELECT id FROM t1 WHERE id IN (9223372036854775806, 9223372036854775807); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL 2 Using where; Using index +EXPLAIN SELECT id FROM t1 WHERE id IN (9223372036854775807, 9223372036854775808); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL 2 Using where; Using index +DROP TABLE t1; +# +# MDEV-18898 SELECT using wrong index when using operator IN with mixed types +# +CREATE TEMPORARY TABLE t1 ( +id int(10) unsigned NOT NULL AUTO_INCREMENT, +name varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, +PRIMARY KEY (`id`), +UNIQUE KEY `name` (`name`) +); +FOR i IN 1..255 +DO +INSERT INTO t1 VALUES (i, MD5(i)); +END FOR +$$ +# +# Constants alone +# +ANALYZE SELECT id, name FROM t1 WHERE id = 1; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 NULL 100.00 NULL +ANALYZE SELECT id, name FROM t1 WHERE id = '2'; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 NULL 100.00 NULL +# +# Two constants using IN +# +ANALYZE SELECT id, name FROM t1 WHERE id IN (1, 2); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 2.00 100.00 100.00 Using index condition +ANALYZE SELECT id, name FROM t1 WHERE id IN ('1', 2) /* Used a wrong index */; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 2.00 100.00 100.00 Using index condition +ANALYZE SELECT id, name FROM t1 WHERE id IN (1, '2') /* Used a wrong index */; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 2.00 100.00 100.00 Using index condition +ANALYZE SELECT id, name FROM t1 WHERE id IN ('1', '2'); +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 2.00 100.00 100.00 Using index condition +# +# Two constants using OR +# +ANALYZE SELECT id, name FROM t1 WHERE id = 1 OR id = 2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 2.00 100.00 100.00 Using index condition +ANALYZE SELECT id, name FROM t1 WHERE id = '1' OR id = '2'; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 2.00 100.00 100.00 Using index condition +ANALYZE SELECT id, name FROM t1 WHERE id = 1 OR id = '2'; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 2.00 100.00 100.00 Using index condition +ANALYZE SELECT id, name FROM t1 WHERE id = '1' OR id = 2; +id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 2.00 100.00 100.00 Using index condition +DROP TABLE t1; +# # End of 10.5 tests # # diff --git a/mysql-test/main/func_in.test b/mysql-test/main/func_in.test index e39932a2d50..b88b68f2724 100644 --- a/mysql-test/main/func_in.test +++ b/mysql-test/main/func_in.test @@ -742,6 +742,66 @@ SELECT c1 FROM a WHERE c1 IN ( 1, 9223372036854775807 ); SELECT c1 FROM a WHERE c1 IN ( 1, 9223372036854775808 ); drop table `a`; +--echo # +--echo # MDEV-18319 BIGINT UNSIGNED Performance issue +--echo # + +CREATE OR REPLACE TABLE t1 ( + id bigint(20) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY +); +DELIMITER $$; +FOR i IN 0..255 +DO + INSERT INTO t1 VALUES (); +END FOR +$$ +DELIMITER ;$$ +SELECT MIN(id), MAX(id), COUNT(*) FROM t1; +EXPLAIN SELECT id FROM t1 WHERE id IN (1,2); +EXPLAIN SELECT id FROM t1 WHERE id IN (9223372036854775806, 9223372036854775807); +EXPLAIN SELECT id FROM t1 WHERE id IN (9223372036854775807, 9223372036854775808); +DROP TABLE t1; + + +--echo # +--echo # MDEV-18898 SELECT using wrong index when using operator IN with mixed types +--echo # + +CREATE TEMPORARY TABLE t1 ( + id int(10) unsigned NOT NULL AUTO_INCREMENT, + name varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`) +); +DELIMITER $$; +FOR i IN 1..255 +DO + INSERT INTO t1 VALUES (i, MD5(i)); +END FOR +$$ +DELIMITER ;$$ +--echo # +--echo # Constants alone +--echo # +ANALYZE SELECT id, name FROM t1 WHERE id = 1; +ANALYZE SELECT id, name FROM t1 WHERE id = '2'; +--echo # +--echo # Two constants using IN +--echo # +ANALYZE SELECT id, name FROM t1 WHERE id IN (1, 2); +ANALYZE SELECT id, name FROM t1 WHERE id IN ('1', 2) /* Used a wrong index */; +ANALYZE SELECT id, name FROM t1 WHERE id IN (1, '2') /* Used a wrong index */; +ANALYZE SELECT id, name FROM t1 WHERE id IN ('1', '2'); +--echo # +--echo # Two constants using OR +--echo # +ANALYZE SELECT id, name FROM t1 WHERE id = 1 OR id = 2; +ANALYZE SELECT id, name FROM t1 WHERE id = '1' OR id = '2'; +ANALYZE SELECT id, name FROM t1 WHERE id = 1 OR id = '2'; +ANALYZE SELECT id, name FROM t1 WHERE id = '1' OR id = 2; +DROP TABLE t1; + + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index ccb68431716..fec066a1177 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -272,7 +272,7 @@ create table t1 as select json_object('id', 87, 'name', 'carrot') as f; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `f` varchar(32) DEFAULT NULL + `f` varchar(46) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci select * from t1; f @@ -1690,6 +1690,33 @@ select json_arrayagg('ä'), json_objectagg(1, 'ä'); json_arrayagg('ä') json_objectagg(1, 'ä') ["ä"] {"1":"ä"} # +# MDEV-32287: JSON_EXTRACT not returning multiple values for same path +# +select JSON_EXTRACT("[1, 2, [30, 40]]", '$[2][1]', '$[2][1]'); +JSON_EXTRACT("[1, 2, [30, 40]]", '$[2][1]', '$[2][1]') +[40, 40] +# +# MDEV-31402: SIGSEGV in json_get_path_next | Item_func_json_extract::read_json +# +CREATE TABLE t (id CHAR AS (JSON_COMPACT (JSON_EXTRACT(doc,"$._id"))) UNIQUE KEY,doc JSON,CONSTRAINT notnu CHECK (id IS NOT NULL)); +INSERT INTO t (doc) VALUES ('{ "_id" : { "$oid" : "0ca0b0f0" },"a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" :0} ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] }'); +ERROR 22001: Data too long for column 'id' at row 1 +DROP TABLE t; +# +# MDEV-19487: JSON_TYPE doesnt detect the type of String Values (returns NULL) and for Date/DateTime returns "INTEGER" +# +SELECT JSON_TYPE(json_value(JSON_OBJECT("id", 1, "name", 'Monty', "date", Cast('2019-01-01' as Date) ), '$.date')) as x; +x +NULL +Warnings: +Warning 4038 Syntax error in JSON text in argument 1 to function 'json_type' at position 5 +# +# MDEV-22141: JSON_REMOVE returns NULL on valid arguments +# +SELECT JSON_REMOVE('{"A": { "B": 1 }}', '$.A.B.C.D'); +JSON_REMOVE('{"A": { "B": 1 }}', '$.A.B.C.D') +{"A": {"B": 1}} +# # End of 10.5 tests # # diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index 721c6b6eef8..050e54f2b21 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -89,15 +89,12 @@ select json_extract('[10, 20, [30, 40], 1, 10]', '$[1]') as exp; select json_extract('[10, 20, [30, 40], 1, 10]', '$[1]', '$[25]') as exp; select json_extract( '[{"a": [3, 4]}, {"b": 2}]', '$[0].a', '$[1].a') as exp; -#enable after MDEV-32454 fix ---disable_view_protocol select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word') as exp; select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3) as exp; select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.a[2]', 2) as exp; select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.c', 'word') as exp; select json_set('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]') as exp; ---enable_view_protocol select json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]') as exp; select json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.b', '[true, false]') as exp; @@ -139,14 +136,11 @@ select json_merge('a','b'); select json_merge('{"a":"b"}','{"c":"d"}'); SELECT JSON_MERGE('[1, 2]', '{"id": 47}'); -#enable after MDEV-32454 fix ---disable_view_protocol select json_type('{"k1":123, "k2":345}'); select json_type('[123, "k2", 345]'); select json_type("true"); select json_type('123'); select json_type('123.12'); ---enable_view_protocol select json_keys('{"a":{"c":1, "d":2}, "b":2}'); select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.a"); @@ -175,11 +169,8 @@ select json_search( json_col, 'all', 'foot' ) as ex from t1; drop table t1; -#enable after MDEV-32454 fix ---disable_view_protocol select json_unquote('"abc"'); select json_unquote('abc'); ---enable_view_protocol # # MDEV-13703 Illegal mix of collations for operation 'json_object' on using JSON_UNQUOTE as an argument. # @@ -190,13 +181,9 @@ select json_object('foo', json_unquote(json_object('bar', c)),'qux', c) as fld f drop table t1; -#enable after MDEV-32454 fix ---disable_view_protocol select json_object("a", json_object("b", "abcd")); select json_object("a", '{"b": "abcd"}'); select json_object("a", json_compact('{"b": "abcd"}')); ---enable_view_protocol - select json_compact(NULL); select json_depth(json_compact(NULL)); @@ -272,11 +259,8 @@ select json_merge('{"a":{"u":12, "x":"b"}}', '{"a":{"x":"c"}}') as ex ; select json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}') as ex ; select json_compact('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') as ex; -#enable after MDEV-32454 fix ---disable_view_protocol select json_loose('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') as ex; select json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}') as ex; ---enable_view_protocol # # MDEV-11856 json_search doesn't search for values with double quotes character (") @@ -471,12 +455,9 @@ drop table t1; --echo # MDEV-16750 JSON_SET mishandles unicode every second pair of arguments. --echo # -#enable after MDEV-32454 fix ---disable_view_protocol SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6) as exp; SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6, '$.b', _utf8 0xC3B6) as exp; SELECT JSON_SET('{}', '$.a', _utf8 X'C3B6', '$.x', 1, '$.b', _utf8 X'C3B6') as exp; ---enable_view_protocol --echo # --echo # MDEV-17121 JSON_ARRAY_APPEND @@ -1139,6 +1120,38 @@ set names latin1; select json_arrayagg('ä'), json_objectagg(1, 'ä'); --enable_service_connection + +--echo # +--echo # MDEV-32287: JSON_EXTRACT not returning multiple values for same path +--echo # + +select JSON_EXTRACT("[1, 2, [30, 40]]", '$[2][1]', '$[2][1]'); + + +--echo # +--echo # MDEV-31402: SIGSEGV in json_get_path_next | Item_func_json_extract::read_json +--echo # + +CREATE TABLE t (id CHAR AS (JSON_COMPACT (JSON_EXTRACT(doc,"$._id"))) UNIQUE KEY,doc JSON,CONSTRAINT notnu CHECK (id IS NOT NULL)); +--error ER_DATA_TOO_LONG +INSERT INTO t (doc) VALUES ('{ "_id" : { "$oid" : "0ca0b0f0" },"a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" :0} ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] }'); + +DROP TABLE t; + +--echo # +--echo # MDEV-19487: JSON_TYPE doesnt detect the type of String Values (returns NULL) and for Date/DateTime returns "INTEGER" +--echo # + +SELECT JSON_TYPE(json_value(JSON_OBJECT("id", 1, "name", 'Monty', "date", Cast('2019-01-01' as Date) ), '$.date')) as x; + + +--echo # +--echo # MDEV-22141: JSON_REMOVE returns NULL on valid arguments +--echo # + +SELECT JSON_REMOVE('{"A": { "B": 1 }}', '$.A.B.C.D'); + + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/func_json_notembedded.result b/mysql-test/main/func_json_notembedded.result index 756d2e85f7c..ba4d38dd623 100644 --- a/mysql-test/main/func_json_notembedded.result +++ b/mysql-test/main/func_json_notembedded.result @@ -10,6 +10,8 @@ select length(@obj), length(@arr); length(@obj) length(@arr) 5000009 5000009 set max_statement_time=0.0001; +SET @old_debug= @@debug_dbug; +SET debug_dbug='+d,debug_max_statement_time exceeded'; select json_array_append(@arr, '$[0]', 1); ERROR 70100: Query execution was interrupted (max_statement_time exceeded) select json_array_insert(@arr, '$[0]', 1); @@ -34,6 +36,7 @@ select json_replace(@obj,'$.foo',1); ERROR 70100: Query execution was interrupted (max_statement_time exceeded) select json_set(@arr,'$[1000]',1); ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +SET debug_dbug= @old_debug; disconnect u; connection default; set global max_allowed_packet=default; diff --git a/mysql-test/main/func_json_notembedded.test b/mysql-test/main/func_json_notembedded.test index 893b248301c..1e05571e16f 100644 --- a/mysql-test/main/func_json_notembedded.test +++ b/mysql-test/main/func_json_notembedded.test @@ -1,6 +1,7 @@ source include/have_profiling.inc; source include/not_embedded.inc; source include/no_valgrind_without_big.inc; +source include/have_debug.inc; set global max_allowed_packet=1073741824; connect u,localhost,root; @@ -16,6 +17,8 @@ select length(@obj), length(@arr); set max_statement_time=0.0001; disable_abort_on_error; +SET @old_debug= @@debug_dbug; +SET debug_dbug='+d,debug_max_statement_time exceeded'; select json_array_append(@arr, '$[0]', 1); select json_array_insert(@arr, '$[0]', 1); select json_insert(@obj, '$.meta', 1); @@ -29,6 +32,7 @@ select json_remove(@obj,'$.foo'); select json_replace(@obj,'$.foo',1); select json_set(@arr,'$[1000]',1); enable_abort_on_error; +SET debug_dbug= @old_debug; disconnect u; connection default; set global max_allowed_packet=default; diff --git a/mysql-test/main/func_math.result b/mysql-test/main/func_math.result index 1c6c780e380..5422cae4ee7 100644 --- a/mysql-test/main/func_math.result +++ b/mysql-test/main/func_math.result @@ -3711,5 +3711,20 @@ SELECT CRC32(ExtractValue('', '/a/b')) AS f; f 0 # +# MDEV-33534 UBSAN: Negation of -X cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself in my_double_round from sql/item_func.cc| +# +SELECT TRUNCATE(EXP(-1.e-2),-1.e+30) AS c1; +c1 +0 +SELECT (TRUNCATE(EXP(-1.e-2),-1.e+30) % RADIANS(-1)) AS c1; +c1 +0 +SELECT (TRUNCATE(EXP(-1.e-2),-1.e+30) % RADIANS(-1)) * (LAST_DAY('1-03-30 1:29:12') MOD 1 + COS(-1)) AS c1; +c1 +0 +SELECT(ASIN(-1)+ LN(-1)) % (ATAN(-1) MOD FLOOR(1)) * (TRUNCATE(EXP(-1.e-2),-1.e+30) % RADIANS(-1)) * (LAST_DAY('1-03-30 1:29:12') MOD 1 + COS(-1)) AS c1; +c1 +NULL +# # End of 10.5 tests # diff --git a/mysql-test/main/func_math.test b/mysql-test/main/func_math.test index d4e853938ad..b32a1a4634b 100644 --- a/mysql-test/main/func_math.test +++ b/mysql-test/main/func_math.test @@ -1980,6 +1980,16 @@ DROP TABLE t2, t1; SELECT CRC32(ExtractValue('', '/a/b')) AS f; +--echo # +--echo # MDEV-33534 UBSAN: Negation of -X cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself in my_double_round from sql/item_func.cc| +--echo # + +SELECT TRUNCATE(EXP(-1.e-2),-1.e+30) AS c1; +SELECT (TRUNCATE(EXP(-1.e-2),-1.e+30) % RADIANS(-1)) AS c1; +SELECT (TRUNCATE(EXP(-1.e-2),-1.e+30) % RADIANS(-1)) * (LAST_DAY('1-03-30 1:29:12') MOD 1 + COS(-1)) AS c1; +SELECT(ASIN(-1)+ LN(-1)) % (ATAN(-1) MOD FLOOR(1)) * (TRUNCATE(EXP(-1.e-2),-1.e+30) % RADIANS(-1)) * (LAST_DAY('1-03-30 1:29:12') MOD 1 + COS(-1)) AS c1; + + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/func_regexp.result b/mysql-test/main/func_regexp.result index b883c8188df..7a9e24f8262 100644 --- a/mysql-test/main/func_regexp.result +++ b/mysql-test/main/func_regexp.result @@ -110,7 +110,7 @@ R2 R3 deallocate prepare stmt1; drop table t1; -End of 4.1 tests +# End of 4.1 tests SELECT 1 REGEXP NULL; 1 REGEXP NULL NULL @@ -126,7 +126,7 @@ NULL SELECT "ABC" REGEXP BINARY NULL; "ABC" REGEXP BINARY NULL NULL -End of 5.0 tests +# End of 5.0 tests CREATE TABLE t1(a INT, b CHAR(4)); INSERT INTO t1 VALUES (1, '6.1'), (1, '7.0'), (1, '8.0'); PREPARE stmt1 FROM "SELECT a FROM t1 WHERE a=1 AND '7.0' REGEXP b LIMIT 1"; @@ -144,7 +144,7 @@ a 1 DEALLOCATE PREPARE stmt1; DROP TABLE t1; -End of 5.1 tests +# End of 5.1 tests SELECT ' ' REGEXP '[[:blank:]]'; ' ' REGEXP '[[:blank:]]' 1 @@ -163,3 +163,49 @@ SELECT '\t' REGEXP '[[:space:]]'; SELECT REGEXP_INSTR('111222333',2); REGEXP_INSTR('111222333',2) 4 +# End of 10.3 tests +# +# MDEV-33344 REGEXP empty string inconsistent +# +create table t1 (x char(5)); +insert t1 values (''), ('x'); +select 'foo' regexp x from t1 order by x asc; +'foo' regexp x +1 +0 +select 'foo' regexp x from t1 order by x desc; +'foo' regexp x +0 +1 +drop table t1; +# +# MDEV-21076 NOT NULL and UNIQUE constraints cause SUM() to yield an incorrect result +# +CREATE TABLE t0(c0 INT NOT NULL, c1 CHAR UNIQUE); +INSERT INTO t0 VALUES (0, 1); +INSERT INTO t0 VALUES (0, ''); +SELECT (c1 RLIKE c1), (c0 IS NULL) FROM t0; +(c1 RLIKE c1) (c0 IS NULL) +1 0 +1 0 +SELECT SUM(a.t) FROM (SELECT (c1 RLIKE c1) = (c0 IS NULL) as t FROM t0) as a; +SUM(a.t) +0 +DROP TABLE t0; +# +# MDEV-21058 CREATE TABLE with generated column and RLIKE results in sigabrt +# +CREATE TABLE t1 (c0 INT); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT ('' RLIKE '[') AS c1 FROM t1; +ERROR 42000: Regex error 'missing terminating ] for character class at offset 1' +SELECT REGEXP_INSTR('','[') AS c1 FROM t1; +ERROR 42000: Regex error 'missing terminating ] for character class at offset 1' +SELECT c0, '' RLIKE NULL AS c1, REGEXP_INSTR('', NULL) AS c2 +FROM t1 ORDER BY c0; +c0 c1 c2 +1 NULL NULL +2 NULL NULL +3 NULL NULL +DROP TABLE t1; +# End of 10.5 tests diff --git a/mysql-test/main/func_regexp.test b/mysql-test/main/func_regexp.test index 6d5186269a5..fb441bde4d2 100644 --- a/mysql-test/main/func_regexp.test +++ b/mysql-test/main/func_regexp.test @@ -55,7 +55,7 @@ execute stmt1 using @a; deallocate prepare stmt1; drop table t1; ---echo End of 4.1 tests +--echo # End of 4.1 tests # @@ -74,7 +74,7 @@ SELECT NULL REGEXP BINARY NULL; SELECT 'A' REGEXP BINARY NULL; SELECT "ABC" REGEXP BINARY NULL; ---echo End of 5.0 tests +--echo # End of 5.0 tests # @@ -91,7 +91,7 @@ DEALLOCATE PREPARE stmt1; DROP TABLE t1; ---echo End of 5.1 tests +--echo # End of 5.1 tests # # MDEV-5820 MySQL Bug #54805 definitions in regex/my_regex.h conflict with /usr/include/regex.h @@ -110,3 +110,44 @@ SELECT '\t' REGEXP '[[:space:]]'; --echo # SELECT REGEXP_INSTR('111222333',2); +--echo # End of 10.3 tests + +--echo # +--echo # MDEV-33344 REGEXP empty string inconsistent +--echo # +create table t1 (x char(5)); +insert t1 values (''), ('x'); +select 'foo' regexp x from t1 order by x asc; +select 'foo' regexp x from t1 order by x desc; +drop table t1; + +--echo # +--echo # MDEV-21076 NOT NULL and UNIQUE constraints cause SUM() to yield an incorrect result +--echo # + +CREATE TABLE t0(c0 INT NOT NULL, c1 CHAR UNIQUE); +INSERT INTO t0 VALUES (0, 1); +INSERT INTO t0 VALUES (0, ''); +SELECT (c1 RLIKE c1), (c0 IS NULL) FROM t0; +SELECT SUM(a.t) FROM (SELECT (c1 RLIKE c1) = (c0 IS NULL) as t FROM t0) as a; +DROP TABLE t0; + +--echo # +--echo # MDEV-21058 CREATE TABLE with generated column and RLIKE results in sigabrt +--echo # + +CREATE TABLE t1 (c0 INT); +INSERT INTO t1 VALUES (1),(2),(3); + +--error ER_REGEXP_ERROR +SELECT ('' RLIKE '[') AS c1 FROM t1; + +--error ER_REGEXP_ERROR +SELECT REGEXP_INSTR('','[') AS c1 FROM t1; + +SELECT c0, '' RLIKE NULL AS c1, REGEXP_INSTR('', NULL) AS c2 +FROM t1 ORDER BY c0; + +DROP TABLE t1; + +--echo # End of 10.5 tests diff --git a/mysql-test/main/func_sformat.result b/mysql-test/main/func_sformat.result index 9e8a11677b5..11825604f1d 100644 --- a/mysql-test/main/func_sformat.result +++ b/mysql-test/main/func_sformat.result @@ -23,10 +23,8 @@ select sformat('{} {}', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); -sformat('{} {}', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) as x; +x 0 0 select sformat('{{{}}}', 0); sformat('{{{}}}', 0) @@ -78,10 +76,8 @@ select sformat('{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} { 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, -106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120); -sformat('{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} - {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} - {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} +106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120) as x; +x 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 @@ -97,10 +93,8 @@ select sformat('{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} { '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', -'115', '116', '117', '118', '119', '120'); -sformat('{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} - {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} - {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} +'115', '116', '117', '118', '119', '120') as x; +x 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 @@ -159,8 +153,8 @@ insert into t2 values (0.0025, 25, 'A', DATE('2020-06-29')), (0.0005, 5, 'B', DATE('2020-6-29')), (5.5555, -5, 'C', DATE('200629')), (-9, -9, 'D', DATE('20*06*29')); -select sformat('p1 {:.4f} p2 {} p3 {} p4 {}', param1, param2, param3, param4) from t2; -sformat('p1 {:.4f} p2 {} p3 {} p4 {}', param1, param2, param3, param4) +select sformat('p1 {:.4f} p2 {} p3 {} p4 {}', param1, param2, param3, param4) x from t2; +x p1 0.0025 p2 25 p3 A p4 2020-06-29 p1 0.0005 p2 5 p3 B p4 2020-06-29 p1 5.5555 p2 -5 p3 C p4 2020-06-29 @@ -279,14 +273,14 @@ sformat('{: f}; {: f}', 3.14, -3.14) select sformat('{:-f}; {:-f}', 3.14, -3.14); sformat('{:-f}; {:-f}', 3.14, -3.14) 3.140000; -3.140000 -select sformat('The temperature is between {: } and {: } degrees celsius.', -3, 7); -sformat('The temperature is between {: } and {: } degrees celsius.', -3, 7) +select sformat('The temperature is between {: } and {: } degrees celsius.', -3, 7) x; +x The temperature is between -3 and 7 degrees celsius. -select sformat('The temperature is between {:-} and {:-} degrees celsius.', -3, 7); -sformat('The temperature is between {:-} and {:-} degrees celsius.', -3, 7) +select sformat('The temperature is between {:-} and {:-} degrees celsius.', -3, 7) x; +x The temperature is between -3 and 7 degrees celsius. -select sformat('The temperature is between {:+} and {:+} degrees celsius.', -3, 7); -sformat('The temperature is between {:+} and {:+} degrees celsius.', -3, 7) +select sformat('The temperature is between {:+} and {:+} degrees celsius.', -3, 7) x; +x The temperature is between -3 and +7 degrees celsius. select sformat('We have {:<8} chickens.', 49); sformat('We have {:<8} chickens.', 49) @@ -427,8 +421,8 @@ set names utf8; select sformat(_ucs2 x'003D007B007D003D', _ucs2 x'0442043504410442'); sformat(_ucs2 x'003D007B007D003D', _ucs2 x'0442043504410442') =тест= -select hex(sformat(_ucs2 x'003D007B007D003D', _ucs2 x'0442043504410442')); -hex(sformat(_ucs2 x'003D007B007D003D', _ucs2 x'0442043504410442')) +select hex(sformat(_ucs2 x'003D007B007D003D', _ucs2 x'0442043504410442')) x; +x 003D0442043504410442003D create table t1 as select sformat(_ucs2 x'003D007B007D003D', _ucs2 x'0442043504410442') as x; show create table t1; diff --git a/mysql-test/main/func_sformat.test b/mysql-test/main/func_sformat.test index 65e4b639179..4744229e79a 100644 --- a/mysql-test/main/func_sformat.test +++ b/mysql-test/main/func_sformat.test @@ -14,14 +14,11 @@ select sformat(0); select sformat('C'); select sformat(-4.2); select sformat(5, 5, 5); -#enable after fix MDEV-27871 ---disable_view_protocol select sformat('{} {}', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); ---enable_view_protocol + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) as x; select sformat('{{{}}}', 0); select sformat('{{{}{{', 0); select sformat('{{{{{}{{', 'param1'); @@ -29,18 +26,13 @@ select sformat(' {{ {{ {} {{ ', 'param1'); select sformat(' {{ {} {}', 'param1', 'param2'); select sformat('A{}C{}E{}', 'B', 'D', 'F'); select sformat('{} {}', FALSE, TRUE); -#enable after fix MDEV-29601 ---disable_service_connection select sformat('Add € != {} != {}?', '$', '£'); select sformat('Check {} != {} != {}?', '€', '$', '£'); ---enable_service_connection select sformat('{}{}{}', 1, 2, 3); select sformat('Float {} Boolean {} Number {}', 3.14159, True, -50); select sformat('SUM {} + {} = {}', 2, 3, 2+3); select sformat('Numbers {} {} {}', 1, 1.11, 1.111); select sformat('what {} is {}?', 'time', 'it'); -#enable after fix MDEV-27871 ---disable_view_protocol select sformat('{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} @@ -49,7 +41,7 @@ select sformat('{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} { 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120); + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120) as x; select sformat('{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} @@ -61,8 +53,7 @@ select sformat('{} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} { '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', - '115', '116', '117', '118', '119', '120'); ---enable_view_protocol + '115', '116', '117', '118', '119', '120') as x; echo #; echo # Error Test Cases; @@ -92,10 +83,7 @@ insert into t2 values (0.0025, 25, 'A', DATE('2020-06-29')), (0.0005, 5, 'B', DATE('2020-6-29')), (5.5555, -5, 'C', DATE('200629')), (-9, -9, 'D', DATE('20*06*29')); -#enable after fix MDEV-27871 ---disable_view_protocol -select sformat('p1 {:.4f} p2 {} p3 {} p4 {}', param1, param2, param3, param4) from t2; ---enable_view_protocol +select sformat('p1 {:.4f} p2 {} p3 {} p4 {}', param1, param2, param3, param4) x from t2; drop table t2; set names utf8; @@ -127,10 +115,7 @@ echo #; echo # Format Test Cases; echo #; select sformat('Num {:L}', 13800000000); -#enable after fix MDEV-29646 ---disable_view_protocol select sformat('Num [{:20}]', 42); ---enable_view_protocol select sformat('Number: {:*^{}}', 4, 5); select sformat('{:02} - {:02} - {:02}', 1, 2, 3); select sformat('Character {:c}', 104); @@ -141,10 +126,7 @@ select sformat('Float {:.2f}', 42.0); select sformat('Float {:f}', 42.0); select sformat('Number {:d}', 42); select sformat('Number {:{}}', 5, 5); -#enable after fix MDEV-29646 ---disable_view_protocol select sformat('Number [{:10}]', 9999); ---enable_view_protocol select sformat('Number {:.3}', 3.1416); select sformat('int: {0:d}; hex: {0:x}; oct: {0:o}', 42); select sformat('int: {0:d}; hex: {0:#x}; oct: {0:#o}', 42); @@ -155,16 +137,10 @@ select sformat('The binary version of {0} is {0:b}', 5); select sformat('{:+f}; {:+f}', 3.14, -3.14); select sformat('{: f}; {: f}', 3.14, -3.14); select sformat('{:-f}; {:-f}', 3.14, -3.14); -#enable after fix MDEV-27871 ---disable_view_protocol -select sformat('The temperature is between {: } and {: } degrees celsius.', -3, 7); -select sformat('The temperature is between {:-} and {:-} degrees celsius.', -3, 7); -select sformat('The temperature is between {:+} and {:+} degrees celsius.', -3, 7); ---enable_view_protocol -#check after fix MDEV-29646 ---disable_view_protocol +select sformat('The temperature is between {: } and {: } degrees celsius.', -3, 7) x; +select sformat('The temperature is between {:-} and {:-} degrees celsius.', -3, 7) x; +select sformat('The temperature is between {:+} and {:+} degrees celsius.', -3, 7) x; select sformat('We have {:<8} chickens.', 49); ---enable_view_protocol select sformat('Center alimgn [{:*^10}]', 'data'); select sformat('Center aling [{:^10}].', 'data'); select sformat('Right aling [{:>10}].', 'data'); @@ -175,20 +151,31 @@ select sformat('Change Order {1} {0}', 'second', 'first'); echo #; echo # Failed Format Test Cases; echo #; +--replace_regex /invalid format specifier/invalid type specifier/ select sformat('Test {:c}', 'word'); select sformat('Test {one} {two} {three}', 1, 2, 3); select sformat('Number {:{<}', 8); select sformat('Number {:10000000000}', 5); select sformat('1={1} 2={2} 0={0}', 0, 1); +--replace_regex /invalid format specifier/precision not allowed for this argument type/ select sformat('Number {:.2d}', 42); +--replace_regex /invalid format specifier/invalid type specifier/ select sformat('You scored {:.0%}', 0.25); +--replace_regex /invalid format specifier/invalid type specifier/ select sformat('You scored {:%}', 0.25); +--replace_regex /invalid format specifier/invalid type specifier/ select sformat('The price is {:f} dollars.', 45); +--replace_regex /invalid format specifier/precision not allowed for this argument type/ select sformat('The price is {:.2f} dollars.', 45); +--replace_regex /invalid format specifier/invalid type specifier/ select sformat('We have {:E} chickens.', 5); +--replace_regex /invalid format specifier/invalid type specifier/ select sformat('We have {:e} chickens.', 5); +--replace_regex /invalid format specifier/invalid type specifier/ select sformat('The universe is {:,} years old.', 13800000000); +--replace_regex /invalid format specifier/invalid type specifier/ select sformat('The universe is {:_} years old.', 13800000000); +--replace_regex /invalid format specifier/format specifier requires numeric argument/ select sformat('String {:-}', 'hello'); echo #; @@ -211,6 +198,7 @@ drop table t2; echo #; echo # Unsupported/disabled features; echo #; +--replace_regex /invalid format specifier/invalid type specifier/ select sformat('{:p}', '50'); echo #; @@ -219,10 +207,7 @@ echo #; select sformat('={}=', _ucs2 x'006100620063'); set names utf8; select sformat(_ucs2 x'003D007B007D003D', _ucs2 x'0442043504410442'); -#enable after fix MDEV-27871 ---disable_view_protocol -select hex(sformat(_ucs2 x'003D007B007D003D', _ucs2 x'0442043504410442')); ---enable_view_protocol +select hex(sformat(_ucs2 x'003D007B007D003D', _ucs2 x'0442043504410442')) x; create table t1 as select sformat(_ucs2 x'003D007B007D003D', _ucs2 x'0442043504410442') as x; show create table t1; drop table t1; @@ -233,6 +218,7 @@ echo # ps parameters; echo #; prepare s from 'select sformat("={:d}=", ?)'; execute s using 100; +--replace_regex /invalid format specifier/invalid type specifier/ execute s using 'abc'; echo #; diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index f0b6fdcb7ed..59595dffa99 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -7,7 +7,7 @@ select 'hello',"'hello'",'""hello""','''h''e''l''l''o''',"hel""lo",'hel\'lo'; hello 'hello' ""hello"" 'h'e'l'l'o' hel"lo hel'lo hello 'hello' ""hello"" 'h'e'l'l'o' hel"lo hel'lo select 'hello' 'monty'; -hello +hellomonty hellomonty select length('\n\t\r\b\0\_\%\\'); length('\n\t\r\b\0\_\%\\') @@ -5488,6 +5488,40 @@ Warning 1292 Truncated incorrect BINARY(2) value: '...random bytes...' # End of 10.10 tests # # +# Start of 10.11 tests +# +# +# MDEV-33392 Server crashes when using RANDOM_BYTES function and GROUP BY clause on a column with a negative value +# +SET sql_mode=''; +CREATE TABLE t1 (a VARCHAR(255)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (9494),(9495),(9496),(9497),(9498),(9499),(9500),(9501),(9502),(9503); +SELECT RANDOM_BYTES (-1) f1,a f2 FROM t1 GROUP BY f1,f2; +f1 f2 +NULL 9494 +NULL 9495 +NULL 9496 +NULL 9497 +NULL 9498 +NULL 9499 +NULL 9500 +NULL 9501 +NULL 9502 +NULL 9503 +CREATE TABLE t2 AS SELECT RANDOM_BYTES (-1) f1,a f2 FROM t1 GROUP BY f1,f2; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `f1` binary(0) DEFAULT NULL, + `f2` varchar(255) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t2; +DROP TABLE t1; +SET sql_mode=DEFAULT; +# +# End of 10.11 tests +# +# # MDEV-9069 extend AES_ENCRYPT() and AES_DECRYPT() to support IV and the algorithm # select aes_encrypt('foo', 'bar', '1234') = aes_encrypt('foo', 'bar') `expected 1`; @@ -5560,6 +5594,13 @@ aes_encrypt(a,a) is null 1 0 # +# MDEV-33659: Server crashed at Create_func_aes_decrypt::create_native +# +select aes_encrypt(); +ERROR 42000: Incorrect parameter count in the call to native function 'aes_encrypt' +select aes_decrypt(); +ERROR 42000: Incorrect parameter count in the call to native function 'aes_decrypt' +# # End of 11.2 tests # # diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index fda4d4aed7d..163b65d5578 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -2458,6 +2458,28 @@ select "a" in ("abc", (convert(random_bytes(8) ,binary(2)))); --echo # End of 10.10 tests --echo # +--echo # +--echo # Start of 10.11 tests +--echo # + +--echo # +--echo # MDEV-33392 Server crashes when using RANDOM_BYTES function and GROUP BY clause on a column with a negative value +--echo # + +SET sql_mode=''; +CREATE TABLE t1 (a VARCHAR(255)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (9494),(9495),(9496),(9497),(9498),(9499),(9500),(9501),(9502),(9503); +SELECT RANDOM_BYTES (-1) f1,a f2 FROM t1 GROUP BY f1,f2; +CREATE TABLE t2 AS SELECT RANDOM_BYTES (-1) f1,a f2 FROM t1 GROUP BY f1,f2; +SHOW CREATE TABLE t2; +DROP TABLE t2; +DROP TABLE t1; +SET sql_mode=DEFAULT; + +--echo # +--echo # End of 10.11 tests +--echo # + --echo # --echo # MDEV-9069 extend AES_ENCRYPT() and AES_DECRYPT() to support IV and the algorithm --echo # @@ -2500,6 +2522,15 @@ set @@block_encryption_mode=default; --echo # select aes_encrypt(a,a) is null from (values('a'),(NULL),('b')) x; +--echo # +--echo # MDEV-33659: Server crashed at Create_func_aes_decrypt::create_native +--echo # + +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +select aes_encrypt(); +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +select aes_decrypt(); + --echo # --echo # End of 11.2 tests --echo # diff --git a/mysql-test/main/func_time.result b/mysql-test/main/func_time.result index ff9b91ad1d5..c3acc114786 100644 --- a/mysql-test/main/func_time.result +++ b/mysql-test/main/func_time.result @@ -3142,7 +3142,7 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is def test t1 t1 a a 12 26 26 Y 128 6 63 def EXTRACT(YEAR FROM a) 3 4 4 Y 32896 0 63 def EXTRACT(YEAR_MONTH FROM a) 3 6 6 Y 32896 0 63 -def EXTRACT(QUARTER FROM a) 3 2 1 Y 32896 0 63 +def EXTRACT(QUARTER FROM a) 3 1 1 Y 32896 0 63 def EXTRACT(MONTH FROM a) 3 2 2 Y 32896 0 63 def EXTRACT(WEEK FROM a) 3 2 2 Y 32896 0 63 def EXTRACT(DAY FROM a) 3 3 2 Y 32896 0 63 @@ -3230,11 +3230,11 @@ SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( `a` datetime(6) DEFAULT NULL, - `EXTRACT(YEAR FROM a)` int(4) DEFAULT NULL, - `EXTRACT(YEAR_MONTH FROM a)` int(6) DEFAULT NULL, + `EXTRACT(YEAR FROM a)` int(5) DEFAULT NULL, + `EXTRACT(YEAR_MONTH FROM a)` int(7) DEFAULT NULL, `EXTRACT(QUARTER FROM a)` int(2) DEFAULT NULL, - `EXTRACT(MONTH FROM a)` int(2) DEFAULT NULL, - `EXTRACT(WEEK FROM a)` int(2) DEFAULT NULL, + `EXTRACT(MONTH FROM a)` int(3) DEFAULT NULL, + `EXTRACT(WEEK FROM a)` int(3) DEFAULT NULL, `EXTRACT(DAY FROM a)` int(3) DEFAULT NULL, `EXTRACT(DAY_HOUR FROM a)` int(5) DEFAULT NULL, `EXTRACT(DAY_MINUTE FROM a)` int(7) DEFAULT NULL, @@ -3281,7 +3281,7 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is def test t1 t1 a a 11 17 17 Y 128 6 63 def EXTRACT(YEAR FROM a) 3 4 1 Y 32896 0 63 def EXTRACT(YEAR_MONTH FROM a) 3 6 1 Y 32896 0 63 -def EXTRACT(QUARTER FROM a) 3 2 1 Y 32896 0 63 +def EXTRACT(QUARTER FROM a) 3 1 1 Y 32896 0 63 def EXTRACT(MONTH FROM a) 3 2 1 Y 32896 0 63 def EXTRACT(WEEK FROM a) 3 2 9 Y 32896 0 63 def EXTRACT(DAY FROM a) 3 3 3 Y 32896 0 63 @@ -3411,11 +3411,11 @@ SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( `a` time(6) DEFAULT NULL, - `EXTRACT(YEAR FROM a)` int(4) DEFAULT NULL, - `EXTRACT(YEAR_MONTH FROM a)` int(6) DEFAULT NULL, + `EXTRACT(YEAR FROM a)` int(5) DEFAULT NULL, + `EXTRACT(YEAR_MONTH FROM a)` int(7) DEFAULT NULL, `EXTRACT(QUARTER FROM a)` int(2) DEFAULT NULL, - `EXTRACT(MONTH FROM a)` int(2) DEFAULT NULL, - `EXTRACT(WEEK FROM a)` int(2) DEFAULT NULL, + `EXTRACT(MONTH FROM a)` int(3) DEFAULT NULL, + `EXTRACT(WEEK FROM a)` int(3) DEFAULT NULL, `EXTRACT(DAY FROM a)` int(3) DEFAULT NULL, `EXTRACT(DAY_HOUR FROM a)` int(5) DEFAULT NULL, `EXTRACT(DAY_MINUTE FROM a)` int(7) DEFAULT NULL, @@ -6365,3 +6365,57 @@ NULL SELECT FROM_UNIXTIME(LEAST(3696610869, NULL)); FROM_UNIXTIME(LEAST(3696610869, NULL)) NULL +# +# Start of 10.5 tests +# +# +# MDEV-29149 Assertion `!is_valid_datetime() || fraction_remainder(((item->decimals) < (6) ? (item->decimals) : (6))) == 0' failed in Datetime_truncation_not_needed::Datetime_truncation_not_needed +# +SET @@timestamp= UNIX_TIMESTAMP('2022-07-21 23:00:00'); +SELECT DATE_SUB('2022-07-21 00:00:00', INTERVAL 800 HOUR) AS expected_result; +expected_result +2022-06-17 16:00:00 +SELECT +IF(1,TIMEDIFF('38:59:59','839:00:00'),CAST('2022-12-12' AS DATE)) AS c1, +IF(1,TIMEDIFF('-839:00:00','-38:59:59'),CAST('2022-12-12' AS DATE)) AS c2; +c1 c2 +2022-06-17 16:00:00 2022-06-17 16:00:00 +Warnings: +Warning 1292 Truncated incorrect time value: '839:00:00' +Warning 1292 Truncated incorrect time value: '-839:00:00' +SELECT +IF(1,TIMEDIFF(385959,8390000),CAST('2022-12-12' AS DATE)) AS c1, +IF(1,TIMEDIFF(-8390000,-385959),CAST('2022-12-12' AS DATE)) AS c2; +c1 c2 +2022-06-17 16:00:00 2022-06-17 16:00:00 +Warnings: +Warning 1292 Truncated incorrect time value: '8390000' +Warning 1292 Truncated incorrect time value: '-8390000' +SELECT +TIMEDIFF('38:59:59','839:00:00') AS c1, +CAST(TIMEDIFF('38:59:59','839:00:00') AS TIME(6)) AS c2, +TIMEDIFF('839:00:00','38:59:59') AS c3, +CAST(TIMEDIFF('839:00:00','38:59:59') AS TIME(6)) AS c4; +c1 c2 c3 c4 +-800:00:00 -800:00:00.000000 800:00:00 800:00:00.000000 +Warnings: +Warning 1292 Truncated incorrect time value: '839:00:00' +Warning 1292 Truncated incorrect time value: '839:00:00' +Warning 1292 Truncated incorrect time value: '839:00:00' +Warning 1292 Truncated incorrect time value: '839:00:00' +SELECT +TIMEDIFF(385959,8390000) AS c1, +CAST(TIMEDIFF(385959,8390000) AS TIME(6)) AS c2, +TIMEDIFF(8390000,385959) AS c3, +CAST(TIMEDIFF(8390000,385959) AS TIME(6)) AS c4; +c1 c2 c3 c4 +-800:00:00 -800:00:00.000000 800:00:00 800:00:00.000000 +Warnings: +Warning 1292 Truncated incorrect time value: '8390000' +Warning 1292 Truncated incorrect time value: '8390000' +Warning 1292 Truncated incorrect time value: '8390000' +Warning 1292 Truncated incorrect time value: '8390000' +SET @@timestamp= DEFAULT; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/func_time.test b/mysql-test/main/func_time.test index fb184ab4e16..caf6ec1c6cf 100644 --- a/mysql-test/main/func_time.test +++ b/mysql-test/main/func_time.test @@ -3218,3 +3218,42 @@ SELECT CONCAT(MAKETIME('01', '01', LEAST( -100, NULL ))); --echo # SELECT FROM_UNIXTIME(LEAST(3696610869, NULL)); + + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-29149 Assertion `!is_valid_datetime() || fraction_remainder(((item->decimals) < (6) ? (item->decimals) : (6))) == 0' failed in Datetime_truncation_not_needed::Datetime_truncation_not_needed +--echo # + +SET @@timestamp= UNIX_TIMESTAMP('2022-07-21 23:00:00'); + +SELECT DATE_SUB('2022-07-21 00:00:00', INTERVAL 800 HOUR) AS expected_result; + +SELECT + IF(1,TIMEDIFF('38:59:59','839:00:00'),CAST('2022-12-12' AS DATE)) AS c1, + IF(1,TIMEDIFF('-839:00:00','-38:59:59'),CAST('2022-12-12' AS DATE)) AS c2; + +SELECT + IF(1,TIMEDIFF(385959,8390000),CAST('2022-12-12' AS DATE)) AS c1, + IF(1,TIMEDIFF(-8390000,-385959),CAST('2022-12-12' AS DATE)) AS c2; + +SELECT + TIMEDIFF('38:59:59','839:00:00') AS c1, + CAST(TIMEDIFF('38:59:59','839:00:00') AS TIME(6)) AS c2, + TIMEDIFF('839:00:00','38:59:59') AS c3, + CAST(TIMEDIFF('839:00:00','38:59:59') AS TIME(6)) AS c4; + +SELECT + TIMEDIFF(385959,8390000) AS c1, + CAST(TIMEDIFF(385959,8390000) AS TIME(6)) AS c2, + TIMEDIFF(8390000,385959) AS c3, + CAST(TIMEDIFF(8390000,385959) AS TIME(6)) AS c4; + +SET @@timestamp= DEFAULT; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/main/function_defaults.result b/mysql-test/main/function_defaults.result index d53e929c128..5f5a4c878e6 100644 --- a/mysql-test/main/function_defaults.result +++ b/mysql-test/main/function_defaults.result @@ -3145,3 +3145,28 @@ a b c 2 2010-10-10 10:10:10 x drop table t1; set timestamp=default; +# +# MDEV-33790: Incorrect DEFAULT expression evaluated in UPDATE +# +create table t1 ( +a int, +b timestamp default '2010-10-10 10:10:10' on update now(), +c varchar(100) default 'x'); +create table t2 (a int primary key); +insert t1 (a) values (1),(2); +insert t2 (a) values (1),(2); +select * from t1; +a b c +1 2010-10-10 10:10:10 x +2 2010-10-10 10:10:10 x +set timestamp=unix_timestamp('2011-11-11 11-11-11'); +update t1,t2 set b=default, c=default(b) where t1.a=1 and t1.a= t2.a; +select * from t1; +a b c +1 2010-10-10 10:10:10 2010-10-10 10:10:10 +2 2010-10-10 10:10:10 x +drop table t1, t2; +set timestamp=default; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/function_defaults.test b/mysql-test/main/function_defaults.test index dd3ba109b2a..59776118e56 100644 --- a/mysql-test/main/function_defaults.test +++ b/mysql-test/main/function_defaults.test @@ -67,3 +67,26 @@ update t1 set b=default, c=default(b) where a=1; select * from t1; drop table t1; set timestamp=default; + +--echo # +--echo # MDEV-33790: Incorrect DEFAULT expression evaluated in UPDATE +--echo # + +create table t1 ( + a int, + b timestamp default '2010-10-10 10:10:10' on update now(), + c varchar(100) default 'x'); +create table t2 (a int primary key); +insert t1 (a) values (1),(2); +insert t2 (a) values (1),(2); + +select * from t1; +set timestamp=unix_timestamp('2011-11-11 11-11-11'); +update t1,t2 set b=default, c=default(b) where t1.a=1 and t1.a= t2.a; +select * from t1; +drop table t1, t2; +set timestamp=default; + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/mysql-test/main/gis.result b/mysql-test/main/gis.result index d8d424897fb..8097c7a8ba8 100644 --- a/mysql-test/main/gis.result +++ b/mysql-test/main/gis.result @@ -5072,37 +5072,37 @@ ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN(PO # MDEV-20009 Add CAST(expr AS pluggable_type) # SELECT CAST(1 AS GEOMETRY); -ERROR HY000: Operator does not exists: 'CAST(expr AS geometry)' +ERROR HY000: Operator does not exist: 'CAST(expr AS geometry)' SELECT CAST(1 AS GEOMETRYCOLLECTION); -ERROR HY000: Operator does not exists: 'CAST(expr AS geometrycollection)' +ERROR HY000: Operator does not exist: 'CAST(expr AS geometrycollection)' SELECT CAST(1 AS POINT); -ERROR HY000: Operator does not exists: 'CAST(expr AS point)' +ERROR HY000: Operator does not exist: 'CAST(expr AS point)' SELECT CAST(1 AS LINESTRING); -ERROR HY000: Operator does not exists: 'CAST(expr AS linestring)' +ERROR HY000: Operator does not exist: 'CAST(expr AS linestring)' SELECT CAST(1 AS POLYGON); -ERROR HY000: Operator does not exists: 'CAST(expr AS polygon)' +ERROR HY000: Operator does not exist: 'CAST(expr AS polygon)' SELECT CAST(1 AS MULTIPOINT); -ERROR HY000: Operator does not exists: 'CAST(expr AS multipoint)' +ERROR HY000: Operator does not exist: 'CAST(expr AS multipoint)' SELECT CAST(1 AS MULTILINESTRING); -ERROR HY000: Operator does not exists: 'CAST(expr AS multilinestring)' +ERROR HY000: Operator does not exist: 'CAST(expr AS multilinestring)' SELECT CAST(1 AS MULTIPOLYGON); -ERROR HY000: Operator does not exists: 'CAST(expr AS multipolygon)' +ERROR HY000: Operator does not exist: 'CAST(expr AS multipolygon)' SELECT CONVERT(1, GEOMETRY); -ERROR HY000: Operator does not exists: 'CAST(expr AS geometry)' +ERROR HY000: Operator does not exist: 'CAST(expr AS geometry)' SELECT CONVERT(1, GEOMETRYCOLLECTION); -ERROR HY000: Operator does not exists: 'CAST(expr AS geometrycollection)' +ERROR HY000: Operator does not exist: 'CAST(expr AS geometrycollection)' SELECT CONVERT(1, POINT); -ERROR HY000: Operator does not exists: 'CAST(expr AS point)' +ERROR HY000: Operator does not exist: 'CAST(expr AS point)' SELECT CONVERT(1, LINESTRING); -ERROR HY000: Operator does not exists: 'CAST(expr AS linestring)' +ERROR HY000: Operator does not exist: 'CAST(expr AS linestring)' SELECT CONVERT(1, POLYGON); -ERROR HY000: Operator does not exists: 'CAST(expr AS polygon)' +ERROR HY000: Operator does not exist: 'CAST(expr AS polygon)' SELECT CONVERT(1, MULTIPOINT); -ERROR HY000: Operator does not exists: 'CAST(expr AS multipoint)' +ERROR HY000: Operator does not exist: 'CAST(expr AS multipoint)' SELECT CONVERT(1, MULTILINESTRING); -ERROR HY000: Operator does not exists: 'CAST(expr AS multilinestring)' +ERROR HY000: Operator does not exist: 'CAST(expr AS multilinestring)' SELECT CONVERT(1, MULTIPOLYGON); -ERROR HY000: Operator does not exists: 'CAST(expr AS multipolygon)' +ERROR HY000: Operator does not exist: 'CAST(expr AS multipolygon)' # # MDEV-17832 Protocol: extensions for Pluggable types and JSON, GEOMETRY # diff --git a/mysql-test/main/host_cache_size_functionality.test b/mysql-test/main/host_cache_size_functionality.test index 9ec26010ab6..f37b2ab8c9e 100644 --- a/mysql-test/main/host_cache_size_functionality.test +++ b/mysql-test/main/host_cache_size_functionality.test @@ -43,10 +43,10 @@ select @@global.Host_Cache_Size > 0; --echo # Restart server with Host_Cache_Size 1 let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; ---exec echo "wait" > $restart_file +--write_line wait $restart_file --shutdown_server --source include/wait_until_disconnected.inc --- exec echo "restart:--host_cache_size=1 " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart:--host_cache_size=1 " $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -- enable_reconnect -- source include/wait_until_connected_again.inc @@ -142,10 +142,10 @@ SELECT Host_Cache_Size = @@SESSION.Host_Cache_Size; #--remove_file $MYSQL_TMP_DIR/bind_ip #let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; -#--exec echo "wait" > $restart_file +#--write_line wait $restart_file #--shutdown_server #--source include/wait_until_disconnected.inc -#-- exec echo "restart:--bind-address=$bind_ip " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +#-- write_line "restart:--bind-address=$bind_ip " $MYSQLTEST_VARDIR/tmp/mysqld.1.expect #-- enable_reconnect #-- source include/wait_until_connected_again.inc diff --git a/mysql-test/main/information_schema2.result b/mysql-test/main/information_schema2.result index e23e81b885c..fa4d71bf227 100644 --- a/mysql-test/main/information_schema2.result +++ b/mysql-test/main/information_schema2.result @@ -1,3 +1,6 @@ +# +# MDEV-4029 SELECT on information_schema using a subquery locks up the information_schema table due to incorrect mutexes handling +# select variable_name from information_schema.session_status where variable_name = (select variable_name from information_schema.session_status where variable_name = 'uptime'); variable_name @@ -6,6 +9,9 @@ select variable_name from information_schema.session_variables where variable_na (select variable_name from information_schema.session_variables where variable_name = 'basedir'); variable_name BASEDIR +# +# MDEV-8796 Delete with sub query with information_schema.TABLES deletes too many rows +# create table t1 (x int); create table t2 (x int); create table t3 (x int); @@ -18,3 +24,15 @@ t2 t3 t4 drop table t1, t2, t3, t4; +# End of 5.5 tests +# INFORMATION_SCHEMA.STATISTICS doesn't show if the index is disabled +create table t1 (a int, key(a)); +select index_name, comment from information_schema.statistics where table_schema='test' and table_name='t1'; +index_name comment +a +alter table t1 disable keys; +select index_name, comment from information_schema.statistics where table_schema='test' and table_name='t1'; +index_name comment +a disabled +drop table t1; +# End of 10.5 tests diff --git a/mysql-test/main/information_schema2.test b/mysql-test/main/information_schema2.test index d2fa3da2b5f..50ceec2c5d3 100644 --- a/mysql-test/main/information_schema2.test +++ b/mysql-test/main/information_schema2.test @@ -1,15 +1,15 @@ -# -# MDEV-4029 SELECT on information_schema using a subquery locks up the information_schema table due to incorrect mutexes handling -# +--echo # +--echo # MDEV-4029 SELECT on information_schema using a subquery locks up the information_schema table due to incorrect mutexes handling +--echo # select variable_name from information_schema.session_status where variable_name = (select variable_name from information_schema.session_status where variable_name = 'uptime'); select variable_name from information_schema.session_variables where variable_name = (select variable_name from information_schema.session_variables where variable_name = 'basedir'); -# -# MDEV-8796 Delete with sub query with information_schema.TABLES deletes too many rows -# +--echo # +--echo # MDEV-8796 Delete with sub query with information_schema.TABLES deletes too many rows +--echo # create table t1 (x int); create table t2 (x int); create table t3 (x int); @@ -17,3 +17,14 @@ create table t4 AS select table_name from information_schema.TABLES where table_ delete from t4 where table_name not in (select table_name from information_schema.TABLES where table_schema = database() and table_type = 'BASE TABLE'); select * from t4 order by table_name; drop table t1, t2, t3, t4; + +--echo # End of 5.5 tests + +--echo # INFORMATION_SCHEMA.STATISTICS doesn't show if the index is disabled +create table t1 (a int, key(a)); +select index_name, comment from information_schema.statistics where table_schema='test' and table_name='t1'; +alter table t1 disable keys; +select index_name, comment from information_schema.statistics where table_schema='test' and table_name='t1'; +drop table t1; + +--echo # End of 10.5 tests diff --git a/mysql-test/main/init_file_set_password-7656.test b/mysql-test/main/init_file_set_password-7656.test index 7bca34a0fcf..ac5baa3b04f 100644 --- a/mysql-test/main/init_file_set_password-7656.test +++ b/mysql-test/main/init_file_set_password-7656.test @@ -15,12 +15,12 @@ EOF --enable_reconnect ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc ---exec echo "restart:--init-file=$MYSQLTEST_VARDIR/init.file " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart:--init-file=$MYSQLTEST_VARDIR/init.file " $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --source include/wait_until_connected_again.inc select user,host,password,plugin,authentication_string from mysql.user where user='foo'; diff --git a/mysql-test/main/innodb_ext_key,covering,innodb,on.rdiff b/mysql-test/main/innodb_ext_key,covering,on.rdiff similarity index 100% rename from mysql-test/main/innodb_ext_key,covering,innodb,on.rdiff rename to mysql-test/main/innodb_ext_key,covering,on.rdiff diff --git a/mysql-test/main/innodb_ext_key,off.rdiff b/mysql-test/main/innodb_ext_key,off.rdiff index ef11f9c05bc..8b24cc9a663 100644 --- a/mysql-test/main/innodb_ext_key,off.rdiff +++ b/mysql-test/main/innodb_ext_key,off.rdiff @@ -163,7 +163,7 @@ where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000 @@ -220,12 +220,12 @@ 5959 3 - show status like 'handler_read_next'; + show /*a*/ status like 'handler_read_next'; Variable_name Value -Handler_read_next 3 +Handler_read_next 9 @@ -177,7 +177,7 @@ select max(l_orderkey) from lineitem where l_partkey between 1 and 10 group by l_partkey; @@ -243,9 +243,9 @@ - show status like 'handler_read%'; + show /*b*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 -Handler_read_key 21 @@ -199,7 +199,7 @@ select max(l_orderkey) from lineitem where l_suppkey in (1,4) group by l_suppkey; @@ -265,9 +265,9 @@ - show status like 'handler_read%'; + show /*c*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 -Handler_read_key 6 diff --git a/mysql-test/main/innodb_ext_key,innodb,on,unoptimized.rdiff b/mysql-test/main/innodb_ext_key,on,unoptimized.rdiff similarity index 100% rename from mysql-test/main/innodb_ext_key,innodb,on,unoptimized.rdiff rename to mysql-test/main/innodb_ext_key,on,unoptimized.rdiff diff --git a/mysql-test/main/innodb_ext_key.result b/mysql-test/main/innodb_ext_key.result index d1f4c60f5b2..35c4e53f970 100644 --- a/mysql-test/main/innodb_ext_key.result +++ b/mysql-test/main/innodb_ext_key.result @@ -14,7 +14,7 @@ flush status; select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01'; count(*) 1 -show status like 'handler_read%'; +show /*1*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 1 @@ -35,7 +35,7 @@ select count(*) from lineitem use index(primary) where l_orderkey=130 and l_linenumber=2 and l_shipdate='1992-07-01'; count(*) 1 -show status like 'handler_read%'; +show /*2*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 1 @@ -56,7 +56,7 @@ select count(*) from lineitem where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000; count(*) 1 -show status like 'handler_read%'; +show /*3*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 1 @@ -79,7 +79,7 @@ l_orderkey l_linenumber 1088 3 1217 1 1221 3 -show status like 'handler_read%'; +show /*4*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 1 @@ -98,7 +98,7 @@ flush status; select min(l_orderkey) from lineitem where l_shipdate='1992-07-01'; min(l_orderkey) 130 -show status like 'handler_read%'; +show /*5*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 1 @@ -119,7 +119,7 @@ select min(l_orderkey) from lineitem where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000; min(l_orderkey) 1088 -show status like 'handler_read%'; +show /*6*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 1 @@ -140,7 +140,7 @@ select max(l_linenumber) from lineitem where l_shipdate='1992-07-01' and l_orderkey=130; max(l_linenumber) 2 -show status like 'handler_read%'; +show /*7*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 1 @@ -166,7 +166,7 @@ or l_receiptdate='1992-07-01' and l_orderkey=5603; l_orderkey l_linenumber 130 2 5603 2 -show status like 'handler_read%'; +show /*8*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 2 @@ -193,7 +193,7 @@ l_orderkey l_linenumber 130 2 5603 2 5959 3 -show status like 'handler_read%'; +show /*9*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 2 @@ -218,7 +218,7 @@ l_orderkey l_linenumber 130 2 5603 2 5959 3 -show status like 'handler_read_next'; +show /*a*/ status like 'handler_read_next'; Variable_name Value Handler_read_next 3 explain @@ -240,7 +240,7 @@ max(l_orderkey) 5894 5859 5632 -show status like 'handler_read%'; +show /*b*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 21 @@ -262,7 +262,7 @@ where l_suppkey in (1,4) group by l_suppkey; max(l_orderkey) 5988 5984 -show status like 'handler_read%'; +show /*c*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 6 @@ -292,7 +292,7 @@ where p_retailprice > 1100 and o_orderdate='1997-01-01' and o_orderkey=l_orderkey and p_partkey=l_partkey; o_orderkey p_partkey 5895 200 -show status like 'handler_read%'; +show /*d*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 3 @@ -458,7 +458,7 @@ select * from t1, t2 where t2.a=t1.a and t2.b < 2; a pk a b 0 0 0 0 1 1 1 1 -show status like 'handler_read%'; +show /*e*/ status like 'handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 10 diff --git a/mysql-test/main/innodb_ext_key.test b/mysql-test/main/innodb_ext_key.test index 49112c10c57..d24bb77e238 100644 --- a/mysql-test/main/innodb_ext_key.test +++ b/mysql-test/main/innodb_ext_key.test @@ -6,6 +6,8 @@ --source include/no_valgrind_without_big.inc --source include/have_sequence.inc +--source include/innodb_stable_estimates.inc + SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; set @innodb_stats_persistent_save= @@innodb_stats_persistent; @@ -33,7 +35,7 @@ explain select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01'; flush status; select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01'; -show status like 'handler_read%'; +show /*1*/ status like 'handler_read%'; explain select count(*) from lineitem use index(primary) @@ -41,7 +43,7 @@ select count(*) from lineitem use index(primary) flush status; select count(*) from lineitem use index(primary) where l_orderkey=130 and l_linenumber=2 and l_shipdate='1992-07-01'; -show status like 'handler_read%'; +show /*2*/ status like 'handler_read%'; explain select count(*) from lineitem @@ -49,7 +51,7 @@ select count(*) from lineitem flush status; select count(*) from lineitem where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000; -show status like 'handler_read%'; +show /*3*/ status like 'handler_read%'; explain select l_orderkey, l_linenumber from lineitem @@ -57,13 +59,13 @@ select l_orderkey, l_linenumber from lineitem flush status; select l_orderkey, l_linenumber from lineitem where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000; -show status like 'handler_read%'; +show /*4*/ status like 'handler_read%'; explain select min(l_orderkey) from lineitem where l_shipdate='1992-07-01'; flush status; select min(l_orderkey) from lineitem where l_shipdate='1992-07-01'; -show status like 'handler_read%'; +show /*5*/ status like 'handler_read%'; explain select min(l_orderkey) from lineitem @@ -71,7 +73,7 @@ select min(l_orderkey) from lineitem flush status; select min(l_orderkey) from lineitem where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000; -show status like 'handler_read%'; +show /*6*/ status like 'handler_read%'; explain select max(l_linenumber) from lineitem @@ -79,7 +81,7 @@ select max(l_linenumber) from lineitem flush status; select max(l_linenumber) from lineitem where l_shipdate='1992-07-01' and l_orderkey=130; -show status like 'handler_read%'; +show /*7*/ status like 'handler_read%'; explain select l_orderkey, l_linenumber @@ -91,7 +93,7 @@ select l_orderkey, l_linenumber from lineitem use index (i_l_shipdate, i_l_receiptdate) where l_shipdate='1992-07-01' and l_orderkey=130 or l_receiptdate='1992-07-01' and l_orderkey=5603; -show status like 'handler_read%'; +show /*8*/ status like 'handler_read%'; --replace_column 7 # explain @@ -104,7 +106,7 @@ select l_orderkey, l_linenumber from lineitem use index (i_l_shipdate, i_l_receiptdate) where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000 or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000; -show status like 'handler_read%'; +show /*9*/ status like 'handler_read%'; --replace_column 7 # 9 # 10 Using explain @@ -115,7 +117,7 @@ flush status; select l_orderkey, l_linenumber from lineitem where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000 or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000; -show status like 'handler_read_next'; +show /*a*/ status like 'handler_read_next'; --replace_column 9 # explain @@ -124,7 +126,7 @@ select max(l_orderkey) from lineitem flush status; select max(l_orderkey) from lineitem where l_partkey between 1 and 10 group by l_partkey; -show status like 'handler_read%'; +show /*b*/ status like 'handler_read%'; --replace_column 9 # explain @@ -133,7 +135,7 @@ select max(l_orderkey) from lineitem flush status; select max(l_orderkey) from lineitem where l_suppkey in (1,4) group by l_suppkey; -show status like 'handler_read%'; +show /*c*/ status like 'handler_read%'; create index i_p_retailprice on part(p_retailprice); @@ -150,7 +152,7 @@ select o_orderkey, p_partkey lineitem use index (i_l_partkey), orders where p_retailprice > 1100 and o_orderdate='1997-01-01' and o_orderkey=l_orderkey and p_partkey=l_partkey; -show status like 'handler_read%'; +show /*d*/ status like 'handler_read%'; --enable_ps2_protocol --echo # @@ -327,7 +329,7 @@ explain select * from t1, t2 where t2.a=t1.a and t2.b < 2; flush status; select * from t1, t2 where t2.a=t1.a and t2.b < 2; -show status like 'handler_read%'; +show /*e*/ status like 'handler_read%'; --enable_ps2_protocol drop table t1,t2; diff --git a/mysql-test/main/insert_select.result b/mysql-test/main/insert_select.result index 29618c6ddd4..463f571b096 100644 --- a/mysql-test/main/insert_select.result +++ b/mysql-test/main/insert_select.result @@ -973,7 +973,6 @@ select * from t1; a 3 1 -2 delete from t1; insert into t1 values (3), (1); insert into t1 @@ -984,8 +983,6 @@ select * from t1; a 3 1 -3 -2 delete from t1; insert into t1 values (3), (1); insert into t1 @@ -996,6 +993,7 @@ select * from t1; a 3 1 +3 2 delete from t1; insert into t1 values (3), (1); @@ -1022,7 +1020,6 @@ select * from t1; a 3 1 -2 delete from t1; insert into t1 values (3), (1); execute stmt; @@ -1030,7 +1027,6 @@ select * from t1; a 3 1 -2 delete from t1; insert into t1 values (3), (1); delete from t1 @@ -1040,6 +1036,8 @@ group by (select * from (select a from t1) dt where a = 1))); select * from t1; a +3 +1 deallocate prepare stmt; drop table t1,t2,t3; # diff --git a/mysql-test/main/join.result b/mysql-test/main/join.result index 402ff26767a..b1d7e155621 100644 --- a/mysql-test/main/join.result +++ b/mysql-test/main/join.result @@ -894,7 +894,7 @@ show status like 'Last_query_cost'; Variable_name Value Last_query_cost 0.011600 select 'The cost of accessing t1 (dont care if it changes' '^'; -The cost of accessing t1 (dont care if it changes +The cost of accessing t1 (dont care if it changes^ The cost of accessing t1 (dont care if it changes^ select 'vv: Following query must use ALL(t1), eq_ref(A), eq_ref(B): vv' Z; Z @@ -3435,6 +3435,62 @@ SELECT COUNT(*) FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b = t3.c) ON t1.a = t2. COUNT(*) 2 DROP TABLE t1, t2, t3; +# +# MDEV-30975: Wrong result with cross Join given join order +# +CREATE TABLE `t1` ( +`t1_seq` INT NOT NULL, +`c1` VARCHAR(10) NOT NULL , +PRIMARY KEY (`t1_seq`) USING BTREE +); +CREATE TABLE `t2` ( +`t2_seq` INT NOT NULL, +`t1_seq` INT NOT NULL, +`c2` VARCHAR(10) NOT NULL , +PRIMARY KEY (`t2_seq`, `t1_seq`) USING BTREE +); +INSERT INTO t1 VALUES(1, 'A'); +INSERT INTO t2 VALUES(1, 1, 'T2-1-1'); +INSERT INTO t2 VALUES(2, 1, 'T2-1-2'); +INSERT INTO t2 VALUES(3, 1, 'T2-1-3'); +SELECT LPAD(@rownum := @rownum + 1, 8, 0) AS str_num +, t1.t1_seq +, t2.t2_seq +, t1.c1 +, t2.c2 +FROM t1 +INNER JOIN t2 ON (t1.t1_seq = t2.t1_seq) +CROSS JOIN ( SELECT @rownum := 0 ) X; +str_num t1_seq t2_seq c1 c2 +00000001 1 1 A T2-1-1 +00000002 1 2 A T2-1-2 +00000003 1 3 A T2-1-3 +SELECT STRAIGHT_JOIN LPAD(@rownum := @rownum + 1, 8, 0) AS str_num +, t1.t1_seq +, t2.t2_seq +, t1.c1 +, t2.c2 +FROM t1 +INNER JOIN t2 ON (t1.t1_seq = t2.t1_seq) +CROSS JOIN ( SELECT @rownum := 0 ) X; +str_num t1_seq t2_seq c1 c2 +00000001 1 1 A T2-1-1 +00000002 1 2 A T2-1-2 +00000003 1 3 A T2-1-3 +SELECT STRAIGHT_JOIN * FROM t1 JOIN t2 ON (t1.t1_seq = t2.t1_seq) JOIN (SELECT @a := 0) x; +t1_seq c1 t2_seq t1_seq c2 @a := 0 +1 A 1 1 T2-1-1 0 +1 A 2 1 T2-1-2 0 +1 A 3 1 T2-1-3 0 +SELECT * FROM t1 JOIN t2 ON (t1.t1_seq = t2.t1_seq) JOIN (SELECT @a := 0) x; +t1_seq c1 t2_seq t1_seq c2 @a := 0 +1 A 1 1 T2-1-1 0 +1 A 2 1 T2-1-2 0 +1 A 3 1 T2-1-3 0 +SELECT STRAIGHT_JOIN c1 FROM t1 JOIN (SELECT @a := 0) x; +c1 +A +DROP TABLE t1, t2; # End of 10.5 tests # # MDEV-31449: Assertion s->table->opt_range_condition_rows <= s->found_records diff --git a/mysql-test/main/join.test b/mysql-test/main/join.test index 4168325046f..7a8c6a09732 100644 --- a/mysql-test/main/join.test +++ b/mysql-test/main/join.test @@ -1842,6 +1842,52 @@ SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b = t3.c) ON t1.a = t2.b; SELECT COUNT(*) FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b = t3.c) ON t1.a = t2.b; DROP TABLE t1, t2, t3; +--echo # +--echo # MDEV-30975: Wrong result with cross Join given join order +--echo # + +CREATE TABLE `t1` ( + `t1_seq` INT NOT NULL, + `c1` VARCHAR(10) NOT NULL , + PRIMARY KEY (`t1_seq`) USING BTREE +); + +CREATE TABLE `t2` ( + `t2_seq` INT NOT NULL, + `t1_seq` INT NOT NULL, + `c2` VARCHAR(10) NOT NULL , + PRIMARY KEY (`t2_seq`, `t1_seq`) USING BTREE +); + +INSERT INTO t1 VALUES(1, 'A'); +INSERT INTO t2 VALUES(1, 1, 'T2-1-1'); +INSERT INTO t2 VALUES(2, 1, 'T2-1-2'); +INSERT INTO t2 VALUES(3, 1, 'T2-1-3'); + +SELECT LPAD(@rownum := @rownum + 1, 8, 0) AS str_num + , t1.t1_seq + , t2.t2_seq + , t1.c1 + , t2.c2 + FROM t1 + INNER JOIN t2 ON (t1.t1_seq = t2.t1_seq) + CROSS JOIN ( SELECT @rownum := 0 ) X; + +SELECT STRAIGHT_JOIN LPAD(@rownum := @rownum + 1, 8, 0) AS str_num + , t1.t1_seq + , t2.t2_seq + , t1.c1 + , t2.c2 + FROM t1 + INNER JOIN t2 ON (t1.t1_seq = t2.t1_seq) + CROSS JOIN ( SELECT @rownum := 0 ) X; + +SELECT STRAIGHT_JOIN * FROM t1 JOIN t2 ON (t1.t1_seq = t2.t1_seq) JOIN (SELECT @a := 0) x; +SELECT * FROM t1 JOIN t2 ON (t1.t1_seq = t2.t1_seq) JOIN (SELECT @a := 0) x; +SELECT STRAIGHT_JOIN c1 FROM t1 JOIN (SELECT @a := 0) x; + +DROP TABLE t1, t2; + --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/join_cache.result b/mysql-test/main/join_cache.result index 26a57dda173..0f29c375cce 100644 --- a/mysql-test/main/join_cache.result +++ b/mysql-test/main/join_cache.result @@ -6464,5 +6464,27 @@ b b d c c 10 NULL NULL NULL NULL DROP TABLE t1,t2,t3,t4; # +# MDEV-21102: Server crashes in JOIN_CACHE::write_record_data upon EXPLAIN with subqueries and constant tables +# +CREATE TABLE t1 (a int, b int) ENGINE=MyISAM; +CREATE TABLE t2 (c int, d int) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1,10); +CREATE TABLE t3 (e int, key (e)) ENGINE=MyISAM; +INSERT INTO t3 VALUES (2),(3); +# Must not crash, must use join buffer in subquery +EXPLAIN +SELECT * FROM t1 +WHERE a > b OR a IN ( +SELECT c FROM t2 WHERE EXISTS ( +SELECT * FROM t3 t3a JOIN t3 t3b WHERE t3a.e < d +) +); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 +3 SUBQUERY t3a range e e 5 NULL 2 Using where; Using index +3 SUBQUERY t3b index NULL e 5 NULL 2 Using index; Using join buffer (flat, BNL join) +DROP TABLE t1,t2,t3; +# # End of 10.4 tests # diff --git a/mysql-test/main/join_cache.test b/mysql-test/main/join_cache.test index dddc0c1a316..cfbd5e2dc5f 100644 --- a/mysql-test/main/join_cache.test +++ b/mysql-test/main/join_cache.test @@ -4362,6 +4362,27 @@ eval $q2; DROP TABLE t1,t2,t3,t4; +--echo # +--echo # MDEV-21102: Server crashes in JOIN_CACHE::write_record_data upon EXPLAIN with subqueries and constant tables +--echo # +CREATE TABLE t1 (a int, b int) ENGINE=MyISAM; + +CREATE TABLE t2 (c int, d int) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1,10); + +CREATE TABLE t3 (e int, key (e)) ENGINE=MyISAM; +INSERT INTO t3 VALUES (2),(3); + +--echo # Must not crash, must use join buffer in subquery +EXPLAIN +SELECT * FROM t1 +WHERE a > b OR a IN ( + SELECT c FROM t2 WHERE EXISTS ( + SELECT * FROM t3 t3a JOIN t3 t3b WHERE t3a.e < d + ) +); +DROP TABLE t1,t2,t3; + --echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/join_outer.test b/mysql-test/main/join_outer.test index 72fffd4fadf..a9292abd5bb 100644 --- a/mysql-test/main/join_outer.test +++ b/mysql-test/main/join_outer.test @@ -685,15 +685,9 @@ create table t1 (a int, b varchar(20)); create table t2 (a int, c varchar(20)); insert into t1 values (1,"aaaaaaaaaa"),(2,"bbbbbbbbbb"); insert into t2 values (1,"cccccccccc"),(2,"dddddddddd"); -#Enable after fix MDEV-31276 ---disable_ps2_protocol select group_concat(t1.b,t2.c) from t1 left join t2 using(a) group by t1.a; ---enable_ps2_protocol select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by t1.a; -#Enable after fix MDEV-31276 ---disable_ps2_protocol select group_concat(t1.b,t2.c) from t1 left join t2 using(a) group by a; ---enable_ps2_protocol select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by a; drop table t1, t2; set group_concat_max_len=default; @@ -2372,11 +2366,8 @@ create view v1 as select * from t1 left join ( select 'Y' AS Voted, ElectionID from t2 ) AS T on T.ElectionID = t1.Election limit 9; -#enable after fix MDEV-31277 ---disable_ps2_protocol # limit X causes merge algorithm select as opposed to temp table select * from v1; ---enable_ps2_protocol drop table t1, t2; drop view v1; @@ -2391,10 +2382,7 @@ create view v10 as select *, 'U' as u from t10 left join (select 'Y' as y, t20.b create table t30 (c int); insert into t30 values (1),(3); create view v20 as select * from t30 left join (select 'X' as x, v10.u, v10.y, v10.b from v10) dt2 on t30.c=dt2.b limit 6; -#check after fix MDEV-31277 ---disable_ps2_protocol select * from v20 limit 9; ---enable_ps2_protocol drop view v10, v20; drop table t10, t20, t30; @@ -2408,8 +2396,6 @@ insert into t3 values (3),(1); create table t1 (a int); insert into t1 values (1),(2),(7),(1); -#check after fix MDEV-31277 ---disable_ps2_protocol select * from ( select * from @@ -2422,7 +2408,6 @@ select * from on dt1.a=dt2.b limit 9 ) dt; ---enable_ps2_protocol ## Same as dt3 above create view v3(x,c) as select * from (select 'X' as x, t3.c from t3) dt3; @@ -2436,10 +2421,7 @@ create view v0(y,b,x,c) as select * from v2 left join v3 on v2.b=v3.c; # Same as above select statement create view v1 as select 'Z' as z, t1.a, v0.* from t1 left join v0 on t1.a=v0.b limit 9; -#check after fix MDEV-31277 ---disable_ps2_protocol select * from v1; ---enable_ps2_protocol set statement join_cache_level=0 for select * from v1; diff --git a/mysql-test/main/kill_processlist-6619.test b/mysql-test/main/kill_processlist-6619.test index c272e68a877..0f53034eaa8 100644 --- a/mysql-test/main/kill_processlist-6619.test +++ b/mysql-test/main/kill_processlist-6619.test @@ -4,8 +4,18 @@ --source include/not_embedded.inc --source include/have_debug_sync.inc +--disable_ps_protocol +# Ensure no lingering connections from an earlier test run, which can very +# rarely still be visible in SHOW PROCESSLIST here. +--let $wait_condition= SELECT COUNT(*) = 1 from information_schema.processlist +--source include/wait_condition.inc + --connect (con1,localhost,root,,) --let $con_id = `SELECT CONNECTION_ID()` + +let $wait_condition=select command = 'sleep' from information_schema.processlist where id != $con_id; +source include/wait_condition.inc; + --replace_result Execute Query --replace_column 1 # 3 # 6 # 7 # SHOW PROCESSLIST; @@ -25,9 +35,7 @@ reap; SET DEBUG_SYNC='reset'; # Wait until default connection has reset query string -let $wait_condition= - SELECT COUNT(*) = 1 from information_schema.processlist - WHERE info is NULL; +let $wait_condition=select command = 'sleep' from information_schema.processlist where id != $con_id; --source include/wait_condition.inc --replace_result Execute Query diff --git a/mysql-test/main/load_timezones_with_alter_algorithm_inplace.result b/mysql-test/main/load_timezones_with_alter_algorithm_inplace.result new file mode 100644 index 00000000000..4992e7ed93b --- /dev/null +++ b/mysql-test/main/load_timezones_with_alter_algorithm_inplace.result @@ -0,0 +1,18 @@ +set global alter_algorithm=INPLACE; +RENAME TABLE mysql.time_zone TO mysql.time_zone_BACKUP; +RENAME TABLE mysql.time_zone_name TO mysql.time_zone_name_BACKUP; +RENAME TABLE mysql.time_zone_transition TO mysql.time_zone_transition_BACKUP; +RENAME TABLE mysql.time_zone_transition_type TO mysql.time_zone_transition_type_BACKUP; +CREATE TABLE mysql.time_zone LIKE mysql.time_zone_BACKUP; +CREATE TABLE mysql.time_zone_name LIKE mysql.time_zone_name_BACKUP; +CREATE TABLE mysql.time_zone_transition LIKE mysql.time_zone_transition_BACKUP; +CREATE TABLE mysql.time_zone_transition_type LIKE mysql.time_zone_transition_type_BACKUP; +DROP TABLE mysql.time_zone; +DROP TABLE mysql.time_zone_name; +DROP TABLE mysql.time_zone_transition; +DROP TABLE mysql.time_zone_transition_type; +RENAME TABLE mysql.time_zone_BACKUP TO mysql.time_zone; +RENAME TABLE mysql.time_zone_name_BACKUP TO mysql.time_zone_name; +RENAME TABLE mysql.time_zone_transition_BACKUP TO mysql.time_zone_transition; +RENAME TABLE mysql.time_zone_transition_type_BACKUP TO mysql.time_zone_transition_type; +set global alter_algorithm=DEFAULT; diff --git a/mysql-test/main/load_timezones_with_alter_algorithm_inplace.test b/mysql-test/main/load_timezones_with_alter_algorithm_inplace.test new file mode 100644 index 00000000000..809f147fe04 --- /dev/null +++ b/mysql-test/main/load_timezones_with_alter_algorithm_inplace.test @@ -0,0 +1,40 @@ +--source include/not_embedded.inc + +# MDEV-33044 Loading time zones does not work with alter_algorithm INPLACE + +set global alter_algorithm=INPLACE; + +# Because loading timezones alters the mysql tables, +# this test will leave mysql in a different state than when it started. +# Furthermore, checksums on the various mysql.timezone_x tables will fail. + +# Therefore we: +# 1. Make "backups" of the existing tables by renaming them +# 2. Make dummy clones of the tables we just backed up +# 3. Load timezones with alterations made to the dummy clone tables +# 4. Drop the newly made tables with changes made to them +# 5. Restore the backed up tables so the checksums will pass + +RENAME TABLE mysql.time_zone TO mysql.time_zone_BACKUP; +RENAME TABLE mysql.time_zone_name TO mysql.time_zone_name_BACKUP; +RENAME TABLE mysql.time_zone_transition TO mysql.time_zone_transition_BACKUP; +RENAME TABLE mysql.time_zone_transition_type TO mysql.time_zone_transition_type_BACKUP; + +CREATE TABLE mysql.time_zone LIKE mysql.time_zone_BACKUP; +CREATE TABLE mysql.time_zone_name LIKE mysql.time_zone_name_BACKUP; +CREATE TABLE mysql.time_zone_transition LIKE mysql.time_zone_transition_BACKUP; +CREATE TABLE mysql.time_zone_transition_type LIKE mysql.time_zone_transition_type_BACKUP; + +--exec $MYSQL_TZINFO_TO_SQL std_data/zoneinfo | $MYSQL mysql + +DROP TABLE mysql.time_zone; +DROP TABLE mysql.time_zone_name; +DROP TABLE mysql.time_zone_transition; +DROP TABLE mysql.time_zone_transition_type; + +RENAME TABLE mysql.time_zone_BACKUP TO mysql.time_zone; +RENAME TABLE mysql.time_zone_name_BACKUP TO mysql.time_zone_name; +RENAME TABLE mysql.time_zone_transition_BACKUP TO mysql.time_zone_transition; +RENAME TABLE mysql.time_zone_transition_type_BACKUP TO mysql.time_zone_transition_type; + +set global alter_algorithm=DEFAULT; diff --git a/mysql-test/main/lock_sync.result b/mysql-test/main/lock_sync.result index af3fbe8a784..69958811d68 100644 --- a/mysql-test/main/lock_sync.result +++ b/mysql-test/main/lock_sync.result @@ -26,28 +26,6 @@ ALWAYS connect con1, localhost, root,,; connect con2, localhost, root,,; connection default; -drop table if exists t0, t1, t2, t3, t4, t5; -drop view if exists v1, v2; -drop procedure if exists p1; -drop procedure if exists p2; -drop procedure if exists p3; -drop function if exists f1; -drop function if exists f2; -drop function if exists f3; -drop function if exists f4; -drop function if exists f5; -drop function if exists f6; -drop function if exists f7; -drop function if exists f8; -drop function if exists f9; -drop function if exists f10; -drop function if exists f11; -drop function if exists f12; -drop function if exists f13; -drop function if exists f14; -drop function if exists f15; -drop function if exists f16; -drop function if exists f17; create table t1 (i int primary key); insert into t1 values (1), (2), (3), (4), (5); create table t2 (j int primary key); @@ -884,6 +862,6 @@ set debug_sync= 'now wait_for s1'; SELECT * FROM ( SELECT * FROM v1 ) sq; COMMIT; DROP VIEW v1; -DROP FUNCTION f; +DROP FUNCTION IF EXISTS f; DROP TABLE t1, t2; set debug_sync= 'reset'; diff --git a/mysql-test/main/lock_sync.test b/mysql-test/main/lock_sync.test index 5543420d824..844d00d3a33 100644 --- a/mysql-test/main/lock_sync.test +++ b/mysql-test/main/lock_sync.test @@ -44,30 +44,6 @@ select @@global.concurrent_insert; connect (con1, localhost, root,,); connect (con2, localhost, root,,); connection default; ---disable_warnings -drop table if exists t0, t1, t2, t3, t4, t5; -drop view if exists v1, v2; -drop procedure if exists p1; -drop procedure if exists p2; -drop procedure if exists p3; -drop function if exists f1; -drop function if exists f2; -drop function if exists f3; -drop function if exists f4; -drop function if exists f5; -drop function if exists f6; -drop function if exists f7; -drop function if exists f8; -drop function if exists f9; -drop function if exists f10; -drop function if exists f11; -drop function if exists f12; -drop function if exists f13; -drop function if exists f14; -drop function if exists f15; -drop function if exists f16; -drop function if exists f17; ---enable_warnings create table t1 (i int primary key); insert into t1 values (1), (2), (3), (4), (5); create table t2 (j int primary key); @@ -1218,7 +1194,8 @@ COMMIT; --disconnect con1 --disconnect con2 --connection default +--source include/wait_until_count_sessions.inc DROP VIEW v1; -DROP FUNCTION f; +DROP FUNCTION IF EXISTS f; DROP TABLE t1, t2; set debug_sync= 'reset'; diff --git a/mysql-test/main/lock_view.result b/mysql-test/main/lock_view.result index 8137300f3e3..e4c666bff52 100644 --- a/mysql-test/main/lock_view.result +++ b/mysql-test/main/lock_view.result @@ -16,6 +16,7 @@ create definer=definer@localhost view mysqltest3.v3is as select schema_name from create definer=definer@localhost view mysqltest3.v3ps as select user from performance_schema.users where current_connections>0 order by user; create definer=definer@localhost view mysqltest3.v3nt as select 1; create definer=definer@localhost sql security invoker view mysqltest3.v3i as select * from mysqltest1.t1; +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; @@ -234,6 +235,7 @@ create view v1 as select * from (select * from t1) dt; lock table v1 read; disconnect con1; connection default; +/*!999999\- enable the sandbox mode */ SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE VIEW `v1` AS SELECT diff --git a/mysql-test/main/log_errchk.test b/mysql-test/main/log_errchk.test index 1afc0e29f3a..c64f6e3c106 100644 --- a/mysql-test/main/log_errchk.test +++ b/mysql-test/main/log_errchk.test @@ -30,12 +30,12 @@ --echo # Case 2: Starting server with fifo file as general log file --echo # and slow query log file. # Restart server with fifo file as general log file. ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc --enable_reconnect # Write file to make mysql-test-run.pl start up the server again ---exec echo "restart: --general-log-file=$gen_log_file --slow-query-log-file=$slow_query_log_file" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart: --general-log-file=$gen_log_file --slow-query-log-file=$slow_query_log_file" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --source include/wait_until_connected_again.inc # Error 6 is reported, because the other end is closed diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index b8fbd40baed..03d40be897f 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -676,6 +676,59 @@ SELECT * FROM t1; a b c 3 2 2 DROP TABLE t1; +# MDEV-30046 wrong row targeted with "insert ... on duplicate" and +# "replace", leading to data corruption +create table t (s blob, n int, unique (s)) engine=innodb; +insert into t values ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); +replace into t values ('Hrecvx_0004mm-00',2); +select * from t; +s n +Hrecvx_0004ln-00 1 +Hrecvx_0004mm-00 2 +drop table t; +create table t (s blob, n int, unique (s)) engine=innodb; +insert into t values ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); +insert into t values ('Hrecvx_0004mm-00',2) +on duplicate key update n = values (n); +select * from t; +s n +Hrecvx_0004ln-00 1 +Hrecvx_0004mm-00 2 +drop table t; # +# MDEV-29345 update case insensitive (large) unique key with insensitive change of value - duplicate key +# +create table t1 (a int, b text, unique (b)); +insert ignore t1 values (1, 'a'), (2, 'A'); +Warnings: +Warning 1062 Duplicate entry 'A' for key 'b' +select * from t1; +a b +1 a +update t1 set b='A' where a=1; +select * from t1; +a b +1 A +drop table t1; +create table t1 (a int, b blob, unique (b)); +insert t1 values (1, 'a'), (2, 'A'); +select * from t1; +a b +1 a +2 A +update t1 set b='A' where a=1; +ERROR 23000: Duplicate entry 'A' for key 'b' +drop table t1; +# +# MDEV-25102 UNIQUE USING HASH error after ALTER ... DISABLE KEYS +# +create table t1 (i int, unique key (i) using hash); +alter table t1 disable keys; +insert into t1 values (1),(2); +insert into t1 values (1); +ERROR 23000: Duplicate entry '1' for key 'i' +alter table t1 enable keys; +insert into t1 values (2); +ERROR 23000: Duplicate entry '2' for key 'i' +drop table t1; # End of 10.5 tests -# diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index 01c3f736df8..8acb5e9e080 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -503,7 +503,6 @@ start transaction; alter table tmp alter column a set default 8; unlock tables; drop table t2; ---source include/have_innodb.inc --echo # --echo # MDEV-22218 InnoDB: Failing assertion: node->pcur->rel_pos == BTR_PCUR_ON upon LOAD DATA with NO_BACKSLASH_ESCAPES in SQL_MODE and unique blob in table @@ -642,7 +641,6 @@ insert into t1 values (0); check table t1 extended; drop table t1; - --echo # --echo # MDEV-32837 long unique does not work like unique key when using replace --echo # @@ -655,6 +653,49 @@ REPLACE INTO t1 VALUES (3,2,2); SELECT * FROM t1; DROP TABLE t1; +--echo # MDEV-30046 wrong row targeted with "insert ... on duplicate" and +--echo # "replace", leading to data corruption +--source include/have_innodb.inc +create table t (s blob, n int, unique (s)) engine=innodb; +insert into t values ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); +replace into t values ('Hrecvx_0004mm-00',2); +select * from t; +drop table t; + +create table t (s blob, n int, unique (s)) engine=innodb; +insert into t values ('Hrecvx_0004ln-00',1), ('Hrecvx_0004mm-00',1); +insert into t values ('Hrecvx_0004mm-00',2) + on duplicate key update n = values (n); +select * from t; +drop table t; --echo # +--echo # MDEV-29345 update case insensitive (large) unique key with insensitive change of value - duplicate key +--echo # +create table t1 (a int, b text, unique (b)); +insert ignore t1 values (1, 'a'), (2, 'A'); +select * from t1; +update t1 set b='A' where a=1; +select * from t1; +drop table t1; + +create table t1 (a int, b blob, unique (b)); +insert t1 values (1, 'a'), (2, 'A'); +select * from t1; +--error ER_DUP_ENTRY +update t1 set b='A' where a=1; +drop table t1; + +--echo # +--echo # MDEV-25102 UNIQUE USING HASH error after ALTER ... DISABLE KEYS +--echo # +create table t1 (i int, unique key (i) using hash); +alter table t1 disable keys; +insert into t1 values (1),(2); +--error ER_DUP_ENTRY +insert into t1 values (1); +alter table t1 enable keys; +--error ER_DUP_ENTRY +insert into t1 values (2); +drop table t1; + --echo # End of 10.5 tests ---echo # diff --git a/mysql-test/main/lowercase_fs_off.result b/mysql-test/main/lowercase_fs_off.result index 560458be410..40e608fa620 100644 --- a/mysql-test/main/lowercase_fs_off.result +++ b/mysql-test/main/lowercase_fs_off.result @@ -272,3 +272,26 @@ CREATE TABLE t1 (a Mariadb_schema.date); ERROR HY000: Unknown data type: 'Mariadb_schema.date' CREATE TABLE t1 (a mariadb_schema.date); DROP TABLE t1; +# End of 10.3 tests +# +# MDEV-32973 SHOW TABLES LIKE shows temporary tables with non-matching names +# +create temporary table t1 (a int); +create temporary table t2 (a int); +create temporary table T1 (a int); +show tables like 't1'; +Tables_in_test (t1) +t1 +select table_name from information_schema.tables where table_schema='test' + and table_name='t1'; +table_name +t1 +show tables like '_1'; +Tables_in_test (_1) +T1 +t1 +show tables like 't%'; +Tables_in_test (t%) +t2 +t1 +# End of 11.2 tests diff --git a/mysql-test/main/lowercase_fs_off.test b/mysql-test/main/lowercase_fs_off.test index 172566a1365..4bff916db83 100644 --- a/mysql-test/main/lowercase_fs_off.test +++ b/mysql-test/main/lowercase_fs_off.test @@ -146,3 +146,19 @@ CREATE TABLE t1 (a Mariadb_schema.date); CREATE TABLE t1 (a mariadb_schema.date); DROP TABLE t1; + +--echo # End of 10.3 tests + +--echo # +--echo # MDEV-32973 SHOW TABLES LIKE shows temporary tables with non-matching names +--echo # +create temporary table t1 (a int); +create temporary table t2 (a int); +create temporary table T1 (a int); +show tables like 't1'; +select table_name from information_schema.tables where table_schema='test' + and table_name='t1'; +show tables like '_1'; +show tables like 't%'; + +--echo # End of 11.2 tests diff --git a/mysql-test/main/lowercase_fs_on.test b/mysql-test/main/lowercase_fs_on.test index 1d306826e27..9a7fc369207 100644 --- a/mysql-test/main/lowercase_fs_on.test +++ b/mysql-test/main/lowercase_fs_on.test @@ -16,7 +16,7 @@ let SEARCH_FILE= $MYSQLTEST_VARDIR/log/my_restart.err; --remove_file $SEARCH_FILE #Shutdown the server ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc @@ -30,7 +30,7 @@ let SEARCH_PATTERN= \[ERROR\] The server option \'lower_case_table_names\' is co --source include/search_pattern_in_file.inc #Restart the server ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --source include/wait_until_connected_again.inc #Cleanup diff --git a/mysql-test/main/lowercase_table2.result b/mysql-test/main/lowercase_table2.result old mode 100755 new mode 100644 index 4180635e6af..e062edd0a69 --- a/mysql-test/main/lowercase_table2.result +++ b/mysql-test/main/lowercase_table2.result @@ -377,6 +377,39 @@ SHOW CREATE DATABASE db1; Database Create Database db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci */ DROP DATABASE Db1; +USE test; +# End of 10.4 tests +# +# MDEV-32973 SHOW TABLES LIKE shows temporary tables with non-matching names +# +create temporary table t2 (a int); +create temporary table T1 (a int); +show tables; +Tables_in_test +t1 +t2 +show tables like 't1'; +Tables_in_test (t1) +t1 +show tables like 'T1'; +Tables_in_test (T1) +t1 +select table_name from information_schema.tables where table_schema='test' + and table_name='t1'; +table_name +t1 +select table_name from information_schema.tables where table_schema='test' + and table_name='T1'; +table_name +t1 +show tables like '_1'; +Tables_in_test (_1) +t1 +show tables like 't%'; +Tables_in_test (t%) +t1 +t2 +# End of 11.2 tests # # MDEV-32026 lowercase_table2.test failures in 11.3 # diff --git a/mysql-test/main/lowercase_table2.test b/mysql-test/main/lowercase_table2.test index 3addb13e2f9..99ba73fed5b 100644 --- a/mysql-test/main/lowercase_table2.test +++ b/mysql-test/main/lowercase_table2.test @@ -328,6 +328,27 @@ ALTER DATABASE Db1 DEFAULT CHARACTER SET utf8; SHOW CREATE DATABASE Db1; SHOW CREATE DATABASE db1; DROP DATABASE Db1; +USE test; + +--echo # End of 10.4 tests + +--echo # +--echo # MDEV-32973 SHOW TABLES LIKE shows temporary tables with non-matching names +--echo # +# temp tables don't preserve the letter case despite lower-case-table-names=2 +create temporary table t2 (a int); +create temporary table T1 (a int); +show tables; +show tables like 't1'; +show tables like 'T1'; +select table_name from information_schema.tables where table_schema='test' + and table_name='t1'; +select table_name from information_schema.tables where table_schema='test' + and table_name='T1'; +show tables like '_1'; +show tables like 't%'; + +--echo # End of 11.2 tests --echo # --echo # MDEV-32026 lowercase_table2.test failures in 11.3 diff --git a/mysql-test/main/mdl_sync.result b/mysql-test/main/mdl_sync.result index 032b686bae5..bece98a675e 100644 --- a/mysql-test/main/mdl_sync.result +++ b/mysql-test/main/mdl_sync.result @@ -2431,6 +2431,9 @@ create table t1 (a int) engine=myisam; create table t2 (a int) stats_persistent=0, engine=innodb; insert into t1 values (1); insert into t2 values (1); +connect con1, localhost, root; +start transaction with consistent snapshot; +connection default; SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL table_opened WAIT_FOR grlwait execute 2'; update t1,t2 set t1.a=2,t2.a=3; connection con2; @@ -2462,6 +2465,7 @@ connection default; SET DEBUG_SYNC= 'RESET'; drop table t1,t2; disconnect con2; +disconnect con1; # # Bug#50786 Assertion `thd->mdl_context.trans_sentinel() == __null' # failed in open_ltable() diff --git a/mysql-test/main/mdl_sync.test b/mysql-test/main/mdl_sync.test index 27e2ff4393c..aa3bd60e64e 100644 --- a/mysql-test/main/mdl_sync.test +++ b/mysql-test/main/mdl_sync.test @@ -3115,6 +3115,12 @@ create table t2 (a int) stats_persistent=0, engine=innodb; insert into t1 values (1); insert into t2 values (1); +connect (con1, localhost, root); +# disable innodb purge thread, otherwise it might start purging t2, +# and will take an mdl, affecting metadata_lock_info output. +start transaction with consistent snapshot; +connection default; + SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL table_opened WAIT_FOR grlwait execute 2'; --send update t1,t2 set t1.a=2,t2.a=3 @@ -3160,6 +3166,7 @@ connection default; SET DEBUG_SYNC= 'RESET'; drop table t1,t2; disconnect con2; +disconnect con1; --echo # --echo # Bug#50786 Assertion `thd->mdl_context.trans_sentinel() == __null' diff --git a/mysql-test/main/myisam.result b/mysql-test/main/myisam.result index 76114ae7c41..dbe9a32ab11 100644 --- a/mysql-test/main/myisam.result +++ b/mysql-test/main/myisam.result @@ -1,6 +1,5 @@ call mtr.add_suppression("Can't find record in '.*'"); call mtr.add_suppression("Table 't1' is marked as crashed and should be repaired"); -SET SQL_WARNINGS=1; CREATE TABLE t1 ( STRING_DATA char(255) default NULL, KEY string_data (STRING_DATA) diff --git a/mysql-test/main/myisam.test b/mysql-test/main/myisam.test index 1a20f97a54f..dbb54e710d5 100644 --- a/mysql-test/main/myisam.test +++ b/mysql-test/main/myisam.test @@ -7,9 +7,6 @@ call mtr.add_suppression("Can't find record in '.*'"); call mtr.add_suppression("Table 't1' is marked as crashed and should be repaired"); -# Initialise -SET SQL_WARNINGS=1; - # # Test problem with CHECK TABLE; # diff --git a/mysql-test/main/myisam_crash_before_flush_keys.test b/mysql-test/main/myisam_crash_before_flush_keys.test index 791e43b0c9b..c48f2b42044 100644 --- a/mysql-test/main/myisam_crash_before_flush_keys.test +++ b/mysql-test/main/myisam_crash_before_flush_keys.test @@ -26,14 +26,14 @@ INSERT INTO t1 VALUES (1,2),(2,3),(3,4),(4,5),(5,6); SET SESSION debug_dbug="d,crash_before_flush_keys"; --echo # Write file to make mysql-test-run.pl expect crash ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --echo # Run the crashing query --error 2013 FLUSH TABLE t1; --echo # Write file to make mysql-test-run.pl start the server ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --echo # Turn on reconnect --enable_reconnect diff --git a/mysql-test/main/mysql-interactive.test b/mysql-test/main/mysql-interactive.test index 2015e9d667d..0051d8e58c6 100644 --- a/mysql-test/main/mysql-interactive.test +++ b/mysql-test/main/mysql-interactive.test @@ -3,6 +3,8 @@ --echo # source include/not_embedded.inc; source include/not_windows.inc; +# this would need an instrumented ncurses library +source include/not_msan.inc; error 0,1; exec $MYSQL -V|grep -q readline; diff --git a/mysql-test/main/mysql.result b/mysql-test/main/mysql.result index 8813d05a74a..f25d649d9bf 100644 --- a/mysql-test/main/mysql.result +++ b/mysql-test/main/mysql.result @@ -552,6 +552,7 @@ Table Create Table a1\`b1 CREATE TABLE `a1\``b1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `a1\``b1` ( @@ -583,6 +584,7 @@ Table Create Table a1\"b1 CREATE TABLE "a1\""b1" ( "a" int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE "a1\""b1" ( @@ -607,11 +609,11 @@ set sql_mode=default; create table t1 (a text); select count(*) from t1; count(*) -43 +44 truncate table t1; select count(*) from t1; count(*) -43 +44 truncate table t1; select count(*) from t1; count(*) @@ -623,7 +625,7 @@ count(*) truncate table t1; select count(*) from t1; count(*) -43 +44 truncate table t1; select count(*) from t1; count(*) @@ -637,9 +639,34 @@ drop table t1; WARNING: option --enable-cleartext-plugin is obsolete. 1 1 +# End of 10.3 tests +# +# MDEV-21778 Disable system commands in mysql/mariadb client +# +ERROR at line 1: Not allowed in the sandbox mode +1 +ERROR at line 1: Not allowed in the sandbox mode +2 +ERROR at line 1: Not allowed in the sandbox mode +3 +1 +entering sandbox +system +tee +source +^^^ +2 +entering sandbox +system +tee +source +^^^ +3 +# End of 10.5 tests # # MDEV-30327 Client crashes in print_last_query_cost # +# End of 11.0 tests # # show whether server cert was verified # diff --git a/mysql-test/main/mysql.test b/mysql-test/main/mysql.test index 3f881807a05..1bd5b8c0dd1 100644 --- a/mysql-test/main/mysql.test +++ b/mysql-test/main/mysql.test @@ -610,6 +610,7 @@ EOF create database `aa``bb````cc`; --exec $MYSQL < $MYSQLTEST_VARDIR/tmp/backticks.sql drop database `aa``bb````cc`; +--remove_file $MYSQLTEST_VARDIR/tmp/backticks.sql # # MySQL Bug#13639125 DELIMITER STRIPS THE NEXT NEW LINE IN A SQL STATEMENT @@ -620,6 +621,7 @@ delimiter <<" as a; EOF --exec $MYSQL < $MYSQLTEST_VARDIR/tmp/13639125.sql +--remove_file $MYSQLTEST_VARDIR/tmp/13639125.sql # # --skip-column-names and alignment @@ -702,7 +704,7 @@ select count(*) from t1; truncate table t1; --exec $MYSQL --disable-local-infile -e "/*q*/$ldli" select count(*) from t1; truncate table t1; drop table t1; - +--remove_file $MYSQLTEST_VARDIR/tmp/bug.sql --echo # --echo # MDEV-15538 '-N' Produce html output wrong @@ -716,6 +718,46 @@ drop table t1; --echo --exec $MYSQL test --enable-cleartext-plugin -e "select 1" +--echo # End of 10.3 tests + +--echo # +--echo # MDEV-21778 Disable system commands in mysql/mariadb client +--echo # + +--error 1 +--exec $MYSQL --sandbox -Ne "select 1; \! echo foo; select 0" 2>&1 +--error 1 +--exec $MYSQL --sandbox -Ne "select 2; \T echo foo; select 0" 2>&1 +--error 1 +--exec $MYSQL --sandbox -Ne "select 3; \. echo.foo; select 0" 2>&1 + +--write_file $MYSQL_TMP_DIR/mysql_in +select 'entering sandbox'; +\- +select 'system'; +\! echo foo +select 'tee'; +\T echo foo +select 'source'; +\. echo.foo +select '^^^'; +EOF + +write_line "select 1; +source $MYSQL_TMP_DIR/mysql_in; +select 2; +source $MYSQL_TMP_DIR/mysql_in; +sandbox; +select 3; +source $MYSQL_TMP_DIR/mysql_in;" $MYSQL_TMP_DIR/mysql_in2; + +--exec $MYSQL -fN <$MYSQL_TMP_DIR/mysql_in2 + +--remove_file $MYSQL_TMP_DIR/mysql_in +--remove_file $MYSQL_TMP_DIR/mysql_in2 + +--echo # End of 10.5 tests + --echo # --echo # MDEV-30327 Client crashes in print_last_query_cost --echo # @@ -726,6 +768,8 @@ drop table t1; --enable_result_log --enable_query_log +--echo # End of 11.0 tests + --echo # --echo # show whether server cert was verified --echo # diff --git a/mysql-test/main/mysql_client_test.result b/mysql-test/main/mysql_client_test.result index e32053e50f3..59e82d7afc3 100644 --- a/mysql-test/main/mysql_client_test.result +++ b/mysql-test/main/mysql_client_test.result @@ -261,3 +261,4 @@ SET @@global.character_set_server= @save_character_set_server; SET @@global.collation_server= @save_collation_server; SET @@global.character_set_client= @save_character_set_client; SET @@global.collation_connection= @save_collation_connection; +FOUND 1 /Aborted connection.*'u' host: '192.0.2.1' real ip: '(localhost|::1)'/ in mysqld.1.err diff --git a/mysql-test/main/mysql_client_test.test b/mysql-test/main/mysql_client_test.test index bcb246a8a06..d620f4c7078 100644 --- a/mysql-test/main/mysql_client_test.test +++ b/mysql-test/main/mysql_client_test.test @@ -23,7 +23,7 @@ call mtr.add_suppression(" IP address .* could not be resolved"); # server or run mysql-test-run --debug mysql_client_test and check # var/log/mysql_client_test.trace ---exec echo "$MYSQL_CLIENT_TEST" > $MYSQLTEST_VARDIR/log/mysql_client_test.out.log 2>&1 +--write_line "$MYSQL_CLIENT_TEST" $MYSQLTEST_VARDIR/log/mysql_client_test.out.log --exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test.out.log 2>&1 # End of 4.1 tests @@ -57,3 +57,9 @@ SET @@global.character_set_server= @save_character_set_server; SET @@global.collation_server= @save_collation_server; SET @@global.character_set_client= @save_character_set_client; SET @@global.collation_connection= @save_collation_connection; + +# Search for "real ip" in Aborted message +# This is indicator for abort of the proxied connections. +let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err; +let SEARCH_PATTERN= Aborted connection.*'u' host: '192.0.2.1' real ip: '(localhost|::1)'; +source include/search_pattern_in_file.inc; diff --git a/mysql-test/main/mysql_client_test_comp.test b/mysql-test/main/mysql_client_test_comp.test index 36a12b6691e..f37d82a20e5 100644 --- a/mysql-test/main/mysql_client_test_comp.test +++ b/mysql-test/main/mysql_client_test_comp.test @@ -12,7 +12,7 @@ SET @old_slow_query_log= @@global.slow_query_log; call mtr.add_suppression(" Error reading file './client_test_db/test_frm_bug.frm'"); call mtr.add_suppression(" IP address .* could not be resolved"); ---exec echo "$MYSQL_CLIENT_TEST" > $MYSQLTEST_VARDIR/log/mysql_client_test_comp.out.log 2>&1 +--write_line "$MYSQL_CLIENT_TEST" $MYSQLTEST_VARDIR/log/mysql_client_test_comp.out.log --exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test_comp.out.log 2>&1 # End of test diff --git a/mysql-test/main/mysql_client_test_nonblock.test b/mysql-test/main/mysql_client_test_nonblock.test index 73e7a6d378d..c4bc4304307 100644 --- a/mysql-test/main/mysql_client_test_nonblock.test +++ b/mysql-test/main/mysql_client_test_nonblock.test @@ -19,7 +19,7 @@ call mtr.add_suppression(" IP address .* could not be resolved"); # server or run mysql-test-run --debug mysql_client_test and check # var/log/mysql_client_test.trace ---exec echo "$MYSQL_CLIENT_TEST --non-blocking-api" > $MYSQLTEST_VARDIR/log/mysql_client_test.out.log 2>&1 +--write_line "$MYSQL_CLIENT_TEST --non-blocking-api" $MYSQLTEST_VARDIR/log/mysql_client_test.out.log --exec $MYSQL_CLIENT_TEST --non-blocking-api --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test.out.log 2>&1 # End of 4.1 tests diff --git a/mysql-test/main/mysql_connector_net.test b/mysql-test/main/mysql_connector_net.test index c1dce65adc8..ad048c20b3d 100644 --- a/mysql-test/main/mysql_connector_net.test +++ b/mysql-test/main/mysql_connector_net.test @@ -4,7 +4,7 @@ let $sys_errno=0; # Error 100 is returned by the powershell script # if MySql.Data is not installed --error 0,100 ---exec powershell -NoLogo -NoProfile -File main\mysql_connector_net.ps1 +--exec powershell -ExecutionPolicy Bypass -NoLogo -NoProfile -File main\mysql_connector_net.ps1 if ($sys_errno != 0) { --skip Connector/NET is not installed diff --git a/mysql-test/main/mysql_install_db_win_admin.result b/mysql-test/main/mysql_install_db_win_admin.result index 06d3d677977..dd0e4e3b260 100644 --- a/mysql-test/main/mysql_install_db_win_admin.result +++ b/mysql-test/main/mysql_install_db_win_admin.result @@ -1,10 +1,4 @@ use mysql; -Running bootstrap -Creating my.ini file -Removing default user -Allowing remote access for user root -Setting root password -Creation of the database was successful # Kill the server # restart: --datadir=MYSQLTEST_VARDIR/tmp/ddir connect root,localhost,root,wrongpass,mysql; diff --git a/mysql-test/main/mysql_install_db_win_admin.test b/mysql-test/main/mysql_install_db_win_admin.test index a6b98f97058..28a2356c465 100644 --- a/mysql-test/main/mysql_install_db_win_admin.test +++ b/mysql-test/main/mysql_install_db_win_admin.test @@ -6,12 +6,15 @@ # and start server from this directory. let $ddir= $MYSQLTEST_VARDIR/tmp/ddir; use mysql; -exec $MYSQL_INSTALL_DB_EXE --datadir=$ddir --password=foo -R; +--disable_result_log +exec $MYSQL_INSTALL_DB_EXE --datadir=$ddir --password=foo --verbose-bootstrap -R; +--enable_result_log --source include/kill_mysqld.inc let $restart_parameters=--datadir=$ddir; --source include/start_mysqld.inc # Check that connect with wrong password succeeds +# (because it can alternatively connect with GSSAPI as admin) connect (root,localhost,root,wrongpass,mysql); --source include/kill_mysqld.inc diff --git a/mysql-test/main/mysql_tzinfo_to_sql_symlink.result b/mysql-test/main/mysql_tzinfo_to_sql_symlink.result index 97548768a2d..86ff8179b44 100644 --- a/mysql-test/main/mysql_tzinfo_to_sql_symlink.result +++ b/mysql-test/main/mysql_tzinfo_to_sql_symlink.result @@ -18,6 +18,8 @@ execute immediate if(@wsrep_cannot_replicate_tz, 'select ENGINE into @time_zone_ execute immediate if(@wsrep_cannot_replicate_tz, 'ALTER TABLE time_zone_transition ENGINE=InnoDB', 'do 0'); execute immediate if(@wsrep_cannot_replicate_tz, 'select ENGINE into @time_zone_transition_type_engine from information_schema.TABLES where TABLE_SCHEMA=DATABASE() and TABLE_NAME=''time_zone_transition_type''', 'do 0'); execute immediate if(@wsrep_cannot_replicate_tz, 'ALTER TABLE time_zone_transition_type ENGINE=InnoDB', 'do 0'); +SET @old_alter_alg=@@SESSION.alter_algorithm; +SET session alter_algorithm='COPY'; TRUNCATE TABLE time_zone; TRUNCATE TABLE time_zone_name; TRUNCATE TABLE time_zone_transition; @@ -52,6 +54,7 @@ execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone E execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone_name ENGINE=', @time_zone_name_engine), 'do 0'); execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone_transition ENGINE=', @time_zone_transition_engine, ', ORDER BY Time_zone_id, Transition_time'), 'do 0'); execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone_transition_type ENGINE=', @time_zone_transition_type_engine, ', ORDER BY Time_zone_id, Transition_type_id'), 'do 0'); +SET session alter_algorithm=@old_alter_alg; # # MDEV-28263: mariadb-tzinfo-to-sql improve wsrep and binlog cases # @@ -67,6 +70,8 @@ execute immediate if(@wsrep_cannot_replicate_tz, 'select ENGINE into @time_zone_ execute immediate if(@wsrep_cannot_replicate_tz, 'ALTER TABLE time_zone_transition ENGINE=InnoDB', 'do 0'); execute immediate if(@wsrep_cannot_replicate_tz, 'select ENGINE into @time_zone_transition_type_engine from information_schema.TABLES where TABLE_SCHEMA=DATABASE() and TABLE_NAME=''time_zone_transition_type''', 'do 0'); execute immediate if(@wsrep_cannot_replicate_tz, 'ALTER TABLE time_zone_transition_type ENGINE=InnoDB', 'do 0'); +SET @old_alter_alg=@@SESSION.alter_algorithm; +SET session alter_algorithm='COPY'; TRUNCATE TABLE time_zone; TRUNCATE TABLE time_zone_name; TRUNCATE TABLE time_zone_transition; @@ -98,6 +103,7 @@ execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone E execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone_name ENGINE=', @time_zone_name_engine), 'do 0'); execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone_transition ENGINE=', @time_zone_transition_engine, ', ORDER BY Time_zone_id, Transition_time'), 'do 0'); execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone_transition_type ENGINE=', @time_zone_transition_type_engine, ', ORDER BY Time_zone_id, Transition_type_id'), 'do 0'); +SET session alter_algorithm=@old_alter_alg; SELECT COUNT(*) FROM time_zone; COUNT(*) 2 @@ -123,6 +129,8 @@ execute immediate if(@wsrep_is_on, 'SET @save_wsrep_on=@@WSREP_ON, WSREP_ON=OFF' SET @save_sql_log_bin=@@SQL_LOG_BIN; SET SESSION SQL_LOG_BIN=0; SET @wsrep_cannot_replicate_tz=0; +SET @old_alter_alg=@@SESSION.alter_algorithm; +SET session alter_algorithm='COPY'; TRUNCATE TABLE time_zone; TRUNCATE TABLE time_zone_name; TRUNCATE TABLE time_zone_transition; @@ -152,6 +160,7 @@ execute immediate if(@wsrep_cannot_replicate_tz, 'do 0','ALTER TABLE time_zone_t execute immediate if(@wsrep_cannot_replicate_tz, 'do 0','ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id'); SET SESSION SQL_LOG_BIN=@save_sql_log_bin; execute immediate if(@wsrep_is_on, 'SET SESSION WSREP_ON=@save_wsrep_on', 'do 0'); +SET session alter_algorithm=@old_alter_alg; SELECT COUNT(*) FROM time_zone; COUNT(*) 2 @@ -505,6 +514,8 @@ execute immediate if(@wsrep_cannot_replicate_tz, 'select ENGINE into @time_zone_ execute immediate if(@wsrep_cannot_replicate_tz, 'ALTER TABLE time_zone_transition ENGINE=InnoDB', 'do 0'); execute immediate if(@wsrep_cannot_replicate_tz, 'select ENGINE into @time_zone_transition_type_engine from information_schema.TABLES where TABLE_SCHEMA=DATABASE() and TABLE_NAME=''time_zone_transition_type''', 'do 0'); execute immediate if(@wsrep_cannot_replicate_tz, 'ALTER TABLE time_zone_transition_type ENGINE=InnoDB', 'do 0'); +SET @old_alter_alg=@@SESSION.alter_algorithm; +SET session alter_algorithm='COPY'; TRUNCATE TABLE time_zone; TRUNCATE TABLE time_zone_name; TRUNCATE TABLE time_zone_transition; @@ -522,6 +533,7 @@ execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone E execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone_name ENGINE=', @time_zone_name_engine), 'do 0'); execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone_transition ENGINE=', @time_zone_transition_engine, ', ORDER BY Time_zone_id, Transition_time'), 'do 0'); execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone_transition_type ENGINE=', @time_zone_transition_type_engine, ', ORDER BY Time_zone_id, Transition_type_id'), 'do 0'); +SET session alter_algorithm=@old_alter_alg; DROP TABLE baseline; DROP TABLE time_zone; DROP TABLE time_zone_name; diff --git a/mysql-test/main/mysqlbinlog_row_compressed.result b/mysql-test/main/mysqlbinlog_row_compressed.result index 96a0ed61a71..410af54441c 100644 --- a/mysql-test/main/mysqlbinlog_row_compressed.result +++ b/mysql-test/main/mysqlbinlog_row_compressed.result @@ -1,3 +1,5 @@ +set pseudo_thread_id=5; +reset master; SET GLOBAL log_bin_compress=on; SET GLOBAL log_bin_compress_min_len=10; CREATE TABLE t1 (pk INT PRIMARY KEY, f1 INT, f2 INT, f3 TINYINT, f4 MEDIUMINT, f5 BIGINT, f6 INT, f7 INT, f8 char(1)); @@ -15,21 +17,21 @@ FLUSH BINARY LOGS; /*!40019 SET @@session.max_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; -# at 4 -# server id 1 end_log_pos 256 CRC32 XXX Start: xxx +# at +# server id 1 end_log_pos CRC32 XXX Start: xxx ROLLBACK/*!*/; -# at 256 -# server id 1 end_log_pos 285 CRC32 XXX Gtid list [] -# at 285 -# server id 1 end_log_pos 329 CRC32 XXX Binlog checkpoint master-bin.000001 -# at 329 -# server id 1 end_log_pos 371 CRC32 XXX GTID 0-1-1 ddl +# at +# server id 1 end_log_pos CRC32 XXX Gtid list [] +# at +# server id 1 end_log_pos CRC32 XXX Binlog checkpoint master-bin.000001 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-1 ddl /*!100101 SET @@session.skip_parallel_replication=0*//*!*/; /*!100001 SET @@session.gtid_domain_id=0*//*!*/; /*!100001 SET @@session.server_id=1*//*!*/; /*!100001 SET @@session.gtid_seq_no=1*//*!*/; -# at 371 -# server id 1 end_log_pos 542 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= use `test`/*!*/; SET TIMESTAMP=X/*!*/; SET @@session.pseudo_thread_id=5/*!*/; @@ -42,26 +44,26 @@ SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; CREATE TABLE t1 (pk INT PRIMARY KEY, f1 INT, f2 INT, f3 TINYINT, f4 MEDIUMINT, f5 BIGINT, f6 INT, f7 INT, f8 char(1)) /*!*/; -# at 542 -# server id 1 end_log_pos 584 CRC32 XXX GTID 0-1-2 ddl +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-2 ddl /*!100001 SET @@session.gtid_seq_no=2*//*!*/; -# at 584 -# server id 1 end_log_pos 745 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; CREATE TABLE t2 (pk INT PRIMARY KEY, f1 INT, f2 INT, f3 INT, f4 INT, f5 MEDIUMINT, f6 INT, f7 INT, f8 char(1)) /*!*/; -# at 745 -# server id 1 end_log_pos 787 CRC32 XXX GTID 0-1-3 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-3 /*!100001 SET @@session.gtid_seq_no=3*//*!*/; START TRANSACTION /*!*/; -# at 787 -# at 861 -# server id 1 end_log_pos 0 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> INSERT INTO t1 VALUES (10, 1, 2, 3, 4, 5, 6, 7, "") -# server id 1 end_log_pos 0 CRC32 XXX Table_map: `test`.`t1` mapped to number num -# at 917 -# server id 1 end_log_pos 0 CRC32 XXX Write_compressed_rows: table id 32 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t1` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Write_compressed_rows: table id flags: STMT_END_F ### INSERT INTO `test`.`t1` ### SET ### @1=10 /* INT meta=0 nullable=0 is_null=0 */ @@ -74,23 +76,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 1 -# at 985 -# server id 1 end_log_pos 1058 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1058 -# server id 1 end_log_pos 1100 CRC32 XXX GTID 0-1-4 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-4 /*!100001 SET @@session.gtid_seq_no=4*//*!*/; START TRANSACTION /*!*/; -# at 1100 -# at 1176 -# server id 1 end_log_pos 0 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> INSERT INTO t1 VALUES (11, 1, 2, 3, 4, 5, 6, 7, NULL) -# server id 1 end_log_pos 0 CRC32 XXX Table_map: `test`.`t1` mapped to number num -# at 1232 -# server id 1 end_log_pos 0 CRC32 XXX Write_compressed_rows: table id 32 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t1` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Write_compressed_rows: table id flags: STMT_END_F ### INSERT INTO `test`.`t1` ### SET ### @1=11 /* INT meta=0 nullable=0 is_null=0 */ @@ -103,23 +105,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9=NULL /* STRING(1) meta=65025 nullable=1 is_null=1 */ # Number of rows: 1 -# at 1299 -# server id 1 end_log_pos 1372 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1372 -# server id 1 end_log_pos 1414 CRC32 XXX GTID 0-1-5 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-5 /*!100001 SET @@session.gtid_seq_no=5*//*!*/; START TRANSACTION /*!*/; -# at 1414 -# at 1492 -# server id 1 end_log_pos 0 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> INSERT INTO t1 VALUES (12, 1, 2, 3, NULL, 5, 6, 7, "A") -# server id 1 end_log_pos 0 CRC32 XXX Table_map: `test`.`t1` mapped to number num -# at 1548 -# server id 1 end_log_pos 0 CRC32 XXX Write_compressed_rows: table id 32 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t1` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Write_compressed_rows: table id flags: STMT_END_F ### INSERT INTO `test`.`t1` ### SET ### @1=12 /* INT meta=0 nullable=0 is_null=0 */ @@ -132,23 +134,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 1 -# at 1614 -# server id 1 end_log_pos 1687 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1687 -# server id 1 end_log_pos 1729 CRC32 XXX GTID 0-1-6 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-6 /*!100001 SET @@session.gtid_seq_no=6*//*!*/; START TRANSACTION /*!*/; -# at 1729 -# at 1804 -# server id 1 end_log_pos 0 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> INSERT INTO t1 VALUES (13, 1, 2, 3, 0, 5, 6, 7, "A") -# server id 1 end_log_pos 0 CRC32 XXX Table_map: `test`.`t1` mapped to number num -# at 1860 -# server id 1 end_log_pos 0 CRC32 XXX Write_compressed_rows: table id 32 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t1` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Write_compressed_rows: table id flags: STMT_END_F ### INSERT INTO `test`.`t1` ### SET ### @1=13 /* INT meta=0 nullable=0 is_null=0 */ @@ -161,23 +163,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 1 -# at 1927 -# server id 1 end_log_pos 2000 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2000 -# server id 1 end_log_pos 2042 CRC32 XXX GTID 0-1-7 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-7 /*!100001 SET @@session.gtid_seq_no=7*//*!*/; START TRANSACTION /*!*/; -# at 2042 -# at 2096 -# server id 1 end_log_pos 0 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> INSERT INTO t2 SELECT * FROM t1 -# server id 1 end_log_pos 0 CRC32 XXX Table_map: `test`.`t2` mapped to number num -# at 2152 -# server id 1 end_log_pos 0 CRC32 XXX Write_compressed_rows: table id 33 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t2` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Write_compressed_rows: table id flags: STMT_END_F ### INSERT INTO `test`.`t2` ### SET ### @1=10 /* INT meta=0 nullable=0 is_null=0 */ @@ -223,23 +225,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 4 -# at 2243 -# server id 1 end_log_pos 2316 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2316 -# server id 1 end_log_pos 2358 CRC32 XXX GTID 0-1-8 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-8 /*!100001 SET @@session.gtid_seq_no=8*//*!*/; START TRANSACTION /*!*/; -# at 2358 -# at 2424 -# server id 1 end_log_pos 0 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> UPDATE t2 SET f4=5 WHERE f4>0 or f4 is NULL -# server id 1 end_log_pos 0 CRC32 XXX Table_map: `test`.`t2` mapped to number num -# at 2480 -# server id 1 end_log_pos 0 CRC32 XXX Update_compressed_rows: table id 33 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t2` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Update_compressed_rows: table id flags: STMT_END_F ### UPDATE `test`.`t2` ### WHERE ### @1=10 /* INT meta=0 nullable=0 is_null=0 */ @@ -304,23 +306,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 3 -# at 2579 -# server id 1 end_log_pos 2652 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2652 -# server id 1 end_log_pos 2694 CRC32 XXX GTID 0-1-9 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-9 /*!100001 SET @@session.gtid_seq_no=9*//*!*/; START TRANSACTION /*!*/; -# at 2694 -# at 2731 -# server id 1 end_log_pos 0 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> DELETE FROM t1 -# server id 1 end_log_pos 0 CRC32 XXX Table_map: `test`.`t1` mapped to number num -# at 2787 -# server id 1 end_log_pos 0 CRC32 XXX Delete_compressed_rows: table id 32 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t1` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Delete_compressed_rows: table id flags: STMT_END_F ### DELETE FROM `test`.`t1` ### WHERE ### @1=10 /* INT meta=0 nullable=0 is_null=0 */ @@ -366,23 +368,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 4 -# at 2879 -# server id 1 end_log_pos 2952 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2952 -# server id 1 end_log_pos 2994 CRC32 XXX GTID 0-1-10 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-10 /*!100001 SET @@session.gtid_seq_no=10*//*!*/; START TRANSACTION /*!*/; -# at 2994 -# at 3031 -# server id 1 end_log_pos 0 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> DELETE FROM t2 -# server id 1 end_log_pos 0 CRC32 XXX Table_map: `test`.`t2` mapped to number num -# at 3087 -# server id 1 end_log_pos 0 CRC32 XXX Delete_compressed_rows: table id 33 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t2` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Delete_compressed_rows: table id flags: STMT_END_F ### DELETE FROM `test`.`t2` ### WHERE ### @1=10 /* INT meta=0 nullable=0 is_null=0 */ @@ -428,13 +430,13 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 4 -# at 3172 -# server id 1 end_log_pos 3245 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 3245 -# server id 1 end_log_pos 3293 CRC32 XXX Rotate to master-bin.000002 pos: 4 +# at +# server id 1 end_log_pos CRC32 XXX Rotate to master-bin.000002 pos: 4 DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; diff --git a/mysql-test/main/mysqlbinlog_row_compressed.test b/mysql-test/main/mysqlbinlog_row_compressed.test index 03868d3e6b3..b3a6add4efc 100644 --- a/mysql-test/main/mysqlbinlog_row_compressed.test +++ b/mysql-test/main/mysqlbinlog_row_compressed.test @@ -4,13 +4,14 @@ --source include/have_log_bin.inc --source include/have_binlog_format_row.inc ---source include/have_normal_zlib.inc # # # mysqlbinlog: compressed row event # # +set pseudo_thread_id=5; +reset master; SET GLOBAL log_bin_compress=on; SET GLOBAL log_bin_compress_min_len=10; @@ -30,7 +31,7 @@ DELETE FROM t2; FLUSH BINARY LOGS; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---replace_regex /\d{6} *\d*:\d\d:\d\d// /Start:.*at startup/Start: xxx/ /SET TIMESTAMP=\d*/SET TIMESTAMP=X/ /exec_time=\d*/exec_time=x/ /mapped to number \d*/mapped to number num/ /CRC32 0x[0-9a-f]+/CRC32 XXX/ /@@session.sql_mode=\d+/@@session.sql_mode=#/ /collation_server=\d+/collation_server=#/ /xid=\d*/xid=/ +--replace_regex /\d{6} *\d*:\d\d:\d\d// /Start:.*at startup/Start: xxx/ /SET TIMESTAMP=\d*/SET TIMESTAMP=X/ /exec_time=\d*/exec_time=x/ /mapped to number \d*/mapped to number num/ /CRC32 0x[0-9a-f]+/CRC32 XXX/ /@@session.sql_mode=\d+/@@session.sql_mode=#/ /collation_server=\d+/collation_server=#/ /xid=\d*/xid=/ /table id \d+/table id / /end_log_pos \d+/end_log_pos / /# at \d+/# at / --exec $MYSQL_BINLOG --verbose --verbose --base64-output=DECODE-ROWS $datadir/$binlog --echo diff --git a/mysql-test/main/mysqlbinlog_row_minimal.result b/mysql-test/main/mysqlbinlog_row_minimal.result index 6871d75a985..88bfe9029ed 100644 --- a/mysql-test/main/mysqlbinlog_row_minimal.result +++ b/mysql-test/main/mysqlbinlog_row_minimal.result @@ -382,7 +382,7 @@ START TRANSACTION # server id 1 end_log_pos END_LOG_POS CRC32 XXX Annotate_rows: #Q> UPDATE t1 t1 INNER JOIN t2 t2 ON t1.ref_id = t2.id #Q> SET t1.is_deleted = TRUE -#Q> WHERE t1.id = +#Q> WHERE t1.id = 1 # server id 1 end_log_pos END_LOG_POS CRC32 XXX Table_map: `test`.`t1` mapped to number TID # at POS # server id 1 end_log_pos END_LOG_POS CRC32 XXX Update_rows: table id TID flags: STMT_END_F diff --git a/mysql-test/main/mysqlbinlog_stmt_compressed.result b/mysql-test/main/mysqlbinlog_stmt_compressed.result index 6321e74127f..471cb4b72c6 100644 --- a/mysql-test/main/mysqlbinlog_stmt_compressed.result +++ b/mysql-test/main/mysqlbinlog_stmt_compressed.result @@ -15,21 +15,21 @@ FLUSH BINARY LOGS; /*!40019 SET @@session.max_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; -# at 4 -# server id 1 end_log_pos 256 CRC32 XXX Start: xxx +# at +# server id 1 end_log_pos CRC32 XXX Start: xxx ROLLBACK/*!*/; -# at 256 -# server id 1 end_log_pos 285 CRC32 XXX Gtid list [] -# at 285 -# server id 1 end_log_pos 329 CRC32 XXX Binlog checkpoint master-bin.000001 -# at 329 -# server id 1 end_log_pos 371 CRC32 XXX GTID 0-1-1 ddl +# at +# server id 1 end_log_pos CRC32 XXX Gtid list [] +# at +# server id 1 end_log_pos CRC32 XXX Binlog checkpoint master-bin.000001 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-1 ddl /*!100101 SET @@session.skip_parallel_replication=0*//*!*/; /*!100001 SET @@session.gtid_domain_id=0*//*!*/; /*!100001 SET @@session.server_id=1*//*!*/; /*!100001 SET @@session.gtid_seq_no=1*//*!*/; -# at 371 -# server id 1 end_log_pos 542 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= use `test`/*!*/; SET TIMESTAMP=X/*!*/; SET @@session.pseudo_thread_id=5/*!*/; @@ -42,136 +42,136 @@ SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; CREATE TABLE t1 (pk INT PRIMARY KEY, f1 INT, f2 INT, f3 TINYINT, f4 MEDIUMINT, f5 BIGINT, f6 INT, f7 INT, f8 char(1)) /*!*/; -# at 542 -# server id 1 end_log_pos 584 CRC32 XXX GTID 0-1-2 ddl +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-2 ddl /*!100001 SET @@session.gtid_seq_no=2*//*!*/; -# at 584 -# server id 1 end_log_pos 745 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; CREATE TABLE t2 (pk INT PRIMARY KEY, f1 INT, f2 INT, f3 INT, f4 INT, f5 MEDIUMINT, f6 INT, f7 INT, f8 char(1)) /*!*/; -# at 745 -# server id 1 end_log_pos 787 CRC32 XXX GTID 0-1-3 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-3 /*!100001 SET @@session.gtid_seq_no=3*//*!*/; START TRANSACTION /*!*/; -# at 787 -# server id 1 end_log_pos 0 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; INSERT INTO t1 VALUES (10, 1, 2, 3, 4, 5, 6, 7, "") /*!*/; -# at 915 -# server id 1 end_log_pos 988 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 988 -# server id 1 end_log_pos 1030 CRC32 XXX GTID 0-1-4 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-4 /*!100001 SET @@session.gtid_seq_no=4*//*!*/; START TRANSACTION /*!*/; -# at 1030 -# server id 1 end_log_pos 0 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; INSERT INTO t1 VALUES (11, 1, 2, 3, 4, 5, 6, 7, NULL) /*!*/; -# at 1158 -# server id 1 end_log_pos 1231 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1231 -# server id 1 end_log_pos 1273 CRC32 XXX GTID 0-1-5 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-5 /*!100001 SET @@session.gtid_seq_no=5*//*!*/; START TRANSACTION /*!*/; -# at 1273 -# server id 1 end_log_pos 0 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; INSERT INTO t1 VALUES (12, 1, 2, 3, NULL, 5, 6, 7, "A") /*!*/; -# at 1403 -# server id 1 end_log_pos 1476 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1476 -# server id 1 end_log_pos 1518 CRC32 XXX GTID 0-1-6 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-6 /*!100001 SET @@session.gtid_seq_no=6*//*!*/; START TRANSACTION /*!*/; -# at 1518 -# server id 1 end_log_pos 0 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; INSERT INTO t1 VALUES (13, 1, 2, 3, 0, 5, 6, 7, "A") /*!*/; -# at 1645 -# server id 1 end_log_pos 1718 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1718 -# server id 1 end_log_pos 1760 CRC32 XXX GTID 0-1-7 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-7 /*!100001 SET @@session.gtid_seq_no=7*//*!*/; START TRANSACTION /*!*/; -# at 1760 -# server id 1 end_log_pos 0 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; INSERT INTO t2 SELECT * FROM t1 /*!*/; -# at 1868 -# server id 1 end_log_pos 1941 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1941 -# server id 1 end_log_pos 1983 CRC32 XXX GTID 0-1-8 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-8 /*!100001 SET @@session.gtid_seq_no=8*//*!*/; START TRANSACTION /*!*/; -# at 1983 -# server id 1 end_log_pos 0 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; UPDATE t2 SET f4=5 WHERE f4>0 or f4 is NULL /*!*/; -# at 2100 -# server id 1 end_log_pos 2173 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2173 -# server id 1 end_log_pos 2215 CRC32 XXX GTID 0-1-9 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-9 /*!100001 SET @@session.gtid_seq_no=9*//*!*/; START TRANSACTION /*!*/; -# at 2215 -# server id 1 end_log_pos 0 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; DELETE FROM t1 /*!*/; -# at 2306 -# server id 1 end_log_pos 2379 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2379 -# server id 1 end_log_pos 2421 CRC32 XXX GTID 0-1-10 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-10 /*!100001 SET @@session.gtid_seq_no=10*//*!*/; START TRANSACTION /*!*/; -# at 2421 -# server id 1 end_log_pos 0 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; DELETE FROM t2 /*!*/; -# at 2512 -# server id 1 end_log_pos 2585 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 xid= SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2585 -# server id 1 end_log_pos 2633 CRC32 XXX Rotate to master-bin.000002 pos: 4 +# at +# server id 1 end_log_pos CRC32 XXX Rotate to master-bin.000002 pos: 4 DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; diff --git a/mysql-test/main/mysqlbinlog_stmt_compressed.test b/mysql-test/main/mysqlbinlog_stmt_compressed.test index 4a65124339d..5c3fb58c50c 100644 --- a/mysql-test/main/mysqlbinlog_stmt_compressed.test +++ b/mysql-test/main/mysqlbinlog_stmt_compressed.test @@ -4,7 +4,6 @@ --source include/have_log_bin.inc --source include/have_binlog_format_statement.inc ---source include/have_normal_zlib.inc # # # mysqlbinlog: compressed query event @@ -29,7 +28,7 @@ DELETE FROM t2; FLUSH BINARY LOGS; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---replace_regex /\d{6} *\d*:\d\d:\d\d// /Start:.*at startup/Start: xxx/ /SET TIMESTAMP=\d*/SET TIMESTAMP=X/ /exec_time=\d*/exec_time=x/ /mapped to number \d*/mapped to number num/ /CRC32 0x[0-9a-f]+/CRC32 XXX/ /@@session.sql_mode=\d+/@@session.sql_mode=#/ /collation_server=\d+/collation_server=#/ /xid=\d*/xid=/ +--replace_regex /\d{6} *\d*:\d\d:\d\d// /Start:.*at startup/Start: xxx/ /SET TIMESTAMP=\d*/SET TIMESTAMP=X/ /exec_time=\d*/exec_time=x/ /mapped to number \d*/mapped to number num/ /CRC32 0x[0-9a-f]+/CRC32 XXX/ /@@session.sql_mode=\d+/@@session.sql_mode=#/ /collation_server=\d+/collation_server=#/ /xid=\d*/xid=/ /table id \d+/table id / /end_log_pos \d+/end_log_pos / /# at \d+/# at / --exec $MYSQL_BINLOG --verbose --verbose --base64-output=DECODE-ROWS $datadir/$binlog --echo diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 431c37c25ed..ee75f586970 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -1962,7 +1962,7 @@ slave-run-triggers-for-rbr NO slave-skip-errors OFF slave-sql-verify-checksum TRUE slave-transaction-retries 10 -slave-transaction-retry-errors 1158,1159,1160,1161,1205,1213,1429,2013,12701 +slave-transaction-retry-errors 1158,1159,1160,1161,1205,1213,1020,1429,2013,12701 slave-transaction-retry-interval 0 slave-type-conversions slow-launch-time 2 diff --git a/mysql-test/main/mysqld_option_err.result b/mysql-test/main/mysqld_option_err.result index 4afcc5e0cb1..157edb58532 100644 --- a/mysql-test/main/mysqld_option_err.result +++ b/mysql-test/main/mysqld_option_err.result @@ -3,6 +3,17 @@ Test bad binlog format. Test bad default storage engine. Test non-numeric value passed to number option. Test that bad value for plugin enum option is rejected correctly. +Test to see if multiple unknown options will be displayed in the error output +FOUND 1 /unknown option '--nonexistentoption2'/ in mysqltest.log +FOUND 1 /unknown option '--alsononexistent'/ in mysqltest.log +FOUND 1 /unknown variable 'nonexistentvariable=1'/ in mysqltest.log +Test to see if multiple ambiguous options and invalid arguments will be displayed in the error output +FOUND 1 /Error while setting value 'invalid_value' to 'sql_mode'/ in mysqltest.log +FOUND 1 /ambiguous option '--character'/ in mysqltest.log +FOUND 1 /option '--bootstrap' cannot take an argument/ in mysqltest.log +FOUND 1 /Integer value out of range for uint64: '18446744073709551616' for binlog_cache_size/ in mysqltest.log +FOUND 1 /Unknown suffix 'y' used for variable 'bulk_insert_buffer_size' \(value '123y'\). Legal suffix characters are: K, M, G, T, P, E/ in mysqltest.log +FOUND 1 /Error while setting value '123y' to 'bulk_insert_buffer_size'/ in mysqltest.log Test that --help --verbose works Test that --not-known-option --help --verbose gives error Done. diff --git a/mysql-test/main/mysqld_option_err.test b/mysql-test/main/mysqld_option_err.test index e9655fd4bfe..c2b943bafa1 100644 --- a/mysql-test/main/mysqld_option_err.test +++ b/mysql-test/main/mysqld_option_err.test @@ -25,7 +25,7 @@ mkdir $MYSQLTEST_VARDIR/tmp/mysqld_option_err; --echo Test bad binlog format. ---error 1 +--error 13 --exec $MYSQLD_BOOTSTRAP_CMD --skip-networking --datadir=$MYSQLTEST_VARDIR/tmp/mysqld_option_err --skip-grant-tables --log-bin --binlog-format=badformat >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 @@ -35,7 +35,7 @@ mkdir $MYSQLTEST_VARDIR/tmp/mysqld_option_err; --echo Test non-numeric value passed to number option. ---error 1 +--error 9 --exec $MYSQLD_BOOTSTRAP_CMD --skip-networking --datadir=$MYSQLTEST_VARDIR/tmp/mysqld_option_err --skip-grant-tables --min-examined-row-limit=notanumber >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 @@ -46,6 +46,36 @@ mkdir $MYSQLTEST_VARDIR/tmp/mysqld_option_err; --error 7 --exec $MYSQLD_BOOTSTRAP_CMD --skip-networking --datadir=$MYSQLTEST_VARDIR/tmp/mysqld_option_err --skip-grant-tables --plugin-dir=$MYSQLTEST_VARDIR/plugins --plugin-load=example=ha_example.so --plugin-example-enum-var=noexist >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 +--let SEARCH_FILE = $MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log + +--echo Test to see if multiple unknown options will be displayed in the error output +--error 7 +--exec $MYSQLD_BOOTSTRAP_CMD --skip-networking --datadir=$MYSQLTEST_VARDIR/tmp/mysqld_option_err --skip-grant-tables --nonexistentoption2 --alsononexistent --nonexistentvariable=1 >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 + +--let SEARCH_PATTERN=unknown option '--nonexistentoption2' +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=unknown option '--alsononexistent' +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=unknown variable 'nonexistentvariable=1' +--source include/search_pattern_in_file.inc + +--echo Test to see if multiple ambiguous options and invalid arguments will be displayed in the error output +--error 9 +--exec $MYSQLD_BOOTSTRAP_CMD --skip-networking --datadir=$MYSQLTEST_VARDIR/tmp/mysqld_option_err --skip-grant-tables --getopt-prefix-matching --sql-mode=invalid_value --character --bootstrap=partstoob --binlog_cache_size=18446744073709551616 --bulk_insert_buffer_size=123y >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 + +--let SEARCH_PATTERN=Error while setting value 'invalid_value' to 'sql_mode' +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=ambiguous option '--character' +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=option '--bootstrap' cannot take an argument +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=Integer value out of range for uint64: '18446744073709551616' for binlog_cache_size +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=Unknown suffix 'y' used for variable 'bulk_insert_buffer_size' \(value '123y'\). Legal suffix characters are: K, M, G, T, P, E +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=Error while setting value '123y' to 'bulk_insert_buffer_size' +--source include/search_pattern_in_file.inc + # # Test that an wrong option with --help --verbose gives an error # diff --git a/mysql-test/main/mysqldump-compat-102.result b/mysql-test/main/mysqldump-compat-102.result index 773db25d0a8..cf8e9a6b65e 100644 --- a/mysql-test/main/mysqldump-compat-102.result +++ b/mysql-test/main/mysqldump-compat-102.result @@ -58,6 +58,7 @@ BEGIN log(0, 'Session ' || connection_id() || ' ' || current_user || ' started'); END; $$ +/*!999999\- enable the sandbox mode */ -- MariaDB dump DUMPVERSION Distrib DISTVERSION, for OS -- -- Host: localhost Database: db1_mdev17429 diff --git a/mysql-test/main/mysqldump-max.result b/mysql-test/main/mysqldump-max.result index bf724188440..8c67b6918ba 100644 --- a/mysql-test/main/mysqldump-max.result +++ b/mysql-test/main/mysqldump-max.result @@ -77,6 +77,7 @@ id name 3 first value 4 first value 5 first value +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -102,7 +103,7 @@ CREATE TABLE `t1` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -INSERT DELAYED IGNORE INTO `t1` VALUES +INSERT DELAYED IGNORE INTO `t1` VALUES (1,'first value'), (2,'first value'), (3,'first value'), @@ -119,7 +120,7 @@ CREATE TABLE `t2` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; -INSERT DELAYED IGNORE INTO `t2` VALUES +INSERT DELAYED IGNORE INTO `t2` VALUES (1,'first value'), (2,'first value'), (3,'first value'), @@ -136,7 +137,7 @@ CREATE TABLE `t3` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t3` DISABLE KEYS */; -INSERT DELAYED IGNORE INTO `t3` VALUES +INSERT DELAYED IGNORE INTO `t3` VALUES (1,'first value'), (2,'first value'), (3,'first value'), @@ -153,7 +154,7 @@ CREATE TABLE `t4` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t4` DISABLE KEYS */; -INSERT DELAYED IGNORE INTO `t4` VALUES +INSERT DELAYED IGNORE INTO `t4` VALUES (1,'first value'), (2,'first value'), (3,'first value'), @@ -170,7 +171,7 @@ CREATE TABLE `t5` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t5` DISABLE KEYS */; -INSERT DELAYED IGNORE INTO `t5` VALUES +INSERT DELAYED IGNORE INTO `t5` VALUES (1,'first value'), (2,'first value'), (3,'first value'), @@ -187,7 +188,7 @@ CREATE TABLE `t6` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t6` DISABLE KEYS */; -INSERT IGNORE INTO `t6` VALUES +INSERT IGNORE INTO `t6` VALUES (1,'first value'), (2,'first value'), (3,'first value'), @@ -204,6 +205,7 @@ INSERT IGNORE INTO `t6` VALUES /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -229,7 +231,7 @@ CREATE TABLE `t1` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -INSERT DELAYED INTO `t1` VALUES +INSERT DELAYED INTO `t1` VALUES (1,'first value'), (2,'first value'), (3,'first value'), @@ -246,7 +248,7 @@ CREATE TABLE `t2` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; -INSERT DELAYED INTO `t2` VALUES +INSERT DELAYED INTO `t2` VALUES (1,'first value'), (2,'first value'), (3,'first value'), @@ -263,7 +265,7 @@ CREATE TABLE `t3` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t3` DISABLE KEYS */; -INSERT DELAYED INTO `t3` VALUES +INSERT DELAYED INTO `t3` VALUES (1,'first value'), (2,'first value'), (3,'first value'), @@ -280,7 +282,7 @@ CREATE TABLE `t4` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t4` DISABLE KEYS */; -INSERT DELAYED INTO `t4` VALUES +INSERT DELAYED INTO `t4` VALUES (1,'first value'), (2,'first value'), (3,'first value'), @@ -297,7 +299,7 @@ CREATE TABLE `t5` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t5` DISABLE KEYS */; -INSERT DELAYED INTO `t5` VALUES +INSERT DELAYED INTO `t5` VALUES (1,'first value'), (2,'first value'), (3,'first value'), diff --git a/mysql-test/main/mysqldump-nl.result b/mysql-test/main/mysqldump-nl.result index 66902492934..1e9928308fc 100644 --- a/mysql-test/main/mysqldump-nl.result +++ b/mysql-test/main/mysqldump-nl.result @@ -12,6 +12,7 @@ create procedure sp() select * from `v1 1v`; flush tables; use test; +/*!999999\- enable the sandbox mode */ -- -- Current Database: `mysqltest1 @@ -134,6 +135,7 @@ test\` \! ls # test` +/*!999999\- enable the sandbox mode */ -- -- Current Database: `test``` diff --git a/mysql-test/main/mysqldump-no-binlog.result b/mysql-test/main/mysqldump-no-binlog.result index 223034d8401..669675ff21b 100644 --- a/mysql-test/main/mysqldump-no-binlog.result +++ b/mysql-test/main/mysqldump-no-binlog.result @@ -1 +1,2 @@ mariadb-dump: Error: Binlogging on server not active +/*!999999\- enable the sandbox mode */ diff --git a/mysql-test/main/mysqldump-order-by-size.result b/mysql-test/main/mysqldump-order-by-size.result index 361852905c0..3bd953b828d 100644 --- a/mysql-test/main/mysqldump-order-by-size.result +++ b/mysql-test/main/mysqldump-order-by-size.result @@ -21,6 +21,7 @@ test.t3 analyze status OK test.t4 analyze status Engine-independent statistics collected test.t4 analyze Warning Engine-independent statistics are not collected for column 'a' test.t4 analyze status OK +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t4` ( diff --git a/mysql-test/main/mysqldump-system.result b/mysql-test/main/mysqldump-system.result index e99d4d4d683..59c0a09e08c 100644 --- a/mysql-test/main/mysqldump-system.result +++ b/mysql-test/main/mysqldump-system.result @@ -41,6 +41,7 @@ CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB"; # # mysqldump of system tables with --system=all # +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -637,6 +638,7 @@ UNLOCK TABLES; # # mysqldump of system tables with --system=all --replace # +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -1256,6 +1258,7 @@ UNLOCK TABLES; # # mysqldump of system tables with --system=all --insert-ignore # +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -1310,28 +1313,28 @@ USE mysql; LOCK TABLES `column_stats` WRITE; /*!40000 ALTER TABLE `column_stats` DISABLE KEYS */; -INSERT IGNORE INTO `column_stats` VALUES +INSERT IGNORE INTO `column_stats` VALUES ('mysql','tz','Time_zone_id','1','6',0.0000,4.0000,78.8000,4,'JSON_HB','{\"target_histogram_size\": 254, \"collected_at\": \"2022-01-07 07:07:00\", \"collected_by\": \"version\", \"histogram_hb\": [{\"start\": \"1\", \"size\": 0.340101523, \"ndv\": 1}, {\"start\": \"3\", \"size\": 0.327411168, \"ndv\": 1}, {\"start\": \"4\", \"size\": 0.327411168, \"ndv\": 1}, {\"start\": \"5\", \"end\": \"6\", \"size\": 0.005076142, \"ndv\": 2}]}'); /*!40000 ALTER TABLE `column_stats` ENABLE KEYS */; UNLOCK TABLES; LOCK TABLES `index_stats` WRITE; /*!40000 ALTER TABLE `index_stats` DISABLE KEYS */; -INSERT IGNORE INTO `index_stats` VALUES +INSERT IGNORE INTO `index_stats` VALUES ('mysql','tz','PRIMARY',1,78.8000); /*!40000 ALTER TABLE `index_stats` ENABLE KEYS */; UNLOCK TABLES; LOCK TABLES `table_stats` WRITE; /*!40000 ALTER TABLE `table_stats` DISABLE KEYS */; -INSERT IGNORE INTO `table_stats` VALUES +INSERT IGNORE INTO `table_stats` VALUES ('mysql','tz',394); /*!40000 ALTER TABLE `table_stats` ENABLE KEYS */; UNLOCK TABLES; LOCK TABLES `innodb_index_stats` WRITE; /*!40000 ALTER TABLE `innodb_index_stats` DISABLE KEYS */; -INSERT IGNORE INTO `innodb_index_stats` VALUES +INSERT IGNORE INTO `innodb_index_stats` VALUES ('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx01',5,1,'Time_zone_id'), ('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx02',394,1,'Time_zone_id,Transition_time'), ('mysql','tz','PRIMARY','2019-12-31 21:00:00','n_leaf_pages',1,NULL,'Number of leaf pages in the index'), @@ -1341,7 +1344,7 @@ UNLOCK TABLES; LOCK TABLES `innodb_table_stats` WRITE; /*!40000 ALTER TABLE `innodb_table_stats` DISABLE KEYS */; -INSERT IGNORE INTO `innodb_table_stats` VALUES +INSERT IGNORE INTO `innodb_table_stats` VALUES ('mysql','tz','2019-12-31 21:00:00',394,1,0); /*!40000 ALTER TABLE `innodb_table_stats` ENABLE KEYS */; UNLOCK TABLES; @@ -1350,7 +1353,7 @@ USE mysql; LOCK TABLES `time_zone` WRITE; /*!40000 ALTER TABLE `time_zone` DISABLE KEYS */; -INSERT IGNORE INTO `time_zone` VALUES +INSERT IGNORE INTO `time_zone` VALUES (1,'N'), (2,'N'), (3,'N'), @@ -1362,7 +1365,7 @@ UNLOCK TABLES; LOCK TABLES `time_zone_name` WRITE; /*!40000 ALTER TABLE `time_zone_name` DISABLE KEYS */; -INSERT IGNORE INTO `time_zone_name` VALUES +INSERT IGNORE INTO `time_zone_name` VALUES ('Europe/Moscow',3), ('India/Kolkata',6), ('Japan',5), @@ -1375,7 +1378,7 @@ UNLOCK TABLES; LOCK TABLES `time_zone_leap_second` WRITE; /*!40000 ALTER TABLE `time_zone_leap_second` DISABLE KEYS */; -INSERT IGNORE INTO `time_zone_leap_second` VALUES +INSERT IGNORE INTO `time_zone_leap_second` VALUES (174834660,1), (78796800,1), (94694401,2), @@ -1404,7 +1407,7 @@ UNLOCK TABLES; LOCK TABLES `time_zone_transition` WRITE; /*!40000 ALTER TABLE `time_zone_transition` DISABLE KEYS */; -INSERT IGNORE INTO `time_zone_transition` VALUES +INSERT IGNORE INTO `time_zone_transition` VALUES (1,-1693706400,0), (1,-1680483600,1), (1,-1663455600,2), @@ -1804,7 +1807,7 @@ UNLOCK TABLES; LOCK TABLES `time_zone_transition_type` WRITE; /*!40000 ALTER TABLE `time_zone_transition_type` DISABLE KEYS */; -INSERT IGNORE INTO `time_zone_transition_type` VALUES +INSERT IGNORE INTO `time_zone_transition_type` VALUES (1,0,7200,1,'MEST'), (1,1,3600,0,'MET'), (1,2,7200,1,'MEST'), diff --git a/mysql-test/main/mysqldump-timing.result b/mysql-test/main/mysqldump-timing.result index e4f89f42348..439339d773e 100644 --- a/mysql-test/main/mysqldump-timing.result +++ b/mysql-test/main/mysqldump-timing.result @@ -7,6 +7,7 @@ CREATE TABLE t1 (i INT); INSERT INTO t1 VALUES (0); LOCK TABLE t1 WRITE; timeout without t1 contents expected +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -30,6 +31,7 @@ SET @save_max_statement_time=@@max_statement_time; SET GLOBAL max_statement_time=0.1; UNLOCK TABLES;; This would be a race condition otherwise, but default max_statement_time=0 makes it succeed +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; diff --git a/mysql-test/main/mysqldump-utf8mb4.result b/mysql-test/main/mysqldump-utf8mb4.result index 0383e95a83e..c75afc2dd91 100644 --- a/mysql-test/main/mysqldump-utf8mb4.result +++ b/mysql-test/main/mysqldump-utf8mb4.result @@ -32,6 +32,7 @@ Testing XML format output ---- Testing text format output ---- +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result index 293e880186c..f814e9c4860 100644 --- a/mysql-test/main/mysqldump.result +++ b/mysql-test/main/mysqldump.result @@ -31,6 +31,7 @@ DROP TABLE t1; CREATE TABLE t1 (a decimal(64, 20)); INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), ("0987654321098765432109876543210987654321"); +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -48,6 +49,7 @@ CREATE TABLE t1 (a double); INSERT IGNORE INTO t1 VALUES ('-9e999999'); Warnings: Warning 1264 Out of range value for column 'a' at row 1 +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -70,6 +72,7 @@ INSERT INTO t1 VALUES ('1.2345', 2.3456); INSERT INTO t1 VALUES ("1.2345", 2.3456); ERROR 42S22: Unknown column '1.2345' in 'field list' SET SQL_MODE=@OLD_SQL_MODE; +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -83,6 +86,7 @@ INSERT INTO `t1` VALUES (1.23450,2.3456), (1.23450,2.3456), (1.23450,2.3456); +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -96,6 +100,7 @@ INSERT INTO `t1` VALUES (1.23450,2.3456), (1.23450,2.3456), (1.23450,2.3456); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -136,6 +141,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -217,6 +223,7 @@ DROP TABLE t1; # CREATE TABLE t1 (a VARCHAR(255)) DEFAULT CHARSET koi8r; INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'), (NULL); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -258,6 +265,7 @@ DROP TABLE t1; # CREATE TABLE t1 (a int) ENGINE=MYISAM; INSERT INTO t1 VALUES (1), (2); +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -283,6 +291,7 @@ UNLOCK TABLES; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -313,6 +322,7 @@ DROP TABLE t1; # Bug#2592 mysqldump doesn't quote "tricky" names correctly # create table ```a` (i int); +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE ```a` ( @@ -324,6 +334,7 @@ drop table ```a`; # Bug#2591 mysqldump quotes names inconsistently # create table t1(a int); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -357,6 +368,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -383,6 +395,7 @@ UNLOCK TABLES; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; set global sql_mode='ANSI_QUOTES'; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -416,6 +429,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -448,6 +462,7 @@ drop table t1; # create table t1(a int); insert into t1 values (1),(2),(3); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -480,6 +495,7 @@ drop table t1; # # Bug#6101 create database problem # +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -506,6 +522,7 @@ USE `test`; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; create database mysqldump_test_db character set latin2 collate latin2_bin; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -540,6 +557,7 @@ drop database mysqldump_test_db; # if it is explicitly set. CREATE TABLE t1 (a CHAR(10)); INSERT INTO t1 VALUES (_latin1 ''); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -582,6 +600,7 @@ UNLOCK TABLES; # If the future we can move this command into a separate test with # checking that "mysqldump" is compiled with "latin1" # +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -606,6 +625,7 @@ UNLOCK TABLES; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -630,6 +650,7 @@ UNLOCK TABLES; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -662,6 +683,7 @@ CREATE TABLE t1 (a int); CREATE TABLE t2 (a int); INSERT INTO t1 VALUES (1),(2),(3); INSERT INTO t2 VALUES (4),(5),(6); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -706,6 +728,7 @@ DROP TABLE t2; # CREATE TABLE t1 (`b` blob); INSERT INTO `t1` VALUES (0x602010000280100005E71A); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -747,6 +770,7 @@ DROP TABLE t1; CREATE TABLE t1 (a INT) ENGINE=MyISAM; INSERT INTO t1 VALUES (1),(2),(3); INSERT INTO t1 VALUES (4),(5),(6); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -768,7 +792,7 @@ CREATE TABLE `t1` ( LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -INSERT IGNORE INTO `t1` VALUES +INSERT IGNORE INTO `t1` VALUES (1), (2), (3), @@ -787,6 +811,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -807,7 +832,7 @@ CREATE TABLE `t1` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -INSERT DELAYED IGNORE INTO `t1` VALUES +INSERT DELAYED IGNORE INTO `t1` VALUES (1), (2), (3), @@ -1162,6 +1187,7 @@ F_cd00692c3bfe59267d5ecfac5310286c int, F_6faa8040da20ef399b63a72d0e4ab575 int, F_fe73f687e5bc5280214e0486b273a5f9 int); insert into t1 (F_8d3bba7425e7c98c50f52ca1b52d3735) values (1); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -1531,6 +1557,7 @@ drop table t1; # CREATE TABLE t1 (a int); INSERT INTO t1 VALUES (1),(2),(3); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -1584,6 +1611,7 @@ CREATE TABLE t1 ( a INT ); CREATE TABLE t2 ( a INT ); INSERT INTO t1 VALUES (1), (2); INSERT INTO t2 VALUES (1), (2); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -1619,6 +1647,7 @@ CREATE TABLE `t2` ( /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -1691,21 +1720,35 @@ create table t3(a varchar(30) primary key, b int not null); test_sequence ------ Testing with illegal table names ------ mariadb-dump: Couldn't find table: "\d-2-1.sql" +/*!999999\- enable the sandbox mode */ mariadb-dump: Couldn't find table: "\t1" +/*!999999\- enable the sandbox mode */ mariadb-dump: Couldn't find table: "\t1" +/*!999999\- enable the sandbox mode */ mariadb-dump: Couldn't find table: "\\t1" +/*!999999\- enable the sandbox mode */ mariadb-dump: Couldn't find table: "t\1" +/*!999999\- enable the sandbox mode */ mariadb-dump: Couldn't find table: "t\1" +/*!999999\- enable the sandbox mode */ mariadb-dump: Couldn't find table: "t/1" +/*!999999\- enable the sandbox mode */ mariadb-dump: Couldn't find table: "T_1" +/*!999999\- enable the sandbox mode */ mariadb-dump: Couldn't find table: "T%1" +/*!999999\- enable the sandbox mode */ mariadb-dump: Couldn't find table: "T'1" +/*!999999\- enable the sandbox mode */ mariadb-dump: Couldn't find table: "T_1" +/*!999999\- enable the sandbox mode */ mariadb-dump: Couldn't find table: "T_" +/*!999999\- enable the sandbox mode */ test_sequence ------ Testing with illegal database names ------ mariadb-dump: Got error: 1049: "Unknown database 'mysqldump_test_d'" when selecting the database +/*!999999\- enable the sandbox mode */ mariadb-dump: Got error: 1049: "Unknown database 'mysqld\ump_test_db'" when selecting the database +/*!999999\- enable the sandbox mode */ drop table t1, t2, t3; drop database mysqldump_test_db; use test; @@ -1767,6 +1810,7 @@ insert into t2 (a, b) values (NULL, NULL),(10, NULL),(NULL, "twenty"),(30, "thir +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -1805,6 +1849,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -1930,6 +1975,7 @@ create table t1(a int); create table t2(a int); create table t3(a int); mariadb-dump: Couldn't find table: "non_existing" +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -1979,6 +2025,7 @@ drop table t1, t2, t3; create table t1 (a int); mariadb-dump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ `a` FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064) mariadb-dump: Got error: 1064: "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1" when retrieving data from server +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -2020,6 +2067,7 @@ CREATE TABLE `t1` ( PRIMARY KEY (`a b`, `c"d`, `e``f`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; insert into t1 values (0815, 4711, 2006); +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -2050,6 +2098,7 @@ UNLOCK TABLES; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -2105,6 +2154,7 @@ INSERT INTO t2 VALUES ('bingo'); INSERT INTO t2 VALUES ('waffle'); INSERT INTO t2 VALUES ('lemon'); create view v2 as select * from t2 where a like 'a%' with check option; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -2204,6 +2254,7 @@ drop database db1; use test; create table t1(a int); create view v1 as select * from t1; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -2274,6 +2325,7 @@ INSERT INTO t2 VALUES ('bingo'); INSERT INTO t2 VALUES ('waffle'); INSERT INTO t2 VALUES ('lemon'); create view v2 as select * from t2 where a like 'a%' with check option; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -2344,6 +2396,7 @@ use test; # CREATE TABLE t1 (a char(10)); INSERT INTO t1 VALUES ('\''); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -2391,6 +2444,7 @@ create view v1 as select * from v3 where b in (1, 2, 3, 4, 5, 6, 7); create view v2 as select v3.a from v3, v1 where v1.a=v3.a and v3.b=3 limit 1; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -2543,6 +2597,7 @@ end if; end AFTER 0000-00-00 00:00:00 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci INSERT INTO t1 (a) VALUES (1),(2),(3),(22); update t1 set a = 4 where a=3; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -2676,6 +2731,7 @@ DELIMITER ; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -2825,6 +2881,7 @@ END // set sql_mode='ansi'; create procedure `a'b` () select 1; set sql_mode=''; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -2981,6 +3038,7 @@ d 2003-10-26 02:00:00 2003-10-26 02:00:00 set global time_zone='Europe/Moscow'; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -3022,6 +3080,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -3084,6 +3143,7 @@ a2 1 2 3 +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -3164,6 +3224,7 @@ a b c 1 first value xxxx 2 second value tttt 3 third value vvv vvv +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -3292,6 +3353,7 @@ BEGIN SET new.a = 0; END| SET SQL_MODE = @old_sql_mode; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -3355,6 +3417,7 @@ DROP TABLE t1; # create table t1 (a binary(1), b blob); insert into t1 values ('',''); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -3390,6 +3453,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -3490,6 +3554,7 @@ insert into t values(5, 51); create view v1 as select qty, price, qty*price as value from t; create view v2 as select qty from v1; mysqldump { +/*!999999\- enable the sandbox mode */ /*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -3505,6 +3570,7 @@ mysqldump { /*!50001 SET collation_connection = @saved_col_connection */; } mysqldump { +/*!999999\- enable the sandbox mode */ /*!50001 DROP VIEW IF EXISTS `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -3550,6 +3616,7 @@ drop table t1; mysqldump { mariadb-dump: Got error: 1356: "View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them" when using LOCK TABLES mariadb-dump: Couldn't execute 'SHOW FIELDS FROM `v1`': View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them (1356) +/*!999999\- enable the sandbox mode */ -- failed on view `v1`: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`id` AS `id` from `t1` @@ -3566,6 +3633,7 @@ insert into t1 values (1232131); insert into t1 values (4711); insert into t1 values (3231); insert into t1 values (0815); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -3644,6 +3712,7 @@ create table basetable ( id serial, tag varchar(64) ); create database mysqldump_views; use mysqldump_views; create view nasishnasifu as select mysqldump_tables.basetable.id from mysqldump_tables.basetable; +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_tables` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; @@ -3729,10 +3798,14 @@ grant all on test.* to mysqltest_1@localhost; create table t1(a int, b varchar(34)); reset master; mariadb-dump: Couldn't execute 'FLUSH /*!40101 LOCAL */ TABLES': Access denied; you need (at least one of) the RELOAD privilege(s) for this operation (1227) +/*!999999\- enable the sandbox mode */ mariadb-dump: Couldn't execute 'FLUSH /*!40101 LOCAL */ TABLES': Access denied; you need (at least one of) the RELOAD privilege(s) for this operation (1227) +/*!999999\- enable the sandbox mode */ grant RELOAD on *.* to mysqltest_1@localhost; mariadb-dump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need (at least one of) the BINLOG MONITOR privilege(s) for this operation (1227) +/*!999999\- enable the sandbox mode */ mariadb-dump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need (at least one of) the BINLOG MONITOR privilege(s) for this operation (1227) +/*!999999\- enable the sandbox mode */ grant REPLICATION CLIENT on *.* to mysqltest_1@localhost; drop table t1; drop user mysqltest_1@localhost; @@ -3791,6 +3864,7 @@ use test; # # Bug #33762: mysqldump can not dump INFORMATION_SCHEMA # +/*!999999\- enable the sandbox mode */ DROP TABLE IF EXISTS `TABLES`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; @@ -3855,6 +3929,7 @@ DROP TABLE t1; CREATE TABLE t2 (a INT) ENGINE=MyISAM; CREATE TABLE t3 (a INT) ENGINE=MyISAM; CREATE TABLE t1 (a INT) ENGINE=merge UNION=(t2, t3); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -3947,10 +4022,12 @@ connect user27293,localhost,user1,,mysqldump_test_db,$MASTER_MYPORT,$MASTER_MYS connection user27293; create procedure mysqldump_test_db.sp1() select 'hello'; mariadb-dump: user2 has insufficient privileges to SHOW CREATE PROCEDURE `sp1`! +/*!999999\- enable the sandbox mode */ -- insufficient privileges to SHOW CREATE PROCEDURE `sp1` -- does user2 have permissions on mysql.proc? +/*!999999\- enable the sandbox mode */ /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; @@ -3978,6 +4055,7 @@ drop database mysqldump_test_db; # CREATE TABLE t1 (c1 INT, c2 LONGBLOB); INSERT INTO t1 SET c1=11, c2=REPEAT('q',509); +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -4057,6 +4135,7 @@ use db42635; create table t1 (id int); create view db42635.v1 (c) as select * from db42635.t1; create view db42635.v2 (c) as select * from db42635.t1; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -4117,6 +4196,7 @@ drop database db42635; # SET NAMES utf8; CREATE TABLE `straße` ( f1 INT ); +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -4139,6 +4219,7 @@ UNLOCK TABLES; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -4163,6 +4244,7 @@ UNLOCK TABLES; DROP TABLE `straße`; CREATE TABLE `כדשגכחךלדגכחשךדגחכךלדגכ` ( f1 INT ); +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -4186,6 +4268,7 @@ UNLOCK TABLES; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; mariadb-dump: Got error: 1146: "Table 'test.???????????????????????' doesn't exist" when using LOCK TABLES +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -4202,6 +4285,7 @@ CREATE TABLE t1(a int, b int); INSERT INTO t1 VALUES (1,1); INSERT INTO t1 VALUES (2,3); INSERT INTO t1 VALUES (3,4), (4,5); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -4476,6 +4560,7 @@ insert into t1 values (1232131); insert into t1 values (4711); insert into t1 values (3231); insert into t1 values (0815); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -4608,6 +4693,7 @@ CREATE DATABASE test; create database `test-database`; use `test-database`; create table test (a int); +/*!999999\- enable the sandbox mode */ DROP TABLE IF EXISTS `test`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; @@ -4830,6 +4916,7 @@ CREATE TRIGGER `trig` BEFORE INSERT ON `test` FOR EACH ROW BEGIN END | ALTER DATABASE `test-database` CHARACTER SET latin1 COLLATE latin1_swedish_ci; ALTER DATABASE `test-database` CHARACTER SET utf8 COLLATE utf8_unicode_ci ; +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `test` ( @@ -5314,6 +5401,7 @@ USE test; # Also verify that a prefix of the mode's name is enough. # CREATE TABLE t1 (a INT); +/*!999999\- enable the sandbox mode */ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -5549,6 +5637,7 @@ CREATE DATABASE `a\"'``b`; USE `a\"'``b`; CREATE PROCEDURE p1() BEGIN END; ALTER DATABASE `a\"'``b` COLLATE utf8_general_ci; +/*!999999\- enable the sandbox mode */ /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; ALTER DATABASE `a\"'``b` CHARACTER SET latin1 COLLATE latin1_swedish_ci ; @@ -5597,6 +5686,7 @@ CREATE VIEW nonunique_table_view_name AS SELECT 1; ################################################## # --compact --databases db1 db2 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `db1` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci */; @@ -5665,6 +5755,7 @@ USE `db2`; ################################################## # --compact db2 +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `nonunique_table_name` ( @@ -5687,6 +5778,7 @@ INSERT INTO `nonunique_table_view_name` VALUES ################################################## # --compact --delayed-insert --no-data-med=0 --databases db2 db1 +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `db2` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci */; @@ -5698,7 +5790,7 @@ CREATE TABLE `nonunique_table_name` ( UNIQUE KEY `i1` (`i1`) ) ENGINE=MEMORY AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -INSERT DELAYED INTO `nonunique_table_name` VALUES +INSERT DELAYED INTO `nonunique_table_name` VALUES (1), (2); /*!40101 SET @saved_cs_client = @@character_set_client */; @@ -5720,7 +5812,7 @@ CREATE TABLE `basetable` ( `id` smallint(6) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -INSERT DELAYED INTO `basetable` VALUES +INSERT DELAYED INTO `basetable` VALUES (5), (6); /*!40101 SET @saved_cs_client = @@character_set_client */; @@ -5821,6 +5913,7 @@ CREATE TABLE t1 (a int, b int); CREATE TRIGGER tt1_t1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.b=NEW.a + 10; INSERT INTO t1 (a) VALUES (1),(2),(3); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -5869,6 +5962,7 @@ DROP TABLE t1; # # Without --replace and --insert-ignore # +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -5964,6 +6058,7 @@ CREATE TABLE IF NOT EXISTS `transaction_registry` ( # # With --replace # +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -6069,6 +6164,7 @@ CREATE TABLE IF NOT EXISTS `transaction_registry` ( # # With --insert-ignore # +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -6193,6 +6289,7 @@ insert into t3 values(2); insert into t3(`invisible`, `a b c & $!@#$%^&*( )`, `ds=~!@ \# $% ^ & * ( ) _ - = +` ) values(1,2,3); CREATE TABLE t4(ËÏÌÏÎËÁ1 INT); insert into t4 values(1); +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -6233,6 +6330,7 @@ CREATE TABLE `t4` ( INSERT INTO `t4` VALUES (1); #Check side effect on --complete insert +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -6478,7 +6576,7 @@ j integer INSERT INTO t VALUES (1,1),(2,2),(3,3),(4,4); # Dump database 1 # Restore from database 1 to database 2 -ERROR 1100 (HY000) at line 45: Table 'seq_t_i' was not locked with LOCK TABLES +ERROR 1100 (HY000) at line 46: Table 'seq_t_i' was not locked with LOCK TABLES SETVAL(`seq_t_i`, 1, 0) 1 DROP DATABASE IF EXISTS test1; @@ -6599,10 +6697,8 @@ TABLE 1 SET GLOBAL LOG_OUTPUT=DEFAULT, GLOBAL GENERAL_LOG=@save_general_log; TRUNCATE TABLE mysql.general_log; DROP DATABASE test1; -# # End of 10.3 tests # -# # MDEV-31092 mysqldump --force doesn't ignore error as it should # create function f1() returns int return 1; @@ -6613,6 +6709,7 @@ Warnings: Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it. update mysql.event set body ='select not_a_value' where db='test' and name='e1'; create table t1 (i int); +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -6660,10 +6757,27 @@ drop function f1; drop function f2; drop event e1; drop table t1; -# # End of 10.4 tests # +# MDEV-33727 mariadb-dump trusts the server and does not validate the data +# +create table t1 (a int); +/*!999999\- enable the sandbox mode */ +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( +`a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +ERROR at line 9: Not allowed in the sandbox mode +drop table t1; +# End of 10.5 tests +# +# MDEV-16733 mysqldump --tab and --xml options are conflicting +# mariadb-dump: --xml can't be used with --tab. +# End of 10.11 tests select @@max_connections into @save_max_connections; set global max_connections=10; mariadb-dump: Got error: 2002: "Received error packet before completion of TLS handshake. The authenticity of the following error cannot be verified: 1040 - Too many connections" when trying to connect diff --git a/mysql-test/main/mysqldump.test b/mysql-test/main/mysqldump.test index d075a4081bb..c7874aa482d 100644 --- a/mysql-test/main/mysqldump.test +++ b/mysql-test/main/mysqldump.test @@ -2992,9 +2992,7 @@ TRUNCATE TABLE mysql.general_log; DROP DATABASE test1; --remove_file $MYSQLTEST_VARDIR/tmp/dumptest1.sql ---echo # --echo # End of 10.3 tests ---echo # --echo # --echo # MDEV-31092 mysqldump --force doesn't ignore error as it should @@ -3013,17 +3011,38 @@ drop function f2; drop event e1; drop table t1; ---echo # --echo # End of 10.4 tests + +--echo # +--echo # MDEV-33727 mariadb-dump trusts the server and does not validate the data --echo # -# -# MDEV-16733 mysqldump --tab and --xml options are conflicting -# +create table t1 (a int); +--exec $MYSQL_DUMP --compact --add-drop-table test > $MYSQLTEST_VARDIR/tmp/mdev33727.sql + +# first let's verify it can be loaded not only by mariadb client +--source $MYSQLTEST_VARDIR/tmp/mdev33727.sql + +# and now test the mariadb client sandbox protection +--append_file $MYSQLTEST_VARDIR/tmp/mdev33727.sql +\! echo foo +EOF +--error 1 +--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/mdev33727.sql 2>&1 +--remove_file $MYSQLTEST_VARDIR/tmp/mdev33727.sql +drop table t1; + +--echo # End of 10.5 tests + +--echo # +--echo # MDEV-16733 mysqldump --tab and --xml options are conflicting +--echo # --replace_result mariadb-dump.exe mariadb-dump --error 1 --exec $MYSQL_DUMP --xml --tab=$MYSQLTEST_VARDIR/tmp 2>&1 +--echo # End of 10.11 tests + # # MDEV-32589 parallel-mysqldump - test "too many connections" # diff --git a/mysql-test/main/openssl_1.result b/mysql-test/main/openssl_1.result index 9828b81e216..59c6ce6bc99 100644 --- a/mysql-test/main/openssl_1.result +++ b/mysql-test/main/openssl_1.result @@ -77,6 +77,7 @@ DROP TABLE thread_status; SET GLOBAL event_scheduler=0; CREATE TABLE t1(a int); INSERT INTO t1 VALUES (1), (2); +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -113,6 +114,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -149,6 +151,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; diff --git a/mysql-test/main/openssl_1.test b/mysql-test/main/openssl_1.test index 9232868bddd..24525287ea0 100644 --- a/mysql-test/main/openssl_1.test +++ b/mysql-test/main/openssl_1.test @@ -68,7 +68,7 @@ drop table t1; # Test that we can't open connection to server if we are using # a different cacert # ---exec echo "this query should not execute;" > $MYSQLTEST_VARDIR/tmp/test.sql +--write_line "this query should not execute;" $MYSQLTEST_VARDIR/tmp/test.sql # Handle that openssl gives different error messages from YaSSL. --replace_regex /2026 TLS\/SSL error.*/2026 TLS\/SSL error: xxxx/ --error 1 diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index 9ed81592b24..7d77bb9d601 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -1790,6 +1790,12 @@ set statement optimizer_scan_setup_cost=0 for EXPLAIN SELECT MIN(d) FROM t1 wher } } ] + }, + { + "prepare_sum_aggregators": { + "function": "min(t1.d)", + "aggregator_type": "simple" + } } ] } @@ -2010,6 +2016,18 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id { }, { "test_if_skip_sort_order": [] + }, + { + "prepare_sum_aggregators": { + "function": "min(t1.a)", + "aggregator_type": "simple" + } + }, + { + "prepare_sum_aggregators": { + "function": "max(t1.a)", + "aggregator_type": "simple" + } } ] } @@ -12268,6 +12286,25 @@ JS drop table t1,t2,t3,t10,t11; set optimizer_trace=DEFAULT; # +# MDEV-29179 Condition pushdown from HAVING into WHERE is not shown in optimizer trace +# +CREATE TABLE t1 (a INT, b VARCHAR(1), KEY (a), KEY(b,a)) ENGINE=MEMORY; +INSERT INTO t1 VALUES (4,'n'),(1,'h'),(NULL,'w'); +SET optimizer_trace= 'enabled=on'; +SELECT b, a FROM t1 WHERE b <> 'p' OR a = 4 GROUP BY b, a HAVING a <= 7; +b a +h 1 +n 4 +SELECT json_detailed(json_extract(trace, '$**.steps[*].join_optimization.steps[*].condition_pushdown_from_having') ) exp1, JSON_VALID(trace) exp2 FROM information_schema.optimizer_trace; +exp1 exp2 +[ + { + "conds": "(t1.b <> 'p' or multiple equal(4, t1.a)) and t1.a <= 7", + "having": null + } +] 1 +DROP TABLE t1; +# # End of 10.4 tests # set optimizer_trace='enabled=on'; diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test index f69a200f629..b3a9c211ead 100644 --- a/mysql-test/main/opt_trace.test +++ b/mysql-test/main/opt_trace.test @@ -775,6 +775,16 @@ from information_schema.optimizer_trace; drop table t1,t2,t3,t10,t11; set optimizer_trace=DEFAULT; +--echo # +--echo # MDEV-29179 Condition pushdown from HAVING into WHERE is not shown in optimizer trace +--echo # + +CREATE TABLE t1 (a INT, b VARCHAR(1), KEY (a), KEY(b,a)) ENGINE=MEMORY; +INSERT INTO t1 VALUES (4,'n'),(1,'h'),(NULL,'w'); +SET optimizer_trace= 'enabled=on'; +SELECT b, a FROM t1 WHERE b <> 'p' OR a = 4 GROUP BY b, a HAVING a <= 7; SELECT json_detailed(json_extract(trace, '$**.steps[*].join_optimization.steps[*].condition_pushdown_from_having') ) exp1, JSON_VALID(trace) exp2 FROM information_schema.optimizer_trace; +DROP TABLE t1; + --echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/partition.result b/mysql-test/main/partition.result index 3cb9b3043cd..68b74aaf1c4 100644 --- a/mysql-test/main/partition.result +++ b/mysql-test/main/partition.result @@ -2063,7 +2063,6 @@ ALTER TABLE t1 ANALYZE PARTITION p1 EXTENDED; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'EXTENDED' at line 1 ALTER TABLE t1 ANALYZE PARTITION p1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK ALTER TABLE t1 CHECK PARTITION p1; Table Op Msg_type Msg_text diff --git a/mysql-test/main/partition_binlog.result b/mysql-test/main/partition_binlog.result index 45cd636c1f9..5ecccde4b91 100644 --- a/mysql-test/main/partition_binlog.result +++ b/mysql-test/main/partition_binlog.result @@ -27,7 +27,6 @@ Table Op Msg_type Msg_text test.t1 repair error Wrong partition name or partition list ALTER TABLE t1 ANALYZE PARTITION p0; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK ALTER TABLE t1 CHECK PARTITION p0; Table Op Msg_type Msg_text diff --git a/mysql-test/main/plugin_auth.result b/mysql-test/main/plugin_auth.result index 12a5156eeb1..9a13b9bad21 100644 --- a/mysql-test/main/plugin_auth.result +++ b/mysql-test/main/plugin_auth.result @@ -338,6 +338,7 @@ FLUSH PRIVILEGES; # Executing 'mysqladmin' mysqld is alive # Executing 'mysqldump' +/*!999999\- enable the sandbox mode */ # Executing 'mysql_upgrade' # # Bug #59657: Move the client authentication_pam plugin into the diff --git a/mysql-test/main/plugin_loaderr.test b/mysql-test/main/plugin_loaderr.test index 85621ad047d..1623630bb81 100644 --- a/mysql-test/main/plugin_loaderr.test +++ b/mysql-test/main/plugin_loaderr.test @@ -13,14 +13,14 @@ FROM INFORMATION_SCHEMA.PLUGINS WHERE plugin_name = 'innodb'; --echo # --echo # MDEV-6351 --plugin=force has no effect for built-in plugins --echo # ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc --error 1 --exec $MYSQLD_CMD --innodb=force --innodb-page-size=6000 --disable-log-error ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc --disable_reconnect diff --git a/mysql-test/main/ps.result b/mysql-test/main/ps.result index 39c93729e9e..2e5b5dbbf15 100644 --- a/mysql-test/main/ps.result +++ b/mysql-test/main/ps.result @@ -5808,5 +5808,186 @@ GROUP_CONCAT(@x) 0 DROP TABLE t; # +# MDEV-15703: Crash in EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 (a INT DEFAULT ?)' USING DEFAULT +# +PREPARE stmt FROM 'CREATE OR REPLACE TABLE t1 (a INT DEFAULT ?)'; +EXECUTE stmt USING DEFAULT; +ERROR HY000: Default/ignore value is not supported for such parameter usage +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'CREATE OR REPLACE TABLE t1 (a INT DEFAULT ?)'; +EXECUTE stmt USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +DEALLOCATE PREPARE stmt; +EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 (a INT DEFAULT ?)' USING DEFAULT; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 (a INT DEFAULT ?)' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'BEGIN NOT ATOMIC DECLARE a INT DEFAULT ?; END' USING DEFAULT; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'BEGIN NOT ATOMIC DECLARE a INT DEFAULT ?; END' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +CREATE PROCEDURE p1(a INT) SELECT 1; +EXECUTE IMMEDIATE 'CALL p1(?)' USING DEFAULT; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'CALL p1(?)' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +DROP PROCEDURE p1; +EXECUTE IMMEDIATE 'SELECT ? UNION SELECT 1' USING DEFAULT; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT ? UNION SELECT 1' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT * FROM (SELECT ? UNION ALL SELECT 1) AS derived' USING DEFAULT; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT * FROM (SELECT ? UNION ALL SELECT 1) AS derived' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT * FROM (SELECT ? UNION DISTINCT SELECT 1) AS derived' USING DEFAULT; +ERROR HY000: Default/ignore value is not supported for such parameter usage +EXECUTE IMMEDIATE 'SELECT * FROM (SELECT ? UNION DISTINCT SELECT 1) AS derived' USING IGNORE; +ERROR HY000: Default/ignore value is not supported for such parameter usage +# multi-update and DEFAULT +CREATE TABLE t1 (a INT, b INT DEFAULT a); +INSERT into t1 VALUES (1,2),(2,3); +CREATE TABLE t2 (a INT, b INT DEFAULT a); +INSERT INTO t2 VALUES (1,10),(2,30); +UPDATE t1,t2 SET t1.b = DEFAULT, t2.b = DEFAULT WHERE t1.a=t2.a; +SELECT * FROM t1; +a b +1 1 +2 2 +SELECT * FROM t2; +a b +1 1 +2 2 +# re-check the case for Prepared Statement with parameters +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +INSERT INTO t1 VALUES (1,2),(2,3); +INSERT INTO t2 VALUES (1,10),(2,30); +EXECUTE IMMEDIATE 'UPDATE t1,t2 SET t1.b = ?, t2.b = ? WHERE t1.a=t2.a' USING DEFAULT, DEFAULT; +SELECT * FROM t1; +a b +1 1 +2 2 +SELECT * FROM t2; +a b +1 1 +2 2 +DROP TABLE t1, t2; +# multi-update and IGNORE +CREATE TABLE t1 (a INT, b INT default a); +INSERT INTO t1 VALUES (1,2),(2,3); +CREATE TABLE t2 (a INT, b INT default a); +INSERT INTO t2 VALUES (1,10),(2,30); +UPDATE t1,t2 SET t1.b = IGNORE, t2.b = IGNORE WHERE t1.a=t2.a; +SELECT * FROM t1; +a b +1 2 +2 3 +SELECT * FROM t2; +a b +1 NULL +2 NULL +# re-check the case for Prepared Statement with parameters +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +INSERT INTO t1 VALUES (1,2),(2,3); +INSERT INTO t2 VALUES (1,10),(2,30); +EXECUTE IMMEDIATE 'UPDATE t1,t2 SET t1.b = ?, t2.b = ? WHERE t1.a=t2.a' USING IGNORE, IGNORE; +SELECT * FROM t1; +a b +1 2 +2 3 +SELECT * FROM t2; +a b +1 10 +2 30 +DROP TABLE t1, t2; +# multi-update and DEFAULT parameter (no default) +CREATE TABLE t1 (a INT, b INT NOT NULL); +INSERT INTO t1 VALUES (1,2),(2,3); +CREATE TABLE t2 (a INT, b INT NOT NULL); +INSERT INTO t2 VALUES (1,10),(2,30); +EXECUTE IMMEDIATE 'UPDATE t1,t2 SET t1.b = ?, t2.b = ? WHERE t1.a=t2.a' USING DEFAULT, DEFAULT; +ERROR HY000: Field 'b' doesn't have a default value +DROP TABLE t1, t2; +# multi-update and IGNORE parameter (no default) +CREATE TABLE t1 (a INT, b INT NOT NULL); +INSERT INTO t1 VALUES (1,2),(2,3); +CREATE TABLE t2 (a INT, b INT NOT NULL); +INSERT INTO t2 VALUES (1,10),(2,30); +EXECUTE IMMEDIATE 'UPDATE t1,t2 SET t1.b = ?, t2.b = ? WHERE t1.a=t2.a' USING IGNORE, IGNORE; +SELECT * FROM t1; +a b +1 2 +2 3 +SELECT * FROM t2; +a b +1 10 +2 30 +DROP TABLE t1, t2; +# +# MDEV-33549: Incorrect handling of UPDATE in PS mode in case a table's colum declared as NOT NULL +# +CREATE TABLE t1 (a INT, b INT DEFAULT NULL); +INSERT INTO t1 VALUES (20, 30); +EXECUTE IMMEDIATE 'UPDATE t1 SET b=?' USING DEFAULT; +SELECT * FROM t1; +a b +20 NULL +# Run twice the same update in PS mode to check +# that no memory relating issues taken place. +PREPARE stmt FROM 'UPDATE t1 SET b=?'; +EXECUTE stmt USING DEFAULT; +EXECUTE stmt USING DEFAULT; +# Clean up +DEALLOCATE PREPARE stmt; +DROP TABLE t1; +# The same test for multi-table update +CREATE TABLE t1 (a INT, b INT DEFAULT NULL); +CREATE TABLE t2 (a INT, c INT DEFAULT NULL); +INSERT INTO t1 VALUES (20, 30); +INSERT INTO t2 VALUES (20, 30); +EXECUTE IMMEDIATE 'UPDATE t1,t2 SET b=? WHERE t1.a=t2.a' USING DEFAULT; +SELECT * FROM t1; +a b +20 NULL +# Run twice the same multi-table update in PS mode to check +# that no memory relating issues taken place. +PREPARE stmt FROM 'UPDATE t1,t2 SET b=? WHERE t1.a=t2.a'; +EXECUTE stmt USING DEFAULT; +EXECUTE stmt USING DEFAULT; +DEALLOCATE PREPARE stmt; +# Clean up +DROP TABLE t1; +# This time checks that a default value for table's column +# represented by a function call is handled correctly on UPDATE in PS mode +CREATE TABLE t1 (a INT, b INT DEFAULT MOD(a, 3)); +INSERT INTO t1 VALUES (20, 30); +EXECUTE IMMEDIATE 'UPDATE t1, t2 SET b=? WHERE t1.a=t2.a' USING DEFAULT; +SELECT * FROM t1; +a b +20 2 +# Run twice the same multi-table update in PS mode to check +# that no memory relating issues taken place. +PREPARE stmt FROM 'UPDATE t1, t2 SET b=? WHERE t1.a=t2.a'; +EXECUTE stmt USING DEFAULT; +EXECUTE stmt USING DEFAULT; +# Clean up +DEALLOCATE PREPARE stmt; +DROP TABLE t1, t2; +# MDEV-33218: Assertion `active_arena->is_stmt_prepare_or_first_stmt_execute() || active_arena->state == Query_arena::STMT_SP_QUERY_ARGUMENTS' failed. in st_select_lex::fix_prepare_information +CREATE TABLE t1 AS SELECT 1 f; +PREPARE stmt FROM 'SHOW CREATE TABLE t1'; +DROP TABLE t1; +EXECUTE stmt; +ERROR 42S02: Table 'test.t1' doesn't exist +CREATE VIEW t1 AS SELECT 1; +EXECUTE stmt; +View Create View character_set_client collation_connection +t1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `t1` AS select 1 AS `1` latin1 latin1_swedish_ci +# Clean up +DEALLOCATE PREPARE stmt; +DROP VIEW t1; +# # End of 10.4 tests # diff --git a/mysql-test/main/ps.test b/mysql-test/main/ps.test index d6a3822832c..bf22385040c 100644 --- a/mysql-test/main/ps.test +++ b/mysql-test/main/ps.test @@ -5248,6 +5248,191 @@ EXECUTE IMMEDIATE 'SELECT GROUP_CONCAT(@x) FROM t GROUP BY @x := f'; DROP TABLE t; +--echo # +--echo # MDEV-15703: Crash in EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 (a INT DEFAULT ?)' USING DEFAULT +--echo # + +PREPARE stmt FROM 'CREATE OR REPLACE TABLE t1 (a INT DEFAULT ?)'; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE stmt USING DEFAULT; +DEALLOCATE PREPARE stmt; + +PREPARE stmt FROM 'CREATE OR REPLACE TABLE t1 (a INT DEFAULT ?)'; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE stmt USING IGNORE; +DEALLOCATE PREPARE stmt; + +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 (a INT DEFAULT ?)' USING DEFAULT; + +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 (a INT DEFAULT ?)' USING IGNORE; + +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'BEGIN NOT ATOMIC DECLARE a INT DEFAULT ?; END' USING DEFAULT; + +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'BEGIN NOT ATOMIC DECLARE a INT DEFAULT ?; END' USING IGNORE; + +CREATE PROCEDURE p1(a INT) SELECT 1; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'CALL p1(?)' USING DEFAULT; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'CALL p1(?)' USING IGNORE; +DROP PROCEDURE p1; + +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT ? UNION SELECT 1' USING DEFAULT; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT ? UNION SELECT 1' USING IGNORE; + +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT * FROM (SELECT ? UNION ALL SELECT 1) AS derived' USING DEFAULT; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT * FROM (SELECT ? UNION ALL SELECT 1) AS derived' USING IGNORE; + +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT * FROM (SELECT ? UNION DISTINCT SELECT 1) AS derived' USING DEFAULT; +--error ER_INVALID_DEFAULT_PARAM +EXECUTE IMMEDIATE 'SELECT * FROM (SELECT ? UNION DISTINCT SELECT 1) AS derived' USING IGNORE; + +--echo # multi-update and DEFAULT +CREATE TABLE t1 (a INT, b INT DEFAULT a); +INSERT into t1 VALUES (1,2),(2,3); +CREATE TABLE t2 (a INT, b INT DEFAULT a); +INSERT INTO t2 VALUES (1,10),(2,30); + +UPDATE t1,t2 SET t1.b = DEFAULT, t2.b = DEFAULT WHERE t1.a=t2.a; +SELECT * FROM t1; +SELECT * FROM t2; + +--echo # re-check the case for Prepared Statement with parameters +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +INSERT INTO t1 VALUES (1,2),(2,3); +INSERT INTO t2 VALUES (1,10),(2,30); + +EXECUTE IMMEDIATE 'UPDATE t1,t2 SET t1.b = ?, t2.b = ? WHERE t1.a=t2.a' USING DEFAULT, DEFAULT; +SELECT * FROM t1; +SELECT * FROM t2; + +# Cleanup +DROP TABLE t1, t2; + +--echo # multi-update and IGNORE +CREATE TABLE t1 (a INT, b INT default a); +INSERT INTO t1 VALUES (1,2),(2,3); +CREATE TABLE t2 (a INT, b INT default a); +INSERT INTO t2 VALUES (1,10),(2,30); + +UPDATE t1,t2 SET t1.b = IGNORE, t2.b = IGNORE WHERE t1.a=t2.a; +SELECT * FROM t1; +SELECT * FROM t2; + +--echo # re-check the case for Prepared Statement with parameters +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +INSERT INTO t1 VALUES (1,2),(2,3); +INSERT INTO t2 VALUES (1,10),(2,30); + +EXECUTE IMMEDIATE 'UPDATE t1,t2 SET t1.b = ?, t2.b = ? WHERE t1.a=t2.a' USING IGNORE, IGNORE; +SELECT * FROM t1; +SELECT * FROM t2; + +# Cleanup +DROP TABLE t1, t2; + +--echo # multi-update and DEFAULT parameter (no default) +CREATE TABLE t1 (a INT, b INT NOT NULL); +INSERT INTO t1 VALUES (1,2),(2,3); +CREATE TABLE t2 (a INT, b INT NOT NULL); +INSERT INTO t2 VALUES (1,10),(2,30); + +--error ER_NO_DEFAULT_FOR_FIELD +EXECUTE IMMEDIATE 'UPDATE t1,t2 SET t1.b = ?, t2.b = ? WHERE t1.a=t2.a' USING DEFAULT, DEFAULT; + +# Cleanup +DROP TABLE t1, t2; + +--echo # multi-update and IGNORE parameter (no default) +CREATE TABLE t1 (a INT, b INT NOT NULL); +INSERT INTO t1 VALUES (1,2),(2,3); +CREATE TABLE t2 (a INT, b INT NOT NULL); +INSERT INTO t2 VALUES (1,10),(2,30); + +EXECUTE IMMEDIATE 'UPDATE t1,t2 SET t1.b = ?, t2.b = ? WHERE t1.a=t2.a' USING IGNORE, IGNORE; +SELECT * FROM t1; +SELECT * FROM t2; + +# Cleanup +DROP TABLE t1, t2; + +--echo # +--echo # MDEV-33549: Incorrect handling of UPDATE in PS mode in case a table's colum declared as NOT NULL +--echo # + +CREATE TABLE t1 (a INT, b INT DEFAULT NULL); +INSERT INTO t1 VALUES (20, 30); +EXECUTE IMMEDIATE 'UPDATE t1 SET b=?' USING DEFAULT; +SELECT * FROM t1; + +--echo # Run twice the same update in PS mode to check +--echo # that no memory relating issues taken place. +PREPARE stmt FROM 'UPDATE t1 SET b=?'; +EXECUTE stmt USING DEFAULT; +EXECUTE stmt USING DEFAULT; + +--echo # Clean up +DEALLOCATE PREPARE stmt; +DROP TABLE t1; + +--echo # The same test for multi-table update +CREATE TABLE t1 (a INT, b INT DEFAULT NULL); +CREATE TABLE t2 (a INT, c INT DEFAULT NULL); + +INSERT INTO t1 VALUES (20, 30); +INSERT INTO t2 VALUES (20, 30); + +EXECUTE IMMEDIATE 'UPDATE t1,t2 SET b=? WHERE t1.a=t2.a' USING DEFAULT; +SELECT * FROM t1; +--echo # Run twice the same multi-table update in PS mode to check +--echo # that no memory relating issues taken place. +PREPARE stmt FROM 'UPDATE t1,t2 SET b=? WHERE t1.a=t2.a'; +EXECUTE stmt USING DEFAULT; +EXECUTE stmt USING DEFAULT; +DEALLOCATE PREPARE stmt; +--echo # Clean up +DROP TABLE t1; + +--echo # This time checks that a default value for table's column +--echo # represented by a function call is handled correctly on UPDATE in PS mode +CREATE TABLE t1 (a INT, b INT DEFAULT MOD(a, 3)); +INSERT INTO t1 VALUES (20, 30); +EXECUTE IMMEDIATE 'UPDATE t1, t2 SET b=? WHERE t1.a=t2.a' USING DEFAULT; +SELECT * FROM t1; + +--echo # Run twice the same multi-table update in PS mode to check +--echo # that no memory relating issues taken place. +PREPARE stmt FROM 'UPDATE t1, t2 SET b=? WHERE t1.a=t2.a'; +EXECUTE stmt USING DEFAULT; +EXECUTE stmt USING DEFAULT; + +--echo # Clean up +DEALLOCATE PREPARE stmt; +DROP TABLE t1, t2; + +--echo # MDEV-33218: Assertion `active_arena->is_stmt_prepare_or_first_stmt_execute() || active_arena->state == Query_arena::STMT_SP_QUERY_ARGUMENTS' failed. in st_select_lex::fix_prepare_information +CREATE TABLE t1 AS SELECT 1 f; +PREPARE stmt FROM 'SHOW CREATE TABLE t1'; +DROP TABLE t1; +--error ER_NO_SUCH_TABLE +EXECUTE stmt; +CREATE VIEW t1 AS SELECT 1; +EXECUTE stmt; +--echo # Clean up +DEALLOCATE PREPARE stmt; +DROP VIEW t1; + --echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/ps_2myisam.result b/mysql-test/main/ps_2myisam.result index 256665ce4cb..ec365498833 100644 --- a/mysql-test/main/ps_2myisam.result +++ b/mysql-test/main/ps_2myisam.result @@ -1798,7 +1798,7 @@ t5 CREATE TABLE `t5` ( `param09` longtext DEFAULT NULL, `const10` bigint(17) DEFAULT NULL, `param10` bigint(20) DEFAULT NULL, - `const11` int(4) DEFAULT NULL, + `const11` int(5) DEFAULT NULL, `param11` bigint(20) DEFAULT NULL, `const12` binary(0) DEFAULT NULL, `param12` bigint(20) DEFAULT NULL, @@ -1828,7 +1828,7 @@ def test t5 t5 const09 const09 12 19 19 Y 128 0 63 def test t5 t5 param09 param09 252 4294967295 19 Y 16 0 8 def test t5 t5 const10 const10 8 17 9 Y 32768 0 63 def test t5 t5 param10 param10 8 20 9 Y 32768 0 63 -def test t5 t5 const11 const11 3 4 4 Y 32768 0 63 +def test t5 t5 const11 const11 3 5 4 Y 32768 0 63 def test t5 t5 param11 param11 8 20 4 Y 32768 0 63 def test t5 t5 const12 const12 254 0 0 Y 128 0 63 def test t5 t5 param12 param12 8 20 0 Y 32768 0 63 diff --git a/mysql-test/main/ps_3innodb.result b/mysql-test/main/ps_3innodb.result index 675587e020a..1c98a59cff5 100644 --- a/mysql-test/main/ps_3innodb.result +++ b/mysql-test/main/ps_3innodb.result @@ -1781,7 +1781,7 @@ t5 CREATE TABLE `t5` ( `param09` longtext DEFAULT NULL, `const10` bigint(17) DEFAULT NULL, `param10` bigint(20) DEFAULT NULL, - `const11` int(4) DEFAULT NULL, + `const11` int(5) DEFAULT NULL, `param11` bigint(20) DEFAULT NULL, `const12` binary(0) DEFAULT NULL, `param12` bigint(20) DEFAULT NULL, @@ -1811,7 +1811,7 @@ def test t5 t5 const09 const09 12 19 19 Y 128 0 63 def test t5 t5 param09 param09 252 4294967295 19 Y 16 0 8 def test t5 t5 const10 const10 8 17 9 Y 32768 0 63 def test t5 t5 param10 param10 8 20 9 Y 32768 0 63 -def test t5 t5 const11 const11 3 4 4 Y 32768 0 63 +def test t5 t5 const11 const11 3 5 4 Y 32768 0 63 def test t5 t5 param11 param11 8 20 4 Y 32768 0 63 def test t5 t5 const12 const12 254 0 0 Y 128 0 63 def test t5 t5 param12 param12 8 20 0 Y 32768 0 63 diff --git a/mysql-test/main/ps_4heap.result b/mysql-test/main/ps_4heap.result index dcde7613bfe..db182536e93 100644 --- a/mysql-test/main/ps_4heap.result +++ b/mysql-test/main/ps_4heap.result @@ -1782,7 +1782,7 @@ t5 CREATE TABLE `t5` ( `param09` longtext DEFAULT NULL, `const10` bigint(17) DEFAULT NULL, `param10` bigint(20) DEFAULT NULL, - `const11` int(4) DEFAULT NULL, + `const11` int(5) DEFAULT NULL, `param11` bigint(20) DEFAULT NULL, `const12` binary(0) DEFAULT NULL, `param12` bigint(20) DEFAULT NULL, @@ -1812,7 +1812,7 @@ def test t5 t5 const09 const09 12 19 19 Y 128 0 63 def test t5 t5 param09 param09 252 4294967295 19 Y 16 0 8 def test t5 t5 const10 const10 8 17 9 Y 32768 0 63 def test t5 t5 param10 param10 8 20 9 Y 32768 0 63 -def test t5 t5 const11 const11 3 4 4 Y 32768 0 63 +def test t5 t5 const11 const11 3 5 4 Y 32768 0 63 def test t5 t5 param11 param11 8 20 4 Y 32768 0 63 def test t5 t5 const12 const12 254 0 0 Y 128 0 63 def test t5 t5 param12 param12 8 20 0 Y 32768 0 63 diff --git a/mysql-test/main/ps_5merge.result b/mysql-test/main/ps_5merge.result index c9d33dbb1ae..963a3a60359 100644 --- a/mysql-test/main/ps_5merge.result +++ b/mysql-test/main/ps_5merge.result @@ -1719,7 +1719,7 @@ t5 CREATE TABLE `t5` ( `param09` longtext DEFAULT NULL, `const10` bigint(17) DEFAULT NULL, `param10` bigint(20) DEFAULT NULL, - `const11` int(4) DEFAULT NULL, + `const11` int(5) DEFAULT NULL, `param11` bigint(20) DEFAULT NULL, `const12` binary(0) DEFAULT NULL, `param12` bigint(20) DEFAULT NULL, @@ -1749,7 +1749,7 @@ def test t5 t5 const09 const09 12 19 19 Y 128 0 63 def test t5 t5 param09 param09 252 4294967295 19 Y 16 0 8 def test t5 t5 const10 const10 8 17 9 Y 32768 0 63 def test t5 t5 param10 param10 8 20 9 Y 32768 0 63 -def test t5 t5 const11 const11 3 4 4 Y 32768 0 63 +def test t5 t5 const11 const11 3 5 4 Y 32768 0 63 def test t5 t5 param11 param11 8 20 4 Y 32768 0 63 def test t5 t5 const12 const12 254 0 0 Y 128 0 63 def test t5 t5 param12 param12 8 20 0 Y 32768 0 63 @@ -5087,7 +5087,7 @@ t5 CREATE TABLE `t5` ( `param09` longtext DEFAULT NULL, `const10` bigint(17) DEFAULT NULL, `param10` bigint(20) DEFAULT NULL, - `const11` int(4) DEFAULT NULL, + `const11` int(5) DEFAULT NULL, `param11` bigint(20) DEFAULT NULL, `const12` binary(0) DEFAULT NULL, `param12` bigint(20) DEFAULT NULL, @@ -5117,7 +5117,7 @@ def test t5 t5 const09 const09 12 19 19 Y 128 0 63 def test t5 t5 param09 param09 252 4294967295 19 Y 16 0 8 def test t5 t5 const10 const10 8 17 9 Y 32768 0 63 def test t5 t5 param10 param10 8 20 9 Y 32768 0 63 -def test t5 t5 const11 const11 3 4 4 Y 32768 0 63 +def test t5 t5 const11 const11 3 5 4 Y 32768 0 63 def test t5 t5 param11 param11 8 20 4 Y 32768 0 63 def test t5 t5 const12 const12 254 0 0 Y 128 0 63 def test t5 t5 param12 param12 8 20 0 Y 32768 0 63 diff --git a/mysql-test/main/query_cache.result b/mysql-test/main/query_cache.result index e73f219e1b0..1532890cbd1 100644 --- a/mysql-test/main/query_cache.result +++ b/mysql-test/main/query_cache.result @@ -2202,12 +2202,42 @@ Qcache_queries_in_cache 0 DROP FUNCTION foo; drop table t1; # +# MDEV-33861: main.query_cache fails with embedded after +# enabling WITH_PROTECT_STATEMENT_MEMROOT +# +create table t1 (s1 int); +create procedure f3 () begin +select * from t1; +end; +// +create procedure f4 () begin +select * from t1; +end; +// +Call f4(); +s1 +cAll f3(); +s1 +insert into t1 values (2); +caLl f3(); +s1 +2 +drop procedure f3; +drop procedure f4; +drop table t1; +# +# End of 10.4 tests +# +# # MDEV-24858 SIGABRT in DbugExit from my_malloc in Query_cache::init_cache Regression # SET @qc= @@query_cache_size; set global Query_cache_size=18446744073709547520; SET GLOBAL query_cache_size= @qc; # +# End of 10.5 tests +# +# # MDEV-22301 JSON_TABLE: Queries are not inserted into query cache. # create table t1 (a text); @@ -2233,6 +2263,7 @@ DROP TABLE t; restore defaults SET GLOBAL query_cache_type= default; SET GLOBAL query_cache_size=@save_query_cache_size; +# End of 10.6 tests # # MDEV-29028: Queries using RANDOM_BYTES get stored in query cache # @@ -2255,6 +2286,4 @@ improbable 0 drop table t1; set global query_cache_type= @qcache; -# # End of 10.10 tests -# diff --git a/mysql-test/main/query_cache.test b/mysql-test/main/query_cache.test index 08756b80697..feb9ecf526c 100644 --- a/mysql-test/main/query_cache.test +++ b/mysql-test/main/query_cache.test @@ -1807,6 +1807,40 @@ show status like "Qcache_queries_in_cache"; DROP FUNCTION foo; drop table t1; +--echo # +--echo # MDEV-33861: main.query_cache fails with embedded after +--echo # enabling WITH_PROTECT_STATEMENT_MEMROOT +--echo # + +create table t1 (s1 int); +--delimiter // +create procedure f3 () begin +select * from t1; +end; +// +create procedure f4 () begin +select * from t1; +end; +// +--delimiter ; + +Call f4(); + +cAll f3(); + +insert into t1 values (2); + +caLl f3(); + +drop procedure f3; +drop procedure f4; +drop table t1; + + +--echo # +--echo # End of 10.4 tests +--echo # + --echo # --echo # MDEV-24858 SIGABRT in DbugExit from my_malloc in Query_cache::init_cache Regression --echo # @@ -1816,6 +1850,10 @@ set global Query_cache_size=18446744073709547520; SET GLOBAL query_cache_size= @qc; --enable_warnings +--echo # +--echo # End of 10.5 tests +--echo # + --echo # --echo # MDEV-22301 JSON_TABLE: Queries are not inserted into query cache. --echo # @@ -1838,6 +1876,8 @@ DROP TABLE t; SET GLOBAL query_cache_type= default; SET GLOBAL query_cache_size=@save_query_cache_size; +--echo # End of 10.6 tests + --echo # --echo # MDEV-29028: Queries using RANDOM_BYTES get stored in query cache --echo # @@ -1866,7 +1906,6 @@ select random_bytes(1024) = random_bytes(1024) as improbable; drop table t1; set global query_cache_type= @qcache; ---echo # --echo # End of 10.10 tests ---echo # + --enable_ps2_protocol diff --git a/mysql-test/main/read_only_innodb.result b/mysql-test/main/read_only_innodb.result index cfc8f2ecb17..85aee64087f 100644 --- a/mysql-test/main/read_only_innodb.result +++ b/mysql-test/main/read_only_innodb.result @@ -70,7 +70,7 @@ UNLOCK TABLES; DROP TABLE t1; DROP USER test@localhost; disconnect con1; -echo End of 5.1 tests +# End of 5.1 tests # # Bug#33669: Transactional temporary tables do not work under --read-only # @@ -244,3 +244,26 @@ connection default; SET GLOBAL READ_ONLY = OFF; DROP USER bug33669@localhost; DROP DATABASE db1; +# End of 5.5 tests +# +# MDEV-33889 Read only server throws error when running a create temporary table as select statement +# +create table t1(a int) engine=innodb; +create user u1@localhost; +grant insert, select, update, delete, create temporary tables on test.* to u1@localhost; +insert into t1 values (1); +set global read_only=1; +connect u1,localhost,u1; +set default_tmp_storage_engine=innodb; +create temporary table tt1 (a int); +create temporary table tt2 like t1; +create temporary table tt3 as select * from t1; +select * from tt3; +a +1 +disconnect u1; +connection default; +drop table t1; +drop user u1@localhost; +set global read_only=0; +# End of 10.5 tests diff --git a/mysql-test/main/read_only_innodb.test b/mysql-test/main/read_only_innodb.test index e2c2979c393..59af952da8d 100644 --- a/mysql-test/main/read_only_innodb.test +++ b/mysql-test/main/read_only_innodb.test @@ -103,7 +103,7 @@ DROP USER test@localhost; disconnect con1; ---echo echo End of 5.1 tests +--echo # End of 5.1 tests --echo # --echo # Bug#33669: Transactional temporary tables do not work under --read-only @@ -250,3 +250,29 @@ SET GLOBAL READ_ONLY = OFF; DROP USER bug33669@localhost; DROP DATABASE db1; +--echo # End of 5.5 tests + +--echo # +--echo # MDEV-33889 Read only server throws error when running a create temporary table as select statement +--echo # +create table t1(a int) engine=innodb; +create user u1@localhost; +grant insert, select, update, delete, create temporary tables on test.* to u1@localhost; +insert into t1 values (1); +set global read_only=1; + +connect u1,localhost,u1; +set default_tmp_storage_engine=innodb; + +create temporary table tt1 (a int); +create temporary table tt2 like t1; +create temporary table tt3 as select * from t1; +select * from tt3; +disconnect u1; + +connection default; +drop table t1; +drop user u1@localhost; +set global read_only=0; + +--echo # End of 10.5 tests diff --git a/mysql-test/main/rowid_filter_innodb.result b/mysql-test/main/rowid_filter_innodb.result index 24b80881c6e..63a744856e4 100644 --- a/mysql-test/main/rowid_filter_innodb.result +++ b/mysql-test/main/rowid_filter_innodb.result @@ -3571,5 +3571,105 @@ pk c1 129 NULL 133 NULL DROP TABLE t1,t2; -set global innodb_stats_persistent= @stats.save; +# +# MDEV-31154: Fatal InnoDB error or assertion `!is_v' failure upon multi-update with indexed virtual column +# +# Test with auto generated Primary Key +# +SET @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='rowid_filter=on'; +CREATE TABLE t0(a int); +INSERT INTO t0 SELECT seq FROM seq_1_to_20; +ANALYZE TABLE t0 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t0 analyze status Engine-independent statistics collected +test.t0 analyze status OK +CREATE TABLE t1 ( +a int, +b int as (a * 2) VIRTUAL, +f char(200), /* Filler */ +key (b), +key (a) +) engine=innodb; +INSERT INTO t1 (a, f) SELECT seq, seq FROM seq_1_to_1000; +ANALYZE TABLE t1 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +# Test for type 'ref|filter' +EXPLAIN SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 ref|filter b,a b|a 5|5 test.t0.a 1 (2%) Using where; Using rowid filter +SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20; +count(*) +10 +EXPLAIN SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 ref|filter b,a b|a 5|5 test.t0.a 1 (2%) Using where; Using rowid filter +SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20 FOR UPDATE; +count(*) +10 +# Test for type 'range|filter' +EXPLAIN SELECT count(*) FROM t1 WHERE a<100 and b <100; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range|filter b,a b|a 5|5 NULL 49 (10%) Using where; Using rowid filter +SELECT count(*) FROM t1 WHERE a<100 and b <100; +count(*) +49 +EXPLAIN SELECT count(*) FROM t1 WHERE a<100 and b <100 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range|filter b,a b|a 5|5 NULL 49 (10%) Using where; Using rowid filter +SELECT count(*) FROM t1 WHERE a<100 and b <100 FOR UPDATE; +count(*) +49 +# Test with Primary Key +# +DROP TABLE t1; +CREATE TABLE t1 ( +p int PRIMARY KEY AUTO_INCREMENT, +a int, +b int as (a * 2) VIRTUAL, +f char(200), /* Filler */ +key (b), +key (a) +) engine=innodb; +INSERT INTO t1 (a, f) SELECT seq, seq FROM seq_1_to_1000; +ANALYZE TABLE t1 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +# Test for type 'ref|filter' +EXPLAIN SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 ref|filter b,a b|a 5|5 test.t0.a 1 (2%) Using where; Using rowid filter +SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20; +count(*) +10 +EXPLAIN SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t1 ref|filter b,a b|a 5|5 test.t0.a 1 (2%) Using where; Using rowid filter +SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20 FOR UPDATE; +count(*) +10 +# Test for type 'range|filter' +EXPLAIN SELECT count(*) FROM t1 WHERE a<100 and b <100; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range|filter b,a b|a 5|5 NULL 49 (10%) Using where; Using rowid filter +SELECT count(*) FROM t1 WHERE a<100 and b <100; +count(*) +49 +EXPLAIN SELECT count(*) FROM t1 WHERE a<100 and b <100 FOR UPDATE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range|filter b,a b|a 5|5 NULL 49 (10%) Using where; Using rowid filter +SELECT count(*) FROM t1 WHERE a<100 and b <100 FOR UPDATE; +count(*) +49 +SET optimizer_switch=@save_optimizer_switch; +DROP TABLE t0, t1; # End of 10.4 tests +# End of 10.6 tests +set global innodb_stats_persistent= @stats.save; diff --git a/mysql-test/main/rowid_filter_innodb.test b/mysql-test/main/rowid_filter_innodb.test index 7e8e1e210fc..d5de649f566 100644 --- a/mysql-test/main/rowid_filter_innodb.test +++ b/mysql-test/main/rowid_filter_innodb.test @@ -1,6 +1,8 @@ --source include/no_valgrind_without_big.inc --source include/have_innodb.inc --source include/have_debug.inc +--source include/have_sequence.inc +--source include/innodb_stable_estimates.inc SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB'; @@ -696,6 +698,82 @@ eval $q; DROP TABLE t1,t2; -set global innodb_stats_persistent= @stats.save; +--echo # +--echo # MDEV-31154: Fatal InnoDB error or assertion `!is_v' failure upon multi-update with indexed virtual column +--echo # + +--echo # Test with auto generated Primary Key +--echo # + +SET @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='rowid_filter=on'; + +CREATE TABLE t0(a int); +INSERT INTO t0 SELECT seq FROM seq_1_to_20; +ANALYZE TABLE t0 PERSISTENT FOR ALL; + +CREATE TABLE t1 ( + a int, + b int as (a * 2) VIRTUAL, + f char(200), /* Filler */ + key (b), + key (a) +) engine=innodb; + +INSERT INTO t1 (a, f) SELECT seq, seq FROM seq_1_to_1000; +ANALYZE TABLE t1 PERSISTENT FOR ALL; + +--echo # Test for type 'ref|filter' +EXPLAIN SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20; +SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20; + +EXPLAIN SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20 FOR UPDATE; +SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20 FOR UPDATE; + +--echo # Test for type 'range|filter' +EXPLAIN SELECT count(*) FROM t1 WHERE a<100 and b <100; +SELECT count(*) FROM t1 WHERE a<100 and b <100; + +EXPLAIN SELECT count(*) FROM t1 WHERE a<100 and b <100 FOR UPDATE; +SELECT count(*) FROM t1 WHERE a<100 and b <100 FOR UPDATE; + +--echo # Test with Primary Key +--echo # + +DROP TABLE t1; +CREATE TABLE t1 ( + p int PRIMARY KEY AUTO_INCREMENT, + a int, + b int as (a * 2) VIRTUAL, + f char(200), /* Filler */ + key (b), + key (a) +) engine=innodb; + +INSERT INTO t1 (a, f) SELECT seq, seq FROM seq_1_to_1000; +ANALYZE TABLE t1 PERSISTENT FOR ALL; + +--echo # Test for type 'ref|filter' +EXPLAIN SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20; +SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20; + +EXPLAIN SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20 FOR UPDATE; +SELECT count(*) from t0,t1 WHERE t0.a=t1.b AND t1.a<20 FOR UPDATE; + +--echo # Test for type 'range|filter' +EXPLAIN SELECT count(*) FROM t1 WHERE a<100 and b <100; +SELECT count(*) FROM t1 WHERE a<100 and b <100; + +EXPLAIN SELECT count(*) FROM t1 WHERE a<100 and b <100 FOR UPDATE; +SELECT count(*) FROM t1 WHERE a<100 and b <100 FOR UPDATE; + +SET optimizer_switch=@save_optimizer_switch; + +DROP TABLE t0, t1; --echo # End of 10.4 tests + +--echo # End of 10.6 tests + +set global innodb_stats_persistent= @stats.save; + diff --git a/mysql-test/main/rpl_mysqldump_slave.result b/mysql-test/main/rpl_mysqldump_slave.result index 9f93e3c405e..6d424adef14 100644 --- a/mysql-test/main/rpl_mysqldump_slave.result +++ b/mysql-test/main/rpl_mysqldump_slave.result @@ -7,25 +7,33 @@ connection slave; connection master; use test; connection slave; +/*!999999\- enable the sandbox mode */ -- SET GLOBAL gtid_slave_pos=''; CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START; + +/*!999999\- enable the sandbox mode */ STOP ALL SLAVES; -- SET GLOBAL gtid_slave_pos=''; CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START; + START ALL SLAVES; +/*!999999\- enable the sandbox mode */ STOP ALL SLAVES; -- SET GLOBAL gtid_slave_pos=''; CHANGE MASTER '' TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_MYPORT, MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START; + START ALL SLAVES; start slave; Warnings: Note 1254 Slave is already running +/*!999999\- enable the sandbox mode */ -- SET GLOBAL gtid_slave_pos=''; CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START; + start slave; Warnings: Note 1254 Slave is already running -*** Test mysqldump --dump-slave GTID functionality. +*** Test mysqldump --dump-slave GTID/non-gtid functionality. connection master; SET gtid_seq_no = 1000; CREATE TABLE t1 (a INT PRIMARY KEY); @@ -35,36 +43,182 @@ connection slave; CREATE TABLE t2 (a INT PRIMARY KEY); DROP TABLE t2; -1. --dump-slave=1 +1. --dump-slave=1 --gtid +/*!999999\- enable the sandbox mode */ SET GLOBAL gtid_slave_pos='0-1-1001'; CHANGE MASTER '' TO MASTER_USE_GTID=slave_pos; -- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START; -2. --dump-slave=2 +1a. --dump-slave=1 + +/*!999999\- enable the sandbox mode */ +-- SET GLOBAL gtid_slave_pos='0-1-1001'; +CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START; + + +2. --dump-slave=2 --gtid + +/*!999999\- enable the sandbox mode */ -- SET GLOBAL gtid_slave_pos='0-1-1001'; -- CHANGE MASTER '' TO MASTER_USE_GTID=slave_pos; -- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START; -*** Test mysqldump --master-data GTID functionality. -1. --master-data=1 --- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START; +2. --dump-slave=2 + +/*!999999\- enable the sandbox mode */ +-- SET GLOBAL gtid_slave_pos='0-1-1001'; +-- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START; + +*** Test mysqldump --master-data GTID/non-gtid functionality. + +1. --master-data=1 --gtid + +/*!999999\- enable the sandbox mode */ CHANGE MASTER TO MASTER_USE_GTID=slave_pos; SET GLOBAL gtid_slave_pos='0-2-1003'; - -2. --master-data=2 - -- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START; + +1a. --master-data=1 + +/*!999999\- enable the sandbox mode */ +-- SET GLOBAL gtid_slave_pos='0-2-1003'; +CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START; + +2. --master-data=2 --gtid + +/*!999999\- enable the sandbox mode */ +-- CHANGE MASTER TO MASTER_USE_GTID=slave_pos; +-- SET GLOBAL gtid_slave_pos='0-2-1003'; +-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START; + +2a. --master-data=2 + +/*!999999\- enable the sandbox mode */ +-- SET GLOBAL gtid_slave_pos='0-2-1003'; +-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START; + +3. --master-data --single-transaction --gtid + +/*!999999\- enable the sandbox mode */ +CHANGE MASTER TO MASTER_USE_GTID=slave_pos; +SET GLOBAL gtid_slave_pos='0-2-1003'; +-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START; + +3a. --master-data --single-transaction + +/*!999999\- enable the sandbox mode */ +-- SET GLOBAL gtid_slave_pos='0-2-1003'; +CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START; + +4. --master-data=2 --dump-slave=2 --single-transaction --gtid (MDEV-4827) + +/*!999999\- enable the sandbox mode */ +-- MariaDB dump-- +-- Host: localhost Database: test +-- ------------------------------------------------------ +-- Server version +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; + +-- Preferably use GTID to start replication from GTID position: + -- CHANGE MASTER TO MASTER_USE_GTID=slave_pos; -- SET GLOBAL gtid_slave_pos='0-2-1003'; -3. --master-data --single-transaction +-- +-- Alternately, following is the position of the binary logging from SHOW MASTER STATUS at point of backup. +-- Use this when creating a replica of the primary server where the backup was made. +-- The new server will be connecting to the primary server where the backup was taken. +-- -- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START; -CHANGE MASTER TO MASTER_USE_GTID=slave_pos; -SET GLOBAL gtid_slave_pos='0-2-1003'; + +-- +-- The following is the SQL position of the replication taken from SHOW SLAVE STATUS at the time of backup. +-- Use this position when creating a clone of, or replacement server, from where the backup was taken. +-- This new server will connects to the same primary server(s). +-- +-- GTID position to start replication: +-- SET GLOBAL gtid_slave_pos='0-1-1001'; + +-- Use only the MASTER_USE_GTID=slave_pos or MASTER_LOG_FILE/MASTER_LOG_POS in the statements below. + +-- CHANGE MASTER '' TO MASTER_USE_GTID=slave_pos; +-- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START; + +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +-- Dump completed + +4a. --master-data=2 --dump-slave=2 --single-transaction (MDEV-4827) + +/*!999999\- enable the sandbox mode */ +-- MariaDB dump-- +-- Host: localhost Database: test +-- ------------------------------------------------------ +-- Server version +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; + +-- Preferably use GTID to start replication from GTID position: + +-- SET GLOBAL gtid_slave_pos='0-2-1003'; + +-- +-- Alternately, following is the position of the binary logging from SHOW MASTER STATUS at point of backup. +-- Use this when creating a replica of the primary server where the backup was made. +-- The new server will be connecting to the primary server where the backup was taken. +-- + +-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START; + +-- +-- The following is the SQL position of the replication taken from SHOW SLAVE STATUS at the time of backup. +-- Use this position when creating a clone of, or replacement server, from where the backup was taken. +-- This new server will connects to the same primary server(s). +-- +-- GTID position to start replication: +-- SET GLOBAL gtid_slave_pos='0-1-1001'; +-- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START; + +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +-- Dump completed connection master; CREATE TABLE t ( id int @@ -77,8 +231,13 @@ include/stop_slave.inc change master to master_use_gtid=slave_pos; connection master; # Ensuring the binlog dump thread is killed on primary... --- CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000002', MASTER_LOG_POS=BINLOG_START; +/*!999999\- enable the sandbox mode */ -- SET GLOBAL gtid_slave_pos='0-1-1005'; +-- CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000002', MASTER_LOG_POS=BINLOG_START; connection slave; include/start_slave.inc +connection master; +connection slave; +connection master; +FOUND 1 matches in MDEV-33212.sql include/rpl_end.inc diff --git a/mysql-test/main/rpl_mysqldump_slave.test b/mysql-test/main/rpl_mysqldump_slave.test index 0273e196db5..75bb85dbe4b 100644 --- a/mysql-test/main/rpl_mysqldump_slave.test +++ b/mysql-test/main/rpl_mysqldump_slave.test @@ -37,7 +37,7 @@ start slave; start slave; ---echo *** Test mysqldump --dump-slave GTID functionality. +--echo *** Test mysqldump --dump-slave GTID/non-gtid functionality. --connection master SET gtid_seq_no = 1000; @@ -52,37 +52,80 @@ CREATE TABLE t2 (a INT PRIMARY KEY); DROP TABLE t2; --echo ---echo 1. --dump-slave=1 +--echo 1. --dump-slave=1 --gtid --echo --replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ --exec $MYSQL_DUMP_SLAVE --compact --dump-slave=1 --gtid test --echo ---echo 2. --dump-slave=2 +--echo 1a. --dump-slave=1 +--echo +--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ +--exec $MYSQL_DUMP_SLAVE --compact --dump-slave=1 test + +--echo +--echo 2. --dump-slave=2 --gtid --echo --replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ --exec $MYSQL_DUMP_SLAVE --compact --dump-slave=2 --gtid test - ---echo *** Test mysqldump --master-data GTID functionality. --echo ---echo 1. --master-data=1 +--echo 2. --dump-slave=2 +--echo +--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ +--exec $MYSQL_DUMP_SLAVE --compact --dump-slave=2 test + + +--echo *** Test mysqldump --master-data GTID/non-gtid functionality. +--echo +--echo 1. --master-data=1 --gtid --echo --replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ --exec $MYSQL_DUMP_SLAVE --compact --master-data=1 --gtid test --echo ---echo 2. --master-data=2 +--echo 1a. --master-data=1 +--echo +--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ +--exec $MYSQL_DUMP_SLAVE --compact --master-data=1 test + +--echo +--echo 2. --master-data=2 --gtid --echo --replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ --exec $MYSQL_DUMP_SLAVE --compact --master-data=2 --gtid test --echo ---echo 3. --master-data --single-transaction +--echo 2a. --master-data=2 +--echo +--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ +--exec $MYSQL_DUMP_SLAVE --compact --master-data=2 test + +--echo +--echo 3. --master-data --single-transaction --gtid --echo --replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ --exec $MYSQL_DUMP_SLAVE --compact --master-data --single-transaction --gtid test +--echo +--echo 3a. --master-data --single-transaction +--echo +--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ +--exec $MYSQL_DUMP_SLAVE --compact --master-data --single-transaction test + +--echo +--echo 4. --master-data=2 --dump-slave=2 --single-transaction --gtid (MDEV-4827) +--echo +--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ /MariaDB dump.*/MariaDB dump/ /Dump completed.*/Dump completed/ /Server version.*/Server version/ +--exec $MYSQL_DUMP_SLAVE --master-data=2 --dump-slave=2 --single-transaction --gtid test +--echo + +--echo +--echo 4a. --master-data=2 --dump-slave=2 --single-transaction (MDEV-4827) +--echo +--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ /MariaDB dump.*/MariaDB dump/ /Dump completed.*/Dump completed/ /Server version.*/Server version/ +--exec $MYSQL_DUMP_SLAVE --master-data=2 --dump-slave=2 --single-transaction test +--echo # # MDEV-32611 Added test for mysqldump --delete-master-logs option. # This options is alias of @@ -155,4 +198,20 @@ if ($postdump_first_binary_log_filename != $postdump_binlog_filename) connection slave; --source include/start_slave.inc +# MDEV-33212: mysqldump uses MASTER_LOG_POS with dump-slave +# The bug was that the MASTER_LOG_POS was wrong. So check that it is correct. +--connection master +--let $pos= query_get_value(SHOW MASTER STATUS, Position, 1) +--sync_slave_with_master +--connection master +--exec $MYSQL_DUMP_SLAVE --compact --dump-slave test >$MYSQLTEST_VARDIR/tmp/MDEV-33212.sql +--let SEARCH_RANGE=500000000 +--let SEARCH_FILE=$MYSQLTEST_VARDIR/tmp/MDEV-33212.sql +--let SEARCH_PATTERN= MASTER_LOG_POS=$pos +--let SEARCH_OUTPUT=count +--source include/search_pattern_in_file.inc + +--remove_file $MYSQLTEST_VARDIR/tmp/MDEV-33212.sql + + --source include/rpl_end.inc diff --git a/mysql-test/main/selectivity_innodb_notembedded.result b/mysql-test/main/selectivity_innodb_notembedded.result index 8b06fe7556b..f2b7e9396ba 100644 --- a/mysql-test/main/selectivity_innodb_notembedded.result +++ b/mysql-test/main/selectivity_innodb_notembedded.result @@ -88,15 +88,151 @@ sel ] set optimizer_trace=@tmp; drop table t0,t1,t10; -set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; set histogram_size=@save_histogram_size; -set use_stat_tables= @save_use_stat_tables; # # End of 10.4 tests # # +# MDEV-33314: Crash inside calculate_cond_selectivity_for_table() with many columns +# +set optimizer_use_condition_selectivity= 4; +set use_stat_tables= preferably; +# +# create table t1 (col0 int, col1 int, col2 int, ...); +# +$create_tbl; +# +# insert into t1 select seq, ... seq from seq_1_to_10; +# +$insert_cmd; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +set @trace_tmp=@@optimizer_trace; +set optimizer_trace=1; +# +# Basic testcase: don't crash for many-column selectivity +# explain extended select * from t1 where col0>1 and col1>1 and col2>1 and ... +# +$query_tbl; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.0322836, + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "loops": 1, + "rows": 100, + "cost": 0.0322836, + "filtered": 53.32928848, + "attached_condition": "t1.col0 > 1 and t1.col1 > 1 and t1.col2 > 1 and t1.col3 > 1 and t1.col4 > 1 and t1.col5 > 1 and t1.col6 > 1 and t1.col7 > 1 and t1.col8 > 1 and t1.col9 > 1 and t1.col10 > 1 and t1.col11 > 1 and t1.col12 > 1 and t1.col13 > 1 and t1.col14 > 1 and t1.col15 > 1 and t1.col16 > 1 and t1.col17 > 1 and t1.col18 > 1 and t1.col19 > 1 and t1.col20 > 1 and t1.col21 > 1 and t1.col22 > 1 and t1.col23 > 1 and t1.col24 > 1 and t1.col25 > 1 and t1.col26 > 1 and t1.col27 > 1 and t1.col28 > 1 and t1.col29 > 1 and t1.col30 > 1 and t1.col31 > 1 and t1.col32 > 1 and t1.col33 > 1 and t1.col34 > 1 and t1.col35 > 1 and t1.col36 > 1 and t1.col37 > 1 and t1.col38 > 1 and t1.col39 > 1 and t1.col40 > 1 and t1.col41 > 1 and t1.col42 > 1 and t1.col43 > 1 and t1.col44 > 1 and t1.col45 > 1 and t1.col46 > 1 and t1.col47 > 1 and t1.col48 > 1 and t1.col49 > 1 and t1.col50 > 1 and t1.col51 > 1 and t1.col52 > 1 and t1.col53 > 1 and t1.col54 > 1 and t1.col55 > 1 and t1.col56 > 1 and t1.col57 > 1 and t1.col58 > 1 and t1.col59 > 1 and t1.col60 > 1 and t1.col61 > 1 and t1.col62 > 1 and t1.col63 > 1 and t1.col64 > 1 and t1.col65 > 1 and t1.col66 > 1 and t1.col67 > 1 and t1.col68 > 1 and t1.col69 > 1 and t1.col70 > 1 and t1.col71 > 1 and t1.col72 > 1 and t1.col73 > 1 and t1.col74 > 1 and t1.col75 > 1 and t1.col76 > 1 and t1.col77 > 1 and t1.col78 > 1 and t1.col79 > 1 and t1.col80 > 1 and t1.col81 > 1 and t1.col82 > 1 and t1.col83 > 1 and t1.col84 > 1 and t1.col85 > 1 and t1.col86 > 1 and t1.col87 > 1 and t1.col88 > 1 and t1.col89 > 1 and t1.col90 > 1 and t1.col91 > 1 and t1.col92 > 1 and t1.col93 > 1 and t1.col94 > 1 and t1.col95 > 1 and t1.col96 > 1 and t1.col97 > 1 and t1.col98 > 1 and t1.col99 > 1 and t1.col100 > 1 and t1.col101 > 1 and t1.col102 > 1 and t1.col103 > 1 and t1.col104 > 1 and t1.col105 > 1 and t1.col106 > 1 and t1.col107 > 1 and t1.col108 > 1 and t1.col109 > 1 and t1.col110 > 1 and t1.col111 > 1 and t1.col112 > 1 and t1.col113 > 1 and t1.col114 > 1 and t1.col115 > 1 and t1.col116 > 1 and t1.col117 > 1 and t1.col118 > 1 and t1.col119 > 1 and t1.col120 > 1 and t1.col121 > 1 and t1.col122 > 1 and t1.col123 > 1 and t1.col124 > 1 and t1.col125 > 1 and t1.col126 > 1 and t1.col127 > 1 and t1.col128 > 1 and t1.col129 > 1 and t1.col130 > 1 and t1.col131 > 1 and t1.col132 > 1 and t1.col133 > 1 and t1.col134 > 1 and t1.col135 > 1 and t1.col136 > 1 and t1.col137 > 1 and t1.col138 > 1 and t1.col139 > 1 and t1.col140 > 1 and t1.col141 > 1 and t1.col142 > 1 and t1.col143 > 1 and t1.col144 > 1 and t1.col145 > 1 and t1.col146 > 1 and t1.col147 > 1 and t1.col148 > 1 and t1.col149 > 1 and t1.col150 > 1 and t1.col151 > 1 and t1.col152 > 1 and t1.col153 > 1 and t1.col154 > 1 and t1.col155 > 1 and t1.col156 > 1 and t1.col157 > 1 and t1.col158 > 1 and t1.col159 > 1" + } + } + ] + } +} +select +json_detailed(json_extract(trace,'$**.selectivity_for_columns[0]')) as JS +from +information_schema.optimizer_trace; +JS +[ + { + "column_name": "col0", + "ranges": + ["1 < col0"], + "selectivity_from_histogram": 0.996078431 + } +] +$query_tbl; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.0322836, + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "loops": 1, + "rows": 100, + "cost": 0.0322836, + "filtered": 53.32928848, + "attached_condition": "t1.col0 > 1 and t1.col1 > 1 and t1.col2 > 1 and t1.col3 > 1 and t1.col4 > 1 and t1.col5 > 1 and t1.col6 > 1 and t1.col7 > 1 and t1.col8 > 1 and t1.col9 > 1 and t1.col10 > 1 and t1.col11 > 1 and t1.col12 > 1 and t1.col13 > 1 and t1.col14 > 1 and t1.col15 > 1 and t1.col16 > 1 and t1.col17 > 1 and t1.col18 > 1 and t1.col19 > 1 and t1.col20 > 1 and t1.col21 > 1 and t1.col22 > 1 and t1.col23 > 1 and t1.col24 > 1 and t1.col25 > 1 and t1.col26 > 1 and t1.col27 > 1 and t1.col28 > 1 and t1.col29 > 1 and t1.col30 > 1 and t1.col31 > 1 and t1.col32 > 1 and t1.col33 > 1 and t1.col34 > 1 and t1.col35 > 1 and t1.col36 > 1 and t1.col37 > 1 and t1.col38 > 1 and t1.col39 > 1 and t1.col40 > 1 and t1.col41 > 1 and t1.col42 > 1 and t1.col43 > 1 and t1.col44 > 1 and t1.col45 > 1 and t1.col46 > 1 and t1.col47 > 1 and t1.col48 > 1 and t1.col49 > 1 and t1.col50 > 1 and t1.col51 > 1 and t1.col52 > 1 and t1.col53 > 1 and t1.col54 > 1 and t1.col55 > 1 and t1.col56 > 1 and t1.col57 > 1 and t1.col58 > 1 and t1.col59 > 1 and t1.col60 > 1 and t1.col61 > 1 and t1.col62 > 1 and t1.col63 > 1 and t1.col64 > 1 and t1.col65 > 1 and t1.col66 > 1 and t1.col67 > 1 and t1.col68 > 1 and t1.col69 > 1 and t1.col70 > 1 and t1.col71 > 1 and t1.col72 > 1 and t1.col73 > 1 and t1.col74 > 1 and t1.col75 > 1 and t1.col76 > 1 and t1.col77 > 1 and t1.col78 > 1 and t1.col79 > 1 and t1.col80 > 1 and t1.col81 > 1 and t1.col82 > 1 and t1.col83 > 1 and t1.col84 > 1 and t1.col85 > 1 and t1.col86 > 1 and t1.col87 > 1 and t1.col88 > 1 and t1.col89 > 1 and t1.col90 > 1 and t1.col91 > 1 and t1.col92 > 1 and t1.col93 > 1 and t1.col94 > 1 and t1.col95 > 1 and t1.col96 > 1 and t1.col97 > 1 and t1.col98 > 1 and t1.col99 > 1 and t1.col100 > 1 and t1.col101 > 1 and t1.col102 > 1 and t1.col103 > 1 and t1.col104 > 1 and t1.col105 > 1 and t1.col106 > 1 and t1.col107 > 1 and t1.col108 > 1 and t1.col109 > 1 and t1.col110 > 1 and t1.col111 > 1 and t1.col112 > 1 and t1.col113 > 1 and t1.col114 > 1 and t1.col115 > 1 and t1.col116 > 1 and t1.col117 > 1 and t1.col118 > 1 and t1.col119 > 1 and t1.col120 > 1 and t1.col121 > 1 and t1.col122 > 1 and t1.col123 > 1 and t1.col124 > 1 and t1.col125 > 1 and t1.col126 > 1 and t1.col127 > 1 and t1.col128 > 1 and t1.col129 > 1 and t1.col130 > 1 and t1.col131 > 1 and t1.col132 > 1 and t1.col133 > 1 and t1.col134 > 1 and t1.col135 > 1 and t1.col136 > 1 and t1.col137 > 1 and t1.col138 > 1 and t1.col139 > 1 and t1.col140 > 1 and t1.col141 > 1 and t1.col142 > 1 and t1.col143 > 1 and t1.col144 > 1 and t1.col145 > 1 and t1.col146 > 1 and t1.col147 > 1 and t1.col148 > 1 and t1.col149 > 1 and t1.col150 > 1 and t1.col151 > 1 and t1.col152 > 1 and t1.col153 > 1 and t1.col154 > 1 and t1.col155 > 1 and t1.col156 > 1 and t1.col157 > 1 and t1.col158 > 1 and t1.col159 > 1" + } + } + ] + } +} +select +json_detailed(json_extract(trace,'$**.selectivity_for_columns[159]')) as JS +from +information_schema.optimizer_trace; +JS +[ + { + "column_name": "col159", + "ranges": + ["1 < col159"], + "selectivity_from_histogram": 0.996078431 + } +] +# +# Check if not being able to infer anything for the first MAX_KEY +# columns doesn't prevent further inferences. +# +# explain extended select * from t1 +# where (1>2 or col0>1 or col1>1 or ...) and col99>1 +# +$query_tbl; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.0322836, + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "loops": 1, + "rows": 100, + "cost": 0.0322836, + "filtered": 99.60784149, + "attached_condition": "(t1.col1 > 1 or t1.col2 > 1 or t1.col3 > 1 or t1.col4 > 1 or t1.col5 > 1 or t1.col6 > 1 or t1.col7 > 1 or t1.col8 > 1 or t1.col9 > 1 or t1.col10 > 1 or t1.col11 > 1 or t1.col12 > 1 or t1.col13 > 1 or t1.col14 > 1 or t1.col15 > 1 or t1.col16 > 1 or t1.col17 > 1 or t1.col18 > 1 or t1.col19 > 1 or t1.col20 > 1 or t1.col21 > 1 or t1.col22 > 1 or t1.col23 > 1 or t1.col24 > 1 or t1.col25 > 1 or t1.col26 > 1 or t1.col27 > 1 or t1.col28 > 1 or t1.col29 > 1 or t1.col30 > 1 or t1.col31 > 1 or t1.col32 > 1 or t1.col33 > 1 or t1.col34 > 1 or t1.col35 > 1 or t1.col36 > 1 or t1.col37 > 1 or t1.col38 > 1 or t1.col39 > 1 or t1.col40 > 1 or t1.col41 > 1 or t1.col42 > 1 or t1.col43 > 1 or t1.col44 > 1 or t1.col45 > 1 or t1.col46 > 1 or t1.col47 > 1 or t1.col48 > 1 or t1.col49 > 1 or t1.col50 > 1 or t1.col51 > 1 or t1.col52 > 1 or t1.col53 > 1 or t1.col54 > 1 or t1.col55 > 1 or t1.col56 > 1 or t1.col57 > 1 or t1.col58 > 1 or t1.col59 > 1 or t1.col60 > 1 or t1.col61 > 1 or t1.col62 > 1 or t1.col63 > 1 or t1.col64 > 1 or t1.col65 > 1 or t1.col66 > 1 or t1.col67 > 1 or t1.col68 > 1 or t1.col69 > 1 or t1.col70 > 1 or t1.col71 > 1 or t1.col72 > 1 or t1.col73 > 1 or t1.col74 > 1 or t1.col75 > 1 or t1.col76 > 1 or t1.col77 > 1 or t1.col78 > 1 or t1.col79 > 1 or t1.col80 > 1 or t1.col81 > 1 or t1.col82 > 1 or t1.col83 > 1 or t1.col84 > 1 or t1.col85 > 1 or t1.col86 > 1 or t1.col87 > 1 or t1.col88 > 1 or t1.col89 > 1 or t1.col90 > 1 or t1.col91 > 1 or t1.col92 > 1 or t1.col93 > 1 or t1.col94 > 1 or t1.col95 > 1 or t1.col96 > 1 or t1.col97 > 1 or t1.col98 > 1 or t1.col99 > 1 or t1.col100 > 1 or t1.col101 > 1 or t1.col102 > 1 or t1.col103 > 1 or t1.col104 > 1 or t1.col105 > 1 or t1.col106 > 1 or t1.col107 > 1 or t1.col108 > 1 or t1.col109 > 1 or t1.col110 > 1 or t1.col111 > 1 or t1.col112 > 1 or t1.col113 > 1 or t1.col114 > 1 or t1.col115 > 1 or t1.col116 > 1 or t1.col117 > 1 or t1.col118 > 1 or t1.col119 > 1 or t1.col120 > 1 or t1.col121 > 1 or t1.col122 > 1 or t1.col123 > 1 or t1.col124 > 1 or t1.col125 > 1 or t1.col126 > 1 or t1.col127 > 1 or t1.col128 > 1 or t1.col129 > 1 or t1.col130 > 1 or t1.col131 > 1 or t1.col132 > 1 or t1.col133 > 1 or t1.col134 > 1 or t1.col135 > 1 or t1.col136 > 1 or t1.col137 > 1 or t1.col138 > 1 or t1.col139 > 1 or t1.col140 > 1 or t1.col141 > 1 or t1.col142 > 1 or t1.col143 > 1 or t1.col144 > 1 or t1.col145 > 1 or t1.col146 > 1 or t1.col147 > 1 or t1.col148 > 1 or t1.col149 > 1 or t1.col150 > 1 or t1.col151 > 1 or t1.col152 > 1 or t1.col153 > 1 or t1.col154 > 1 or t1.col155 > 1 or t1.col156 > 1 or t1.col157 > 1 or t1.col158 > 1) and t1.col159 > 1" + } + } + ] + } +} +select +json_detailed(json_extract(trace,'$**.selectivity_for_columns')) as JS +from +information_schema.optimizer_trace; +JS +[ + [ + { + "column_name": "col159", + "ranges": + ["1 < col159"], + "selectivity_from_histogram": 0.996078431 + } + ] +] +set optimizer_trace=@trace_tmp; +drop table t1; +# # Clean up # +set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; +set use_stat_tables= @save_use_stat_tables; set @@global.histogram_size=@save_histogram_size; set optimizer_switch=@save_optimizer_switch_for_selectivity_test; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/main/selectivity_notembedded.result b/mysql-test/main/selectivity_notembedded.result index d2e90a19a68..d47154fd294 100644 --- a/mysql-test/main/selectivity_notembedded.result +++ b/mysql-test/main/selectivity_notembedded.result @@ -83,13 +83,149 @@ sel ] set optimizer_trace=@tmp; drop table t0,t1,t10; -set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; set histogram_size=@save_histogram_size; -set use_stat_tables= @save_use_stat_tables; # # End of 10.4 tests # # +# MDEV-33314: Crash inside calculate_cond_selectivity_for_table() with many columns +# +set optimizer_use_condition_selectivity= 4; +set use_stat_tables= preferably; +# +# create table t1 (col0 int, col1 int, col2 int, ...); +# +$create_tbl; +# +# insert into t1 select seq, ... seq from seq_1_to_10; +# +$insert_cmd; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +set @trace_tmp=@@optimizer_trace; +set optimizer_trace=1; +# +# Basic testcase: don't crash for many-column selectivity +# explain extended select * from t1 where col0>1 and col1>1 and col2>1 and ... +# +$query_tbl; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.0295225, + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "loops": 1, + "rows": 100, + "cost": 0.0295225, + "filtered": 53.32928848, + "attached_condition": "t1.col0 > 1 and t1.col1 > 1 and t1.col2 > 1 and t1.col3 > 1 and t1.col4 > 1 and t1.col5 > 1 and t1.col6 > 1 and t1.col7 > 1 and t1.col8 > 1 and t1.col9 > 1 and t1.col10 > 1 and t1.col11 > 1 and t1.col12 > 1 and t1.col13 > 1 and t1.col14 > 1 and t1.col15 > 1 and t1.col16 > 1 and t1.col17 > 1 and t1.col18 > 1 and t1.col19 > 1 and t1.col20 > 1 and t1.col21 > 1 and t1.col22 > 1 and t1.col23 > 1 and t1.col24 > 1 and t1.col25 > 1 and t1.col26 > 1 and t1.col27 > 1 and t1.col28 > 1 and t1.col29 > 1 and t1.col30 > 1 and t1.col31 > 1 and t1.col32 > 1 and t1.col33 > 1 and t1.col34 > 1 and t1.col35 > 1 and t1.col36 > 1 and t1.col37 > 1 and t1.col38 > 1 and t1.col39 > 1 and t1.col40 > 1 and t1.col41 > 1 and t1.col42 > 1 and t1.col43 > 1 and t1.col44 > 1 and t1.col45 > 1 and t1.col46 > 1 and t1.col47 > 1 and t1.col48 > 1 and t1.col49 > 1 and t1.col50 > 1 and t1.col51 > 1 and t1.col52 > 1 and t1.col53 > 1 and t1.col54 > 1 and t1.col55 > 1 and t1.col56 > 1 and t1.col57 > 1 and t1.col58 > 1 and t1.col59 > 1 and t1.col60 > 1 and t1.col61 > 1 and t1.col62 > 1 and t1.col63 > 1 and t1.col64 > 1 and t1.col65 > 1 and t1.col66 > 1 and t1.col67 > 1 and t1.col68 > 1 and t1.col69 > 1 and t1.col70 > 1 and t1.col71 > 1 and t1.col72 > 1 and t1.col73 > 1 and t1.col74 > 1 and t1.col75 > 1 and t1.col76 > 1 and t1.col77 > 1 and t1.col78 > 1 and t1.col79 > 1 and t1.col80 > 1 and t1.col81 > 1 and t1.col82 > 1 and t1.col83 > 1 and t1.col84 > 1 and t1.col85 > 1 and t1.col86 > 1 and t1.col87 > 1 and t1.col88 > 1 and t1.col89 > 1 and t1.col90 > 1 and t1.col91 > 1 and t1.col92 > 1 and t1.col93 > 1 and t1.col94 > 1 and t1.col95 > 1 and t1.col96 > 1 and t1.col97 > 1 and t1.col98 > 1 and t1.col99 > 1 and t1.col100 > 1 and t1.col101 > 1 and t1.col102 > 1 and t1.col103 > 1 and t1.col104 > 1 and t1.col105 > 1 and t1.col106 > 1 and t1.col107 > 1 and t1.col108 > 1 and t1.col109 > 1 and t1.col110 > 1 and t1.col111 > 1 and t1.col112 > 1 and t1.col113 > 1 and t1.col114 > 1 and t1.col115 > 1 and t1.col116 > 1 and t1.col117 > 1 and t1.col118 > 1 and t1.col119 > 1 and t1.col120 > 1 and t1.col121 > 1 and t1.col122 > 1 and t1.col123 > 1 and t1.col124 > 1 and t1.col125 > 1 and t1.col126 > 1 and t1.col127 > 1 and t1.col128 > 1 and t1.col129 > 1 and t1.col130 > 1 and t1.col131 > 1 and t1.col132 > 1 and t1.col133 > 1 and t1.col134 > 1 and t1.col135 > 1 and t1.col136 > 1 and t1.col137 > 1 and t1.col138 > 1 and t1.col139 > 1 and t1.col140 > 1 and t1.col141 > 1 and t1.col142 > 1 and t1.col143 > 1 and t1.col144 > 1 and t1.col145 > 1 and t1.col146 > 1 and t1.col147 > 1 and t1.col148 > 1 and t1.col149 > 1 and t1.col150 > 1 and t1.col151 > 1 and t1.col152 > 1 and t1.col153 > 1 and t1.col154 > 1 and t1.col155 > 1 and t1.col156 > 1 and t1.col157 > 1 and t1.col158 > 1 and t1.col159 > 1" + } + } + ] + } +} +select +json_detailed(json_extract(trace,'$**.selectivity_for_columns[0]')) as JS +from +information_schema.optimizer_trace; +JS +[ + { + "column_name": "col0", + "ranges": + ["1 < col0"], + "selectivity_from_histogram": 0.996078431 + } +] +$query_tbl; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.0295225, + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "loops": 1, + "rows": 100, + "cost": 0.0295225, + "filtered": 53.32928848, + "attached_condition": "t1.col0 > 1 and t1.col1 > 1 and t1.col2 > 1 and t1.col3 > 1 and t1.col4 > 1 and t1.col5 > 1 and t1.col6 > 1 and t1.col7 > 1 and t1.col8 > 1 and t1.col9 > 1 and t1.col10 > 1 and t1.col11 > 1 and t1.col12 > 1 and t1.col13 > 1 and t1.col14 > 1 and t1.col15 > 1 and t1.col16 > 1 and t1.col17 > 1 and t1.col18 > 1 and t1.col19 > 1 and t1.col20 > 1 and t1.col21 > 1 and t1.col22 > 1 and t1.col23 > 1 and t1.col24 > 1 and t1.col25 > 1 and t1.col26 > 1 and t1.col27 > 1 and t1.col28 > 1 and t1.col29 > 1 and t1.col30 > 1 and t1.col31 > 1 and t1.col32 > 1 and t1.col33 > 1 and t1.col34 > 1 and t1.col35 > 1 and t1.col36 > 1 and t1.col37 > 1 and t1.col38 > 1 and t1.col39 > 1 and t1.col40 > 1 and t1.col41 > 1 and t1.col42 > 1 and t1.col43 > 1 and t1.col44 > 1 and t1.col45 > 1 and t1.col46 > 1 and t1.col47 > 1 and t1.col48 > 1 and t1.col49 > 1 and t1.col50 > 1 and t1.col51 > 1 and t1.col52 > 1 and t1.col53 > 1 and t1.col54 > 1 and t1.col55 > 1 and t1.col56 > 1 and t1.col57 > 1 and t1.col58 > 1 and t1.col59 > 1 and t1.col60 > 1 and t1.col61 > 1 and t1.col62 > 1 and t1.col63 > 1 and t1.col64 > 1 and t1.col65 > 1 and t1.col66 > 1 and t1.col67 > 1 and t1.col68 > 1 and t1.col69 > 1 and t1.col70 > 1 and t1.col71 > 1 and t1.col72 > 1 and t1.col73 > 1 and t1.col74 > 1 and t1.col75 > 1 and t1.col76 > 1 and t1.col77 > 1 and t1.col78 > 1 and t1.col79 > 1 and t1.col80 > 1 and t1.col81 > 1 and t1.col82 > 1 and t1.col83 > 1 and t1.col84 > 1 and t1.col85 > 1 and t1.col86 > 1 and t1.col87 > 1 and t1.col88 > 1 and t1.col89 > 1 and t1.col90 > 1 and t1.col91 > 1 and t1.col92 > 1 and t1.col93 > 1 and t1.col94 > 1 and t1.col95 > 1 and t1.col96 > 1 and t1.col97 > 1 and t1.col98 > 1 and t1.col99 > 1 and t1.col100 > 1 and t1.col101 > 1 and t1.col102 > 1 and t1.col103 > 1 and t1.col104 > 1 and t1.col105 > 1 and t1.col106 > 1 and t1.col107 > 1 and t1.col108 > 1 and t1.col109 > 1 and t1.col110 > 1 and t1.col111 > 1 and t1.col112 > 1 and t1.col113 > 1 and t1.col114 > 1 and t1.col115 > 1 and t1.col116 > 1 and t1.col117 > 1 and t1.col118 > 1 and t1.col119 > 1 and t1.col120 > 1 and t1.col121 > 1 and t1.col122 > 1 and t1.col123 > 1 and t1.col124 > 1 and t1.col125 > 1 and t1.col126 > 1 and t1.col127 > 1 and t1.col128 > 1 and t1.col129 > 1 and t1.col130 > 1 and t1.col131 > 1 and t1.col132 > 1 and t1.col133 > 1 and t1.col134 > 1 and t1.col135 > 1 and t1.col136 > 1 and t1.col137 > 1 and t1.col138 > 1 and t1.col139 > 1 and t1.col140 > 1 and t1.col141 > 1 and t1.col142 > 1 and t1.col143 > 1 and t1.col144 > 1 and t1.col145 > 1 and t1.col146 > 1 and t1.col147 > 1 and t1.col148 > 1 and t1.col149 > 1 and t1.col150 > 1 and t1.col151 > 1 and t1.col152 > 1 and t1.col153 > 1 and t1.col154 > 1 and t1.col155 > 1 and t1.col156 > 1 and t1.col157 > 1 and t1.col158 > 1 and t1.col159 > 1" + } + } + ] + } +} +select +json_detailed(json_extract(trace,'$**.selectivity_for_columns[159]')) as JS +from +information_schema.optimizer_trace; +JS +[ + { + "column_name": "col159", + "ranges": + ["1 < col159"], + "selectivity_from_histogram": 0.996078431 + } +] +# +# Check if not being able to infer anything for the first MAX_KEY +# columns doesn't prevent further inferences. +# +# explain extended select * from t1 +# where (1>2 or col0>1 or col1>1 or ...) and col99>1 +# +$query_tbl; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.0295225, + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "loops": 1, + "rows": 100, + "cost": 0.0295225, + "filtered": 99.60784149, + "attached_condition": "(t1.col1 > 1 or t1.col2 > 1 or t1.col3 > 1 or t1.col4 > 1 or t1.col5 > 1 or t1.col6 > 1 or t1.col7 > 1 or t1.col8 > 1 or t1.col9 > 1 or t1.col10 > 1 or t1.col11 > 1 or t1.col12 > 1 or t1.col13 > 1 or t1.col14 > 1 or t1.col15 > 1 or t1.col16 > 1 or t1.col17 > 1 or t1.col18 > 1 or t1.col19 > 1 or t1.col20 > 1 or t1.col21 > 1 or t1.col22 > 1 or t1.col23 > 1 or t1.col24 > 1 or t1.col25 > 1 or t1.col26 > 1 or t1.col27 > 1 or t1.col28 > 1 or t1.col29 > 1 or t1.col30 > 1 or t1.col31 > 1 or t1.col32 > 1 or t1.col33 > 1 or t1.col34 > 1 or t1.col35 > 1 or t1.col36 > 1 or t1.col37 > 1 or t1.col38 > 1 or t1.col39 > 1 or t1.col40 > 1 or t1.col41 > 1 or t1.col42 > 1 or t1.col43 > 1 or t1.col44 > 1 or t1.col45 > 1 or t1.col46 > 1 or t1.col47 > 1 or t1.col48 > 1 or t1.col49 > 1 or t1.col50 > 1 or t1.col51 > 1 or t1.col52 > 1 or t1.col53 > 1 or t1.col54 > 1 or t1.col55 > 1 or t1.col56 > 1 or t1.col57 > 1 or t1.col58 > 1 or t1.col59 > 1 or t1.col60 > 1 or t1.col61 > 1 or t1.col62 > 1 or t1.col63 > 1 or t1.col64 > 1 or t1.col65 > 1 or t1.col66 > 1 or t1.col67 > 1 or t1.col68 > 1 or t1.col69 > 1 or t1.col70 > 1 or t1.col71 > 1 or t1.col72 > 1 or t1.col73 > 1 or t1.col74 > 1 or t1.col75 > 1 or t1.col76 > 1 or t1.col77 > 1 or t1.col78 > 1 or t1.col79 > 1 or t1.col80 > 1 or t1.col81 > 1 or t1.col82 > 1 or t1.col83 > 1 or t1.col84 > 1 or t1.col85 > 1 or t1.col86 > 1 or t1.col87 > 1 or t1.col88 > 1 or t1.col89 > 1 or t1.col90 > 1 or t1.col91 > 1 or t1.col92 > 1 or t1.col93 > 1 or t1.col94 > 1 or t1.col95 > 1 or t1.col96 > 1 or t1.col97 > 1 or t1.col98 > 1 or t1.col99 > 1 or t1.col100 > 1 or t1.col101 > 1 or t1.col102 > 1 or t1.col103 > 1 or t1.col104 > 1 or t1.col105 > 1 or t1.col106 > 1 or t1.col107 > 1 or t1.col108 > 1 or t1.col109 > 1 or t1.col110 > 1 or t1.col111 > 1 or t1.col112 > 1 or t1.col113 > 1 or t1.col114 > 1 or t1.col115 > 1 or t1.col116 > 1 or t1.col117 > 1 or t1.col118 > 1 or t1.col119 > 1 or t1.col120 > 1 or t1.col121 > 1 or t1.col122 > 1 or t1.col123 > 1 or t1.col124 > 1 or t1.col125 > 1 or t1.col126 > 1 or t1.col127 > 1 or t1.col128 > 1 or t1.col129 > 1 or t1.col130 > 1 or t1.col131 > 1 or t1.col132 > 1 or t1.col133 > 1 or t1.col134 > 1 or t1.col135 > 1 or t1.col136 > 1 or t1.col137 > 1 or t1.col138 > 1 or t1.col139 > 1 or t1.col140 > 1 or t1.col141 > 1 or t1.col142 > 1 or t1.col143 > 1 or t1.col144 > 1 or t1.col145 > 1 or t1.col146 > 1 or t1.col147 > 1 or t1.col148 > 1 or t1.col149 > 1 or t1.col150 > 1 or t1.col151 > 1 or t1.col152 > 1 or t1.col153 > 1 or t1.col154 > 1 or t1.col155 > 1 or t1.col156 > 1 or t1.col157 > 1 or t1.col158 > 1) and t1.col159 > 1" + } + } + ] + } +} +select +json_detailed(json_extract(trace,'$**.selectivity_for_columns')) as JS +from +information_schema.optimizer_trace; +JS +[ + [ + { + "column_name": "col159", + "ranges": + ["1 < col159"], + "selectivity_from_histogram": 0.996078431 + } + ] +] +set optimizer_trace=@trace_tmp; +drop table t1; +# # Clean up # +set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; +set use_stat_tables= @save_use_stat_tables; set @@global.histogram_size=@save_histogram_size; diff --git a/mysql-test/main/selectivity_notembedded.test b/mysql-test/main/selectivity_notembedded.test index 6752bd3c7e1..30e0b7f0d2f 100644 --- a/mysql-test/main/selectivity_notembedded.test +++ b/mysql-test/main/selectivity_notembedded.test @@ -105,17 +105,113 @@ from information_schema.optimizer_trace; set optimizer_trace=@tmp; drop table t0,t1,t10; -set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; set histogram_size=@save_histogram_size; -set use_stat_tables= @save_use_stat_tables; - --echo # --echo # End of 10.4 tests --echo # +--echo # +--echo # MDEV-33314: Crash inside calculate_cond_selectivity_for_table() with many columns +--echo # +set optimizer_use_condition_selectivity= 4; +set use_stat_tables= preferably; + +let $N_CONDS=160; +let $N_LAST_COND=159; +--echo # +--echo # create table t1 (col0 int, col1 int, col2 int, ...); +--echo # +let $create_tbl= create table t1 ( col0 int; +let $i=1; + +while ($i < $N_CONDS) { + let $create_tbl= $create_tbl, col$i int; + let $i=`select $i + 1`; +} + +let $create_tbl= $create_tbl ); +#echo $create_tbl; +evalp $create_tbl; + + +--echo # +--echo # insert into t1 select seq, ... seq from seq_1_to_10; +--echo # +let $insert_cmd= insert into t1 select seq; +let $i=1; + +while ($i < $N_CONDS) { + let $insert_cmd = $insert_cmd ,seq; + let $i=`select $i + 1`; +} +let $insert_cmd= $insert_cmd from seq_1_to_100; + +# echo $insert_cmd; +evalp $insert_cmd; + +analyze table t1 persistent for all; +set @trace_tmp=@@optimizer_trace; +set optimizer_trace=1; + +--echo # +--echo # Basic testcase: don't crash for many-column selectivity +--echo # explain extended select * from t1 where col0>1 and col1>1 and col2>1 and ... +--echo # +let $query_tbl= explain format=json select * from t1 where col0>1; + +let $i=1; +while ($i < $N_CONDS) { + let $query_tbl= $query_tbl and col$i>1; + let $i=`select $i + 1`; +} + +#echo $query_tbl; +evalp $query_tbl; + +select + json_detailed(json_extract(trace,'$**.selectivity_for_columns[0]')) as JS +from + information_schema.optimizer_trace; + +evalp $query_tbl; +eval select + json_detailed(json_extract(trace,'\$**.selectivity_for_columns[$N_LAST_COND]')) as JS +from + information_schema.optimizer_trace; + + +--echo # +--echo # Check if not being able to infer anything for the first MAX_KEY +--echo # columns doesn't prevent further inferences. +--echo # +--echo # explain extended select * from t1 +--echo # where (1>2 or col0>1 or col1>1 or ...) and col99>1 +--echo # +let $query_tbl= explain format=json select * from t1 where (1>2 ; + +let $i=1; +while ($i < $N_LAST_COND) { + let $query_tbl= $query_tbl or col$i>1; + let $i=`select $i + 1`; +} +let $query_tbl= $query_tbl) and col$N_LAST_COND>1; + +#echo $query_tbl; +evalp $query_tbl; + +select + json_detailed(json_extract(trace,'$**.selectivity_for_columns')) as JS +from + information_schema.optimizer_trace; + +set optimizer_trace=@trace_tmp; +drop table t1; + --echo # --echo # Clean up --echo # --source include/restore_charset.inc +set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; +set use_stat_tables= @save_use_stat_tables; set @@global.histogram_size=@save_histogram_size; diff --git a/mysql-test/main/show_analyze.result b/mysql-test/main/show_analyze.result index 6f4159804f4..f55a8be7bf2 100644 --- a/mysql-test/main/show_analyze.result +++ b/mysql-test/main/show_analyze.result @@ -207,9 +207,12 @@ id select_type table type possible_keys key key_len ref rows r_rows filtered r_f SET debug_dbug=@old_debug; # Try to do SHOW ANALYZE for a query that runs a SET command: # -set @show_explain_probe_select_id=2; +create table t2 (a int); +insert into t2 values (1),(2); +set @show_explain_probe_select_id=3; SET debug_dbug='+d,show_explain_probe_join_exec_start'; -set @foo= (select max(a) from t0 where sin(a) >0); +set @foo= (select max(a) from t2 +where a + (select max(a) from t0 where t0.a>t2.a) < 10000); connection default; show analyze for $thr2; ERROR HY000: Target is not executing an operation with a query plan @@ -217,6 +220,7 @@ kill query $thr2; connection con1; ERROR 70100: Query execution was interrupted SET debug_dbug=@old_debug; +drop table t2; # # Attempt SHOW ANALYZE for an UPDATE # diff --git a/mysql-test/main/show_analyze.test b/mysql-test/main/show_analyze.test index 832c8d7a378..e7ddea53116 100644 --- a/mysql-test/main/show_analyze.test +++ b/mysql-test/main/show_analyze.test @@ -213,9 +213,15 @@ SET debug_dbug=@old_debug; --echo # Try to do SHOW ANALYZE for a query that runs a SET command: --echo # -set @show_explain_probe_select_id=2; # <--- +create table t2 (a int); +insert into t2 values (1),(2); +set @show_explain_probe_select_id=3; # Stop in the subquery. SET debug_dbug='+d,show_explain_probe_join_exec_start'; -send set @foo= (select max(a) from t0 where sin(a) >0); +# t2 has 2 rows so we will stop in the subquery twice: +# - first one to serve the SHOW ANALYZE request +# - second one when waiting to be KILLed. +send set @foo= (select max(a) from t2 + where a + (select max(a) from t0 where t0.a>t2.a) < 10000); connection default; --source include/wait_condition.inc --error ER_TARGET_NOT_EXPLAINABLE @@ -225,7 +231,7 @@ connection con1; --error ER_QUERY_INTERRUPTED reap; SET debug_dbug=@old_debug; - +drop table t2; --echo # --echo # Attempt SHOW ANALYZE for an UPDATE diff --git a/mysql-test/main/show_explain_json.result b/mysql-test/main/show_explain_json.result index 1b6a19d24c5..1768406c371 100644 --- a/mysql-test/main/show_explain_json.result +++ b/mysql-test/main/show_explain_json.result @@ -563,9 +563,12 @@ SET debug_dbug=@old_debug; # Try to do SHOW EXPLAIN for a query that runs a SET command: # I've found experimentally that select_id==2 here... # -set @show_explain_probe_select_id=2; +create table t2 (a int); +insert into t2 values (1),(2); +set @show_explain_probe_select_id=3; SET debug_dbug='+d,show_explain_probe_join_exec_start'; -set @foo= (select max(a) from t0 where sin(a) >0); +set @foo= (select max(a) from t2 +where a + (select max(a) from t0 where t0.a>t2.a) < 10000); connection default; show explain format=JSON for $thr2; ERROR HY000: Target is not executing an operation with a query plan @@ -573,6 +576,7 @@ kill query $thr2; connection con1; ERROR 70100: Query execution was interrupted SET debug_dbug=@old_debug; +drop table t2; # # Attempt SHOW EXPLAIN for an UPDATE # diff --git a/mysql-test/main/show_explain_json.test b/mysql-test/main/show_explain_json.test index d5acb8707e2..c29bfade011 100644 --- a/mysql-test/main/show_explain_json.test +++ b/mysql-test/main/show_explain_json.test @@ -281,9 +281,16 @@ SET debug_dbug=@old_debug; --echo # Try to do SHOW EXPLAIN for a query that runs a SET command: --echo # I've found experimentally that select_id==2 here... --echo # -set @show_explain_probe_select_id=2; + +create table t2 (a int); +insert into t2 values (1),(2); +set @show_explain_probe_select_id=3; # Stop in the subquery. SET debug_dbug='+d,show_explain_probe_join_exec_start'; -send set @foo= (select max(a) from t0 where sin(a) >0); +# t2 has 2 rows so we will stop in the subquery twice: +# - first one to serve the SHOW ANALYZE request +# - second one when waiting to be KILLed. +send set @foo= (select max(a) from t2 + where a + (select max(a) from t0 where t0.a>t2.a) < 10000); connection default; --source include/wait_condition.inc --error ER_TARGET_NOT_EXPLAINABLE @@ -293,6 +300,7 @@ connection con1; --error ER_QUERY_INTERRUPTED reap; SET debug_dbug=@old_debug; +drop table t2; --echo # --echo # Attempt SHOW EXPLAIN for an UPDATE diff --git a/mysql-test/main/shutdown.test b/mysql-test/main/shutdown.test index 71f2156a17f..b26a6d4b6f6 100644 --- a/mysql-test/main/shutdown.test +++ b/mysql-test/main/shutdown.test @@ -20,13 +20,13 @@ drop procedure try_shutdown; --let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')` --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect ---exec echo "wait" > $_expect_file_name +--write_line wait $_expect_file_name --send shutdown --connection default --source include/wait_until_disconnected.inc ---exec echo "restart" > $_expect_file_name +--write_line restart $_expect_file_name --enable_reconnect --source include/wait_until_connected_again.inc diff --git a/mysql-test/main/skip_grants.test b/mysql-test/main/skip_grants.test index 7b49d75e85a..999a716c911 100644 --- a/mysql-test/main/skip_grants.test +++ b/mysql-test/main/skip_grants.test @@ -175,12 +175,12 @@ drop user baz@baz; SELECT @@skip_grant_tables AS EXPECT_1; # Also check when the server starts without "--skip-grant-table" option ---let $restart_parameters = "--skip-skip-grant-tables" +--let $restart_parameters = --skip-skip-grant-tables --source include/restart_mysqld.inc SELECT @@skip_grant_tables AS EXPECT_0; # Need to restart the server to restore the "--skip-grant-tables" state ---let $restart_parameters = "--skip-grant-tables" +--let $restart_parameters = --skip-grant-tables --source include/restart_mysqld.inc --echo # diff --git a/mysql-test/main/sp.result b/mysql-test/main/sp.result index 155e497140a..91405e60f21 100644 --- a/mysql-test/main/sp.result +++ b/mysql-test/main/sp.result @@ -7172,15 +7172,14 @@ CREATE VIEW t1 AS SELECT 10 AS f1; CALL p1(1); ERROR HY000: The target table t1 of the INSERT is not insertable-into CREATE TEMPORARY TABLE t1 (f1 INT); -# t1 still refers to the view since it was inlined CALL p1(2); -ERROR HY000: The target table t1 of the INSERT is not insertable-into DROP VIEW t1; # t1 now refers to the temporary table CALL p1(3); # Check which values were inserted into the temp table. SELECT * FROM t1; f1 +2 3 DROP TEMPORARY TABLE t1; DROP PROCEDURE p1; diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test index 4deb1d05cb0..97626570519 100644 --- a/mysql-test/main/sp.test +++ b/mysql-test/main/sp.test @@ -8632,8 +8632,6 @@ CALL p1(1); CREATE TEMPORARY TABLE t1 (f1 INT); ---echo # t1 still refers to the view since it was inlined ---error ER_NON_INSERTABLE_TABLE CALL p1(2); DROP VIEW t1; diff --git a/mysql-test/main/sp_validation.result b/mysql-test/main/sp_validation.result index c9771f8f862..b95e84aad87 100644 --- a/mysql-test/main/sp_validation.result +++ b/mysql-test/main/sp_validation.result @@ -1965,4 +1965,32 @@ b 2 3 DROP TABLE t1, t2; +# +# MDEV-33525: Recreate/reuse temporary table +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +CREATE FUNCTION f1() +RETURNS INT +BEGIN +DECLARE res INT; +DECLARE t1_cur CURSOR FOR SELECT 100 FROM t1, t1_tmp; +CREATE TEMPORARY TABLE t1_tmp SELECT 1 a; +OPEN t1_cur; +CLOSE t1_cur; +DROP TEMPORARY TABLE t1_tmp; +RETURN 0; +END +| +SELECT f1(); +f1() +0 +# Without the patch, the second call of f1 would result in error: +# ER_NO_SUCH_TABLE (1146): Table 'test.t1' doesn't exist +SELECT f1(); +f1() +0 +# Clean up +DROP FUNCTION f1; +DROP TABLE t1; SET sql_mode = default; diff --git a/mysql-test/main/sp_validation.test b/mysql-test/main/sp_validation.test index 990095f1a7f..6f095710e2c 100644 --- a/mysql-test/main/sp_validation.test +++ b/mysql-test/main/sp_validation.test @@ -2760,5 +2760,40 @@ SELECT * FROM t2; DROP TABLE t1, t2; +--echo # +--echo # MDEV-33525: Recreate/reuse temporary table +--echo # +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); + +--delimiter | +CREATE FUNCTION f1() +RETURNS INT +BEGIN + DECLARE res INT; + + DECLARE t1_cur CURSOR FOR SELECT 100 FROM t1, t1_tmp; + + CREATE TEMPORARY TABLE t1_tmp SELECT 1 a; + + OPEN t1_cur; + CLOSE t1_cur; + + DROP TEMPORARY TABLE t1_tmp; + + RETURN 0; +END +| + +--delimiter ; +SELECT f1(); +--echo # Without the patch, the second call of f1 would result in error: +--echo # ER_NO_SUCH_TABLE (1146): Table 'test.t1' doesn't exist +SELECT f1(); + +--echo # Clean up +DROP FUNCTION f1; +DROP TABLE t1; + SET sql_mode = default; --enable_ps2_protocol diff --git a/mysql-test/main/ssl_and_innodb.test b/mysql-test/main/ssl_and_innodb.test index 4966f05b37b..2104eb5c8bf 100644 --- a/mysql-test/main/ssl_and_innodb.test +++ b/mysql-test/main/ssl_and_innodb.test @@ -1,5 +1,5 @@ -- source include/have_innodb.inc --- source include/have_ssl_crypto_functs.inc +-- source include/have_des.inc CREATE TABLE t1(a int) engine=innodb; INSERT INTO t1 VALUES (1); diff --git a/mysql-test/main/ssl_crl.result b/mysql-test/main/ssl_crl.result index d5603254ea5..58e3e07f746 100644 --- a/mysql-test/main/ssl_crl.result +++ b/mysql-test/main/ssl_crl.result @@ -2,4 +2,4 @@ Variable_name Value Ssl_version TLS_VERSION # try logging in with a certificate in the server's --ssl-crl : should fail -ERROR 2026 (HY000): TLS/SSL error: sslv3 alert certificate revoked +ERROR 2026 (HY000): TLS/SSL error: ssl/tls alert certificate revoked diff --git a/mysql-test/main/ssl_crl.test b/mysql-test/main/ssl_crl.test index 9b4758578a7..a09490f2b9b 100644 --- a/mysql-test/main/ssl_crl.test +++ b/mysql-test/main/ssl_crl.test @@ -7,7 +7,7 @@ --exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/server-new-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/server-new-cert.pem test -e "SHOW STATUS LIKE 'Ssl_version'" --echo # try logging in with a certificate in the server's --ssl-crl : should fail -# OpenSSL 1.1.1a correctly rejects the certificate, but the error message is different ---replace_regex /ERROR 2013 \(HY000\): Lost connection to server at '.*', system error: [0-9]+/ERROR 2026 (HY000): TLS\/SSL error: sslv3 alert certificate revoked/ +# OpenSSL 1.1.1a and later releases correctly rejects the certificate, but the error message is different +--replace_regex /(ERROR 2013 \(HY000\): Lost connection to server at '.*', system error: [0-9]+|ERROR 2026 \(HY000\): TLS\/SSL error: sslv3 alert certificate revoked)/ERROR 2026 (HY000): TLS\/SSL error: ssl\/tls alert certificate revoked/ --error 1 --exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_version'" 2>&1 diff --git a/mysql-test/main/ssl_timeout.result b/mysql-test/main/ssl_timeout.result index 208be527a6b..d94cfed8571 100644 --- a/mysql-test/main/ssl_timeout.result +++ b/mysql-test/main/ssl_timeout.result @@ -1,5 +1,5 @@ # connect with read timeout so SLEEP() should timeout -connect ssl_con,localhost,root,,,,,SSL read_timeout=5; +connect ssl_con,localhost,root,,,,,SSL read_timeout=5$_timeout_adjustment; # Check ssl turned on SELECT (VARIABLE_VALUE <> '') AS have_ssl FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='Ssl_cipher'; have_ssl diff --git a/mysql-test/main/ssl_timeout.test b/mysql-test/main/ssl_timeout.test index 60b45178d81..d762ebc35a9 100644 --- a/mysql-test/main/ssl_timeout.test +++ b/mysql-test/main/ssl_timeout.test @@ -1,12 +1,11 @@ --source include/have_ssl_communication.inc -# Do not run this test with valgrind as may timeout ---source include/not_valgrind.inc +--source include/slow_environ.inc # Save the initial number of concurrent sessions --source include/count_sessions.inc --echo # connect with read timeout so SLEEP() should timeout -connect (ssl_con,localhost,root,,,,,SSL read_timeout=5); +connect (ssl_con,localhost,root,,,,,SSL read_timeout=5$_timeout_adjustment); --echo # Check ssl turned on SELECT (VARIABLE_VALUE <> '') AS have_ssl FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='Ssl_cipher'; diff --git a/mysql-test/main/stat_tables_partition.result b/mysql-test/main/stat_tables_partition.result index 2619026b231..2dd63e858d4 100644 --- a/mysql-test/main/stat_tables_partition.result +++ b/mysql-test/main/stat_tables_partition.result @@ -34,13 +34,12 @@ set session use_stat_tables='preferably'; # Must NOT show "Engine-independent statistics collected": alter table t1 analyze partition p0; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK # Should not have Handler_read_rnd_next=34 show session status like 'Handler_read_rnd%'; Variable_name Value Handler_read_rnd 0 Handler_read_rnd_deleted 0 -Handler_read_rnd_next 34 +Handler_read_rnd_next 0 drop table t1; SET use_stat_tables = DEFAULT; diff --git a/mysql-test/main/stat_tables_rbr.result b/mysql-test/main/stat_tables_rbr.result index 38f774412bd..9d5e7f85530 100644 --- a/mysql-test/main/stat_tables_rbr.result +++ b/mysql-test/main/stat_tables_rbr.result @@ -17,7 +17,6 @@ SET use_stat_tables = PREFERABLY; CREATE TABLE t1 ( a INT ) ENGINE=MyISAM PARTITION BY HASH(a) PARTITIONS 2; ALTER TABLE t1 ANALYZE PARTITION p1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result index a08d4f72e99..e15d488eea3 100644 --- a/mysql-test/main/subselect4.result +++ b/mysql-test/main/subselect4.result @@ -2990,34 +2990,31 @@ where a >= any (select b from t2 group by (select c from t3 where c = 1)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 +3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a`,(/* select#2 */ select min(`test`.`t2`.`b`) from `test`.`t2`) <= (`test`.`t1`.`a`))) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a`,(/* select#2 */ select `test`.`t2`.`b` from `test`.`t2` group by (/* select#3 */ select `test`.`t3`.`c` from `test`.`t3` where `test`.`t3`.`c` = 1)) <= (`test`.`t1`.`a`))) select a from t1 where a >= any (select b from t2 group by (select c from t3 where c = 1)); a -3 -2 prepare stmt from "select a from t1 where a >= any (select b from t2 group by (select c from t3 where c = 1))"; execute stmt; a -3 -2 execute stmt; a -3 -2 deallocate prepare stmt; explain extended select a from t1 where a <= all (select b from t2 group by (select c from t3 where c = 1)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 +3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a`,(/* select#2 */ select min(`test`.`t2`.`b`) from `test`.`t2`) < (`test`.`t1`.`a`))) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a`,(/* select#2 */ select `test`.`t2`.`b` from `test`.`t2` group by (/* select#3 */ select `test`.`t3`.`c` from `test`.`t3` where `test`.`t3`.`c` = 1)) < (`test`.`t1`.`a`))) select a from t1 where a <= all (select b from t2 group by (select c from t3 where c = 1)); a +3 1 2 explain extended select a from t1 @@ -3025,13 +3022,12 @@ where a >= any (select b from t2 group by 1 + (select c from t3 where c = 1)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where 2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 +3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a`,(/* select#2 */ select min(`test`.`t2`.`b`) from `test`.`t2`) <= (`test`.`t1`.`a`))) +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a`,(/* select#2 */ select `test`.`t2`.`b` from `test`.`t2` group by 1 + (/* select#3 */ select `test`.`t3`.`c` from `test`.`t3` where `test`.`t3`.`c` = 1)) <= (`test`.`t1`.`a`))) select a from t1 where a >= any (select b from t2 group by 1 + (select c from t3 where c = 1)); a -3 -2 drop table t1,t2,t3; # # MDEV-29139: Redundant IN/ALL/ANY predicand in GROUP BY clause of @@ -3051,8 +3047,10 @@ group by (select a from t1 where a = 1) in (select d from t4)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 +4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where 1 +Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where (1,exists(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by ((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) = `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null))) limit 1)) select b from t2 where exists (select c from t3 group by (select a from t1 where a = 1) in (select d from t4)); @@ -3078,8 +3076,10 @@ any (select d from t4)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 +4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where 1 +Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where (1,exists(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by (<(/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)>(((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) >= `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null))))) limit 1)) select b from t2 where exists (select c from t3 group by (select a from t1 where a = 1) >= @@ -3094,8 +3094,10 @@ all (select d from t4)); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 +4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where 1 +Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where (1,exists(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by (<(/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)>(((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) >= `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null))))) limit 1)) select b from t2 where exists (select c from t3 group by (select a from t1 where a = 1) < @@ -3107,15 +3109,17 @@ explain extended select b from t2 where b in (select c from t3 group by (select a from t1 where a = 1) in (select d from t4)); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 -1 PRIMARY t3 ALL NULL NULL NULL NULL 2 50.00 Using where; FirstMatch(t2); Using join buffer (flat, BNL join) +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t2.b 1 100.00 +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 100.00 +4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 select `test`.`t2`.`b` AS `b` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t3`.`c` = `test`.`t2`.`b` +Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from (/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by ((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) = `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null)))) join `test`.`t2` where ``.`c` = `test`.`t2`.`b` select b from t2 where b in (select c from t3 group by (select a from t1 where a = 1) in (select d from t4)); b -2 explain extended select b from t2 where b >= any (select c from t3 group by (select a from t1 where a = 1) in @@ -3123,30 +3127,33 @@ group by (select a from t1 where a = 1) in id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where 2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 +4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where ((`test`.`t2`.`b`,(/* select#2 */ select min(`test`.`t3`.`c`) from `test`.`t3`) <= (`test`.`t2`.`b`))) +Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where ((`test`.`t2`.`b`,(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by ((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) = `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null)))) <= (`test`.`t2`.`b`))) select b from t2 where b >= any (select c from t3 group by (select a from t1 where a = 1) in (select d from t4)); b +explain extended select b from t2 +where b <= all (select c from t3 +group by (select a from t1 where a = 1) in +(select d from t4)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where +2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 +4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where ((`test`.`t2`.`b`,(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by ((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) = `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null)))) < (`test`.`t2`.`b`))) +select b from t2 +where b <= all (select c from t3 +group by (select a from t1 where a = 1) in +(select d from t4)); +b 3 2 -explain extended select b from t2 -where b <= all (select c from t3 -group by (select a from t1 where a = 1) in -(select d from t4)); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where -2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 -Warnings: -Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where ((`test`.`t2`.`b`,(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3`) < (`test`.`t2`.`b`))) -select b from t2 -where b <= all (select c from t3 -group by (select a from t1 where a = 1) in -(select d from t4)); -b -2 drop table t1,t2,t3,t4; # End of 10.3 tests # @@ -3327,4 +3334,33 @@ a 2 DEALLOCATE PREPARE stmt; DROP TABLE t1,t2,t3; +# +# MDEV-33747: Optimization of (SELECT) IN (SELECT ...) executes subquery at prepare stage +# +create table t1 (a int, b int); +insert into t1 select seq, seq from seq_1_to_200; +create table t2 as select * from t1; +create table t3 as select * from t1; +analyze table t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status OK +select @@expensive_subquery_limit < 200 as DEFAULTS_ARE_SUITABLE; +DEFAULTS_ARE_SUITABLE +1 +flush status; +explain select * from t1 where a<3 or (select max(a) from t2) in (select b from t3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 200 Using where +3 SUBQUERY t3 ALL NULL NULL NULL NULL 200 Using where +2 SUBQUERY t2 ALL NULL NULL NULL NULL 200 +# Must show 0. If this shows 200, this means subquery was executed and you have a bug: +show status like 'Handler_read_rnd_next%'; +Variable_name Value +Handler_read_rnd_next 0 +drop table t1,t2,t3; # End of 10.4 tests diff --git a/mysql-test/main/subselect4.test b/mysql-test/main/subselect4.test index 851c7975982..49484c4ea30 100644 --- a/mysql-test/main/subselect4.test +++ b/mysql-test/main/subselect4.test @@ -2647,5 +2647,20 @@ DEALLOCATE PREPARE stmt; DROP TABLE t1,t2,t3; +--echo # +--echo # MDEV-33747: Optimization of (SELECT) IN (SELECT ...) executes subquery at prepare stage +--echo # +create table t1 (a int, b int); +insert into t1 select seq, seq from seq_1_to_200; +create table t2 as select * from t1; +create table t3 as select * from t1; +analyze table t1,t2,t3; +select @@expensive_subquery_limit < 200 as DEFAULTS_ARE_SUITABLE; +flush status; +explain select * from t1 where a<3 or (select max(a) from t2) in (select b from t3); +--echo # Must show 0. If this shows 200, this means subquery was executed and you have a bug: +show status like 'Handler_read_rnd_next%'; +drop table t1,t2,t3; + --echo # End of 10.4 tests diff --git a/mysql-test/main/subselect_elimination.result b/mysql-test/main/subselect_elimination.result new file mode 100644 index 00000000000..17400e490bc --- /dev/null +++ b/mysql-test/main/subselect_elimination.result @@ -0,0 +1,268 @@ +# +# MDEV-28621 group by optimization incorrectly removing subquery where +# subject buried in a function +# +CREATE TABLE t1 (i int) ; +INSERT INTO t1 VALUES (1),(2),(3); +SELECT 1 FROM t1 +WHERE i in +( SELECT a+1 +FROM +(SELECT (SELECT i FROM (SELECT 1 FROM t1) dt) AS a FROM t1) dt2 +GROUP BY a +); +ERROR 21000: Subquery returns more than 1 row +DROP TABLE t1; +create table t1 (a int, b int, c int); +insert into t1 select seq, seq, seq from seq_1_to_10; +create table t2 as select * from t1; +create table t20 as select * from t1; +create table t21 as select * from t1; +create table t3 as select * from t1; +select a, a in +( +select +( +select max(c) from t20 where t20.a<=t2.a +) as SUBQ1 from t2 group by SUBQ1+1 +) as COL +from t1; +a COL +1 1 +2 1 +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +9 1 +10 1 +create view v2 as +select +a, b, +(select max(c) from t20 where t20.a<=t2.a) as SUBQ1, +(select max(c) from t21 where t21.a<=t2.a) as SUBQ2 +from t2; +# test partial elimination +explain +select +a, +a in (select a from v2 where a>3 and v2.SUBQ2>=0 group by v2.SUBQ1, v2.SUBQ2) +from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 Using where; Using temporary +5 DEPENDENT SUBQUERY t21 ALL NULL NULL NULL NULL 10 Using where +4 DEPENDENT SUBQUERY t20 ALL NULL NULL NULL NULL 10 Using where +# test buried subselects in group by clause +select a, a in +( +select +( +select max(c) from t20 where t20.a<=t2.a +)*2 as SUBQ1 from t2 group by SUBQ1+1 +) as COL +from t1; +a COL +1 0 +2 1 +3 0 +4 1 +5 0 +6 1 +7 0 +8 1 +9 0 +10 1 +drop view v2; +drop table t1, t2, t20, t21, t3; +# Testcase from MDEV-32311 +SELECT ( +( WITH x ( x ) AS +(SELECT ( SELECT 'x' UNION SELECT 'x' ) FROM ( SELECT ( 'x' ) ) x) +SELECT x FROM x +WHERE x IN ( ( SELECT 'x' AND x GROUP BY x ) ) +) +) AS SUBQ; +SUBQ +x +# MDEV-32390: +CREATE TABLE t0 ( c43 DECIMAL ( 31 ) DEFAULT ( 45 ) ) ; +INSERT INTO t0 VALUES ( 13 ) , ( 29 ) ; +ALTER TABLE t0 ADD COLUMN c24 INT AFTER c43 ; +INSERT INTO t0 VALUES ( DEFAULT , DEFAULT ) , ( DEFAULT , DEFAULT ) ; +SELECT t1 . c22 AS c9 FROM ( SELECT ( SELECT + EXISTS ( SELECT -128 AS c29 ) << +LOCATE ( t0 . c43 , t0 . c24 <= t0 . c24 NOT BETWEEN 4642475734208631537 AND +-108 , NULLIF ( 57 , -8 ) SOUNDS LIKE TRIM( TRAILING FROM 6107036197732405580 ) +) - t0 . c43 AS c57 FROM t0 LIMIT 1 ) AS c22 FROM t0 ) AS t1 HAVING TRIM( CASE +t1 . c22 WHEN -16 THEN RAND ( ) % HEX ( t1 . c22 ) - SUBSTRING_INDEX ( t1 . c22, +':A9SEZxtjN,fKN*zR' , 'V*vhJb}&c%Op,[T[S,j`F9NDsK;\'8 4;m" +P,ce}1r"3ID1DN' ) >> NULLIF ( t1 . c22 , -95 ) ELSE -2 END IS TRUE +FROM t1 . c22 >= EXISTS ( SELECT t2 . c57 AS c59 FROM ( SELECT CASE c24 WHEN +-103 THEN 85 ELSE 22 END IS TRUE AS c57 FROM t0 ) AS t2 WHERE MOD ( 64 , 46 ) = +CONVERT ( 73 , BINARY ) % RAND ( ) IS NOT NULL = -65 GROUP BY c57 , c22 , c22 +WINDOW w0 AS ( PARTITION BY t2 . c57 ) ) & PI ( ) ) ; +c9 +DROP TABLE t0; +# MDEV-32309 +SELECT +( WITH x ( x ) AS +( +WITH x ( x ) AS ( SELECT 1 ) SELECT ( SELECT x ) FROM x +) +SELECT x FROM x WHERE x IN ( SELECT NULL GROUP BY x ) +) as col1 ; +col1 +NULL +# MDEV-32391 +CREATE TABLE t0 ( c15 INT , c33 INT ) engine=innodb; +INSERT INTO t0 ( c15 ) WITH t1 AS ( SELECT SQRT ( 123 ) NOT +REGEXP MOD ( 91 , -121 ) = ALL ( SELECT c15 AS c33 FROM t0 ) AS c49 FROM t0 ) +SELECT t1 . c49 IS UNKNOWN AS c59 FROM t1 CROSS JOIN t0 AS t2 +WHERE t1 . c49 = + EXISTS ( SELECT -5839312620871436105 AS c17 GROUP BY c49 ) +BETWEEN -109 AND CHAR_LENGTH ( 2694839150676403988 ) - - LOWER ( -13 ) ; +DROP TABLE t0; +# MDEV-28620 +CREATE TABLE t1 ( a int); +INSERT INTO t1 VALUES (1),(2); +SELECT EXISTS +( SELECT 1 FROM t1 GROUP BY 1 IN (SELECT a FROM t1) +ORDER BY a + (SELECT 1 FROM t1 WHERE (1,2) NOT IN (SELECT 1,0)) +) as SUBQ; +ERROR 21000: Subquery returns more than 1 row +DROP TABLE t1; +# MDEV-30842 Item_subselect::get_cache_parameters and UBSAN member +# access within null pointer +CREATE TABLE x (x INT) ENGINE=InnoDB; +INSERT INTO x (x) VALUES (0); +INSERT INTO x (x) VALUES (x IN (SELECT (SELECT x FROM (SELECT x FROM +(SELECT 0 IN (SELECT x=0 FROM (SELECT x FROM (SELECT (SELECT (SELECT (SELECT +(SELECT 0 AS x) FROM x AS x) IN (SELECT 0 AS x) AS x) FROM x AS x) IN +(SELECT x WHERE x=0) AS x FROM x AS x) AS x) AS x GROUP BY x) AS x FROM x) AS x) +AS x) IN (SELECT 0 AS x) AS x FROM x)); +ERROR HY000: Table 'x' is specified twice, both as a target for 'INSERT' and as a separate source for data +DROP TABLE x; +# MDEV-28622: Item_subselect eliminated flag set but Item still +# evaluated/used. +CREATE TABLE t1 ( a int) ; +CREATE VIEW v1 (i) AS SELECT EXISTS(SELECT 1) FROM t1; +SELECT 1 FROM v1 WHERE i NOT IN (SELECT i = 0 FROM v1 WHERE i = -1 GROUP BY i); +1 +DROP TABLE t1; +DROP VIEW v1; +CREATE TABLE t(c1 INT); +SELECT 0 +WHERE 0 IN +( +SELECT 0 FROM +( +SELECT 0 IN +( +SELECT +( +SELECT c1 FROM t +) +) AS c +FROM t +) AS dt +WHERE c GROUP BY c +); +0 +DROP TABLE t; +create table t1 (a int, b int, c int); +insert into t1 select seq, seq, seq from seq_1_to_10; +create table t2 as select * from t1; +create table t20 as select * from t1; +create table t3 as select * from t1; +create view v2 as +select +a, b, (select max(c) from t20 where t20.a<=t2.a) as SUBQ1 +from t2; +explain +select +a, a in (select a from v2 where a>3 group by v2.SUBQ1) +from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 Using where; Using temporary +4 DEPENDENT SUBQUERY t20 ALL NULL NULL NULL NULL 10 Using where +prepare s from ' +explain +select + a, a in (select a from v2 where a>3 group by v2.SUBQ1) +from t1'; +execute s; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 Using where; Using temporary +4 DEPENDENT SUBQUERY t20 ALL NULL NULL NULL NULL 10 Using where +execute s; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 Using where; Using temporary +4 DEPENDENT SUBQUERY t20 ALL NULL NULL NULL NULL 10 Using where +execute s; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 Using where; Using temporary +4 DEPENDENT SUBQUERY t20 ALL NULL NULL NULL NULL 10 Using where +prepare s from ' +explain +select + a, a in (select a from v2 where a>3 and SUBQ1+1 group by v2.SUBQ1) +from t1'; +execute s; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 Using where; Using temporary +4 DEPENDENT SUBQUERY t20 ALL NULL NULL NULL NULL 10 Using where +execute s; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 Using where; Using temporary +4 DEPENDENT SUBQUERY t20 ALL NULL NULL NULL NULL 10 Using where +execute s; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 Using where; Using temporary +4 DEPENDENT SUBQUERY t20 ALL NULL NULL NULL NULL 10 Using where +create procedure p1() +begin +explain +select +a, a in (select a from v2 where a>3 group by v2.SUBQ1) +from t1; +end// +create procedure p2() +begin +explain +select +a, a in (select a from v2 where a>3 and SUBQ1+1 group by v2.SUBQ1) +from t1; +end// +call p1(); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 Using where; Using temporary +4 DEPENDENT SUBQUERY t20 ALL NULL NULL NULL NULL 10 Using where +call p1(); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 Using where; Using temporary +4 DEPENDENT SUBQUERY t20 ALL NULL NULL NULL NULL 10 Using where +call p2(); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 Using where; Using temporary +4 DEPENDENT SUBQUERY t20 ALL NULL NULL NULL NULL 10 Using where +call p2(); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 10 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 Using where; Using temporary +4 DEPENDENT SUBQUERY t20 ALL NULL NULL NULL NULL 10 Using where +drop procedure p1; +drop procedure p2; +drop view v2; +drop table t1,t2,t3,t20; +# end of 10.4 tests diff --git a/mysql-test/main/subselect_elimination.test b/mysql-test/main/subselect_elimination.test new file mode 100644 index 00000000000..9d973477b28 --- /dev/null +++ b/mysql-test/main/subselect_elimination.test @@ -0,0 +1,242 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc + +--echo # +--echo # MDEV-28621 group by optimization incorrectly removing subquery where +--echo # subject buried in a function +--echo # + +CREATE TABLE t1 (i int) ; +INSERT INTO t1 VALUES (1),(2),(3); + +--error ER_SUBQUERY_NO_1_ROW +SELECT 1 FROM t1 +WHERE i in +( SELECT a+1 + FROM + (SELECT (SELECT i FROM (SELECT 1 FROM t1) dt) AS a FROM t1) dt2 + GROUP BY a +); + +DROP TABLE t1; + +create table t1 (a int, b int, c int); +insert into t1 select seq, seq, seq from seq_1_to_10; +create table t2 as select * from t1; +create table t20 as select * from t1; +create table t21 as select * from t1; +create table t3 as select * from t1; +select a, a in +( + select + ( + select max(c) from t20 where t20.a<=t2.a + ) as SUBQ1 from t2 group by SUBQ1+1 +) as COL +from t1; + +create view v2 as +select + a, b, + (select max(c) from t20 where t20.a<=t2.a) as SUBQ1, + (select max(c) from t21 where t21.a<=t2.a) as SUBQ2 +from t2; + +--echo # test partial elimination + +explain +select + a, + a in (select a from v2 where a>3 and v2.SUBQ2>=0 group by v2.SUBQ1, v2.SUBQ2) +from t1; + +--echo # test buried subselects in group by clause + +select a, a in +( + select + ( + select max(c) from t20 where t20.a<=t2.a + )*2 as SUBQ1 from t2 group by SUBQ1+1 +) as COL +from t1; + +drop view v2; +drop table t1, t2, t20, t21, t3; + +--echo # Testcase from MDEV-32311 + +# some warning duplicated using ps-protocol +--disable_warnings +SELECT ( + ( WITH x ( x ) AS + (SELECT ( SELECT 'x' UNION SELECT 'x' ) FROM ( SELECT ( 'x' ) ) x) + SELECT x FROM x + WHERE x IN ( ( SELECT 'x' AND x GROUP BY x ) ) + ) +) AS SUBQ; +--enable_warnings + +--echo # MDEV-32390: + +CREATE TABLE t0 ( c43 DECIMAL ( 31 ) DEFAULT ( 45 ) ) ; +INSERT INTO t0 VALUES ( 13 ) , ( 29 ) ; +ALTER TABLE t0 ADD COLUMN c24 INT AFTER c43 ; +INSERT INTO t0 VALUES ( DEFAULT , DEFAULT ) , ( DEFAULT , DEFAULT ) ; +SELECT t1 . c22 AS c9 FROM ( SELECT ( SELECT + EXISTS ( SELECT -128 AS c29 ) << +LOCATE ( t0 . c43 , t0 . c24 <= t0 . c24 NOT BETWEEN 4642475734208631537 AND +-108 , NULLIF ( 57 , -8 ) SOUNDS LIKE TRIM( TRAILING FROM 6107036197732405580 ) +) - t0 . c43 AS c57 FROM t0 LIMIT 1 ) AS c22 FROM t0 ) AS t1 HAVING TRIM( CASE +t1 . c22 WHEN -16 THEN RAND ( ) % HEX ( t1 . c22 ) - SUBSTRING_INDEX ( t1 . c22, +':A9SEZxtjN,fKN*zR' , 'V*vhJb}&c%Op,[T[S,j`F9NDsK;\'8 4;m" +P,ce}1r"3ID1DN' ) >> NULLIF ( t1 . c22 , -95 ) ELSE -2 END IS TRUE +FROM t1 . c22 >= EXISTS ( SELECT t2 . c57 AS c59 FROM ( SELECT CASE c24 WHEN +-103 THEN 85 ELSE 22 END IS TRUE AS c57 FROM t0 ) AS t2 WHERE MOD ( 64 , 46 ) = +CONVERT ( 73 , BINARY ) % RAND ( ) IS NOT NULL = -65 GROUP BY c57 , c22 , c22 +WINDOW w0 AS ( PARTITION BY t2 . c57 ) ) & PI ( ) ) ; + +DROP TABLE t0; + +--echo # MDEV-32309 + +SELECT + ( WITH x ( x ) AS + ( + WITH x ( x ) AS ( SELECT 1 ) SELECT ( SELECT x ) FROM x + ) + SELECT x FROM x WHERE x IN ( SELECT NULL GROUP BY x ) +) as col1 ; + +--echo # MDEV-32391 + +CREATE TABLE t0 ( c15 INT , c33 INT ) engine=innodb; +INSERT INTO t0 ( c15 ) WITH t1 AS ( SELECT SQRT ( 123 ) NOT +REGEXP MOD ( 91 , -121 ) = ALL ( SELECT c15 AS c33 FROM t0 ) AS c49 FROM t0 ) +SELECT t1 . c49 IS UNKNOWN AS c59 FROM t1 CROSS JOIN t0 AS t2 +WHERE t1 . c49 = + EXISTS ( SELECT -5839312620871436105 AS c17 GROUP BY c49 ) +BETWEEN -109 AND CHAR_LENGTH ( 2694839150676403988 ) - - LOWER ( -13 ) ; +DROP TABLE t0; + +--echo # MDEV-28620 +CREATE TABLE t1 ( a int); +INSERT INTO t1 VALUES (1),(2); + +--error ER_SUBQUERY_NO_1_ROW +SELECT EXISTS +( SELECT 1 FROM t1 GROUP BY 1 IN (SELECT a FROM t1) + ORDER BY a + (SELECT 1 FROM t1 WHERE (1,2) NOT IN (SELECT 1,0)) +) as SUBQ; +DROP TABLE t1; + +--echo # MDEV-30842 Item_subselect::get_cache_parameters and UBSAN member +--echo # access within null pointer + +CREATE TABLE x (x INT) ENGINE=InnoDB; +INSERT INTO x (x) VALUES (0); +--error ER_UPDATE_TABLE_USED +INSERT INTO x (x) VALUES (x IN (SELECT (SELECT x FROM (SELECT x FROM +(SELECT 0 IN (SELECT x=0 FROM (SELECT x FROM (SELECT (SELECT (SELECT (SELECT +(SELECT 0 AS x) FROM x AS x) IN (SELECT 0 AS x) AS x) FROM x AS x) IN +(SELECT x WHERE x=0) AS x FROM x AS x) AS x) AS x GROUP BY x) AS x FROM x) AS x) +AS x) IN (SELECT 0 AS x) AS x FROM x)); +DROP TABLE x; + +--echo # MDEV-28622: Item_subselect eliminated flag set but Item still +--echo # evaluated/used. + +CREATE TABLE t1 ( a int) ; +CREATE VIEW v1 (i) AS SELECT EXISTS(SELECT 1) FROM t1; + +SELECT 1 FROM v1 WHERE i NOT IN (SELECT i = 0 FROM v1 WHERE i = -1 GROUP BY i); +DROP TABLE t1; +DROP VIEW v1; + +CREATE TABLE t(c1 INT); + +SELECT 0 +WHERE 0 IN +( + SELECT 0 FROM + ( + SELECT 0 IN + ( + SELECT + ( + SELECT c1 FROM t + ) + ) AS c + FROM t + ) AS dt + WHERE c GROUP BY c +); + +DROP TABLE t; + +create table t1 (a int, b int, c int); +insert into t1 select seq, seq, seq from seq_1_to_10; +create table t2 as select * from t1; +create table t20 as select * from t1; +create table t3 as select * from t1; + +create view v2 as +select + a, b, (select max(c) from t20 where t20.a<=t2.a) as SUBQ1 +from t2; + +explain +select + a, a in (select a from v2 where a>3 group by v2.SUBQ1) +from t1; + +prepare s from ' +explain +select + a, a in (select a from v2 where a>3 group by v2.SUBQ1) +from t1'; + +execute s; +execute s; +execute s; + +prepare s from ' +explain +select + a, a in (select a from v2 where a>3 and SUBQ1+1 group by v2.SUBQ1) +from t1'; + +execute s; +execute s; +execute s; + +delimiter //; + +create procedure p1() +begin +explain +select + a, a in (select a from v2 where a>3 group by v2.SUBQ1) +from t1; +end// + +create procedure p2() +begin +explain +select + a, a in (select a from v2 where a>3 and SUBQ1+1 group by v2.SUBQ1) +from t1; +end// + +delimiter ;// + +call p1(); +call p1(); +call p2(); +call p2(); +drop procedure p1; +drop procedure p2; + + +drop view v2; +drop table t1,t2,t3,t20; + +--echo # end of 10.4 tests diff --git a/mysql-test/main/subselect_sj_mat.test b/mysql-test/main/subselect_sj_mat.test index a6262323991..e411c29dc10 100644 --- a/mysql-test/main/subselect_sj_mat.test +++ b/mysql-test/main/subselect_sj_mat.test @@ -524,8 +524,6 @@ where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0'); # group_concat with a blob argument - depends on # the variable group_concat_max_len, and # convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB -#Check after fix MDEV-31276 ---disable_ps2_protocol explain extended select left(a1,7), left(a2,7) from t1_512 where a1 in (select group_concat(b1) from t2_512 group by b2); @@ -543,7 +541,6 @@ where a1 in (select group_concat(b1) from t2_512 group by b2); select left(a1,7), left(a2,7) from t1_512 where a1 in (select group_concat(b1) from t2_512 group by b2); ---enable_ps2_protocol drop table t1_512, t2_512, t3_512; @@ -609,8 +606,6 @@ where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0'); # group_concat with a blob argument - depends on # the variable group_concat_max_len, and # convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB -#Check after fix MDEV-31276 ---disable_ps2_protocol explain extended select left(a1,7), left(a2,7) from t1_1024 where a1 in (select group_concat(b1) from t2_1024 group by b2); @@ -628,7 +623,6 @@ where a1 in (select group_concat(b1) from t2_1024 group by b2); select left(a1,7), left(a2,7) from t1_1024 where a1 in (select group_concat(b1) from t2_1024 group by b2); ---enable_ps2_protocol drop table t1_1024, t2_1024, t3_1024; @@ -694,8 +688,6 @@ where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0'); # group_concat with a blob argument - depends on # the variable group_concat_max_len, and # convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB -#Check after fix MDEV-31276 ---disable_ps2_protocol explain extended select left(a1,7), left(a2,7) from t1_1025 where a1 in (select group_concat(b1) from t2_1025 group by b2); @@ -713,7 +705,6 @@ where a1 in (select group_concat(b1) from t2_1025 group by b2); select left(a1,7), left(a2,7) from t1_1025 where a1 in (select group_concat(b1) from t2_1025 group by b2); ---enable_ps2_protocol drop table t1_1025, t2_1025, t3_1025; diff --git a/mysql-test/main/system_mysql_db_fix50030.result b/mysql-test/main/system_mysql_db_fix50030.result index c9594d494d6..ea2ea1c1044 100644 --- a/mysql-test/main/system_mysql_db_fix50030.result +++ b/mysql-test/main/system_mysql_db_fix50030.result @@ -152,7 +152,7 @@ columns_priv CREATE TABLE `columns_priv` ( show create table procs_priv; Table Create Table procs_priv CREATE TABLE `procs_priv` ( - `Host` char(60) NOT NULL DEFAULT '', + `Host` char(255) NOT NULL DEFAULT '', `Db` char(64) NOT NULL DEFAULT '', `User` char(128) NOT NULL DEFAULT '', `Routine_name` char(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '', diff --git a/mysql-test/main/system_mysql_db_fix50117.result b/mysql-test/main/system_mysql_db_fix50117.result index 9057187a7a3..7c85ca98253 100644 --- a/mysql-test/main/system_mysql_db_fix50117.result +++ b/mysql-test/main/system_mysql_db_fix50117.result @@ -132,7 +132,7 @@ columns_priv CREATE TABLE `columns_priv` ( show create table procs_priv; Table Create Table procs_priv CREATE TABLE `procs_priv` ( - `Host` char(60) NOT NULL DEFAULT '', + `Host` char(255) NOT NULL DEFAULT '', `Db` char(64) NOT NULL DEFAULT '', `User` char(128) NOT NULL DEFAULT '', `Routine_name` char(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '', diff --git a/mysql-test/main/system_mysql_db_fix50568.result b/mysql-test/main/system_mysql_db_fix50568.result index 561e7f7f4db..2dad3c47e75 100644 --- a/mysql-test/main/system_mysql_db_fix50568.result +++ b/mysql-test/main/system_mysql_db_fix50568.result @@ -153,7 +153,7 @@ columns_priv CREATE TABLE `columns_priv` ( show create table procs_priv; Table Create Table procs_priv CREATE TABLE `procs_priv` ( - `Host` char(60) NOT NULL DEFAULT '', + `Host` char(255) NOT NULL DEFAULT '', `Db` char(64) NOT NULL DEFAULT '', `User` char(128) NOT NULL DEFAULT '', `Routine_name` char(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '', diff --git a/mysql-test/main/table_value_constr.result b/mysql-test/main/table_value_constr.result index 6d8dd6826e8..857808f6b60 100644 --- a/mysql-test/main/table_value_constr.result +++ b/mysql-test/main/table_value_constr.result @@ -2617,9 +2617,9 @@ ERROR HY000: 'ignore' is not allowed in this context VALUES (DEFAULT); ERROR HY000: 'default' is not allowed in this context EXECUTE IMMEDIATE 'VALUES (?)' USING IGNORE; -ERROR HY000: 'ignore' is not allowed in this context +ERROR HY000: Default/ignore value is not supported for such parameter usage EXECUTE IMMEDIATE 'VALUES (?)' USING DEFAULT; -ERROR HY000: 'default' is not allowed in this context +ERROR HY000: Default/ignore value is not supported for such parameter usage # # MDEV-24675: TVC using subqueries # diff --git a/mysql-test/main/table_value_constr.test b/mysql-test/main/table_value_constr.test index ac623eaaf0b..29347a16f98 100644 --- a/mysql-test/main/table_value_constr.test +++ b/mysql-test/main/table_value_constr.test @@ -1368,9 +1368,9 @@ DELIMITER ;$$ VALUES (IGNORE); --error ER_NOT_ALLOWED_IN_THIS_CONTEXT VALUES (DEFAULT); ---error ER_NOT_ALLOWED_IN_THIS_CONTEXT +--error ER_INVALID_DEFAULT_PARAM EXECUTE IMMEDIATE 'VALUES (?)' USING IGNORE; ---error ER_NOT_ALLOWED_IN_THIS_CONTEXT +--error ER_INVALID_DEFAULT_PARAM EXECUTE IMMEDIATE 'VALUES (?)' USING DEFAULT; --echo # diff --git a/mysql-test/main/temp_table.result b/mysql-test/main/temp_table.result index ac5d82bab44..9724c2c0173 100644 --- a/mysql-test/main/temp_table.result +++ b/mysql-test/main/temp_table.result @@ -618,6 +618,55 @@ tmp # in 11.2 and above here should be listed above used temporary tables DROP TEMPORARY TABLE t1, t2; # +# MDEV-33218: Assertion `active_arena->is_stmt_prepare_or_first_stmt_execute() || active_arena->state == Query_arena::STMT_SP_QUERY_ARGUMENTS' failed. in st_select_lex::fix_prepare_information +# +CREATE VIEW v1 AS SELECT 5; +CREATE PROCEDURE sp() SELECT * FROM v1; +CREATE TEMPORARY TABLE v1 as SELECT 7; +# sp() accesses the temporary table v1 that hides the view with the same name +# Therefore expected output is the row (7) +CALL sp(); +7 +7 +DROP TEMPORARY TABLE v1; +# After the temporary table v1 has been dropped the next invocation of sp() +# accesses the view v1. So, expected output is the row (5) +CALL sp(); +5 +5 +# Clean up +DROP VIEW v1; +DROP PROCEDURE sp; +# Another use case is when a temporary table hides a view is dropped +# inside a stored routine being called. +CREATE VIEW t1 AS SELECT 1; +CREATE PROCEDURE p1() +BEGIN +DROP TEMPORARY TABLE t1; +END +| +CREATE FUNCTION f1() RETURNS INT +BEGIN +CALL p1(); +RETURN 1; +END +| +CREATE TEMPORARY TABLE t1 AS SELECT 1 AS a; +PREPARE stmt FROM 'SELECT f1()'; +EXECUTE stmt; +f1() +1 +# The temporary table t1 has been dropped on first +# execution of the prepared statement 'stmt', +# next time this statement is run it results in issuing +# the error ER_BAD_TABLE_ERROR +EXECUTE stmt; +ERROR 42S02: Unknown table 'test.t1' +# Clean up +DROP VIEW t1; +DROP FUNCTION f1; +DROP PROCEDURE p1; +# # End of 10.4 tests # create function f1() returns int diff --git a/mysql-test/main/temp_table.test b/mysql-test/main/temp_table.test index 11a667435d1..529ce4a6af6 100644 --- a/mysql-test/main/temp_table.test +++ b/mysql-test/main/temp_table.test @@ -669,6 +669,60 @@ SHOW TABLES; DROP TEMPORARY TABLE t1, t2; +--echo # +--echo # MDEV-33218: Assertion `active_arena->is_stmt_prepare_or_first_stmt_execute() || active_arena->state == Query_arena::STMT_SP_QUERY_ARGUMENTS' failed. in st_select_lex::fix_prepare_information +--echo # +CREATE VIEW v1 AS SELECT 5; +CREATE PROCEDURE sp() SELECT * FROM v1; +CREATE TEMPORARY TABLE v1 as SELECT 7; +--echo # sp() accesses the temporary table v1 that hides the view with the same name +--echo # Therefore expected output is the row (7) +CALL sp(); +DROP TEMPORARY TABLE v1; +--echo # After the temporary table v1 has been dropped the next invocation of sp() +--echo # accesses the view v1. So, expected output is the row (5) +CALL sp(); + +--echo # Clean up +DROP VIEW v1; +DROP PROCEDURE sp; + +--echo # Another use case is when a temporary table hides a view is dropped +--echo # inside a stored routine being called. + +CREATE VIEW t1 AS SELECT 1; + +--delimiter | +CREATE PROCEDURE p1() +BEGIN + DROP TEMPORARY TABLE t1; +END +| + +CREATE FUNCTION f1() RETURNS INT +BEGIN + CALL p1(); + RETURN 1; +END +| + +--delimiter ; + +CREATE TEMPORARY TABLE t1 AS SELECT 1 AS a; +PREPARE stmt FROM 'SELECT f1()'; +EXECUTE stmt; +--echo # The temporary table t1 has been dropped on first +--echo # execution of the prepared statement 'stmt', +--echo # next time this statement is run it results in issuing +--echo # the error ER_BAD_TABLE_ERROR +--error ER_BAD_TABLE_ERROR +EXECUTE stmt; + +--echo # Clean up +DROP VIEW t1; +DROP FUNCTION f1; +DROP PROCEDURE p1; + --echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/trigger.result b/mysql-test/main/trigger.result index b3ab5585d92..dd6fa2156ab 100644 --- a/mysql-test/main/trigger.result +++ b/mysql-test/main/trigger.result @@ -1,9 +1,3 @@ -drop table if exists t1, t2, t3, t4; -drop view if exists v1; -drop database if exists mysqltest; -drop function if exists f1; -drop function if exists f2; -drop procedure if exists p1; connect addconroot1, localhost, root,,; connect addconroot2, localhost, root,,; connect addconwithoutdb, localhost, root,,*NO-ONE*; diff --git a/mysql-test/main/trigger.test b/mysql-test/main/trigger.test index 466e9b8f3e5..f54a09bf7a4 100644 --- a/mysql-test/main/trigger.test +++ b/mysql-test/main/trigger.test @@ -7,15 +7,6 @@ # Basic triggers test # ---disable_warnings -drop table if exists t1, t2, t3, t4; -drop view if exists v1; -drop database if exists mysqltest; -drop function if exists f1; -drop function if exists f2; -drop procedure if exists p1; ---enable_warnings - # Create additional connections used through test connect (addconroot1, localhost, root,,); connect (addconroot2, localhost, root,,); diff --git a/mysql-test/main/trigger_wl3253.result b/mysql-test/main/trigger_wl3253.result index ed08b336c19..e501b2640b0 100644 --- a/mysql-test/main/trigger_wl3253.result +++ b/mysql-test/main/trigger_wl3253.result @@ -310,6 +310,7 @@ CREATE TABLE t1 (a INT); CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; CREATE TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET @a:=3; +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -372,6 +373,7 @@ CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; CREATE TRIGGER tr0_bi BEFORE INSERT ON t1 FOR EACH ROW PRECEDES tr1_bi SET @a:=0; CREATE TRIGGER tr1_1_bi BEFORE INSERT ON t1 FOR EACH ROW FOLLOWS tr1_bi SET @a:=0; # Expected order of triggers in the dump is: tr0_bi, tr1_bi, tr1_1_bi, tr2_i. +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( diff --git a/mysql-test/main/type_decimal.result b/mysql-test/main/type_decimal.result index b2853f18f1c..e219124a8cf 100644 --- a/mysql-test/main/type_decimal.result +++ b/mysql-test/main/type_decimal.result @@ -1323,3 +1323,176 @@ SET sql_mode=DEFAULT; # # End of 10.4 tests # +# +# Start of 10.11 tests +# +# +# MDEV-33442 REPAIR TABLE corrupts UUIDs +# +CREATE PROCEDURE show_table() +BEGIN +SHOW CREATE TABLE t1; +SELECT VERSION FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; +SELECT * FROM t1 ORDER BY a; +END; +$$ +# Upgrade using REPAIR +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(10,2)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +9 +a +123.45 +123.46 +123.47 +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check error Upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(10,2)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +9 +a +123.45 +123.46 +123.47 +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check error Upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(10,2)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +9 +a +123.45 +123.46 +123.47 +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +# Expect old decimal, as it does not implicitly upgrade to new decimal +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(10,2)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a +123.45 +123.46 +123.47 +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check status OK +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(10,2)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a +123.45 +123.46 +123.47 +DROP TABLE t1; +# Upgrade using ALTER, adding a table COMMENT +# Upgrade a 10.11.4 table using ALTER, adding a table COMMENT +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(10,2)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +9 +a +123.45 +123.46 +123.47 +# ALTER..INPLACE should fail - the FRM file is too old and needs upgrade +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, COMMENT 'test10'; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +ALTER IGNORE TABLE t1 COMMENT 'test11'; +# Expect old decimal, as it does not implicitly upgrade to new decimal +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(10,2)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci COMMENT='test11' +VERSION +10 +a +123.45 +123.46 +123.47 +# Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, COMMENT 'test12'; +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(10,2)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci COMMENT='test12' +VERSION +10 +a +123.45 +123.46 +123.47 +DROP TABLE t1; +# Upgrade using ALTER, adding a column DEFAULT +# Upgrade a 10.11.4 table using ALTER, adding a table COMMENT +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(10,2)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +9 +a +123.45 +123.46 +123.47 +# ALTER..INPLACE should fail - the FRM file is too old and needs upgrade +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, MODIFY a DECIMAL(10,2) DEFAULT 10; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +ALTER IGNORE TABLE t1 MODIFY a DECIMAL(10,2) DEFAULT 11; +# Expect new decimal, as we explicitly redefined the data type +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(10,2) DEFAULT 11.00 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a +123.45 +123.46 +123.47 +# Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, MODIFY a DECIMAL(10,2) DEFAULT 12; +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(10,2) DEFAULT 12.00 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a +123.45 +123.46 +123.47 +DROP TABLE t1; +DROP PROCEDURE show_table; +# +# End of 10.11 tests +# diff --git a/mysql-test/main/type_decimal.test b/mysql-test/main/type_decimal.test index 9e294410a38..5f02d16e4ad 100644 --- a/mysql-test/main/type_decimal.test +++ b/mysql-test/main/type_decimal.test @@ -826,3 +826,93 @@ SET sql_mode=DEFAULT; --echo # --echo # End of 10.4 tests --echo # + +--echo # +--echo # Start of 10.11 tests +--echo # + +--echo # +--echo # MDEV-33442 REPAIR TABLE corrupts UUIDs +--echo # + +DELIMITER $$; +CREATE PROCEDURE show_table() +BEGIN + SHOW CREATE TABLE t1; + SELECT VERSION FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; + SELECT * FROM t1 ORDER BY a; +END; +$$ +DELIMITER ;$$ + +--echo # Upgrade using REPAIR + +--copy_file std_data/old_decimal/t1dec102.frm $MYSQLD_DATADIR/test/t1.frm +--copy_file std_data/old_decimal/t1dec102.MYD $MYSQLD_DATADIR/test/t1.MYD +--copy_file std_data/old_decimal/t1dec102.MYI $MYSQLD_DATADIR/test/t1.MYI +CALL show_table; + +CHECK TABLE t1 FOR UPGRADE; +CALL show_table; + +CHECK TABLE t1 FOR UPGRADE; +CALL show_table; + +REPAIR TABLE t1; +--echo # Expect old decimal, as it does not implicitly upgrade to new decimal +CALL show_table; + +CHECK TABLE t1 FOR UPGRADE; +CALL show_table; +DROP TABLE t1; + + +--echo # Upgrade using ALTER, adding a table COMMENT + +--echo # Upgrade a 10.11.4 table using ALTER, adding a table COMMENT +--copy_file std_data/old_decimal/t1dec102.frm $MYSQLD_DATADIR/test/t1.frm +--copy_file std_data/old_decimal/t1dec102.MYD $MYSQLD_DATADIR/test/t1.MYD +--copy_file std_data/old_decimal/t1dec102.MYI $MYSQLD_DATADIR/test/t1.MYI +CALL show_table; + +--echo # ALTER..INPLACE should fail - the FRM file is too old and needs upgrade +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, COMMENT 'test10'; +ALTER IGNORE TABLE t1 COMMENT 'test11'; +-- echo # Expect old decimal, as it does not implicitly upgrade to new decimal +CALL show_table; + +--echo # Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, COMMENT 'test12'; +CALL show_table; + +DROP TABLE t1; + + +--echo # Upgrade using ALTER, adding a column DEFAULT + +--echo # Upgrade a 10.11.4 table using ALTER, adding a table COMMENT +--copy_file std_data/old_decimal/t1dec102.frm $MYSQLD_DATADIR/test/t1.frm +--copy_file std_data/old_decimal/t1dec102.MYD $MYSQLD_DATADIR/test/t1.MYD +--copy_file std_data/old_decimal/t1dec102.MYI $MYSQLD_DATADIR/test/t1.MYI +CALL show_table; + +--echo # ALTER..INPLACE should fail - the FRM file is too old and needs upgrade +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, MODIFY a DECIMAL(10,2) DEFAULT 10; +ALTER IGNORE TABLE t1 MODIFY a DECIMAL(10,2) DEFAULT 11; +--echo # Expect new decimal, as we explicitly redefined the data type +CALL show_table; + +--echo # Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, MODIFY a DECIMAL(10,2) DEFAULT 12; +CALL show_table; + +DROP TABLE t1; + +DROP PROCEDURE show_table; + + +--echo # +--echo # End of 10.11 tests +--echo # diff --git a/mysql-test/main/type_json.result b/mysql-test/main/type_json.result index 431a7f138f6..91686704ebd 100644 --- a/mysql-test/main/type_json.result +++ b/mysql-test/main/type_json.result @@ -155,7 +155,7 @@ DROP TABLE t1; # SELECT json_object('a', (SELECT json_objectagg(b, c) FROM (SELECT 'b','c') d)) AS j FROM DUAL; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def j 250 (format=json) 9437283 16 Y 0 39 33 +def j 250 (format=json) 9437310 16 Y 0 39 33 j {"a": {"b":"c"}} # diff --git a/mysql-test/main/type_timestamp.result b/mysql-test/main/type_timestamp.result index 2e797cb2b42..a378ab808d2 100644 --- a/mysql-test/main/type_timestamp.result +++ b/mysql-test/main/type_timestamp.result @@ -1904,6 +1904,122 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci drop table t1; # +# MDEV-34069 Zero datetime reinterprets as '1970-01-01 00:00:00' on field_datetime=field_timestamp +# +SET sql_mode=''; +SET time_zone='+00:00'; +CREATE TABLE t1 (a TIMESTAMP); +INSERT INTO t1 VALUES ('0000-00-00 00:00:00'); +SELECT * FROM t1; +a +0000-00-00 00:00:00 +CREATE TABLE t2 (a DATETIME); +INSERT INTO t2 SELECT a FROM t1; +SELECT * FROM t2; +a +0000-00-00 00:00:00 +SET sql_mode='NO_ZERO_DATE,NO_ZERO_IN_DATE'; +INSERT INTO t2 VALUES ('0000-00-00 00:00:00'); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +INSERT INTO t2 SELECT a FROM t1; +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +SELECT * FROM t2; +a +0000-00-00 00:00:00 +0000-00-00 00:00:00 +0000-00-00 00:00:00 +DROP TABLE t2, t1; +SET time_zone=DEFAULT; +SET sql_mode=DEFAULT; +# +# MDEV-34061 unix_timestamp(coalesce(timestamp_column)) returns NULL on '1970-01-01 00:00:00.000001' +# +SET time_zone='+00:00'; +CREATE TABLE t1 (a TIMESTAMP(6) NULL); +INSERT INTO t1 VALUES ('1970-01-01 00:00:00.000001'); +SELECT unix_timestamp(a) AS c1, unix_timestamp(coalesce(a)) AS c2 FROM t1; +c1 c2 +0.000001 0.000001 +DROP TABLE t1; +SET time_zone=DEFAULT; +# +# MDEV-34088 The TIMESTAMP value of '1970-01-01 00:00:00' can be indirectly inserted in strict mode +# +SET sql_mode='STRICT_TRANS_TABLES,STRICT_ALL_TABLES'; +SET time_zone='+00:00'; +CREATE TABLE t1 (a TIMESTAMP); +INSERT INTO t1 VALUES ('1970-01-01 00:00:00'); +ERROR 22007: Incorrect datetime value: '1970-01-01 00:00:00' for column `test`.`t1`.`a` at row 1 +INSERT INTO t1 VALUES ('1970-01-01 00:00:00.1'); +ERROR 22007: Incorrect datetime value: '1970-01-01 00:00:00.1' for column `test`.`t1`.`a` at row 1 +CREATE TABLE t2 (a TIMESTAMP(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('1970-01-01 00:00:00.1'); +INSERT INTO t1 SELECT a FROM t2; +ERROR 22007: Incorrect datetime value: '1970-01-01 00:00:00 +00:00' for column `test`.`t1`.`a` at row 1 +DROP TABLE t2; +DROP TABLE t1; +SET sql_mode=DEFAULT; +SET sql_mode='STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE'; +SET time_zone='+00:00'; +CREATE TABLE t1 (a TIMESTAMP); +INSERT INTO t1 VALUES ('1970-01-01 00:00:00'); +ERROR 22007: Incorrect datetime value: '1970-01-01 00:00:00' for column `test`.`t1`.`a` at row 1 +INSERT INTO t1 VALUES ('1970-01-01 00:00:00.1'); +ERROR 22007: Incorrect datetime value: '1970-01-01 00:00:00.1' for column `test`.`t1`.`a` at row 1 +CREATE TABLE t2 (a TIMESTAMP(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('1970-01-01 00:00:00.1'); +INSERT INTO t1 SELECT a FROM t2; +ERROR 22007: Incorrect datetime value: '1970-01-01 00:00:00 +00:00' for column `test`.`t1`.`a` at row 1 +DROP TABLE t2; +DROP TABLE t1; +SET sql_mode=DEFAULT; +SET sql_mode=''; +SET time_zone='+00:00'; +CREATE TABLE t1 (a TIMESTAMP); +INSERT INTO t1 VALUES ('1970-01-01 00:00:00'); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +INSERT INTO t1 VALUES ('1970-01-01 00:00:00.1'); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +CREATE TABLE t2 (a TIMESTAMP(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('1970-01-01 00:00:00.1'); +INSERT INTO t1 SELECT a FROM t2; +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t2; +SELECT * FROM t1; +a +0000-00-00 00:00:00 +0000-00-00 00:00:00 +0000-00-00 00:00:00 +DROP TABLE t1; +SET sql_mode=DEFAULT; +SET sql_mode='NO_ZERO_DATE,NO_ZERO_IN_DATE'; +SET time_zone='+00:00'; +CREATE TABLE t1 (a TIMESTAMP); +INSERT INTO t1 VALUES ('1970-01-01 00:00:00'); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +INSERT INTO t1 VALUES ('1970-01-01 00:00:00.1'); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +CREATE TABLE t2 (a TIMESTAMP(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('1970-01-01 00:00:00.1'); +INSERT INTO t1 SELECT a FROM t2; +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t2; +SELECT * FROM t1; +a +0000-00-00 00:00:00 +0000-00-00 00:00:00 +0000-00-00 00:00:00 +DROP TABLE t1; +SET sql_mode=DEFAULT; +# # End of 10.5 tests # # diff --git a/mysql-test/main/type_timestamp.test b/mysql-test/main/type_timestamp.test index 1b362251d76..56f02c750d8 100644 --- a/mysql-test/main/type_timestamp.test +++ b/mysql-test/main/type_timestamp.test @@ -1160,6 +1160,98 @@ create table t1 (f1 timestamp, f2 timestamp); show create table t1; drop table t1; +--echo # +--echo # MDEV-34069 Zero datetime reinterprets as '1970-01-01 00:00:00' on field_datetime=field_timestamp +--echo # + +SET sql_mode=''; +SET time_zone='+00:00'; +CREATE TABLE t1 (a TIMESTAMP); +INSERT INTO t1 VALUES ('0000-00-00 00:00:00'); +SELECT * FROM t1; +CREATE TABLE t2 (a DATETIME); +INSERT INTO t2 SELECT a FROM t1; +SELECT * FROM t2; +SET sql_mode='NO_ZERO_DATE,NO_ZERO_IN_DATE'; +INSERT INTO t2 VALUES ('0000-00-00 00:00:00'); +INSERT INTO t2 SELECT a FROM t1; +SELECT * FROM t2; +DROP TABLE t2, t1; +SET time_zone=DEFAULT; +SET sql_mode=DEFAULT; + +--echo # +--echo # MDEV-34061 unix_timestamp(coalesce(timestamp_column)) returns NULL on '1970-01-01 00:00:00.000001' +--echo # + +SET time_zone='+00:00'; +CREATE TABLE t1 (a TIMESTAMP(6) NULL); +INSERT INTO t1 VALUES ('1970-01-01 00:00:00.000001'); +SELECT unix_timestamp(a) AS c1, unix_timestamp(coalesce(a)) AS c2 FROM t1; +DROP TABLE t1; +SET time_zone=DEFAULT; + +--echo # +--echo # MDEV-34088 The TIMESTAMP value of '1970-01-01 00:00:00' can be indirectly inserted in strict mode +--echo # + +SET sql_mode='STRICT_TRANS_TABLES,STRICT_ALL_TABLES'; +SET time_zone='+00:00'; +CREATE TABLE t1 (a TIMESTAMP); +--error ER_TRUNCATED_WRONG_VALUE +INSERT INTO t1 VALUES ('1970-01-01 00:00:00'); +--error ER_TRUNCATED_WRONG_VALUE +INSERT INTO t1 VALUES ('1970-01-01 00:00:00.1'); +CREATE TABLE t2 (a TIMESTAMP(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('1970-01-01 00:00:00.1'); +--error ER_TRUNCATED_WRONG_VALUE +INSERT INTO t1 SELECT a FROM t2; +DROP TABLE t2; +DROP TABLE t1; +SET sql_mode=DEFAULT; + + +SET sql_mode='STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE'; +SET time_zone='+00:00'; +CREATE TABLE t1 (a TIMESTAMP); +--error ER_TRUNCATED_WRONG_VALUE +INSERT INTO t1 VALUES ('1970-01-01 00:00:00'); +--error ER_TRUNCATED_WRONG_VALUE +INSERT INTO t1 VALUES ('1970-01-01 00:00:00.1'); +CREATE TABLE t2 (a TIMESTAMP(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('1970-01-01 00:00:00.1'); +--error ER_TRUNCATED_WRONG_VALUE +INSERT INTO t1 SELECT a FROM t2; +DROP TABLE t2; +DROP TABLE t1; +SET sql_mode=DEFAULT; + +SET sql_mode=''; +SET time_zone='+00:00'; +CREATE TABLE t1 (a TIMESTAMP); +INSERT INTO t1 VALUES ('1970-01-01 00:00:00'); +INSERT INTO t1 VALUES ('1970-01-01 00:00:00.1'); +CREATE TABLE t2 (a TIMESTAMP(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('1970-01-01 00:00:00.1'); +INSERT INTO t1 SELECT a FROM t2; +DROP TABLE t2; +SELECT * FROM t1; +DROP TABLE t1; +SET sql_mode=DEFAULT; + +SET sql_mode='NO_ZERO_DATE,NO_ZERO_IN_DATE'; +SET time_zone='+00:00'; +CREATE TABLE t1 (a TIMESTAMP); +INSERT INTO t1 VALUES ('1970-01-01 00:00:00'); +INSERT INTO t1 VALUES ('1970-01-01 00:00:00.1'); +CREATE TABLE t2 (a TIMESTAMP(1)) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('1970-01-01 00:00:00.1'); +INSERT INTO t1 SELECT a FROM t2; +DROP TABLE t2; +SELECT * FROM t1; +DROP TABLE t1; +SET sql_mode=DEFAULT; + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/type_varchar_mysql41.result b/mysql-test/main/type_varchar_mysql41.result index cc7f663d709..eb8bafe0f36 100644 --- a/mysql-test/main/type_varchar_mysql41.result +++ b/mysql-test/main/type_varchar_mysql41.result @@ -111,3 +111,152 @@ t2 CREATE TABLE `t2` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci DROP TABLE t1old; DROP PROCEDURE p1; +# +# Start of 10.11 tests +# +# +# MDEV-33442 REPAIR TABLE corrupts UUIDs +# +CREATE PROCEDURE show_table() +BEGIN +SHOW CREATE TABLE t1; +SELECT VERSION FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; +SELECT * FROM t1 ORDER BY a,b; +END; +$$ +# Upgrade using REPAIR +TRUNCATE TABLE t1; +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255)/*old*/ DEFAULT NULL, + `b` varchar(255)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +9 +a b +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check error Upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255)/*old*/ DEFAULT NULL, + `b` varchar(255)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +9 +a b +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check error Upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255)/*old*/ DEFAULT NULL, + `b` varchar(255)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +9 +a b +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255) DEFAULT NULL, + `b` varchar(255) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check status OK +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255) DEFAULT NULL, + `b` varchar(255) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +DROP TABLE t1; +# Upgrade using ALTER, adding a table COMMENT +TRUNCATE TABLE t1; +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255)/*old*/ DEFAULT NULL, + `b` varchar(255)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +9 +a b +# ALTER..INPLACE should fail - the old columns need upgrade +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, COMMENT 'test10'; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +ALTER IGNORE TABLE t1 COMMENT 'test11'; +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255) DEFAULT NULL, + `b` varchar(255) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci COMMENT='test11' +VERSION +10 +a b +# Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, COMMENT 'test12'; +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255) DEFAULT NULL, + `b` varchar(255) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci COMMENT='test12' +VERSION +10 +a b +DROP TABLE t1; +# Upgrade using ALTER, adding a column DEFAULT +TRUNCATE TABLE t1; +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255)/*old*/ DEFAULT NULL, + `b` varchar(255)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +9 +a b +# ALTER..INPLACE should fail - the old columns need upgrade +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, MODIFY a VARBINARY(255) DEFAULT 'a10'; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +ALTER IGNORE TABLE t1 MODIFY a VARBINARY(255) DEFAULT 'a11'; +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255) DEFAULT 'a11', + `b` varchar(255) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +# Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 MODIFY a VARBINARY(255) DEFAULT 'a12'; +CALL show_table; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255) DEFAULT 'a12', + `b` varchar(255) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +DROP TABLE t1; +DROP PROCEDURE show_table; +# +# End of 10.11 tests +# diff --git a/mysql-test/main/type_varchar_mysql41.test b/mysql-test/main/type_varchar_mysql41.test index 5624e9edaaa..c963d3a3bb4 100644 --- a/mysql-test/main/type_varchar_mysql41.test +++ b/mysql-test/main/type_varchar_mysql41.test @@ -57,3 +57,88 @@ CALL p1('a'); DROP TABLE t1old; DROP PROCEDURE p1; + +--echo # +--echo # Start of 10.11 tests +--echo # + +--echo # +--echo # MDEV-33442 REPAIR TABLE corrupts UUIDs +--echo # + +DELIMITER $$; +CREATE PROCEDURE show_table() +BEGIN + SHOW CREATE TABLE t1; + SELECT VERSION FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; + SELECT * FROM t1 ORDER BY a,b; +END; +$$ +DELIMITER ;$$ + + +--echo # Upgrade using REPAIR + +--copy_file $MYSQL_TEST_DIR/std_data/bug19371.frm $MYSQLD_DATADIR/test/t1.frm +TRUNCATE TABLE t1; +CALL show_table; + +CHECK TABLE t1 FOR UPGRADE; +CALL show_table; + +CHECK TABLE t1 FOR UPGRADE; +CALL show_table; + +REPAIR TABLE t1; +CALL show_table; + +CHECK TABLE t1 FOR UPGRADE; +CALL show_table; + +DROP TABLE t1; + + +--echo # Upgrade using ALTER, adding a table COMMENT + +--copy_file $MYSQL_TEST_DIR/std_data/bug19371.frm $MYSQLD_DATADIR/test/t1.frm +TRUNCATE TABLE t1; +CALL show_table; + +--echo # ALTER..INPLACE should fail - the old columns need upgrade +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, COMMENT 'test10'; +ALTER IGNORE TABLE t1 COMMENT 'test11'; +CALL show_table; + +--echo # Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, COMMENT 'test12'; +CALL show_table; + +DROP TABLE t1; + + +--echo # Upgrade using ALTER, adding a column DEFAULT + +--copy_file $MYSQL_TEST_DIR/std_data/bug19371.frm $MYSQLD_DATADIR/test/t1.frm +TRUNCATE TABLE t1; +CALL show_table; + +--echo # ALTER..INPLACE should fail - the old columns need upgrade +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, MODIFY a VARBINARY(255) DEFAULT 'a10'; +ALTER IGNORE TABLE t1 MODIFY a VARBINARY(255) DEFAULT 'a11'; +CALL show_table; + +--echo # Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 MODIFY a VARBINARY(255) DEFAULT 'a12'; +CALL show_table; + +DROP TABLE t1; + + +DROP PROCEDURE show_table; + + +--echo # +--echo # End of 10.11 tests +--echo # diff --git a/mysql-test/main/udf.result b/mysql-test/main/udf.result index 8dc24a8dd38..53abd9c11c1 100644 --- a/mysql-test/main/udf.result +++ b/mysql-test/main/udf.result @@ -607,4 +607,68 @@ drop table t1; DROP FUNCTION avgcost; DROP FUNCTION avg2; DROP FUNCTION myfunc_double; +# +# MDEV-24507: Server Crash using UDF in WHERE clause of VIEW +# +CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB"; +create table t1(pk int primary key, a varchar(20)); +create table t2(pk int primary key, a varchar(20)); +create view v1 as select pk, a from t1 union select pk, a from t2; +insert into t1 values (1, "One"), (3, "Three"), (5, "Five"); +insert into t2 values (2, "Dos"), (4, "Quatro"), (6, "Seis"); +select pk, myfunc_int(a) from t1; +pk myfunc_int(a) +1 3 +3 5 +5 4 +select pk, myfunc_int(a) from t2; +pk myfunc_int(a) +2 3 +4 6 +6 4 +select pk, myfunc_int(a) from v1; +pk myfunc_int(a) +1 3 +3 5 +5 4 +2 3 +4 6 +6 4 +select pk from t1 where myfunc_int(a) > 4; +pk +3 +select pk from (select pk, a from t1) A where myfunc_int(A.a) > 4; +pk +3 +set @save_optimizer_switch = @@optimizer_switch; +set optimizer_switch = 'derived_merge=OFF'; +select pk, myfunc_int(a) from t1; +pk myfunc_int(a) +1 3 +3 5 +5 4 +select pk, myfunc_int(a) from t2; +pk myfunc_int(a) +2 3 +4 6 +6 4 +select pk, myfunc_int(a) from v1; +pk myfunc_int(a) +1 3 +3 5 +5 4 +2 3 +4 6 +6 4 +select pk from t1 where myfunc_int(a) > 4; +pk +3 +select pk from (select pk, a from t1) A where myfunc_int(A.a) > 4; +pk +3 +set optimizer_switch = @save_optimizer_switch; +drop view v1; +drop table t2; +drop table t1; +drop function myfunc_int; # End of 10.4 tests diff --git a/mysql-test/main/udf.test b/mysql-test/main/udf.test index e9823a31863..d87d446f733 100644 --- a/mysql-test/main/udf.test +++ b/mysql-test/main/udf.test @@ -647,4 +647,38 @@ DROP FUNCTION avgcost; DROP FUNCTION avg2; DROP FUNCTION myfunc_double; +--echo # +--echo # MDEV-24507: Server Crash using UDF in WHERE clause of VIEW +--echo # + +--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB +eval CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_SO"; + +create table t1(pk int primary key, a varchar(20)); +create table t2(pk int primary key, a varchar(20)); +create view v1 as select pk, a from t1 union select pk, a from t2; + +insert into t1 values (1, "One"), (3, "Three"), (5, "Five"); +insert into t2 values (2, "Dos"), (4, "Quatro"), (6, "Seis"); + +select pk, myfunc_int(a) from t1; +select pk, myfunc_int(a) from t2; +select pk, myfunc_int(a) from v1; +select pk from t1 where myfunc_int(a) > 4; +select pk from (select pk, a from t1) A where myfunc_int(A.a) > 4; + +set @save_optimizer_switch = @@optimizer_switch; +set optimizer_switch = 'derived_merge=OFF'; +select pk, myfunc_int(a) from t1; +select pk, myfunc_int(a) from t2; +select pk, myfunc_int(a) from v1; +select pk from t1 where myfunc_int(a) > 4; +select pk from (select pk, a from t1) A where myfunc_int(A.a) > 4; + +set optimizer_switch = @save_optimizer_switch; +drop view v1; +drop table t2; +drop table t1; +drop function myfunc_int; + --echo # End of 10.4 tests diff --git a/mysql-test/main/update_innodb.result b/mysql-test/main/update_innodb.result index beab54833d1..fbcbf78d865 100644 --- a/mysql-test/main/update_innodb.result +++ b/mysql-test/main/update_innodb.result @@ -143,3 +143,111 @@ connection default; disconnect con2; drop table t1,t2; # End of 10.4 tests +# +# MDEV-33533: multi-delete using rowid filter +# +set @save_default_storage_engine=@@default_storage_engine; +set default_storage_engine=InnoDB; +CREATE DATABASE dbt3_s001; +use dbt3_s001; +create index i_n_name on nation(n_name); +analyze table +nation, lineitem, customer, orders, part, supplier, partsupp, region +persistent for all; +Table Op Msg_type Msg_text +dbt3_s001.nation analyze status Engine-independent statistics collected +dbt3_s001.nation analyze status OK +dbt3_s001.lineitem analyze status Engine-independent statistics collected +dbt3_s001.lineitem analyze status OK +dbt3_s001.customer analyze status Engine-independent statistics collected +dbt3_s001.customer analyze status OK +dbt3_s001.orders analyze status Engine-independent statistics collected +dbt3_s001.orders analyze status OK +dbt3_s001.part analyze status Engine-independent statistics collected +dbt3_s001.part analyze status OK +dbt3_s001.supplier analyze status Engine-independent statistics collected +dbt3_s001.supplier analyze status OK +dbt3_s001.partsupp analyze status Engine-independent statistics collected +dbt3_s001.partsupp analyze status OK +dbt3_s001.region analyze status Engine-independent statistics collected +dbt3_s001.region analyze status OK +explain +update orders, customer, nation set orders.o_comment = "+++" where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and c_nationkey = n_nationkey and n_name='PERU'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE nation ref PRIMARY,i_n_name i_n_name 26 const 1 Using where; Using index +1 SIMPLE customer ref PRIMARY,i_c_nationkey i_c_nationkey 5 dbt3_s001.nation.n_nationkey 6 Using index +1 SIMPLE orders ref|filter i_o_orderdate,i_o_custkey i_o_custkey|i_o_orderdate 5|4 dbt3_s001.customer.c_custkey 15 (8%) Using where; Using rowid filter +explain format=json +update orders, customer, nation set orders.o_comment = "+++" where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and c_nationkey = n_nationkey and n_name='PERU'; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": "COST_REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "nation", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_n_name"], + "key": "i_n_name", + "key_length": "26", + "used_key_parts": ["n_name"], + "ref": ["const"], + "loops": 1, + "rows": 1, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "nation.n_name = 'PERU'", + "using_index": true + } + }, + { + "table": { + "table_name": "customer", + "access_type": "ref", + "possible_keys": ["PRIMARY", "i_c_nationkey"], + "key": "i_c_nationkey", + "key_length": "5", + "used_key_parts": ["c_nationkey"], + "ref": ["dbt3_s001.nation.n_nationkey"], + "loops": 1, + "rows": 6, + "cost": "COST_REPLACED", + "filtered": 100, + "using_index": true + } + }, + { + "table": { + "table_name": "orders", + "access_type": "ref", + "possible_keys": ["i_o_orderdate", "i_o_custkey"], + "key": "i_o_custkey", + "key_length": "5", + "used_key_parts": ["o_custkey"], + "ref": ["dbt3_s001.customer.c_custkey"], + "rowid_filter": { + "range": { + "key": "i_o_orderdate", + "used_key_parts": ["o_orderDATE"] + }, + "rows": 119, + "selectivity_pct": 7.933333333 + }, + "loops": 6, + "rows": 15, + "cost": "COST_REPLACED", + "filtered": 7.933333397, + "attached_condition": "orders.o_orderDATE between '1992-01-01' and '1992-06-30'" + } + } + ] + } +} +update orders, customer, nation set orders.o_comment = "+++" where o_orderDATE between '1992-01-01' and '1992-06-30' and +o_custkey = c_custkey and c_nationkey = n_nationkey and n_name='PERU'; +DROP DATABASE dbt3_s001; +set default_storage_engine=@save_default_storage_engine; diff --git a/mysql-test/main/update_innodb.test b/mysql-test/main/update_innodb.test index c213ba8b331..ad728fb8e28 100644 --- a/mysql-test/main/update_innodb.test +++ b/mysql-test/main/update_innodb.test @@ -162,3 +162,50 @@ drop table t1,t2; --enable_view_protocol --echo # End of 10.4 tests + +--echo # +--echo # MDEV-33533: multi-delete using rowid filter +--echo # + +set @save_default_storage_engine=@@default_storage_engine; +set default_storage_engine=InnoDB; + +CREATE DATABASE dbt3_s001; + +use dbt3_s001; + +--disable_query_log +--disable_result_log +--disable_warnings +--source include/dbt3_s001.inc +--enable_warnings +--enable_result_log +--enable_query_log + +create index i_n_name on nation(n_name); +analyze table + nation, lineitem, customer, orders, part, supplier, partsupp, region +persistent for all; + +let $c1= + o_orderDATE between '1992-01-01' and '1992-06-30' and + o_custkey = c_custkey and + c_nationkey = n_nationkey and + n_name='PERU'; + + +explain +update orders, customer, nation set orders.o_comment = "+++" where o_orderDATE between '1992-01-01' and '1992-06-30' and + o_custkey = c_custkey and c_nationkey = n_nationkey and n_name='PERU'; +--source include/explain-no-costs.inc +explain format=json +update orders, customer, nation set orders.o_comment = "+++" where o_orderDATE between '1992-01-01' and '1992-06-30' and + o_custkey = c_custkey and c_nationkey = n_nationkey and n_name='PERU'; + +update orders, customer, nation set orders.o_comment = "+++" where o_orderDATE between '1992-01-01' and '1992-06-30' and + o_custkey = c_custkey and c_nationkey = n_nationkey and n_name='PERU'; + +DROP DATABASE dbt3_s001; + +set default_storage_engine=@save_default_storage_engine; + diff --git a/mysql-test/mariadb-test-run.pl b/mysql-test/mariadb-test-run.pl index 9d3991fad20..e2d3fa64c92 100755 --- a/mysql-test/mariadb-test-run.pl +++ b/mysql-test/mariadb-test-run.pl @@ -436,6 +436,10 @@ sub main { { $opt_parallel= $ENV{NUMBER_OF_PROCESSORS} || 1; } + elsif (IS_MAC) + { + $opt_parallel= `sysctl -n hw.ncpu`; + } else { my $sys_info= My::SysInfo->new(); @@ -3106,12 +3110,13 @@ sub mysql_install_db { # starting from 10.0 bootstrap scripts require InnoDB mtr_add_arg($args, "--loose-innodb"); mtr_add_arg($args, "--loose-innodb-log-file-size=10M"); + mtr_add_arg($args, "--loose-innodb-fast-shutdown=0"); mtr_add_arg($args, "--disable-sync-frm"); mtr_add_arg($args, "--tmpdir=%s", "$opt_vardir/tmp/"); mtr_add_arg($args, "--core-file"); mtr_add_arg($args, "--console"); mtr_add_arg($args, "--character-set-server=latin1"); - mtr_add_arg($args, "--disable-performance-schema"); + mtr_add_arg($args, "--loose-disable-performance-schema"); if ( $opt_debug ) { @@ -4496,6 +4501,14 @@ sub extract_warning_lines ($$) { qr/Slave I\/0: Master command COM_BINLOG_DUMP failed/, qr/Error reading packet/, qr/Lost connection to MariaDB server at 'reading initial communication packet'/, + qr/Could not read packet:.* state: [2-3] /, + qr/Could not read packet:.* errno: 104 /, + qr/Could not read packet:.* errno: 0 .* length: 0/, + qr/Could not write packet:.* errno: 32 /, + qr/Could not write packet:.* errno: 104 /, + qr/Semisync ack receiver got error 1158/, + qr/Semisync ack receiver got hangup/, + qr/Connection was killed/, qr/Failed on request_dump/, qr/Slave: Can't drop database.* database doesn't exist/, qr/Slave: Operation DROP USER failed for 'create_rout_db'/, @@ -4551,8 +4564,7 @@ sub extract_warning_lines ($$) { qr/WSREP: Failed to guess base node address/, qr/WSREP: Guessing address for incoming client/, - # for UBSAN - qr/decimal\.c.*: runtime error: signed integer overflow/, + qr/InnoDB: Difficult to find free blocks in the buffer pool*/, # Disable test for UBSAN on dynamically loaded objects qr/runtime error: member call.*object.*'Handler_share'/, qr/sql_type\.cc.* runtime error: member call.*object.* 'Type_collection'/, @@ -5713,6 +5725,8 @@ sub start_mysqltest ($) { mtr_add_arg($args, "--result-file=%s", $tinfo->{'result_file'}); } + mtr_add_arg($args, "--wait-for-pos-timeout=%d", $opt_debug_sync_timeout); + client_debug_arg($args, "mysqltest"); if ( $opt_record ) diff --git a/mysql-test/std_data/autoinc_import_101.frm b/mysql-test/std_data/autoinc_import_101.frm new file mode 100644 index 00000000000..b16ae91b110 Binary files /dev/null and b/mysql-test/std_data/autoinc_import_101.frm differ diff --git a/mysql-test/std_data/autoinc_import_57.frm b/mysql-test/std_data/autoinc_import_57.frm new file mode 100644 index 00000000000..a333931b97b Binary files /dev/null and b/mysql-test/std_data/autoinc_import_57.frm differ diff --git a/mysql-test/std_data/mdev-25731.dat b/mysql-test/std_data/mdev-25731.dat new file mode 100644 index 00000000000..e6c779a8292 --- /dev/null +++ b/mysql-test/std_data/mdev-25731.dat @@ -0,0 +1,6 @@ +1 +2 +3 +1 +5 +6 diff --git a/mysql-test/suite.pm b/mysql-test/suite.pm index 0c9c556417b..3e5e024ab88 100644 --- a/mysql-test/suite.pm +++ b/mysql-test/suite.pm @@ -4,14 +4,7 @@ use My::Platform; @ISA = qw(My::Suite); sub skip_combinations { - my @combinations; - - # disable innodb combinations for configurations that were not built - push @combinations, 'innodb_plugin' unless $ENV{HA_INNODB_SO}; - - push @combinations, 'innodb' unless $::mysqld_variables{'innodb'} eq "ON"; - - my %skip = ( 'include/have_innodb.combinations' => [ @combinations ]); + my %skip; $skip{'include/innodb_encrypt_log.combinations'} = [ 'crypt' ] unless $ENV{DEBUG_KEY_MANAGEMENT_SO}; diff --git a/mysql-test/suite/archive/archive.test b/mysql-test/suite/archive/archive.test index c968ed1e138..2319154cbd3 100644 --- a/mysql-test/suite/archive/archive.test +++ b/mysql-test/suite/archive/archive.test @@ -1610,7 +1610,7 @@ SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; INSERT INTO t1 VALUES(1, 'sampleblob1'),(2, 'sampleblob2'); # Compression length depends on zip library ---replace_result 583 584 291 292 +--replace_result 583 584 585 584 291 292 SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; DROP TABLE t1; diff --git a/mysql-test/suite/archive/archive_bitfield.result b/mysql-test/suite/archive/archive_bitfield.result index 8c30a5f88f6..8cb4190e842 100644 --- a/mysql-test/suite/archive/archive_bitfield.result +++ b/mysql-test/suite/archive/archive_bitfield.result @@ -180,6 +180,7 @@ INSERT INTO `t1` VALUES (NULL,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'100000',b'010010',b'011111',4,5,5,5,5,5,5,5,5,5,3,2,1), (NULL,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'000000',b'001100',b'111111',4,5,5,5,5,5,5,5,5,5,3,2,1), (NULL,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'111111',b'000000',b'000000',4,5,5,5,5,5,5,5,5,5,3,2,1); +/*!999999\- enable the sandbox mode */ INSERT INTO `t1` VALUES (1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x01,0x3F,0x3E,4,5,5,5,5,5,5,5,5,5,3,2,1); INSERT INTO `t1` VALUES (2,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x02,0x00,0x3D,4,5,5,5,5,5,5,5,5,5,3,2,1); INSERT INTO `t1` VALUES (3,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x04,0x0F,0x3B,4,5,5,5,5,5,5,5,5,5,3,2,1); diff --git a/mysql-test/suite/atomic/alter_table.test b/mysql-test/suite/atomic/alter_table.test index 1f87b7e71b8..aa265c92b7e 100644 --- a/mysql-test/suite/atomic/alter_table.test +++ b/mysql-test/suite/atomic/alter_table.test @@ -1,7 +1,12 @@ --source include/have_debug.inc --source include/have_innodb.inc --source include/have_log_bin.inc ---source include/not_valgrind.inc + +if (!$BIG_TEST) +{ + --source include/not_valgrind.inc + --source include/not_msan.inc +} # # Testing of atomic create table with crashes in a lot of different places diff --git a/mysql-test/suite/binlog/include/binlog_index.inc b/mysql-test/suite/binlog/include/binlog_index.inc index da6cac18e30..69498f42b82 100644 --- a/mysql-test/suite/binlog/include/binlog_index.inc +++ b/mysql-test/suite/binlog/include/binlog_index.inc @@ -98,7 +98,7 @@ reset master; --echo # crash_purge_before_update_index flush logs; ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect SET SESSION debug_dbug="+d,crash_purge_before_update_index"; --source include/wait_for_binlog_checkpoint.inc --error 2013 @@ -119,7 +119,7 @@ SELECT @index; --echo # crash_purge_non_critical_after_update_index flush logs; ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect SET SESSION debug_dbug="+d,crash_purge_non_critical_after_update_index"; --source include/wait_for_binlog_checkpoint.inc --error 2013 @@ -143,7 +143,7 @@ SELECT @index; --echo # crash_purge_critical_after_update_index flush logs; ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect SET SESSION debug_dbug="+d,crash_purge_critical_after_update_index"; --source include/wait_for_binlog_checkpoint.inc --error 2013 @@ -167,7 +167,7 @@ file_exists $MYSQLD_DATADIR/master-bin.000008; SELECT @index; --echo # crash_create_non_critical_before_update_index ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect SET SESSION debug_dbug="+d,crash_create_non_critical_before_update_index"; --error 2013 flush logs; @@ -185,7 +185,7 @@ file_exists $MYSQLD_DATADIR/master-bin.000009; SELECT @index; --echo # crash_create_critical_before_update_index ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect SET SESSION debug_dbug="+d,crash_create_critical_before_update_index"; --error 2013 flush logs; @@ -205,7 +205,7 @@ file_exists $MYSQLD_DATADIR/master-bin.000011; SELECT @index; --echo # crash_create_after_update_index ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect SET SESSION debug_dbug="+d,crash_create_after_update_index"; --error 2013 flush logs; diff --git a/mysql-test/suite/binlog/include/print_optional_metadata.inc b/mysql-test/suite/binlog/include/print_optional_metadata.inc index 739903ab190..47feede80ec 100644 --- a/mysql-test/suite/binlog/include/print_optional_metadata.inc +++ b/mysql-test/suite/binlog/include/print_optional_metadata.inc @@ -16,10 +16,9 @@ if ($stop_position) --exec $MYSQL_BINLOG -F --print-table-metadata $_stop_position_opt $binlog_file > $output_file ---let SEARCH_PATTERN= # (?:Columns\(| {8}).* +--let SEARCH_PATTERN= (?m-s:# (?:Columns\(| {8}).*) --let SEARCH_FILE= $output_file --let SEARCH_OUTPUT=matches ---let SEARCH_TYPE="_gm_" --source include/search_pattern_in_file.inc if ($print_primary_key) diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result index 9ee854bd192..c0c6b7dbc7f 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result @@ -2461,7 +2461,10 @@ START TRANSACTION #Q> '', -- c76 #Q> # #Q> 'a', -- c77 -#Q> '', +#Q> '', -- c78 +#Q> # +#Q> 1 -- crn -- row number +#Q> ) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -2643,7 +2646,10 @@ START TRANSACTION #Q> 'longtext-ucs2', -- c76 not using maximum value here #Q> # #Q> 'c', -- c77 -#Q> 'a,b,c +#Q> 'a,b,c', -- c78 +#Q> # +#Q> 2 -- crn -- row number +#Q> ) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -2910,7 +2916,13 @@ START TRANSACTION #Q> 'mediumtext-ucs2', -- c73 #Q> 'longblob', -- c74 #Q> 'longtext', -- c75 -#Q> 'longtext +#Q> 'longtext-ucs2', -- c76 +#Q> # +#Q> 'b', -- c77 +#Q> 'b,c', -- c78 +#Q> # +#Q> 4 -- crn -- row number +#Q> ) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -3251,7 +3263,21 @@ START TRANSACTION #Q> # #Q> c65 = '' AND #Q> c66 = '' AND -#Q> c67 = +#Q> c67 = '' AND +#Q> c68 = '' AND +#Q> c69 = '' AND +#Q> c70 = '' AND +#Q> c71 = '' AND +#Q> c72 = '' AND +#Q> c73 = '' AND +#Q> c74 = '' AND +#Q> c75 = '' AND +#Q> c76 = '' AND +#Q> # +#Q> c77 = 'a' AND +#Q> c78 = '' AND +#Q> # +#Q> crn = 1 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Update_rows: table id # flags: STMT_END_F @@ -3596,7 +3622,17 @@ START TRANSACTION #Q> c68 = 'blob' AND #Q> c69 = 'text' AND #Q> c70 = 'text-ucs2' AND -#Q> c71 = 'mediumblob +#Q> c71 = 'mediumblob' AND +#Q> c72 = 'mediumtext' AND +#Q> c73 = 'mediumtext-ucs2' AND +#Q> c74 = 'longblob' AND +#Q> c75 = 'longtext' AND +#Q> c76 = 'longtext-ucs2' AND +#Q> # +#Q> c77 = 'c' AND +#Q> c78 = 'a,b,c' AND +#Q> # +#Q> crn = 2 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Update_rows: table id # flags: STMT_END_F @@ -3939,7 +3975,18 @@ START TRANSACTION #Q> c67 IS NULL AND #Q> c68 IS NULL AND #Q> c69 IS NULL AND -#Q> c70 IS NULL +#Q> c70 IS NULL AND +#Q> c71 IS NULL AND +#Q> c72 IS NULL AND +#Q> c73 IS NULL AND +#Q> c74 IS NULL AND +#Q> c75 IS NULL AND +#Q> c76 IS NULL AND +#Q> # +#Q> c77 IS NULL AND +#Q> c78 IS NULL AND +#Q> # +#Q> crn = 3 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Update_rows: table id # flags: STMT_END_F @@ -4285,7 +4332,16 @@ START TRANSACTION #Q> c69 = 'text' AND #Q> c70 = 'text-ucs2' AND #Q> c71 = 'mediumblob' AND -#Q> c72 = 'me +#Q> c72 = 'mediumtext' AND +#Q> c73 = 'mediumtext-ucs2' AND +#Q> c74 = 'longblob' AND +#Q> c75 = 'longtext' AND +#Q> c76 = 'longtext-ucs2' AND +#Q> # +#Q> c77 = 'b' AND +#Q> c78 = 'b,c' AND +#Q> # +#Q> crn = 4 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Update_rows: table id # flags: STMT_END_F @@ -4545,7 +4601,13 @@ START TRANSACTION #Q> c72 = 'mediumtext' AND #Q> c73 = 'mediumtext-ucs2' AND #Q> c74 = 'longblob' AND -#Q> c75 = ' +#Q> c75 = 'longtext' AND +#Q> c76 = 'longtext-ucs2' AND +#Q> # +#Q> c77 = 'c' AND +#Q> c78 = 'a,b,c' AND +#Q> # +#Q> crn = 1 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F @@ -4722,7 +4784,15 @@ START TRANSACTION #Q> c70 = '' AND #Q> c71 = '' AND #Q> c72 = '' AND -#Q> c73 = '' A +#Q> c73 = '' AND +#Q> c74 = '' AND +#Q> c75 = '' AND +#Q> c76 = '' AND +#Q> # +#Q> c77 = 'a' AND +#Q> c78 = '' AND +#Q> # +#Q> crn = 2 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F @@ -4902,7 +4972,13 @@ START TRANSACTION #Q> c72 = 'mediumtext' AND #Q> c73 = 'mediumtext-ucs2' AND #Q> c74 = 'longblob' AND -#Q> c75 = 'longtext' +#Q> c75 = 'longtext' AND +#Q> c76 = 'longtext-ucs2' AND +#Q> # +#Q> c77 = 'b' AND +#Q> c78 = 'b,c' AND +#Q> # +#Q> crn = 3 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F @@ -5080,7 +5156,14 @@ START TRANSACTION #Q> c71 IS NULL AND #Q> c72 IS NULL AND #Q> c73 IS NULL AND -#Q> c74 IS NUL +#Q> c74 IS NULL AND +#Q> c75 IS NULL AND +#Q> c76 IS NULL AND +#Q> # +#Q> c77 IS NULL AND +#Q> c78 IS NULL AND +#Q> # +#Q> crn = 4 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F @@ -5311,7 +5394,7 @@ START TRANSACTION #Q> ('2008-08-06','VARCHAR-06',6), #Q> ('2008-08-07','VARCHAR-07',7), #Q> ('2008-08-08','VARCHAR-08',8), -#Q> ('2008-08-09','VARCH +#Q> ('2008-08-09','VARCHAR-09',9) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -5738,7 +5821,7 @@ START TRANSACTION #Q> ('2008-01-06','VARCHAR-01-06',6), #Q> ('2008-01-07','VARCHAR-01-07',7), #Q> ('2008-01-08','VARCHAR-01-08',18), -#Q> ('2008-01-09','VARCHAR-0 +#Q> ('2008-01-09','VARCHAR-01-09',19) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -5808,7 +5891,7 @@ START TRANSACTION #Q> ('2008-02-06','VARCHAR-02-06',6), #Q> ('2008-02-07','VARCHAR-02-07',7), #Q> ('2008-02-08','VARCHAR-02-08',28), -#Q> ('2008-02-09','VARCHAR-0 +#Q> ('2008-02-09','VARCHAR-02-09',29) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t2` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -5878,7 +5961,7 @@ START TRANSACTION #Q> ('2008-03-06','VARCHAR-03-06',6), #Q> ('2008-03-07','VARCHAR-03-07',7), #Q> ('2008-03-08','VARCHAR-03-08',38), -#Q> ('2008-03-09','VARCHAR-0 +#Q> ('2008-03-09','VARCHAR-03-09',39) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t3` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -5943,7 +6026,7 @@ START TRANSACTION #Q> c_1_1 = ADDDATE(c_1_1,INTERVAL 10 YEAR), #Q> c_2_1 = ADDDATE(c_2_1,INTERVAL 20 YEAR), #Q> c_3_1 = ADDDATE(c_3_1,INTERVAL 30 YEAR) -#Q> WHERE c_1_n = c_2_n AND c_2_n = c +#Q> WHERE c_1_n = c_2_n AND c_2_n = c_3_n #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t2` mapped to number # @@ -6130,7 +6213,7 @@ START TRANSACTION # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows: #Q> DELETE FROM t1,t2,t3 USING t1 INNER JOIN t2 INNER JOIN t3 -#Q> WHERE c_1_n = c_2_n AND c_2_n = c_3_ +#Q> WHERE c_1_n = c_2_n AND c_2_n = c_3_n #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t2` mapped to number # @@ -6346,7 +6429,7 @@ START TRANSACTION #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows: #Q> LOAD DATA INFILE '../../std_data/loaddata5.dat' #Q> INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (c1,c2) -#Q> SET c3 = 'Wo +#Q> SET c3 = 'Wow' #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result index a20816e9c20..9186d065ac7 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result @@ -2459,7 +2459,10 @@ START TRANSACTION #Q> '', -- c76 #Q> # #Q> 'a', -- c77 -#Q> '', +#Q> '', -- c78 +#Q> # +#Q> 1 -- crn -- row number +#Q> ) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -2643,7 +2646,10 @@ START TRANSACTION #Q> 'longtext-ucs2', -- c76 not using maximum value here #Q> # #Q> 'c', -- c77 -#Q> 'a,b,c +#Q> 'a,b,c', -- c78 +#Q> # +#Q> 2 -- crn -- row number +#Q> ) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -2912,7 +2918,13 @@ START TRANSACTION #Q> 'mediumtext-ucs2', -- c73 #Q> 'longblob', -- c74 #Q> 'longtext', -- c75 -#Q> 'longtext +#Q> 'longtext-ucs2', -- c76 +#Q> # +#Q> 'b', -- c77 +#Q> 'b,c', -- c78 +#Q> # +#Q> 4 -- crn -- row number +#Q> ) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -3255,7 +3267,21 @@ START TRANSACTION #Q> # #Q> c65 = '' AND #Q> c66 = '' AND -#Q> c67 = +#Q> c67 = '' AND +#Q> c68 = '' AND +#Q> c69 = '' AND +#Q> c70 = '' AND +#Q> c71 = '' AND +#Q> c72 = '' AND +#Q> c73 = '' AND +#Q> c74 = '' AND +#Q> c75 = '' AND +#Q> c76 = '' AND +#Q> # +#Q> c77 = 'a' AND +#Q> c78 = '' AND +#Q> # +#Q> crn = 1 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Update_rows: table id # flags: STMT_END_F @@ -3602,7 +3628,17 @@ START TRANSACTION #Q> c68 = 'blob' AND #Q> c69 = 'text' AND #Q> c70 = 'text-ucs2' AND -#Q> c71 = 'mediumblob +#Q> c71 = 'mediumblob' AND +#Q> c72 = 'mediumtext' AND +#Q> c73 = 'mediumtext-ucs2' AND +#Q> c74 = 'longblob' AND +#Q> c75 = 'longtext' AND +#Q> c76 = 'longtext-ucs2' AND +#Q> # +#Q> c77 = 'c' AND +#Q> c78 = 'a,b,c' AND +#Q> # +#Q> crn = 2 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Update_rows: table id # flags: STMT_END_F @@ -3947,7 +3983,18 @@ START TRANSACTION #Q> c67 IS NULL AND #Q> c68 IS NULL AND #Q> c69 IS NULL AND -#Q> c70 IS NULL +#Q> c70 IS NULL AND +#Q> c71 IS NULL AND +#Q> c72 IS NULL AND +#Q> c73 IS NULL AND +#Q> c74 IS NULL AND +#Q> c75 IS NULL AND +#Q> c76 IS NULL AND +#Q> # +#Q> c77 IS NULL AND +#Q> c78 IS NULL AND +#Q> # +#Q> crn = 3 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Update_rows: table id # flags: STMT_END_F @@ -4295,7 +4342,16 @@ START TRANSACTION #Q> c69 = 'text' AND #Q> c70 = 'text-ucs2' AND #Q> c71 = 'mediumblob' AND -#Q> c72 = 'me +#Q> c72 = 'mediumtext' AND +#Q> c73 = 'mediumtext-ucs2' AND +#Q> c74 = 'longblob' AND +#Q> c75 = 'longtext' AND +#Q> c76 = 'longtext-ucs2' AND +#Q> # +#Q> c77 = 'b' AND +#Q> c78 = 'b,c' AND +#Q> # +#Q> crn = 4 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Update_rows: table id # flags: STMT_END_F @@ -4557,7 +4613,13 @@ START TRANSACTION #Q> c72 = 'mediumtext' AND #Q> c73 = 'mediumtext-ucs2' AND #Q> c74 = 'longblob' AND -#Q> c75 = ' +#Q> c75 = 'longtext' AND +#Q> c76 = 'longtext-ucs2' AND +#Q> # +#Q> c77 = 'c' AND +#Q> c78 = 'a,b,c' AND +#Q> # +#Q> crn = 1 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F @@ -4736,7 +4798,15 @@ START TRANSACTION #Q> c70 = '' AND #Q> c71 = '' AND #Q> c72 = '' AND -#Q> c73 = '' A +#Q> c73 = '' AND +#Q> c74 = '' AND +#Q> c75 = '' AND +#Q> c76 = '' AND +#Q> # +#Q> c77 = 'a' AND +#Q> c78 = '' AND +#Q> # +#Q> crn = 2 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F @@ -4918,7 +4988,13 @@ START TRANSACTION #Q> c72 = 'mediumtext' AND #Q> c73 = 'mediumtext-ucs2' AND #Q> c74 = 'longblob' AND -#Q> c75 = 'longtext' +#Q> c75 = 'longtext' AND +#Q> c76 = 'longtext-ucs2' AND +#Q> # +#Q> c77 = 'b' AND +#Q> c78 = 'b,c' AND +#Q> # +#Q> crn = 3 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F @@ -5098,7 +5174,14 @@ START TRANSACTION #Q> c71 IS NULL AND #Q> c72 IS NULL AND #Q> c73 IS NULL AND -#Q> c74 IS NUL +#Q> c74 IS NULL AND +#Q> c75 IS NULL AND +#Q> c76 IS NULL AND +#Q> # +#Q> c77 IS NULL AND +#Q> c78 IS NULL AND +#Q> # +#Q> crn = 4 #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F @@ -5331,7 +5414,7 @@ START TRANSACTION #Q> ('2008-08-06','VARCHAR-06',6), #Q> ('2008-08-07','VARCHAR-07',7), #Q> ('2008-08-08','VARCHAR-08',8), -#Q> ('2008-08-09','VARCH +#Q> ('2008-08-09','VARCHAR-09',9) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -5764,7 +5847,7 @@ START TRANSACTION #Q> ('2008-01-06','VARCHAR-01-06',6), #Q> ('2008-01-07','VARCHAR-01-07',7), #Q> ('2008-01-08','VARCHAR-01-08',18), -#Q> ('2008-01-09','VARCHAR-0 +#Q> ('2008-01-09','VARCHAR-01-09',19) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -5836,7 +5919,7 @@ START TRANSACTION #Q> ('2008-02-06','VARCHAR-02-06',6), #Q> ('2008-02-07','VARCHAR-02-07',7), #Q> ('2008-02-08','VARCHAR-02-08',28), -#Q> ('2008-02-09','VARCHAR-0 +#Q> ('2008-02-09','VARCHAR-02-09',29) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t2` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -5908,7 +5991,7 @@ START TRANSACTION #Q> ('2008-03-06','VARCHAR-03-06',6), #Q> ('2008-03-07','VARCHAR-03-07',7), #Q> ('2008-03-08','VARCHAR-03-08',38), -#Q> ('2008-03-09','VARCHAR-0 +#Q> ('2008-03-09','VARCHAR-03-09',39) #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t3` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -5975,7 +6058,7 @@ START TRANSACTION #Q> c_1_1 = ADDDATE(c_1_1,INTERVAL 10 YEAR), #Q> c_2_1 = ADDDATE(c_2_1,INTERVAL 20 YEAR), #Q> c_3_1 = ADDDATE(c_3_1,INTERVAL 30 YEAR) -#Q> WHERE c_1_n = c_2_n AND c_2_n = c +#Q> WHERE c_1_n = c_2_n AND c_2_n = c_3_n #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t2` mapped to number # @@ -6164,7 +6247,7 @@ START TRANSACTION # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows: #Q> DELETE FROM t1,t2,t3 USING t1 INNER JOIN t2 INNER JOIN t3 -#Q> WHERE c_1_n = c_2_n AND c_2_n = c_3_ +#Q> WHERE c_1_n = c_2_n AND c_2_n = c_3_n #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t2` mapped to number # @@ -6382,7 +6465,7 @@ START TRANSACTION #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows: #Q> LOAD DATA INFILE '../../std_data/loaddata5.dat' #Q> INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (c1,c2) -#Q> SET c3 = 'Wo +#Q> SET c3 = 'Wow' #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F diff --git a/mysql-test/suite/binlog/r/binlog_row_annotate.result b/mysql-test/suite/binlog/r/binlog_row_annotate.result index bb4d318bdd4..edf8f4e7f71 100644 --- a/mysql-test/suite/binlog/r/binlog_row_annotate.result +++ b/mysql-test/suite/binlog/r/binlog_row_annotate.result @@ -232,7 +232,7 @@ START TRANSACTION #010909 4:46:40 server id # end_log_pos # Annotate_rows: #Q> DELETE test1.t1, test2.t2 #Q> FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3 -#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3 +#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3.a #010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number # # at # #010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # @@ -301,7 +301,7 @@ START TRANSACTION #010909 4:46:40 server id # end_log_pos # Annotate_rows: #Q> DELETE xtest1.xt1, test2.t2 #Q> FROM xtest1.xt1 INNER JOIN test2.t2 INNER JOIN test3.t3 -#Q> WHERE xtest1.xt1.a=test2.t2.a AND test2.t2.a=test3.t3 +#Q> WHERE xtest1.xt1.a=test2.t2.a AND test2.t2.a=test3.t3.a #010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # # at # #010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F @@ -434,7 +434,7 @@ START TRANSACTION #010909 4:46:40 server id # end_log_pos # Annotate_rows: #Q> DELETE test1.t1, test2.t2 #Q> FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3 -#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3 +#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3.a #010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number # # at # # at # @@ -855,7 +855,7 @@ START TRANSACTION #010909 4:46:40 server id # end_log_pos # Annotate_rows: #Q> DELETE test1.t1, test2.t2 #Q> FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3 -#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3 +#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3.a #010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number # # at # #010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # @@ -924,7 +924,7 @@ START TRANSACTION #010909 4:46:40 server id # end_log_pos # Annotate_rows: #Q> DELETE xtest1.xt1, test2.t2 #Q> FROM xtest1.xt1 INNER JOIN test2.t2 INNER JOIN test3.t3 -#Q> WHERE xtest1.xt1.a=test2.t2.a AND test2.t2.a=test3.t3 +#Q> WHERE xtest1.xt1.a=test2.t2.a AND test2.t2.a=test3.t3.a #010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # # at # #010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F @@ -1057,7 +1057,7 @@ START TRANSACTION #010909 4:46:40 server id # end_log_pos # Annotate_rows: #Q> DELETE test1.t1, test2.t2 #Q> FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3 -#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3 +#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3.a #010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number # # at # # at # diff --git a/mysql-test/suite/binlog/r/binlog_row_img.result b/mysql-test/suite/binlog/r/binlog_row_img.result index ebd760dd767..b4c4f26e14c 100644 --- a/mysql-test/suite/binlog/r/binlog_row_img.result +++ b/mysql-test/suite/binlog/r/binlog_row_img.result @@ -28,7 +28,7 @@ START TRANSACTION /*!*/; #Q> INSERT INTO t1 VALUES(1, "insert_to_t1", 1, repeat('a', 20)), #Q> (2, "insert_to_t1", 2, repeat('a', 20)), -#Q> (3, "insert_to_t1", 3, repeat('a', 20 +#Q> (3, "insert_to_t1", 3, repeat('a', 20)) ### INSERT INTO `test`.`t1` ### SET ### @1=1 /* INT meta=0 nullable=0 is_null=0 */ @@ -182,7 +182,7 @@ START TRANSACTION /*!*/; #Q> INSERT INTO t2 VALUES(1, "insert_to_t2", 1, repeat('a', 20)), #Q> (2, "insert_to_t2", 2, repeat('a', 20)), -#Q> (3, "insert_to_t2", 3, repeat('a', 20 +#Q> (3, "insert_to_t2", 3, repeat('a', 20)) ### INSERT INTO `test`.`t2` ### SET ### @1=1 /* INT meta=0 nullable=1 is_null=0 */ @@ -370,7 +370,7 @@ START TRANSACTION /*!*/; #Q> INSERT INTO t1 VALUES(1, "insert_to_t1", 1, repeat('a', 20)), #Q> (2, "insert_to_t1", 2, repeat('a', 20)), -#Q> (3, "insert_to_t1", 3, repeat('a', 20 +#Q> (3, "insert_to_t1", 3, repeat('a', 20)) ### INSERT INTO `test`.`t1` ### SET ### @1=1 /* INT meta=0 nullable=0 is_null=0 */ @@ -494,7 +494,7 @@ START TRANSACTION /*!*/; #Q> INSERT INTO t2 VALUES(1, "insert_to_t2", 1, repeat('a', 20)), #Q> (2, "insert_to_t2", 2, repeat('a', 20)), -#Q> (3, "insert_to_t2", 3, repeat('a', 20 +#Q> (3, "insert_to_t2", 3, repeat('a', 20)) ### INSERT INTO `test`.`t2` ### SET ### @1=1 /* INT meta=0 nullable=1 is_null=0 */ @@ -682,7 +682,7 @@ START TRANSACTION /*!*/; #Q> INSERT INTO t1 VALUES(1, "insert_to_t1", 1, repeat('a', 20)), #Q> (2, "insert_to_t1", 2, repeat('a', 20)), -#Q> (3, "insert_to_t1", 3, repeat('a', 20 +#Q> (3, "insert_to_t1", 3, repeat('a', 20)) ### INSERT INTO `test`.`t1` ### SET ### @1=1 /* INT meta=0 nullable=0 is_null=0 */ @@ -842,7 +842,7 @@ START TRANSACTION /*!*/; #Q> INSERT INTO t2 VALUES(1, "insert_to_t2", 1, repeat('a', 20)), #Q> (2, "insert_to_t2", 2, repeat('a', 20)), -#Q> (3, "insert_to_t2", 3, repeat('a', 20 +#Q> (3, "insert_to_t2", 3, repeat('a', 20)) ### INSERT INTO `test`.`t2` ### SET ### @1=1 /* INT meta=0 nullable=1 is_null=0 */ @@ -1030,7 +1030,7 @@ START TRANSACTION /*!*/; #Q> INSERT INTO t1 VALUES(1, "insert_to_t1", 1, repeat('a', 20)), #Q> (2, "insert_to_t1", 2, repeat('a', 20)), -#Q> (3, "insert_to_t1", 3, repeat('a', 20 +#Q> (3, "insert_to_t1", 3, repeat('a', 20)) ### INSERT INTO `test`.`t1` ### SET ### @1=1 /* INT meta=0 nullable=0 is_null=0 */ @@ -1204,7 +1204,7 @@ START TRANSACTION /*!*/; #Q> INSERT INTO t2 VALUES(1, "insert_to_t2", 1, repeat('a', 20)), #Q> (2, "insert_to_t2", 2, repeat('a', 20)), -#Q> (3, "insert_to_t2", 3, repeat('a', 20 +#Q> (3, "insert_to_t2", 3, repeat('a', 20)) ### INSERT INTO `test`.`t2` ### SET ### @1=1 /* INT meta=0 nullable=1 is_null=0 */ diff --git a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result index a0cf5b2dcdb..07e469333da 100644 --- a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result +++ b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result @@ -204,7 +204,7 @@ START TRANSACTION # at # #010909 4:46:40 server id # end_log_pos # CRC32 XXX Annotate_rows: #Q> LOAD DATA INFILE '../../std_data/loaddata7.dat' INTO TABLE t1 -#Q> FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n +#Q> FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n' #010909 4:46:40 server id # end_log_pos # CRC32 XXX Table_map: `new_test1`.`t1` mapped to number # # at # #010909 4:46:40 server id # end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F @@ -445,7 +445,7 @@ START TRANSACTION # at # #010909 4:46:40 server id # end_log_pos # CRC32 XXX Annotate_rows: #Q> LOAD DATA INFILE '../../std_data/loaddata7.dat' INTO TABLE t1 -#Q> FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n +#Q> FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n' #010909 4:46:40 server id # end_log_pos # CRC32 XXX Table_map: `new_test1`.`t1` mapped to number # # at # #010909 4:46:40 server id # end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F diff --git a/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test b/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test index 8f1dbb2a2dd..149b1a8d97d 100644 --- a/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test +++ b/mysql-test/suite/binlog/t/binlog_autocommit_off_no_hang.test @@ -26,10 +26,10 @@ ALTER TABLE mysql.gtid_slave_pos ENGINE=innodb; --echo # Restart the server so mysqld reads the gtid_slave_pos using innodb ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc diff --git a/mysql-test/suite/binlog/t/binlog_rotate_perf.test b/mysql-test/suite/binlog/t/binlog_rotate_perf.test index 74c91feca97..512471e2de1 100644 --- a/mysql-test/suite/binlog/t/binlog_rotate_perf.test +++ b/mysql-test/suite/binlog/t/binlog_rotate_perf.test @@ -68,10 +68,10 @@ while ($loop_times) { # try to change the log-bin configs and restart --echo # ======= now try to change the log-bin config for mysqld ======= ---let $restart_parameters="--log-bin=new_log_bin" +--let $restart_parameters=--log-bin=new_log_bin --echo #begin to restart mysqld --source include/restart_mysqld.inc ---let $restart_parameters= "" +--let $restart_parameters= --source include/show_binary_logs.inc let $loop_times= 10; diff --git a/mysql-test/suite/binlog_encryption/binlog_row_annotate.result b/mysql-test/suite/binlog_encryption/binlog_row_annotate.result index 583d9a30a5a..2a20f9391b2 100644 --- a/mysql-test/suite/binlog_encryption/binlog_row_annotate.result +++ b/mysql-test/suite/binlog_encryption/binlog_row_annotate.result @@ -236,7 +236,7 @@ START TRANSACTION #010909 4:46:40 server id # end_log_pos # Annotate_rows: #Q> DELETE test1.t1, test2.t2 #Q> FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3 -#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3 +#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3.a #010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number # # at # #010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # @@ -305,7 +305,7 @@ START TRANSACTION #010909 4:46:40 server id # end_log_pos # Annotate_rows: #Q> DELETE xtest1.xt1, test2.t2 #Q> FROM xtest1.xt1 INNER JOIN test2.t2 INNER JOIN test3.t3 -#Q> WHERE xtest1.xt1.a=test2.t2.a AND test2.t2.a=test3.t3 +#Q> WHERE xtest1.xt1.a=test2.t2.a AND test2.t2.a=test3.t3.a #010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # # at # #010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F @@ -441,7 +441,7 @@ START TRANSACTION #010909 4:46:40 server id # end_log_pos # Annotate_rows: #Q> DELETE test1.t1, test2.t2 #Q> FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3 -#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3 +#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3.a #010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number # # at # # at # diff --git a/mysql-test/suite/binlog_encryption/restart_server.inc b/mysql-test/suite/binlog_encryption/restart_server.inc index 8f0fe7d8970..f71858be741 100644 --- a/mysql-test/suite/binlog_encryption/restart_server.inc +++ b/mysql-test/suite/binlog_encryption/restart_server.inc @@ -20,7 +20,7 @@ --connection $_cur_con --enable_reconnect ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect shutdown_server; @@ -31,5 +31,5 @@ if ($rpl_server_parameters) { --let $_rpl_start_server_command= restart:$rpl_server_parameters } ---exec echo "$_rpl_start_server_command" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect +--write_line "$_rpl_start_server_command" $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect --source include/wait_until_connected_again.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result b/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result index e1186d65ec2..99721813159 100644 --- a/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result +++ b/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result @@ -69,8 +69,6 @@ INSERT INTO t2 VALUES (5, "i1a"); connection server_4; CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT, MASTER_USE_GTID=CURRENT_POS; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead include/start_slave.inc SELECT * FROM t1 ORDER BY a; a b @@ -91,8 +89,6 @@ connection server_2; include/stop_slave.inc CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_4, MASTER_USE_GTID=CURRENT_POS; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead include/start_slave.inc connection server_4; UPDATE t2 SET b="j1a" WHERE a=5; @@ -121,8 +117,6 @@ include/save_master_gtid.inc connection server_3; CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_4, MASTER_USE_GTID=CURRENT_POS; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead include/start_slave.inc include/sync_with_master_gtid.inc SELECT * FROM t2 ORDER BY a; diff --git a/mysql-test/suite/binlog_encryption/rpl_packet.result b/mysql-test/suite/binlog_encryption/rpl_packet.result index 4a2a5d70d39..bb6269607fe 100644 --- a/mysql-test/suite/binlog_encryption/rpl_packet.result +++ b/mysql-test/suite/binlog_encryption/rpl_packet.result @@ -2,6 +2,8 @@ include/master-slave.inc [connection master] call mtr.add_suppression("Slave I/O: Got a packet bigger than 'slave_max_allowed_packet' bytes, .*error.* 1153"); call mtr.add_suppression("Log entry on master is longer than slave_max_allowed_packet"); +call mtr.add_suppression("Could not write packet:"); +call mtr.add_suppression("Got a packet bigger than 'max_allowed_packet' bytes"); drop database if exists DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________; create database DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________; connection master; diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_slave_bgc_kill.result b/mysql-test/suite/binlog_encryption/rpl_parallel_slave_bgc_kill.result index ba131ea094f..6b75dbf6181 100644 --- a/mysql-test/suite/binlog_encryption/rpl_parallel_slave_bgc_kill.result +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_slave_bgc_kill.result @@ -206,10 +206,12 @@ RETURN x; END || SET sql_log_bin=1; +include/stop_slave_io.inc connection server_1; INSERT INTO t3 VALUES (49,0); connection server_2; -START SLAVE SQL_THREAD; +CHANGE MASTER TO master_use_gtid=no; +include/start_slave.inc SELECT * FROM t3 WHERE a >= 40 ORDER BY a; a b 41 41 @@ -239,10 +241,6 @@ SET GLOBAL slave_parallel_threads=0; SET GLOBAL slave_parallel_threads=10; include/start_slave.inc *** 3. Same as (2), but not using gtid mode *** -connection server_2; -include/stop_slave.inc -CHANGE MASTER TO master_use_gtid=no; -include/start_slave.inc connection server_1; connection con_temp3; SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_stop_slave.result b/mysql-test/suite/binlog_encryption/rpl_parallel_stop_slave.result index 0c810d2a3f4..b0a4fa59c69 100644 --- a/mysql-test/suite/binlog_encryption/rpl_parallel_stop_slave.result +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_stop_slave.result @@ -37,7 +37,9 @@ connection con_temp1; BEGIN; INSERT INTO t2 VALUES (21); connection server_2; -START SLAVE; +START SLAVE IO_THREAD; +include/wait_for_slave_param.inc [Read_Master_Log_Pos] +START SLAVE SQL_THREAD; connection con_temp2; SET @old_dbug= @@GLOBAL.debug_dbug; SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; diff --git a/mysql-test/suite/compat/oracle/r/empty_string_literal.result b/mysql-test/suite/compat/oracle/r/empty_string_literal.result index 4af576e90c0..1260c7aa75d 100644 --- a/mysql-test/suite/compat/oracle/r/empty_string_literal.result +++ b/mysql-test/suite/compat/oracle/r/empty_string_literal.result @@ -64,7 +64,7 @@ SET sql_mode=@mode; # Test litteral concat # SELECT 'a' 'b'; -a +ab ab SELECT 'a' ''; a @@ -76,13 +76,13 @@ SELECT '' ''; NULL NULL SELECT '' 'b' 'c'; -b +bc bc SELECT '' '' 'c'; c c SELECT 'a' '' 'c'; -a +ac ac SELECT 'a' '' ''; a diff --git a/mysql-test/suite/compat/oracle/r/gis.result b/mysql-test/suite/compat/oracle/r/gis.result index 113cb0ea402..8145b97d695 100644 --- a/mysql-test/suite/compat/oracle/r/gis.result +++ b/mysql-test/suite/compat/oracle/r/gis.result @@ -33,37 +33,37 @@ ERROR 42000: Incorrect parameter count in the call to native function 'WITHIN(PO # MDEV-20009 Add CAST(expr AS pluggable_type) # SELECT CAST(1 AS GEOMETRY); -ERROR HY000: Operator does not exists: 'CAST(expr AS geometry)' +ERROR HY000: Operator does not exist: 'CAST(expr AS geometry)' SELECT CAST(1 AS GEOMETRYCOLLECTION); -ERROR HY000: Operator does not exists: 'CAST(expr AS geometrycollection)' +ERROR HY000: Operator does not exist: 'CAST(expr AS geometrycollection)' SELECT CAST(1 AS POINT); -ERROR HY000: Operator does not exists: 'CAST(expr AS point)' +ERROR HY000: Operator does not exist: 'CAST(expr AS point)' SELECT CAST(1 AS LINESTRING); -ERROR HY000: Operator does not exists: 'CAST(expr AS linestring)' +ERROR HY000: Operator does not exist: 'CAST(expr AS linestring)' SELECT CAST(1 AS POLYGON); -ERROR HY000: Operator does not exists: 'CAST(expr AS polygon)' +ERROR HY000: Operator does not exist: 'CAST(expr AS polygon)' SELECT CAST(1 AS MULTIPOINT); -ERROR HY000: Operator does not exists: 'CAST(expr AS multipoint)' +ERROR HY000: Operator does not exist: 'CAST(expr AS multipoint)' SELECT CAST(1 AS MULTILINESTRING); -ERROR HY000: Operator does not exists: 'CAST(expr AS multilinestring)' +ERROR HY000: Operator does not exist: 'CAST(expr AS multilinestring)' SELECT CAST(1 AS MULTIPOLYGON); -ERROR HY000: Operator does not exists: 'CAST(expr AS multipolygon)' +ERROR HY000: Operator does not exist: 'CAST(expr AS multipolygon)' SELECT CONVERT(1, GEOMETRY); -ERROR HY000: Operator does not exists: 'CAST(expr AS geometry)' +ERROR HY000: Operator does not exist: 'CAST(expr AS geometry)' SELECT CONVERT(1, GEOMETRYCOLLECTION); -ERROR HY000: Operator does not exists: 'CAST(expr AS geometrycollection)' +ERROR HY000: Operator does not exist: 'CAST(expr AS geometrycollection)' SELECT CONVERT(1, POINT); -ERROR HY000: Operator does not exists: 'CAST(expr AS point)' +ERROR HY000: Operator does not exist: 'CAST(expr AS point)' SELECT CONVERT(1, LINESTRING); -ERROR HY000: Operator does not exists: 'CAST(expr AS linestring)' +ERROR HY000: Operator does not exist: 'CAST(expr AS linestring)' SELECT CONVERT(1, POLYGON); -ERROR HY000: Operator does not exists: 'CAST(expr AS polygon)' +ERROR HY000: Operator does not exist: 'CAST(expr AS polygon)' SELECT CONVERT(1, MULTIPOINT); -ERROR HY000: Operator does not exists: 'CAST(expr AS multipoint)' +ERROR HY000: Operator does not exist: 'CAST(expr AS multipoint)' SELECT CONVERT(1, MULTILINESTRING); -ERROR HY000: Operator does not exists: 'CAST(expr AS multilinestring)' +ERROR HY000: Operator does not exist: 'CAST(expr AS multilinestring)' SELECT CONVERT(1, MULTIPOLYGON); -ERROR HY000: Operator does not exists: 'CAST(expr AS multipolygon)' +ERROR HY000: Operator does not exist: 'CAST(expr AS multipolygon)' # # End of 10.5 tests # diff --git a/mysql-test/suite/compat/oracle/r/mysqldump_restore_func_qualified.result b/mysql-test/suite/compat/oracle/r/mysqldump_restore_func_qualified.result index fd3dd787f1e..c01524b3cfa 100644 --- a/mysql-test/suite/compat/oracle/r/mysqldump_restore_func_qualified.result +++ b/mysql-test/suite/compat/oracle/r/mysqldump_restore_func_qualified.result @@ -24,6 +24,7 @@ b1 VARCHAR(64) AS (LPAD(b0,10)) PERSISTENT CREATE VIEW v2 AS SELECT LTRIM(now()) AS a0, LPAD(now(),10) AS b0; +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( diff --git a/mysql-test/suite/compat/oracle/r/sp-package-mysqldump.result b/mysql-test/suite/compat/oracle/r/sp-package-mysqldump.result index 5efd66d8054..7b423e85f64 100644 --- a/mysql-test/suite/compat/oracle/r/sp-package-mysqldump.result +++ b/mysql-test/suite/compat/oracle/r/sp-package-mysqldump.result @@ -34,6 +34,7 @@ PROCEDURE p1; FUNCTION f1 RETURN INT; END; $$ +/*!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; diff --git a/mysql-test/suite/encryption/r/corrupted_during_recovery.result b/mysql-test/suite/encryption/r/corrupted_during_recovery.result index 7329999dd27..8fef209ee7b 100644 --- a/mysql-test/suite/encryption/r/corrupted_during_recovery.result +++ b/mysql-test/suite/encryption/r/corrupted_during_recovery.result @@ -9,7 +9,7 @@ INSERT INTO t2 VALUES(2); SELECT * FROM t1; ERROR 42000: Unknown storage engine 'InnoDB' SELECT * FROM t1; -Got one of the listed errors +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. SELECT * FROM t2; a 2 diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change.result b/mysql-test/suite/encryption/r/innodb-bad-key-change.result index a034e68e251..d2ad5fb9909 100644 --- a/mysql-test/suite/encryption/r/innodb-bad-key-change.result +++ b/mysql-test/suite/encryption/r/innodb-bad-key-change.result @@ -32,7 +32,7 @@ foobar 2 # Restart server with keysbad3.txt # restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keysbad3.txt SELECT * FROM t1; -ERROR 42S02: Table 'test.t1' doesn't exist in engine +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. # restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keysbad3.txt DROP TABLE t1; # Start server with keys3.txt @@ -44,31 +44,31 @@ INSERT INTO t2 VALUES ('foobar',1,2); # Restart server with keys2.txt # restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt SELECT * FROM t2; -ERROR 42S02: Table 'test.t2' doesn't exist in engine +ERROR HY000: Table `test`.`t2` is corrupted. Please drop the table and recreate. SELECT * FROM t2 where id = 1; -ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +ERROR HY000: Table `test`.`t2` is corrupted. Please drop the table and recreate. SELECT * FROM t2 where b = 1; -ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +ERROR HY000: Table `test`.`t2` is corrupted. Please drop the table and recreate. INSERT INTO t2 VALUES ('tmp',3,3); -ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +ERROR HY000: Table `test`.`t2` is corrupted. Please drop the table and recreate. DELETE FROM t2 where b = 3; -ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +ERROR HY000: Table `test`.`t2` is corrupted. Please drop the table and recreate. DELETE FROM t2 where id = 3; -ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +ERROR HY000: Table `test`.`t2` is corrupted. Please drop the table and recreate. UPDATE t2 set b = b +1; -ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +ERROR HY000: Table `test`.`t2` is corrupted. Please drop the table and recreate. OPTIMIZE TABLE t2; Table Op Msg_type Msg_text -test.t2 optimize Error Table test/t2 is corrupted. Please drop the table and recreate. +test.t2 optimize Error Table `test`.`t2` is corrupted. Please drop the table and recreate. test.t2 optimize error Corrupt ALTER TABLE t2 ADD COLUMN d INT; -ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +ERROR HY000: Table `test`.`t2` is corrupted. Please drop the table and recreate. ANALYZE TABLE t2; Table Op Msg_type Msg_text -test.t2 analyze Error Table test/t2 is corrupted. Please drop the table and recreate. +test.t2 analyze Error Table `test`.`t2` is corrupted. Please drop the table and recreate. test.t2 analyze error Corrupt TRUNCATE TABLE t2; -ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +ERROR HY000: Table `test`.`t2` is corrupted. Please drop the table and recreate. DROP TABLE t2; # Start server with keys2.txt diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change2.result b/mysql-test/suite/encryption/r/innodb-bad-key-change2.result index ab67b6fedad..129de6e9c46 100644 --- a/mysql-test/suite/encryption/r/innodb-bad-key-change2.result +++ b/mysql-test/suite/encryption/r/innodb-bad-key-change2.result @@ -13,24 +13,24 @@ ENCRYPTED=YES ENCRYPTION_KEY_ID=4; INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); # restart: --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys3.txt SELECT * FROM t1; -ERROR 42S02: Table 'test.t1' doesn't exist in engine +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. SHOW WARNINGS; Level Code Message -Error 1932 Table 'test.t1' doesn't exist in engine +Error 1877 Table `test`.`t1` is corrupted. Please drop the table and recreate. ALTER TABLE t1 ENGINE=InnoDB; -ERROR HY000: Table test/t1 is corrupted. Please drop the table and recreate. +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. SHOW WARNINGS; Level Code Message -Error 1877 Table test/t1 is corrupted. Please drop the table and recreate. +Error 1877 Table `test`.`t1` is corrupted. Please drop the table and recreate. OPTIMIZE TABLE t1; Table Op Msg_type Msg_text -test.t1 optimize Error Table test/t1 is corrupted. Please drop the table and recreate. +test.t1 optimize Error Table `test`.`t1` is corrupted. Please drop the table and recreate. test.t1 optimize error Corrupt SHOW WARNINGS; Level Code Message CHECK TABLE t1; Table Op Msg_type Msg_text -test.t1 check Error Table test/t1 is corrupted. Please drop the table and recreate. +test.t1 check Error Table `test`.`t1` is corrupted. Please drop the table and recreate. test.t1 check error Corrupt SHOW WARNINGS; Level Code Message @@ -40,7 +40,7 @@ backup: t1 UNLOCK TABLES; # restart: --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys3.txt ALTER TABLE t1 DISCARD TABLESPACE; -ERROR 42S02: Table 'test.t1' doesn't exist in engine +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. DROP TABLE t1; CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=4; @@ -61,7 +61,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `ENCRYPTED`=YES `ENCRYPTION_KEY_ID`=4 # restart: --innodb-encrypt-tables --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys3.txt RENAME TABLE t1 TO t1new; -ERROR HY000: Error on rename of './test/t1' to './test/t1new' (errno: 155 "The table does not exist in the storage engine") +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. ALTER TABLE t1 RENAME TO t1new; -ERROR HY000: Table test/t1 is corrupted. Please drop the table and recreate. +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. DROP TABLE t1; diff --git a/mysql-test/suite/encryption/r/innodb-compressed-blob.result b/mysql-test/suite/encryption/r/innodb-compressed-blob.result index bb87d171601..fd095f70bf2 100644 --- a/mysql-test/suite/encryption/r/innodb-compressed-blob.result +++ b/mysql-test/suite/encryption/r/innodb-compressed-blob.result @@ -1,7 +1,7 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted; key_version=1"); call mtr.add_suppression("InnoDB: Recovery failed to read page"); call mtr.add_suppression("InnoDB: Unable to decompress ..test.t[1-3]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]"); -call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted"); +call mtr.add_suppression("Table `test`\\.`t[12]` is corrupted"); # Restart mysqld --file-key-management-filename=keys2.txt # restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt set GLOBAL innodb_default_encryption_key_id=4; @@ -16,9 +16,9 @@ insert into t3 values (1, repeat('secret',6000)); # Restart mysqld --file-key-management-filename=keys3.txt # restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys3.txt select count(*) from t1 FORCE INDEX (b) where b like 'secret%'; -ERROR 42S02: Table 'test.t1' doesn't exist in engine +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. select count(*) from t2 FORCE INDEX (b) where b like 'secret%'; -ERROR 42S02: Table 'test.t2' doesn't exist in engine +ERROR HY000: Table `test`.`t2` is corrupted. Please drop the table and recreate. select count(*) from t3 FORCE INDEX (b) where b like 'secret%'; count(*) 1 diff --git a/mysql-test/suite/encryption/r/innodb-encryption-disable.result b/mysql-test/suite/encryption/r/innodb-encryption-disable.result index 179bc550617..86c6d63649f 100644 --- a/mysql-test/suite/encryption/r/innodb-encryption-disable.result +++ b/mysql-test/suite/encryption/r/innodb-encryption-disable.result @@ -1,8 +1,7 @@ -call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` (has an unreadable root page|is corrupted)"); +call mtr.add_suppression("Table `test`\\.`t[15]` (has an unreadable root page|is corrupted)"); call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[15]\\.ibd' cannot be decrypted\\."); call mtr.add_suppression("InnoDB: Recovery failed to read page"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t[15].ibd looks corrupted; key_version=1"); -call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` is corrupted"); call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); # restart: --innodb-encrypt-tables=ON --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt create table t5 ( @@ -24,9 +23,9 @@ insert into t1 values (1,2,'maria','db','encryption'); alter table t1 encrypted='yes' `encryption_key_id`=1; # restart: --innodb-encrypt-tables=OFF select * from t1; -ERROR 42S02: Table 'test.t1' doesn't exist in engine +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. select * from t5; -ERROR 42S02: Table 'test.t5' doesn't exist in engine +ERROR HY000: Table `test`.`t5` is corrupted. Please drop the table and recreate. # restart: --innodb-encrypt-tables=ON --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt drop table t1; drop table t5; diff --git a/mysql-test/suite/encryption/r/innodb-force-corrupt.result b/mysql-test/suite/encryption/r/innodb-force-corrupt.result index 219dbd7cfc3..40b85bebabb 100644 --- a/mysql-test/suite/encryption/r/innodb-force-corrupt.result +++ b/mysql-test/suite/encryption/r/innodb-force-corrupt.result @@ -1,4 +1,4 @@ -call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)"); +call mtr.add_suppression("Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version="); call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption in an InnoDB type table"); call mtr.add_suppression("\\[ERROR\\] (mysqld|mariadbd).*: Index for table 't2' is corrupt; try to repair it"); @@ -17,11 +17,11 @@ COMMIT; # Corrupt tables # restart SELECT * FROM t1; -ERROR 42S02: Table 'test.t1' doesn't exist in engine +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. SELECT * FROM t2; Got one of the listed errors SELECT * FROM t3; -ERROR 42S02: Table 'test.t3' doesn't exist in engine +ERROR HY000: Table `test`.`t3` is corrupted. Please drop the table and recreate. # Restore the original tables # restart DROP TABLE t1,t2,t3; diff --git a/mysql-test/suite/encryption/r/innodb-missing-key.result b/mysql-test/suite/encryption/r/innodb-missing-key.result index d5c1e079e96..83c9166d05b 100644 --- a/mysql-test/suite/encryption/r/innodb-missing-key.result +++ b/mysql-test/suite/encryption/r/innodb-missing-key.result @@ -38,11 +38,11 @@ SELECT COUNT(1) FROM t2; COUNT(1) 2048 SELECT COUNT(1) FROM t2,t1 where t2.a = t1.a; -ERROR 42S02: Table 'test.t1' doesn't exist in engine +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. SELECT COUNT(1) FROM t1 where b = 'ab'; -ERROR HY000: Table test/t1 is corrupted. Please drop the table and recreate. +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. SELECT COUNT(1) FROM t1; -ERROR HY000: Table test/t1 is corrupted. Please drop the table and recreate. +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. # Start server with keys2.txt # restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt diff --git a/mysql-test/suite/encryption/r/innodb-redo-nokeys.result b/mysql-test/suite/encryption/r/innodb-redo-nokeys.result index e503cb9a95c..cd17bd508dd 100644 --- a/mysql-test/suite/encryption/r/innodb-redo-nokeys.result +++ b/mysql-test/suite/encryption/r/innodb-redo-nokeys.result @@ -22,6 +22,15 @@ insert into t2 select * from t1; insert into t3 select * from t1; insert into t4 select * from t1; commit; + +# Flush all dirty pages from buffer pool +SET @no_checkpoint_save_pct= @@GLOBAL.innodb_max_dirty_pages_pct; +SET @no_checkpoint_save_pct_lwm= @@GLOBAL.innodb_max_dirty_pages_pct_lwm; +SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0; +SET GLOBAL innodb_max_dirty_pages_pct=0.0; +SET GLOBAL innodb_max_dirty_pages_pct= @no_checkpoint_save_pct; +SET GLOBAL innodb_max_dirty_pages_pct_lwm= @no_checkpoint_save_pct_lwm; + CREATE TABLE t5 (a VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES; SET GLOBAL innodb_flush_log_at_trx_commit=1; begin; @@ -41,6 +50,6 @@ SELECT * FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'innodb' AND support IN ('YES', 'DEFAULT', 'ENABLED'); ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS -FOUND 1 /\[ERROR\] InnoDB: Encryption key is not found for .*test.t1.ibd/ in mysqld.1.err +FOUND 1 /\[ERROR\] InnoDB: Encryption key is not found for .*test.t[1-5].ibd/ in mysqld.1.err # restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/suite/encryption/t/corrupted_during_recovery.test b/mysql-test/suite/encryption/t/corrupted_during_recovery.test index 1240ee1a8ff..e4a31a0b478 100644 --- a/mysql-test/suite/encryption/t/corrupted_during_recovery.test +++ b/mysql-test/suite/encryption/t/corrupted_during_recovery.test @@ -60,7 +60,7 @@ call mtr.add_suppression("Table .*t1.* is corrupted. Please drop the table and r let $restart_parameters=--innodb_force_recovery=1 --skip-innodb-buffer-pool-load-at-startup; --source include/restart_mysqld.inc ---error ER_NO_SUCH_TABLE_IN_ENGINE,ER_TABLE_CORRUPT +--error ER_TABLE_CORRUPT SELECT * FROM t1; SELECT * FROM t2; CHECK TABLE t2; diff --git a/mysql-test/suite/encryption/t/encrypt_and_grep.test b/mysql-test/suite/encryption/t/encrypt_and_grep.test index 485a3eb2ec8..648ad80780c 100644 --- a/mysql-test/suite/encryption/t/encrypt_and_grep.test +++ b/mysql-test/suite/encryption/t/encrypt_and_grep.test @@ -22,8 +22,9 @@ insert t2 values (repeat('tempsecret', 12)); insert t3 values (repeat('dummysecret', 12)); --echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $tables_count= `select count(*) + @@global.innodb_undo_tablespaces from information_schema.tables where engine = 'InnoDB'` --let $wait_timeout= 600 ---let $wait_condition=SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +--let $wait_condition=SELECT COUNT(*) = $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 --source include/wait_condition.inc --sorted_result @@ -93,8 +94,9 @@ UNLOCK TABLES; SET GLOBAL innodb_encrypt_tables = on; --echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $tables_count= `select count(*) + @@global.innodb_undo_tablespaces from information_schema.tables where engine = 'InnoDB'` --let $wait_timeout= 600 ---let $wait_condition=SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +--let $wait_condition=SELECT COUNT(*) = $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 --source include/wait_condition.inc --sorted_result diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change.test b/mysql-test/suite/encryption/t/innodb-bad-key-change.test index 27483ae35d0..a5060cb8195 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change.test +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change.test @@ -42,7 +42,7 @@ SELECT * FROM t1; -- source include/restart_mysqld.inc --disable_warnings ---error ER_NO_SUCH_TABLE_IN_ENGINE +--error ER_TABLE_CORRUPT SELECT * FROM t1; --enable_warnings @@ -71,7 +71,7 @@ INSERT INTO t2 VALUES ('foobar',1,2); -- source include/restart_mysqld.inc --disable_warnings ---error ER_NO_SUCH_TABLE_IN_ENGINE +--error ER_TABLE_CORRUPT SELECT * FROM t2; --error ER_TABLE_CORRUPT diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change2.test b/mysql-test/suite/encryption/t/innodb-bad-key-change2.test index a6cc581e448..ac8e18b4980 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change2.test +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change2.test @@ -30,7 +30,7 @@ INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); --let $restart_parameters=--plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt --source include/restart_mysqld.inc ---error ER_NO_SUCH_TABLE_IN_ENGINE +--error ER_TABLE_CORRUPT SELECT * FROM t1; --replace_regex /key_id [1-9][0-9]*/\1 / SHOW WARNINGS; @@ -61,7 +61,7 @@ UNLOCK TABLES; --let $restart_parameters=--plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt --source include/restart_mysqld.inc ---error ER_NO_SUCH_TABLE_IN_ENGINE +--error ER_TABLE_CORRUPT ALTER TABLE t1 DISCARD TABLESPACE; # Drop table will succeed. DROP TABLE t1; @@ -93,7 +93,7 @@ SHOW CREATE TABLE t1; --let $restart_parameters= --innodb-encrypt-tables --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt --source include/restart_mysqld.inc ---error ER_ERROR_ON_RENAME +--error ER_TABLE_CORRUPT RENAME TABLE t1 TO t1new; --error ER_TABLE_CORRUPT ALTER TABLE t1 RENAME TO t1new; diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change3.test b/mysql-test/suite/encryption/t/innodb-bad-key-change3.test index 9c2918f3118..f4065290938 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change3.test +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change3.test @@ -16,7 +16,7 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* becau --let $MYSQLD_DATADIR = `SELECT @@datadir` --let SEARCH_RANGE = 10000000 --let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc @@ -25,7 +25,7 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* becau 4;770A8A65DA156D24EE2A093277530143 EOF ---exec echo "restart:--innodb-encrypt-tables --innodb-stats-persistent --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart:--innodb-encrypt-tables --innodb-stats-persistent --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc @@ -47,7 +47,7 @@ UNLOCK TABLES; ALTER TABLE t1 DISCARD TABLESPACE; ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc @@ -62,7 +62,7 @@ ib_discard_tablespaces("test", "t1"); ib_restore_tablespaces("test", "t1"); EOF ---exec echo "restart:--innodb-encrypt-tables --innodb-stats-persistent --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys2.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart:--innodb-encrypt-tables --innodb-stats-persistent --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys2.txt" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc --source include/restart_mysqld.inc @@ -80,7 +80,7 @@ SELECT * FROM t1; -- let SEARCH_FILE=$t1_IBD -- source include/search_pattern_in_file.inc ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc --remove_file $MYSQLTEST_VARDIR/keys1.txt @@ -89,7 +89,7 @@ SELECT * FROM t1; 4;770A8A65DA156D24EE2A093277530143 EOF ---exec echo "restart:--innodb-encrypt-tables --innodb-stats-persistent --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart:--innodb-encrypt-tables --innodb-stats-persistent --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc DROP TABLE t1; diff --git a/mysql-test/suite/encryption/t/innodb-compressed-blob.test b/mysql-test/suite/encryption/t/innodb-compressed-blob.test index d3d53e2c41a..124b3ed17a2 100644 --- a/mysql-test/suite/encryption/t/innodb-compressed-blob.test +++ b/mysql-test/suite/encryption/t/innodb-compressed-blob.test @@ -7,7 +7,7 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted; key_version=1"); call mtr.add_suppression("InnoDB: Recovery failed to read page"); call mtr.add_suppression("InnoDB: Unable to decompress ..test.t[1-3]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]"); -call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted"); +call mtr.add_suppression("Table `test`\\.`t[12]` is corrupted"); --echo # Restart mysqld --file-key-management-filename=keys2.txt -- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt @@ -26,9 +26,9 @@ insert into t3 values (1, repeat('secret',6000)); -- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt -- source include/restart_mysqld.inc ---error ER_NO_SUCH_TABLE_IN_ENGINE +--error ER_TABLE_CORRUPT select count(*) from t1 FORCE INDEX (b) where b like 'secret%'; ---error ER_NO_SUCH_TABLE_IN_ENGINE +--error ER_TABLE_CORRUPT select count(*) from t2 FORCE INDEX (b) where b like 'secret%'; select count(*) from t3 FORCE INDEX (b) where b like 'secret%'; diff --git a/mysql-test/suite/encryption/t/innodb-encryption-disable.test b/mysql-test/suite/encryption/t/innodb-encryption-disable.test index 939ad2b5547..7a7e590e304 100644 --- a/mysql-test/suite/encryption/t/innodb-encryption-disable.test +++ b/mysql-test/suite/encryption/t/innodb-encryption-disable.test @@ -7,11 +7,10 @@ # MDEV-9559: Server without encryption configs crashes if selecting from an implicitly encrypted table # -call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` (has an unreadable root page|is corrupted)"); +call mtr.add_suppression("Table `test`\\.`t[15]` (has an unreadable root page|is corrupted)"); call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[15]\\.ibd' cannot be decrypted\\."); call mtr.add_suppression("InnoDB: Recovery failed to read page"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t[15].ibd looks corrupted; key_version=1"); -call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` is corrupted"); # Suppression for builds where file_key_management plugin is linked statically call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); @@ -43,9 +42,9 @@ alter table t1 encrypted='yes' `encryption_key_id`=1; --let $restart_parameters=--innodb-encrypt-tables=OFF --source include/restart_mysqld.inc ---error ER_NO_SUCH_TABLE_IN_ENGINE +--error ER_TABLE_CORRUPT select * from t1; ---error ER_NO_SUCH_TABLE_IN_ENGINE +--error ER_TABLE_CORRUPT select * from t5; --let $restart_parameters=--innodb-encrypt-tables=ON --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt diff --git a/mysql-test/suite/encryption/t/innodb-force-corrupt.test b/mysql-test/suite/encryption/t/innodb-force-corrupt.test index 73fa0cde0cf..32205decf09 100644 --- a/mysql-test/suite/encryption/t/innodb-force-corrupt.test +++ b/mysql-test/suite/encryption/t/innodb-force-corrupt.test @@ -7,7 +7,7 @@ # Don't test under embedded -- source include/not_embedded.inc -call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)"); +call mtr.add_suppression("Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version="); call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption in an InnoDB type table"); call mtr.add_suppression("\\[ERROR\\] (mysqld|mariadbd).*: Index for table 't2' is corrupt; try to repair it"); @@ -67,11 +67,11 @@ EOF --source include/start_mysqld.inc ---error ER_NO_SUCH_TABLE_IN_ENGINE +--error ER_TABLE_CORRUPT SELECT * FROM t1; --error ER_GET_ERRMSG,ER_NOT_KEYFILE SELECT * FROM t2; ---error ER_NO_SUCH_TABLE_IN_ENGINE +--error ER_TABLE_CORRUPT SELECT * FROM t3; --source include/shutdown_mysqld.inc diff --git a/mysql-test/suite/encryption/t/innodb-missing-key.test b/mysql-test/suite/encryption/t/innodb-missing-key.test index 53fc820a1c9..0c7a1df9ae2 100644 --- a/mysql-test/suite/encryption/t/innodb-missing-key.test +++ b/mysql-test/suite/encryption/t/innodb-missing-key.test @@ -46,7 +46,7 @@ CREATE TABLE t4(a int not null primary key auto_increment, b varchar(128)) engin SELECT SLEEP(5); SELECT COUNT(1) FROM t3; SELECT COUNT(1) FROM t2; ---error ER_NO_SUCH_TABLE_IN_ENGINE +--error ER_TABLE_CORRUPT SELECT COUNT(1) FROM t2,t1 where t2.a = t1.a; --error ER_TABLE_CORRUPT SELECT COUNT(1) FROM t1 where b = 'ab'; diff --git a/mysql-test/suite/encryption/t/innodb-redo-nokeys.test b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test index 22fcd75446e..87a9e7a146e 100644 --- a/mysql-test/suite/encryption/t/innodb-redo-nokeys.test +++ b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test @@ -42,7 +42,9 @@ insert into t3 select * from t1; insert into t4 select * from t1; commit; +let $no_checkpoint_flush= 1; --source ../../suite/innodb/include/no_checkpoint_start.inc + # # We test redo log page read at recv_read_page using # keys that are not in std_data/keys.txt. If checkpoint @@ -75,7 +77,7 @@ WHERE engine = 'innodb' AND support IN ('YES', 'DEFAULT', 'ENABLED'); let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err; -let SEARCH_PATTERN = \[ERROR\] InnoDB: Encryption key is not found for .*test.t1.ibd; +let SEARCH_PATTERN = \[ERROR\] InnoDB: Encryption key is not found for .*test.t[1-5].ibd; --source include/search_pattern_in_file.inc # diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_freed.test b/mysql-test/suite/encryption/t/innodb_encrypt_freed.test index 85d232bc1ac..408e874a3b2 100644 --- a/mysql-test/suite/encryption/t/innodb_encrypt_freed.test +++ b/mysql-test/suite/encryption/t/innodb_encrypt_freed.test @@ -21,7 +21,7 @@ CREATE TABLE t1(f1 BIGINT PRIMARY KEY, f2 int not null, SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; CREATE TABLE t2 (f1 int not null)engine=innodb; -let $restart_parameters="--debug-dbug=d,ib_log_checkpoint_avoid"; +let $restart_parameters=--debug-dbug=d,ib_log_checkpoint_avoid; --source include/restart_mysqld.inc # Stop the purge diff --git a/mysql-test/suite/engines/funcs/r/rpl_change_master.result b/mysql-test/suite/engines/funcs/r/rpl_change_master.result index 59d83a1e385..48cec72d917 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_change_master.result +++ b/mysql-test/suite/engines/funcs/r/rpl_change_master.result @@ -26,9 +26,4 @@ connection master; CHANGE MASTER TO MASTER_USER='root', MASTER_SSL=0, MASTER_SSL_CA='', MASTER_SSL_CERT='', MASTER_SSL_KEY='', MASTER_SSL_CRL='', MASTER_SSL_CRLPATH=''; CHANGE MASTER TO MASTER_USER='root', MASTER_PASSWORD='', MASTER_SSL=0; -"Usage of CURRENT_POS in CHANGE MASTER MASTER_USE_GTID is dreprecated. -CHANGE MASTER TO MASTER_USE_GTID=CURRENT_POS; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead -CHANGE MASTER TO MASTER_USE_GTID=SLAVE_POS; include/rpl_end.inc diff --git a/mysql-test/suite/engines/funcs/r/rpl_get_lock.result b/mysql-test/suite/engines/funcs/r/rpl_get_lock.result index b852546e1bf..cbb02a32648 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_get_lock.result +++ b/mysql-test/suite/engines/funcs/r/rpl_get_lock.result @@ -1,6 +1,6 @@ include/master-slave.inc [connection master] -CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +SET GLOBAL LOG_WARNINGS=4; create table t1(n int); insert into t1 values(get_lock("lock",2)); disconnect master; @@ -35,4 +35,5 @@ NULL connection master1; drop table t1; connection slave; +connection default; include/rpl_end.inc diff --git a/mysql-test/suite/engines/funcs/r/tc_partition_analyze.result b/mysql-test/suite/engines/funcs/r/tc_partition_analyze.result index cd4a0294ba5..ae3305b3fc2 100644 --- a/mysql-test/suite/engines/funcs/r/tc_partition_analyze.result +++ b/mysql-test/suite/engines/funcs/r/tc_partition_analyze.result @@ -33,7 +33,6 @@ t1 CREATE TABLE `t1` ( PARTITION `p5` VALUES LESS THAN MAXVALUE ENGINE = ENGINE) ALTER TABLE t1 ANALYZE PARTITION p1,p2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK SELECT * FROM t1 ORDER BY c1; c1 c2 diff --git a/mysql-test/suite/federated/federatedx.result b/mysql-test/suite/federated/federatedx.result index bb817b210f2..e75fb25304c 100644 --- a/mysql-test/suite/federated/federatedx.result +++ b/mysql-test/suite/federated/federatedx.result @@ -2243,6 +2243,7 @@ connection master; CREATE TABLE t1(id VARCHAR(20) NOT NULL, PRIMARY KEY(id)) ENGINE=FEDERATED CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1'; # Dump table t1 using mysqldump tool +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( diff --git a/mysql-test/suite/federated/federatedx_create_handlers.result b/mysql-test/suite/federated/federatedx_create_handlers.result index 231862f76ad..698dfab9449 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.result +++ b/mysql-test/suite/federated/federatedx_create_handlers.result @@ -536,6 +536,22 @@ use federated; SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3 WHERE id=2) dt2) dt; id name +PREPARE stmt FROM " +SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3 + WHERE id=3) dt2) dt; +"; +EXECUTE stmt; +id name +3 xxx +EXECUTE stmt; +id name +3 xxx +DEALLOCATE PREPARE stmt; +EXPLAIN +SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3 +WHERE id=3) dt2) dt; +id select_type table type possible_keys key key_len ref rows Extra +1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL connection slave; CREATE TABLE federated.t10 (a INT,b INT); CREATE TABLE federated.t11 (a INT, b INT); @@ -556,6 +572,54 @@ WHERE id=2) dt2) dt a b a b id name 1 1 NULL NULL NULL NULL 2 2 NULL NULL NULL NULL +# +# MDEV-31361: Second execution of PS for query with derived table +# +connection slave; +DROP TABLE IF EXISTS federated.t1; +CREATE TABLE federated.t1 ( +id int(20) NOT NULL, +name varchar(16) NOT NULL default '' +) +DEFAULT CHARSET=latin1; +INSERT INTO federated.t1 VALUES +(3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy'); +connection master; +DROP TABLE IF EXISTS federated.t1; +CREATE TABLE federated.t1 ( +id int(20) NOT NULL, +name varchar(16) NOT NULL default '' +) +ENGINE="FEDERATED" DEFAULT CHARSET=latin1 +CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +use federated; +SELECT * FROM +(SELECT * FROM +(SELECT * FROM +(SELECT * FROM t1 where id>3) dt3 +WHERE id>3) dt2 +) dt; +id name +7 yyy +4 xxx +5 yyy +PREPARE stmt FROM "SELECT * FROM +(SELECT * FROM +(SELECT * FROM +(SELECT * FROM t1 where id>3) dt3 +WHERE id>3) dt2 +) dt"; +EXECUTE stmt; +id name +7 yyy +4 xxx +5 yyy +EXECUTE stmt; +id name +7 yyy +4 xxx +5 yyy +DEALLOCATE PREPARE stmt; DROP TABLES federated.t1, federated.t2, federated.t3, federated.t10, federated.t11; connection slave; diff --git a/mysql-test/suite/federated/federatedx_create_handlers.test b/mysql-test/suite/federated/federatedx_create_handlers.test index e65972635e0..736d42e9773 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.test +++ b/mysql-test/suite/federated/federatedx_create_handlers.test @@ -95,12 +95,9 @@ DEFAULT CHARSET=latin1; INSERT INTO federated.t3 VALUES ('yyy'), ('www'), ('yyy'), ('xxx'), ('www'), ('yyy'), ('www'); -#Enable after fix MDEV-31361 ---disable_ps2_protocol SELECT * FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t WHERE federated.t3.name=t.name; ---enable_ps2_protocol EXPLAIN SELECT * @@ -358,6 +355,18 @@ use federated; SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3 WHERE id=2) dt2) dt; +PREPARE stmt FROM " +SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3 + WHERE id=3) dt2) dt; +"; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +EXPLAIN +SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3 + WHERE id=3) dt2) dt; + connection slave; CREATE TABLE federated.t10 (a INT,b INT); CREATE TABLE federated.t11 (a INT, b INT); @@ -383,6 +392,52 @@ SELECT * FROM t10 LEFT JOIN WHERE id=2) dt2) dt ) ON t10.a=t11.a; +--echo # +--echo # MDEV-31361: Second execution of PS for query with derived table +--echo # + +connection slave; +DROP TABLE IF EXISTS federated.t1; + +CREATE TABLE federated.t1 ( + id int(20) NOT NULL, + name varchar(16) NOT NULL default '' +) +DEFAULT CHARSET=latin1; + +INSERT INTO federated.t1 VALUES + (3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy'); + +connection master; +DROP TABLE IF EXISTS federated.t1; + +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval +CREATE TABLE federated.t1 ( + id int(20) NOT NULL, + name varchar(16) NOT NULL default '' +) +ENGINE="FEDERATED" DEFAULT CHARSET=latin1 +CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + +use federated; + +let $q= +SELECT * FROM + (SELECT * FROM + (SELECT * FROM + (SELECT * FROM t1 where id>3) dt3 + WHERE id>3) dt2 + ) dt; + +eval $q; + +eval PREPARE stmt FROM "$q"; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + + DROP TABLES federated.t1, federated.t2, federated.t3, federated.t10, federated.t11; connection slave; diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index d6b30bba6ff..752994c4a26 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -17,14 +17,10 @@ galera_ssl_upgrade : [Warning] Failed to load slave replication state from table galera_parallel_simple : timeout related to wsrep_sync_wait galera_insert_bulk : MDEV-30536 no expected deadlock in galera_insert_bulk test galera_sequences : MDEV-32561 WSREP FSM failure: no such a transition REPLICATING -> COMMITTED -galera_shutdown_nonprim : MDEV-32635 galera_shutdown_nonprim: mysql_shutdown failed -versioning_trx_id : MDEV-18590 : galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch galera_concurrent_ctas : MDEV-32779 galera_concurrent_ctas: assertion in the galera::ReplicatorSMM::finish_cert() galera_as_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() galera_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() galera_sst_mysqldump_with_key : MDEV-32782 galera_sst_mysqldump_with_key test failed -mdev-31285 : MDEV-25089 Assertion `error.len > 0' failed in galera::ReplicatorSMM::handle_apply_error() galera_var_ignore_apply_errors : MENT-1997 galera_var_ignore_apply_errors test freezes -MW-402 : temporarily disabled at the request of Codership -MDEV-22232 : temporarily disabled at the request of Codership galera_desync_overlapped : MDEV-21538 galera_desync_overlapped MTR failed: Result content mismatch +galera_create_table_as_select : MDEV-33952 fails sporadically diff --git a/mysql-test/suite/galera/galera_4nodes.cnf b/mysql-test/suite/galera/galera_4nodes.cnf index a4b02f1513d..e39f206abd4 100644 --- a/mysql-test/suite/galera/galera_4nodes.cnf +++ b/mysql-test/suite/galera/galera_4nodes.cnf @@ -21,6 +21,7 @@ wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#gale wsrep_node_address='127.0.0.1:@mysqld.1.#galera_port' wsrep_node_incoming_address=127.0.0.1:@mysqld.1.port wsrep_sst_receive_address='127.0.0.1:@mysqld.1.#sst_port' +auto-increment-offset=1 [mysqld.2] wsrep-on=1 @@ -32,6 +33,7 @@ wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#gale wsrep_node_address='127.0.0.1:@mysqld.2.#galera_port' wsrep_node_incoming_address=127.0.0.1:@mysqld.2.port wsrep_sst_receive_address='127.0.0.1:@mysqld.2.#sst_port' +auto-increment-offset=2 [mysqld.3] wsrep-on=1 @@ -43,6 +45,7 @@ wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.3.#gale wsrep_node_address='127.0.0.1:@mysqld.3.#galera_port' wsrep_node_incoming_address=127.0.0.1:@mysqld.3.port wsrep_sst_receive_address='127.0.0.1:@mysqld.3.#sst_port' +auto-increment-offset=3 [mysqld.4] wsrep-on=1 @@ -54,6 +57,7 @@ wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.4.#gale wsrep_node_address='127.0.0.1:@mysqld.4.#galera_port' wsrep_node_incoming_address=127.0.0.1:@mysqld.4.port wsrep_sst_receive_address='127.0.0.1:@mysqld.4.#sst_port' +auto-increment-offset=4 [ENV] NODE_MYPORT_1= @mysqld.1.port diff --git a/mysql-test/suite/galera/include/kill_galera.inc b/mysql-test/suite/galera/include/kill_galera.inc index 28a1b0f368c..3c218a19bee 100644 --- a/mysql-test/suite/galera/include/kill_galera.inc +++ b/mysql-test/suite/galera/include/kill_galera.inc @@ -8,7 +8,7 @@ if (!$kill_signal) # Write file to make mysql-test-run.pl expect the crash, but don't start it --let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')` --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect ---exec echo "wait" > $_expect_file_name +--write_line wait $_expect_file_name # Kill the connected server --disable_reconnect diff --git a/mysql-test/suite/galera/include/shutdown_mysqld.inc b/mysql-test/suite/galera/include/shutdown_mysqld.inc deleted file mode 100644 index 793be8d76ac..00000000000 --- a/mysql-test/suite/galera/include/shutdown_mysqld.inc +++ /dev/null @@ -1,18 +0,0 @@ -# This is the first half of include/restart_mysqld.inc. -if ($rpl_inited) -{ - if (!$allow_rpl_inited) - { - --die ERROR IN TEST: When using the replication test framework (master-slave.inc, rpl_init.inc etc), use rpl_restart_server.inc instead of restart_mysqld.inc. If you know what you are doing and you really have to use restart_mysqld.inc, set allow_rpl_inited=1 before you source restart_mysqld.inc - } -} - -# Write file to make mysql-test-run.pl expect the "crash", but don't start it ---let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')` ---let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect ---exec echo "wait" > $_expect_file_name - -# Send shutdown to the connected server ---shutdown_server ---source include/wait_until_disconnected.inc - diff --git a/mysql-test/suite/galera/include/start_mysqld.inc b/mysql-test/suite/galera/include/start_mysqld.inc index 57af9203d0f..c9bed71f517 100644 --- a/mysql-test/suite/galera/include/start_mysqld.inc +++ b/mysql-test/suite/galera/include/start_mysqld.inc @@ -4,12 +4,12 @@ if ($galera_wsrep_start_position != '') { --echo Using --wsrep-start-position when starting mysqld ... - --exec echo "restart:$start_mysqld_params --wsrep-start-position=$galera_wsrep_start_position" > $_expect_file_name + --write_line "restart:$start_mysqld_params --wsrep-start-position=$galera_wsrep_start_position" $_expect_file_name --let $galera_wsrep_start_position = 0 } if ($galera_wsrep_start_position == '') { - --exec echo "restart:$start_mysqld_params" > $_expect_file_name + --write_line "restart:$start_mysqld_params" $_expect_file_name } --source include/galera_wait_ready.inc diff --git a/mysql-test/suite/galera/r/MDEV-22232.result b/mysql-test/suite/galera/r/MDEV-22232.result index a6a619458f0..79db271bc50 100644 --- a/mysql-test/suite/galera/r/MDEV-22232.result +++ b/mysql-test/suite/galera/r/MDEV-22232.result @@ -3,21 +3,21 @@ connection node_1; connect con1,127.0.0.1,root,,test,$NODE_MYPORT_1; --- CTAS with empty result set --- CREATE TABLE t1 (a INT) ENGINE=InnoDB; -SET DEBUG_SYNC = 'create_table_select_before_create SIGNAL may_alter WAIT_FOR bf_abort'; +SET DEBUG_SYNC = 'create_table_select_before_create SIGNAL may_run WAIT_FOR bf_abort'; CREATE TABLE t2 SELECT * FROM t1; connection node_1; -SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; -ALTER TABLE t1 DROP FOREIGN KEY b, ALGORITHM=COPY; +SET DEBUG_SYNC = 'now WAIT_FOR may_run'; +TRUNCATE TABLE t1; connection con1; ERROR 70100: Query execution was interrupted SET DEBUG_SYNC = 'RESET'; --- CTAS with non-empty result set --- INSERT INTO t1 VALUES (10), (20), (30); -SET DEBUG_SYNC = 'create_table_select_before_create SIGNAL may_alter WAIT_FOR bf_abort'; +SET DEBUG_SYNC = 'create_table_select_before_create SIGNAL may_run WAIT_FOR bf_abort'; CREATE TABLE t2 SELECT * FROM t1; connection node_1; -SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; -ALTER TABLE t1 DROP FOREIGN KEY b, ALGORITHM=COPY; +SET DEBUG_SYNC = 'now WAIT_FOR may_run'; +TRUNCATE TABLE t1; connection con1; ERROR 70100: Query execution was interrupted SET DEBUG_SYNC = 'RESET'; diff --git a/mysql-test/suite/galera/r/MDEV-24143.result b/mysql-test/suite/galera/r/MDEV-24143.result index 860d8a35834..879e7d9c32c 100644 --- a/mysql-test/suite/galera/r/MDEV-24143.result +++ b/mysql-test/suite/galera/r/MDEV-24143.result @@ -14,7 +14,7 @@ c1 INSERT INTO t1 VALUES (4),(3),(1),(2); ERROR 40001: Deadlock found when trying to get lock; try restarting transaction CREATE TABLE t1 (pk INT PRIMARY KEY, b INT) ENGINE=SEQUENCE; -ERROR 42S01: Table 't1' already exists +ERROR 42000: This version of MariaDB doesn't yet support 'non-InnoDB sequences in Galera cluster' ALTER TABLE t1 DROP COLUMN c2; ERROR 42000: Can't DROP COLUMN `c2`; check that it exists SELECT get_lock ('test', 1.5); diff --git a/mysql-test/suite/galera/r/MDEV-25731.result b/mysql-test/suite/galera/r/MDEV-25731.result new file mode 100644 index 00000000000..11a72730fb1 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-25731.result @@ -0,0 +1,47 @@ +connection node_2; +connection node_1; +connection node_1; +SET GLOBAL wsrep_load_data_splitting=ON; +Warnings: +Warning 1287 '@@wsrep_load_data_splitting' is deprecated and will be removed in a future release +SET GLOBAL wsrep_mode=REPLICATE_MYISAM; +CREATE TABLE t1 (c1 int) ENGINE=MYISAM; +LOAD DATA INFILE '../../std_data/mdev-25731.dat' IGNORE INTO TABLE t1 LINES TERMINATED BY '\n'; +Warnings: +Warning 1235 wsrep_load_data_splitting for other than InnoDB tables +SELECT COUNT(*) AS EXPECT_6 FROM t1; +EXPECT_6 +6 +connection node_2; +SELECT COUNT(*) AS EXPECT_6 FROM t1; +EXPECT_6 +6 +connection node_1; +ALTER TABLE t1 ENGINE=Aria; +SET GLOBAL wsrep_mode=REPLICATE_ARIA; +LOAD DATA INFILE '../../std_data/mdev-25731.dat' IGNORE INTO TABLE t1 LINES TERMINATED BY '\n'; +Warnings: +Warning 1235 wsrep_load_data_splitting for other than InnoDB tables +SELECT COUNT(*) AS EXPECT_12 FROM t1; +EXPECT_12 +12 +connection node_2; +SELECT COUNT(*) AS EXPECT_12 FROM t1; +EXPECT_12 +12 +connection node_1; +ALTER TABLE t1 ENGINE=InnoDB; +LOAD DATA INFILE '../../std_data/mdev-25731.dat' IGNORE INTO TABLE t1 LINES TERMINATED BY '\n'; +SELECT COUNT(*) AS EXPECT_18 FROM t1; +EXPECT_18 +18 +connection node_2; +SELECT COUNT(*) AS EXPECT_18 FROM t1; +EXPECT_18 +18 +connection node_1; +DROP TABLE t1; +SET GLOBAL wsrep_load_data_splitting=OFF; +Warnings: +Warning 1287 '@@wsrep_load_data_splitting' is deprecated and will be removed in a future release +SET GLOBAL wsrep_mode=DEFAULT; diff --git a/mysql-test/suite/galera/r/MDEV-26499.result b/mysql-test/suite/galera/r/MDEV-26499.result new file mode 100644 index 00000000000..15d372470a4 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-26499.result @@ -0,0 +1,6 @@ +connection node_2; +connection node_1; +connection node_1; +connection node_2; +connection node_2; +SET GLOBAL debug_dbug="+d,simulate_slow_client_at_shutdown"; diff --git a/mysql-test/suite/galera/r/MDEV-27276.result b/mysql-test/suite/galera/r/MDEV-27276.result index 7e5b29fad7e..38e217a9ea8 100644 --- a/mysql-test/suite/galera/r/MDEV-27276.result +++ b/mysql-test/suite/galera/r/MDEV-27276.result @@ -16,17 +16,15 @@ connection node_1a; SET SESSION wsrep_on = 0; SET SESSION wsrep_on = 1; SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; connection node_1; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; SET GLOBAL wsrep_provider_options = 'dbug='; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +connection node_1a; +SET SESSION DEBUG_SYNC = "RESET"; connection node_2; SELECT * FROM p; id f2 diff --git a/mysql-test/suite/galera/r/MDEV-27806.result b/mysql-test/suite/galera/r/MDEV-27806.result index 0f7ac79e4cd..6fe288f4e8e 100644 --- a/mysql-test/suite/galera/r/MDEV-27806.result +++ b/mysql-test/suite/galera/r/MDEV-27806.result @@ -37,7 +37,7 @@ mysqld-bin.000002 # Gtid # # BEGIN GTID #-#-# mysqld-bin.000002 # Query # # use `test`; CREATE TABLE `ts1` ( `f1` int(11) NOT NULL ) -mysqld-bin.000002 # Xid # # COMMIT /* XID */ +mysqld-bin.000002 # Query # # COMMIT connection node_2; include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info diff --git a/mysql-test/suite/galera/r/MDEV-33136.result b/mysql-test/suite/galera/r/MDEV-33136.result new file mode 100644 index 00000000000..36159fa05cd --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-33136.result @@ -0,0 +1,21 @@ +connection node_2; +connection node_1; +connect node_1a,127.0.0.1,root,,test,$NODE_MYPORT_1; +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; +connection node_1a; +TRUNCATE TABLE t1; +SET SESSION wsrep_retry_autocommit = 0; +SET DEBUG_SYNC = 'dict_stats_mdl_acquired SIGNAL may_toi WAIT_FOR bf_abort'; +INSERT INTO t1 VALUES (1); +connection node_1; +SET DEBUG_SYNC = 'now WAIT_FOR may_toi'; +TRUNCATE TABLE t1; +connection node_1a; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +connection node_1; +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t1; +disconnect node_1a; +disconnect node_2; +disconnect node_1; diff --git a/mysql-test/suite/galera/r/MDEV-33828.result b/mysql-test/suite/galera/r/MDEV-33828.result new file mode 100644 index 00000000000..a3ce68166ab --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-33828.result @@ -0,0 +1,41 @@ +connection node_2; +connection node_1; +SET AUTOCOMMIT=ON; +SELECT @@autocommit; +@@autocommit +1 +SET LOCAL enforce_storage_engine=InnoDB; +CREATE TABLE t1(id int not null primary key auto_increment, name varchar(64)) ENGINE=InnoDB; +INSERT INTO t1(name) VALUES ('name1'),('name3'),('name6'),('name2'); +CREATE PROCEDURE sel_proc() +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +SELECT * FROM t1; +END| +CREATE PROCEDURE ins_proc() +BEGIN +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; +INSERT INTO t1 VALUES ('name_proc'); +END| +SET AUTOCOMMIT=OFF; +SELECT @@autocommit; +@@autocommit +0 +START TRANSACTION; +insert into t1(name) values('name10'); +select param_list, returns, db, type from mysql.proc where name='sel_proc'; +param_list returns db type + test PROCEDURE +call ins_proc(); +COMMIT; +SET AUTOCOMMIT=ON; +SELECT * FROM t1; +id name +1 name1 +3 name3 +5 name6 +7 name2 +9 name10 +DROP TABLE t1; +DROP PROCEDURE sel_proc; +DROP PROCEDURE ins_proc; diff --git a/mysql-test/suite/galera/r/MW-336.result b/mysql-test/suite/galera/r/MW-336.result index 8996b85c77c..e0cb1ee0464 100644 --- a/mysql-test/suite/galera/r/MW-336.result +++ b/mysql-test/suite/galera/r/MW-336.result @@ -1,7 +1,8 @@ connection node_2; connection node_1; connection node_1; -CREATE TABLE t1 (f1 INTEGER) Engine=InnoDB; +SET @wsrep_slave_threads_orig = @@wsrep_slave_threads; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT) Engine=InnoDB; SET GLOBAL wsrep_slave_threads = 10; # Set slave threads to 10 step 1 SELECT VARIABLE_VALUE AS EXPECT_10 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; @@ -9,7 +10,7 @@ EXPECT_10 10 SET GLOBAL wsrep_slave_threads = 1; connection node_2; -INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (NULL); connection node_1; # Wait until one of the appliers has exited SELECT VARIABLE_VALUE AS EXPECT_9 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; @@ -27,33 +28,14 @@ EXPECT_20 20 SET GLOBAL wsrep_slave_threads = 1; connection node_2; -INSERT INTO t1 VALUES (1); -INSERT INTO t1 VALUES (2); -INSERT INTO t1 VALUES (3); -INSERT INTO t1 VALUES (4); -INSERT INTO t1 VALUES (5); -INSERT INTO t1 VALUES (6); -INSERT INTO t1 VALUES (7); -INSERT INTO t1 VALUES (8); -INSERT INTO t1 VALUES (9); -INSERT INTO t1 VALUES (10); -INSERT INTO t1 VALUES (11); -INSERT INTO t1 VALUES (12); -INSERT INTO t1 VALUES (13); -INSERT INTO t1 VALUES (14); -INSERT INTO t1 VALUES (16); -INSERT INTO t1 VALUES (17); -INSERT INTO t1 VALUES (18); -INSERT INTO t1 VALUES (19); -INSERT INTO t1 VALUES (20); connection node_1; # Wait until 19 of the appliers has exited SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; EXPECT_1 1 -SELECT COUNT(*) FROM t1; -COUNT(*) -20 +SELECT COUNT(*) AS EXPECT_51 FROM t1; +EXPECT_51 +51 SET GLOBAL wsrep_slave_threads = 10; # Set slave threads to 10 step 3 SELECT VARIABLE_VALUE AS EXPECT_10 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; @@ -62,22 +44,12 @@ EXPECT_10 connection node_1; SET GLOBAL wsrep_slave_threads = 1; connection node_2; -INSERT INTO t1 VALUES (21); -INSERT INTO t1 VALUES (22); -INSERT INTO t1 VALUES (23); -INSERT INTO t1 VALUES (24); -INSERT INTO t1 VALUES (25); -INSERT INTO t1 VALUES (26); -INSERT INTO t1 VALUES (27); -INSERT INTO t1 VALUES (28); -INSERT INTO t1 VALUES (29); -INSERT INTO t1 VALUES (30); connection node_1; # Wait until slave threads back to 1 SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; EXPECT_1 1 -SELECT COUNT(*) FROM t1; -COUNT(*) -30 +SELECT COUNT(*) AS EXPECT_101 FROM t1; +EXPECT_101 +101 DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/MW-369.result b/mysql-test/suite/galera/r/MW-369.result index 9f0a77edbbc..b4fb8668e74 100644 --- a/mysql-test/suite/galera/r/MW-369.result +++ b/mysql-test/suite/galera/r/MW-369.result @@ -12,22 +12,20 @@ START TRANSACTION; DELETE FROM p WHERE f1 = 1; connection node_1a; SET SESSION wsrep_sync_wait = 0; -SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; connection node_2; INSERT INTO c VALUES (1, 1); connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; -SET GLOBAL wsrep_provider_options = 'dbug='; +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction connection node_2; @@ -54,22 +52,20 @@ START TRANSACTION; UPDATE p SET f2 = 1 WHERE f1 = 1; connection node_1a; SET SESSION wsrep_sync_wait = 0; -SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; connection node_2; UPDATE c SET f2 = 1 WHERE f1 = 1; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; -SET GLOBAL wsrep_provider_options = 'dbug='; +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; connection node_1; connection node_2; SELECT * FROM p; @@ -94,22 +90,20 @@ START TRANSACTION; UPDATE p SET f2 = 1 WHERE f1 = 1; connection node_1a; SET SESSION wsrep_sync_wait = 0; -SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; connection node_2; DELETE FROM c WHERE f1 = 1; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; -SET GLOBAL wsrep_provider_options = 'dbug='; +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; connection node_1; connection node_2; SELECT * FROM p; @@ -130,22 +124,20 @@ START TRANSACTION; UPDATE p SET f2 = 1 WHERE f1 = 1; connection node_1a; SET SESSION wsrep_sync_wait = 0; -SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; connection node_2; INSERT INTO c VALUES (1, 0);; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; -SET GLOBAL wsrep_provider_options = 'dbug='; +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction connection node_2; @@ -170,22 +162,20 @@ START TRANSACTION; DELETE FROM p WHERE f1 = 1; connection node_1a; SET SESSION wsrep_sync_wait = 0; -SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; connection node_2; UPDATE c SET f2 = 1 WHERE f1 = 1; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; -SET GLOBAL wsrep_provider_options = 'dbug='; +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction connection node_2; @@ -215,22 +205,20 @@ START TRANSACTION; INSERT INTO cf (f1, p_id) VALUES (10, 1); connection node_1a; SET SESSION wsrep_sync_wait = 0; -SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; connection node_2; INSERT INTO cf (f1, p_id) VALUES (20, 1); connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; -SET GLOBAL wsrep_provider_options = 'dbug='; +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; connection node_1; connection node_2; SELECT * FROM pf; @@ -255,22 +243,20 @@ START TRANSACTION; UPDATE pg SET f2 = 1 WHERE f1 = 1; connection node_1a; SET SESSION wsrep_sync_wait = 0; -SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; connection node_2; INSERT INTO cg VALUES (1, 1, 0); connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; -SET GLOBAL wsrep_provider_options = 'dbug='; +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; connection node_1; connection node_2; SELECT * FROM pg; diff --git a/mysql-test/suite/galera/r/MW-402.result b/mysql-test/suite/galera/r/MW-402.result index f692c90d611..e936b83553d 100644 --- a/mysql-test/suite/galera/r/MW-402.result +++ b/mysql-test/suite/galera/r/MW-402.result @@ -15,22 +15,20 @@ START TRANSACTION; UPDATE c SET f2=1 where f1=1; connection node_1a; SET SESSION wsrep_sync_wait = 0; -SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; connection node_2; DELETE FROM p WHERE f1 = 1; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; -SET GLOBAL wsrep_provider_options = 'dbug='; +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction connection node_2; @@ -55,22 +53,20 @@ START TRANSACTION; UPDATE c SET f2=2 where f1=1; connection node_1a; SET SESSION wsrep_sync_wait = 0; -SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; connection node_2; UPDATE p set f1=11 WHERE f1 = 1; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; -SET GLOBAL wsrep_provider_options = 'dbug='; +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction connection node_2; @@ -97,22 +93,20 @@ START TRANSACTION; UPDATE c SET p_id=2 where f1=1; connection node_1a; SET SESSION wsrep_sync_wait = 0; -SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; connection node_2; UPDATE p set f1=11 WHERE f1 = 1; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; -SET GLOBAL wsrep_provider_options = 'dbug='; +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction connection node_2; @@ -130,22 +124,20 @@ START TRANSACTION; UPDATE p set f1=21 WHERE f1 = 11; connection node_1a; SET SESSION wsrep_sync_wait = 0; -SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; connection node_2; UPDATE c SET p_id=2 where f1=1; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; -SET GLOBAL wsrep_provider_options = 'dbug='; +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction connection node_2; @@ -176,22 +168,20 @@ START TRANSACTION; UPDATE p2 SET f2=2 where f1=1; connection node_1a; SET SESSION wsrep_sync_wait = 0; -SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; connection node_2; DELETE FROM p1 WHERE f1 = 1; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; -SET GLOBAL wsrep_provider_options = 'dbug='; +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; connection node_1; connection node_2; SELECT * FROM p1; @@ -223,22 +213,20 @@ START TRANSACTION; DELETE FROM p2 WHERE f1=1; connection node_1a; SET SESSION wsrep_sync_wait = 0; -SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; connection node_2; DELETE FROM p1 WHERE f1=1; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; connection node_1; +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; -SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; -SET GLOBAL wsrep_provider_options = 'dbug='; +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction connection node_2; diff --git a/mysql-test/suite/galera/r/galera_bf_abort_mariabackup.result b/mysql-test/suite/galera/r/galera_bf_abort_mariabackup.result index 88c200ee933..fa0568035a6 100644 --- a/mysql-test/suite/galera/r/galera_bf_abort_mariabackup.result +++ b/mysql-test/suite/galera/r/galera_bf_abort_mariabackup.result @@ -12,9 +12,9 @@ connection node_1; connection node_2; Starting server ... connection node_1; -# Both should return FOUND 2 as we have bootstrap and SST -FOUND 2 /Desyncing and pausing the provider/ in mysqld.1.err -FOUND 2 /Resuming and resyncing the provider/ in mysqld.1.err +# Both should return NOT FOUND as we have mariabackup with backup locks +NOT FOUND /Desyncing and pausing the provider/ in mysqld.1.err +NOT FOUND /Resuming and resyncing the provider/ in mysqld.1.err connection node_1; SET GLOBAL wsrep_mode = "BF_ABORT_MARIABACKUP"; # Restart node_2, force SST. @@ -25,9 +25,9 @@ connection node_2; Starting server ... connection node_2; connection node_1; -# Both should return FOUND 3 as we have 1 new SST -FOUND 3 /Desyncing and pausing the provider/ in mysqld.1.err -FOUND 3 /Resuming and resyncing the provider/ in mysqld.1.err +# Both should return NOT FOUND as we have mariabackup with backup locks +NOT FOUND /Desyncing and pausing the provider/ in mysqld.1.err +NOT FOUND /Resuming and resyncing the provider/ in mysqld.1.err SET GLOBAL wsrep_mode = ""; DROP TABLE t; # Case 2: MariaBackup backup from node_2 @@ -46,11 +46,13 @@ SET GLOBAL wsrep_mode = "BF_ABORT_MARIABACKUP"; SELECT @@wsrep_mode; @@wsrep_mode BF_ABORT_MARIABACKUP -# Both should return FOUND 1 as node should not desync -FOUND 1 /Desyncing and pausing the provider/ in mysqld.2.err -FOUND 1 /Resuming and resyncing the provider/ in mysqld.2.err -# Should return FOUND 1 because only last backup does not desync -FOUND 1 /Server not desynched from group because WSREP_MODE_BF_MARIABACKUP used./ in mysqld.2.err +# Both should return FOUND 2 because both backups do desync but on different points +FOUND 2 /Desyncing and pausing the provider/ in mysqld.2.err +FOUND 2 /Resuming and resyncing the provider/ in mysqld.2.err +# Should return FOUND 1 as server did not desync at BLOCK_DDL +FOUND 1 /Server not desynched from group at BLOCK_DDL because WSREP_MODE_BF_MARIABACKUP is used./ in mysqld.2.err +# Should return FOUND 1 as server did desync and pause at BLOCK_COMMIT +FOUND 1 /Server desynched from group during BACKUP STAGE BLOCK_COMMIT./ in mysqld.2.err SET GLOBAL wsrep_mode = ""; connection node_1; DROP TABLE t; diff --git a/mysql-test/suite/galera/r/galera_load_data.result b/mysql-test/suite/galera/r/galera_load_data.result index 84e96f8a36c..c275eb02ca5 100644 --- a/mysql-test/suite/galera/r/galera_load_data.result +++ b/mysql-test/suite/galera/r/galera_load_data.result @@ -26,9 +26,308 @@ PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1324 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED; LOCK TABLES cardtest_tbl WRITE; ALTER TABLE cardtest_tbl DISABLE KEYS; -Warnings: -Note 1031 Storage engine InnoDB of the table `cardtest02`.`cardtest_tbl` doesn't have this option -INSERT INTO cardtest_tbl VALUES (1,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(2,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(3,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(4,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(5,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(6,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(7,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(8,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(9,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(10,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(11,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(12,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(13,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(14,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(15,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(16,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(17,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(18,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(19,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(20,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(21,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(22,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(23,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(24,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(25,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(26,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(27,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(28,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(29,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(30,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(31,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(32,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(33,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(34,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(35,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(36,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(37,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(38,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(39,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(40,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(41,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(42,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(43,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(44,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(45,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(46,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(47,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(48,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(49,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(50,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(51,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(52,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(53,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(54,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(55,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(56,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(57,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(58,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(59,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(60,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(61,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(62,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(63,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(64,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(65,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(66,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(67,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(68,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(69,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(70,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(71,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(72,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(73,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(74,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(75,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(76,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(77,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(78,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(79,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(80,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(81,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(82,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(83,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(84,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(85,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(86,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(87,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(88,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(89,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(90,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(91,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(92,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(93,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(94,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(95,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(96,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(97,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(98,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(99,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(100,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(101,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(102,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(103,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(104,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(105,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(106,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(107,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(108,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(109,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(110,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(111,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(112,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(113,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(114,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(115,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(116,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(117,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(118,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(119,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(120,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(121,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(122,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(123,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(124,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(125,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(126,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(127,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(128,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(129,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(130,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(131,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(132,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(133,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(134,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(135,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(136,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(137,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(138,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(139,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(140,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(141,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(142,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(143,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(144,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(145,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(146,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(147,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(148,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(149,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(150,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(151,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(152,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(153,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(154,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(155,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(156,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(157,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(158,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(159,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(160,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(161,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(162,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(163,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(164,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(165,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(166,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(167,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(168,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(169,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(170,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(171,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(172,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(173,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(174,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(175,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(176,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(177,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(178,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(179,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(180,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(181,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(182,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(183,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(184,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(185,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(186,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(187,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(188,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(189,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(190,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(191,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(192,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(193,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(194,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(195,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(196,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(197,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(198,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(199,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(200,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(201,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(202,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(203,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(204,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(205,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(206,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(207,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(208,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(209,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(210,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(211,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(212,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(213,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(214,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(215,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(216,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(217,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(218,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(219,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(220,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(221,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(222,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(223,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(224,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(225,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(226,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(227,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(228,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(229,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(230,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(231,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(232,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(233,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(234,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(235,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(236,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(237,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(238,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(239,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(240,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(241,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(242,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(243,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(244,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(245,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(246,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(247,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(248,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(249,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(250,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(251,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(252,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(253,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(254,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(255,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(256,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(257,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(258,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(259,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(260,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(261,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(262,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(263,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(264,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(265,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(266,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(267,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(268,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(269,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(270,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(271,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(272,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(273,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(274,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(275,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(276,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(277,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(278,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(279,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(280,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(281,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(282,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(283,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(284,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(285,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(286,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(287,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(288,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(289,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(290,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(291,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(292,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(293,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(294,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(295,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(296,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(297,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(298,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(299,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(300,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(301,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL); +INSERT INTO cardtest_tbl VALUES +(1,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(2,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(3,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(4,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(5,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(6,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(7,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(8,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(9,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(10,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(11,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(12,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(13,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(14,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(15,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(16,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(17,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(18,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(19,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(20,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(21,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(22,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(23,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(24,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(25,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(26,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(27,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(28,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(29,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(30,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(31,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(32,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(33,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(34,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(35,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(36,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(37,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(38,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(39,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(40,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(41,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(42,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(43,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(44,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(45,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(46,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(47,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(48,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(49,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(50,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(51,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(52,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(53,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(54,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(55,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(56,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(57,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(58,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(59,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(60,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(61,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(62,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(63,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(64,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(65,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(66,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(67,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(68,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(69,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(70,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(71,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(72,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(73,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(74,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(75,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(76,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(77,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(78,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(79,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(80,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(81,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(82,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(83,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(84,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(85,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(86,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(87,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(88,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(89,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(90,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(91,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(92,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(93,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(94,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(95,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(96,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(97,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(98,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(99,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(100,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(101,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(102,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(103,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(104,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(105,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(106,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(107,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(108,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(109,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(110,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(111,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(112,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(113,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(114,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(115,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(116,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(117,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(118,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(119,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(120,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(121,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(122,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(123,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(124,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(125,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(126,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(127,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(128,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(129,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(130,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(131,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(132,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(133,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(134,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(135,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(136,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(137,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(138,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(139,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(140,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(141,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(142,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(143,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(144,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(145,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(146,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(147,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(148,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(149,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(150,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(151,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(152,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(153,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(154,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(155,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(156,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(157,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(158,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(159,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(160,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(161,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(162,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(163,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(164,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(165,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(166,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(167,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(168,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(169,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(170,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(171,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(172,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(173,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(174,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(175,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(176,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(177,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(178,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(179,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(180,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(181,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(182,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(183,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(184,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(185,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(186,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(187,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(188,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(189,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(190,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(191,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(192,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(193,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(194,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(195,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(196,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(197,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(198,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(199,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(200,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(201,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(202,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(203,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(204,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(205,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(206,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(207,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(208,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(209,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(210,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(211,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(212,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(213,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(214,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(215,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(216,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(217,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(218,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(219,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(220,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(221,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(222,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(223,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(224,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(225,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(226,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(227,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(228,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(229,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(230,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(231,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(232,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(233,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(234,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(235,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(236,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(237,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(238,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(239,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(240,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(241,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(242,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(243,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(244,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(245,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(246,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(247,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(248,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(249,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(250,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(251,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(252,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(253,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(254,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(255,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(256,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(257,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(258,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(259,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(260,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(261,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(262,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(263,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(264,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(265,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(266,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(267,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(268,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(269,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(270,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(271,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(272,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(273,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(274,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(275,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(276,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(277,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(278,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(279,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(280,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(281,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(282,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(283,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(284,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(285,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(286,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(287,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(288,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(289,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(290,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(291,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(292,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(293,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(294,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(295,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(296,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(297,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(298,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(299,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(300,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), +(301,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL); ALTER TABLE cardtest_tbl ENABLE KEYS; Warnings: Note 1031 Storage engine InnoDB of the table `cardtest02`.`cardtest_tbl` doesn't have this option diff --git a/mysql-test/suite/galera/r/galera_mdl_race.result b/mysql-test/suite/galera/r/galera_mdl_race.result index cf747ed8efb..a7f0bc8e672 100644 --- a/mysql-test/suite/galera/r/galera_mdl_race.result +++ b/mysql-test/suite/galera/r/galera_mdl_race.result @@ -1,44 +1,68 @@ connection node_2; connection node_1; +connection node_1; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)) engine=innodb; CREATE TABLE t2 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)) engine=innodb; INSERT INTO t1 VALUES (1, 'a'); INSERT INTO t1 VALUES (2, 'a'); -connection node_1; SET AUTOCOMMIT=ON; START TRANSACTION; UPDATE t1 SET f2 = 'b' WHERE f1 = 1; connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; connection node_1a; +SET SESSION wsrep_sync_wait=0; LOCK TABLE t2 WRITE; connection node_1; -SET @@debug_dbug = "d,sync.wsrep_before_mdl_wait"; +SET DEBUG_SYNC= 'wsrep_before_mdl_wait SIGNAL before_mdl_wait WAIT_FOR mdl_wait_continue'; SELECT * FROM t2;; connection node_1a; +# Wait until select is blocked before MDL lock wait +SET DEBUG_SYNC= 'now WAIT_FOR before_mdl_wait'; +connection node_1a; SET @@debug_dbug = "d,sync.wsrep_after_BF_victim_lock"; connection node_2; UPDATE t1 SET f2 = 'c' WHERE f1 = 1; -connection node_1a; -SET @@debug_dbug = ""; -SET DEBUG_SYNC = "now SIGNAL signal.wsrep_before_mdl_wait"; +connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connection node_1b; +SET SESSION wsrep_sync_wait=0; +# Wait for conflicting update to block SET DEBUG_SYNC = "now SIGNAL signal.wsrep_after_BF_victim_lock"; +connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connection node_1c; +connection node_1a; +SET DEBUG_SYNC = "now SIGNAL BF_victim_continue"; UNLOCK TABLES; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction -SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'a'; -COUNT(*) = 1 +connection node_1; +SELECT COUNT(*) AS EXPECT_1 FROM t1 WHERE f2 = 'a'; +EXPECT_1 1 -SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'c'; -COUNT(*) = 1 +SELECT COUNT(*) AS EXPECT_1 FROM t1 WHERE f2 = 'c'; +EXPECT_1 1 +SELECT * FROM t1; +f1 f2 +1 c +2 a connection node_2; -SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'a'; -COUNT(*) = 1 +SELECT COUNT(*) AS EXPECT_1 FROM t1 WHERE f2 = 'a'; +EXPECT_1 1 -SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'c'; -COUNT(*) = 1 +SELECT COUNT(*) AS EXPECT_1 FROM t1 WHERE f2 = 'c'; +EXPECT_1 1 +SELECT * FROM t1; +f1 f2 +1 c +2 a DROP TABLE t1; DROP TABLE t2; connection node_1a; SET DEBUG_SYNC = "RESET"; +connection node_1b; +SET DEBUG_SYNC = "RESET"; +connection node_1; +disconnect node_1a; +disconnect node_1b; +disconnect node_1c; diff --git a/mysql-test/suite/galera/r/galera_myisam_autocommit.result b/mysql-test/suite/galera/r/galera_myisam_autocommit.result index b80af779430..23883ef3a2f 100644 --- a/mysql-test/suite/galera/r/galera_myisam_autocommit.result +++ b/mysql-test/suite/galera/r/galera_myisam_autocommit.result @@ -15,16 +15,37 @@ UPDATE t1 SET f1 = 9; UPDATE t2 SET f1 = 9 WHERE f1 = 1; DELETE FROM t1 WHERE f1 = 9; DELETE FROM t2 WHERE f1 = 9; -TRUNCATE TABLE t1; -TRUNCATE TABLE t1; +SELECT * FROM t1 ORDER BY f1; +f1 +SELECT * FROM t2 ORDER BY f1; +f1 +2 +3 +4 +5 +6 connection node_2; -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 -SELECT COUNT(*) = 0 FROM t2; -COUNT(*) = 0 -0 +SELECT * FROM t1 ORDER BY f1; +f1 +SELECT * FROM t2 ORDER BY f1; +f1 +2 +3 +4 +5 +6 +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +SELECT * FROM t1 ORDER BY f1; +f1 +SELECT * FROM t2 ORDER BY f1; +f1 +connection node_2; +SELECT * FROM t1 ORDER BY f1; +f1 +SELECT * FROM t2 ORDER BY f1; +f1 connection node_1; +SET GLOBAL wsrep_mode=DEFAULT; DROP TABLE t1; DROP TABLE t2; -SET GLOBAL wsrep_mode=DEFAULT; diff --git a/mysql-test/suite/galera/r/galera_parallel_apply_lock_table.result b/mysql-test/suite/galera/r/galera_parallel_apply_lock_table.result index a15b0c7df69..bc61cfb4d6f 100644 --- a/mysql-test/suite/galera/r/galera_parallel_apply_lock_table.result +++ b/mysql-test/suite/galera/r/galera_parallel_apply_lock_table.result @@ -10,7 +10,7 @@ INSERT INTO t1 VALUES (1); INSERT INTO t2 VALUES (1); connection node_2a; SET SESSION wsrep_sync_wait=0; -SELECT COUNT(*) AS EXPECT_1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE (STATE LIKE '%committing%' or STATE = 'Waiting for certification'); +SELECT COUNT(*) AS EXPECT_1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE (STATE LIKE 'Commit' or STATE = 'Waiting for certification'); EXPECT_1 1 SELECT COUNT(*) AS EXPECT_1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%Waiting for table metadata lock%'; diff --git a/mysql-test/suite/galera/r/galera_query_cache_invalidate.result b/mysql-test/suite/galera/r/galera_query_cache_invalidate.result index b14511134e3..24c6c38810a 100644 --- a/mysql-test/suite/galera/r/galera_query_cache_invalidate.result +++ b/mysql-test/suite/galera/r/galera_query_cache_invalidate.result @@ -8,8 +8,6 @@ connection node_4; call mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node."); connection node_3; CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_port=NODE_MYPORT_1, master_ssl_verify_server_cert=0, master_use_gtid=current_pos; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead START SLAVE; include/wait_for_slave_to_start.inc connection node_1; diff --git a/mysql-test/suite/galera/r/galera_sequence_engine.result b/mysql-test/suite/galera/r/galera_sequence_engine.result new file mode 100644 index 00000000000..93e6c46bd7a --- /dev/null +++ b/mysql-test/suite/galera/r/galera_sequence_engine.result @@ -0,0 +1,12 @@ +connection node_2; +connection node_1; +SET GLOBAL wsrep_ignore_apply_errors=0; +SET SESSION AUTOCOMMIT=0; +SET SESSION max_error_count=0; +CREATE TABLE t0 (id GEOMETRY,parent_id GEOMETRY)ENGINE=SEQUENCE; +ERROR 42000: This version of MariaDB doesn't yet support 'non-InnoDB sequences in Galera cluster' +connection node_2; +SHOW CREATE TABLE t0; +ERROR 42S02: Table 'test.t0' doesn't exist +connection node_1; +SET GLOBAL wsrep_ignore_apply_errors=DEFAULT; diff --git a/mysql-test/suite/galera/r/galera_shutdown_nonprim.result b/mysql-test/suite/galera/r/galera_shutdown_nonprim.result index 8b7697432a3..d577eab9f1a 100644 --- a/mysql-test/suite/galera/r/galera_shutdown_nonprim.result +++ b/mysql-test/suite/galera/r/galera_shutdown_nonprim.result @@ -5,7 +5,12 @@ connection node_2; connection node_1; SET GLOBAL wsrep_provider_options = 'pc.weight=2'; connection node_2; -SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; +connection node_1; +connection node_2; +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status non-Primary connection node_1; SET GLOBAL wsrep_provider_options = 'pc.weight = 1'; diff --git a/mysql-test/suite/galera/r/galera_sst_mariabackup,debug.rdiff b/mysql-test/suite/galera/r/galera_sst_mariabackup,debug.rdiff index 3aad611cacb..9dc845499ad 100644 --- a/mysql-test/suite/galera/r/galera_sst_mariabackup,debug.rdiff +++ b/mysql-test/suite/galera/r/galera_sst_mariabackup,debug.rdiff @@ -1,6 +1,6 @@ ---- r/galera_sst_mariabackup.result -+++ r/galera_sst_mariabackup.reject -@@ -516,5 +516,189 @@ +--- galera/r/galera_sst_mariabackup.result 2024-04-11 09:53:12.950512316 +0300 ++++ galera/r/galera_sst_mariabackup,debug.reject 2024-04-11 10:00:36.771144955 +0300 +@@ -524,6 +524,190 @@ 1 DROP TABLE t1; COMMIT; @@ -188,5 +188,6 @@ +DROP TABLE t1; +COMMIT; +SET GLOBAL debug_dbug = $debug_orig; - disconnect node_2; - disconnect node_1; + connection node_2; + Shutting down server ... + connection node_1; diff --git a/mysql-test/suite/galera/r/galera_sst_mariabackup.result b/mysql-test/suite/galera/r/galera_sst_mariabackup.result index caf602c017c..374f714efb3 100644 --- a/mysql-test/suite/galera/r/galera_sst_mariabackup.result +++ b/mysql-test/suite/galera/r/galera_sst_mariabackup.result @@ -2,6 +2,14 @@ connection node_2; connection node_1; connection node_1; connection node_2; +connection node_1; +select @@innodb_undo_tablespaces; +@@innodb_undo_tablespaces +0 +connection node_2; +select @@innodb_undo_tablespaces; +@@innodb_undo_tablespaces +3 Performing State Transfer on a server that has been shut down cleanly and restarted connection node_1; CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB; @@ -516,5 +524,17 @@ COUNT(*) = 0 1 DROP TABLE t1; COMMIT; +connection node_2; +Shutting down server ... +connection node_1; +connection node_2; +Starting server ... +Using --wsrep-start-position when starting mysqld ... +connection node_1; +connection node_2; +select @@innodb_undo_tablespaces; +@@innodb_undo_tablespaces +3 +call mtr.add_suppression("InnoDB: Cannot change innodb_undo_tablespaces=3 because previous shutdown was not with innodb_fast_shutdown=0"); disconnect node_2; disconnect node_1; diff --git a/mysql-test/suite/galera/r/galera_table_with_hyphen.result b/mysql-test/suite/galera/r/galera_table_with_hyphen.result new file mode 100644 index 00000000000..c9993004b53 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_table_with_hyphen.result @@ -0,0 +1,52 @@ +connection node_2; +connection node_1; +connection node_1; +set wsrep_sync_wait=0; +connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET SESSION wsrep_sync_wait = 0; +connection node_1; +SET GLOBAL wsrep_slave_threads=2; +CREATE TABLE `par-ent` ( id INT AUTO_INCREMENT PRIMARY KEY, j INT) ENGINE=InnoDB; +CREATE TABLE `child` (id INT AUTO_INCREMENT PRIMARY KEY, parent_id INT, j INT, FOREIGN KEY (parent_id) REFERENCES `par-ent`(id)) ENGINE=InnoDB; +INSERT INTO `par-ent` VALUES (23,0); +connection node_2; +connection node_1a; +SET GLOBAL DEBUG_DBUG='+d,wsrep_ha_write_row'; +connection node_2; +INSERT INTO `child` VALUES (21,23,0),(22,23,0),(23,23,0); +connection node_1a; +SET DEBUG_SYNC='now WAIT_FOR wsrep_ha_write_row_reached'; +connection node_2; +UPDATE `par-ent` SET j=2 WHERE id=23; +connection node_1a; +SET GLOBAL DEBUG_DBUG='-d,wsrep_ha_write_row'; +SET DEBUG_SYNC='now SIGNAL wsrep_ha_write_row_continue'; +SET GLOBAL DEBUG_DBUG="RESET"; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_2; +drop table `child`; +drop table `par-ent`; +connection node_1; +SET GLOBAL wsrep_slave_threads=2; +CREATE TABLE `p-arent-` ( id INT AUTO_INCREMENT PRIMARY KEY, j INT) ENGINE=InnoDB; +CREATE TABLE `c-hild` (id INT AUTO_INCREMENT PRIMARY KEY, parent_id INT, j INT, FOREIGN KEY (parent_id) REFERENCES `p-arent-`(id)) ENGINE=InnoDB; +INSERT INTO `p-arent-` VALUES (23,0); +connection node_2; +connection node_1a; +SET GLOBAL DEBUG_DBUG='+d,wsrep_ha_write_row'; +connection node_2; +INSERT INTO `c-hild` VALUES (21,23,0),(22,23,0),(23,23,0); +connection node_1a; +SET DEBUG_SYNC='now WAIT_FOR wsrep_ha_write_row_reached'; +connection node_2; +UPDATE `p-arent-` SET j=2 WHERE id=23; +connection node_1a; +SET GLOBAL DEBUG_DBUG='-d,wsrep_ha_write_row'; +SET DEBUG_SYNC='now SIGNAL wsrep_ha_write_row_continue'; +SET GLOBAL DEBUG_DBUG="RESET"; +SET DEBUG_SYNC = 'RESET'; +SET GLOBAL wsrep_slave_threads=DEFAULT; +connection node_2; +drop table `c-hild`; +drop table `p-arent-`; diff --git a/mysql-test/suite/galera/r/galera_vote_rejoin_ddl.result b/mysql-test/suite/galera/r/galera_vote_rejoin_ddl.result index c6b3d8fa554..ff0063fbf7b 100644 --- a/mysql-test/suite/galera/r/galera_vote_rejoin_ddl.result +++ b/mysql-test/suite/galera/r/galera_vote_rejoin_ddl.result @@ -1,7 +1,5 @@ connection node_2; connection node_1; -connection node_1; -connection node_2; connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4; connection node_1; @@ -55,6 +53,7 @@ expect_0 SELECT COUNT(*) AS expect_1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; expect_1 1 +CALL mtr.add_suppression("WSREP: Vote 0 \\(success\\) on .* is inconsistent with group. Leaving cluster."); connection node_4; SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; expect_0 @@ -64,3 +63,5 @@ expect_1 1 CALL mtr.add_suppression("WSREP: Vote 0 \\(success\\) on .* is inconsistent with group. Leaving cluster."); DROP TABLE t2; +disconnect node_3; +disconnect node_4; diff --git a/mysql-test/suite/galera/r/galera_wan_restart_sst.result b/mysql-test/suite/galera/r/galera_wan_restart_sst.result index 2433a1d9c48..edaefe0e563 100644 --- a/mysql-test/suite/galera/r/galera_wan_restart_sst.result +++ b/mysql-test/suite/galera/r/galera_wan_restart_sst.result @@ -10,7 +10,7 @@ SELECT VARIABLE_VALUE AS EXPECT_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VA EXPECT_4 4 connection node_1; -CREATE TABLE t1 (f1 INTEGER); +CREATE TABLE t1 (f1 INTEGER NOT NULL PRIMARY KEY) ENGINE=INNODB; INSERT INTO t1 VALUES (1); connection node_2; INSERT INTO t1 VALUES (2); @@ -20,6 +20,8 @@ connection node_4; INSERT INTO t1 VALUES (4); connection node_3; INSERT INTO t1 VALUES (13); +connection node_1; +connection node_3; Killing server ... connection node_1; INSERT INTO t1 VALUES (11); @@ -29,8 +31,11 @@ connection node_4; INSERT INTO t1 VALUES (14); connection node_3; INSERT INTO t1 VALUES (131); +connection node_1; connection node_2; INSERT INTO t1 VALUES (22); +connection node_1; +connection node_2; Killing server ... connection node_1; INSERT INTO t1 VALUES (21); @@ -42,6 +47,8 @@ connection node_2; INSERT INTO t1 VALUES (221); connection node_4; INSERT INTO t1 VALUES (34); +connection node_1; +connection node_4; Killing server ... connection node_1; INSERT INTO t1 VALUES (31); diff --git a/mysql-test/suite/galera/r/mdev-22063.result b/mysql-test/suite/galera/r/mdev-22063.result new file mode 100644 index 00000000000..155d1ebbe4f --- /dev/null +++ b/mysql-test/suite/galera/r/mdev-22063.result @@ -0,0 +1,241 @@ +connection node_2; +connection node_1; +# Case 1 CREATE SEQUENCE with no NOCACHE +CREATE SEQUENCE s ENGINE=InnoDB; +ERROR 42000: This version of MariaDB doesn't yet support 'CACHE without INCREMENT BY 0 in Galera cluster' +CREATE SEQUENCE s NOCACHE ENGINE=InnoDB; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +START TRANSACTION; +REPLACE INTO s VALUES (1,1,9223372036854775806,1,1,1000,0,0); +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize status OK +SELECT * FROM t1; +a +SELECT * FROM s; +next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count +1 1 9223372036854775806 1 1 1000 0 0 +connection node_2; +SELECT * FROM t1; +a +SELECT * FROM s; +next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count +1 1 9223372036854775806 1 1 1000 0 0 +connection node_1; +DROP TABLE t1; +DROP SEQUENCE s; +# Case 2 REPLACE INTO ... SELECT with error +CREATE TABLE t (id INT KEY,a YEAR,INDEX (id,a)) engine=innodb; +REPLACE INTO t (id,a)SELECT /*!99997 */ 1; +ERROR 21S01: Column count doesn't match value count at row 1 +REPLACE INTO t (id,a)SELECT /*!99997 */ 1,2; +SELECT * FROM t; +id a +1 2002 +CREATE TABLE t2 (id INT KEY,a YEAR,INDEX (id,a)) engine=myisam; +REPLACE INTO t2 (id,a)SELECT /*!99997 */ 1; +ERROR 21S01: Column count doesn't match value count at row 1 +REPLACE INTO t2 (id,a)SELECT /*!99997 */ 1,2; +Warnings: +Warning 138 Galera cluster does support consistency check only for InnoDB tables. +SELECT * FROM t2; +id a +1 2002 +CREATE TABLE t3 (id INT KEY,a YEAR,INDEX (id,a)) engine=aria; +REPLACE INTO t3 (id,a)SELECT /*!99997 */ 1; +ERROR 21S01: Column count doesn't match value count at row 1 +REPLACE INTO t3 (id,a)SELECT /*!99997 */ 1,2; +Warnings: +Warning 138 Galera cluster does support consistency check only for InnoDB tables. +SELECT * FROM t3; +id a +1 2002 +connection node_2; +SELECT * FROM t; +id a +1 2002 +SELECT * FROM t2; +id a +1 2002 +SELECT * FROM t3; +id a +1 2002 +connection node_1; +DROP TABLE t,t2,t3; +# Bigger REPLACE ... AS SELECT test +CREATE TABLE t1(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t2(id int not null primary key ,b int) ENGINE=MyISAM; +CREATE TABLE t3(id int not null primary key ,b int) ENGINE=Aria; +CREATE TABLE t4(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t5(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t6(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t7(id int not null primary key ,b int) ENGINE=MyISAM; +CREATE TABLE t8(id int not null primary key ,b int) ENGINE=Aria; +INSERT INTO t1(id) SELECT seq FROM seq_1_to_1000; +INSERT INTO t2(id) SELECT seq FROM seq_1_to_1000; +INSERT INTO t3(id) SELECT seq FROM seq_1_to_1000; +REPLACE INTO t4 SELECT * FROM t1; +REPLACE INTO t5 SELECT * FROM t2; +REPLACE INTO t6 SELECT * FROM t3; +REPLACE INTO t7 SELECT * FROM t2; +REPLACE INTO t8 SELECT * FROM t3; +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t2; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t3; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t4; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t5; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t6; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t7; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t8; +EXPECT_1000 +1000 +connection node_2; +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t2; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t3; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t4; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t5; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t6; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t7; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t8; +EXPECT_1000 +1000 +connection node_1; +DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; +# Bigger INSERT INTO ... SELECT test +CREATE TABLE t1(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t2(id int not null primary key ,b int) ENGINE=MyISAM; +CREATE TABLE t3(id int not null primary key ,b int) ENGINE=Aria; +CREATE TABLE t4(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t5(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t6(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t7(id int not null primary key ,b int) ENGINE=MyISAM; +CREATE TABLE t8(id int not null primary key ,b int) ENGINE=Aria; +INSERT INTO t1(id) SELECT seq FROM seq_1_to_1000; +INSERT INTO t2(id) SELECT seq FROM seq_1_to_1000; +INSERT INTO t3(id) SELECT seq FROM seq_1_to_1000; +INSERT INTO t4 SELECT * FROM t1; +INSERT INTO t5 SELECT * FROM t2; +INSERT INTO t6 SELECT * FROM t3; +INSERT INTO t7 SELECT * FROM t2; +INSERT INTO t8 SELECT * FROM t3; +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t2; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t3; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t4; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t5; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t6; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t7; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t8; +EXPECT_1000 +1000 +connection node_2; +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t2; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t3; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t4; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t5; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t6; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t7; +EXPECT_1000 +1000 +SELECT COUNT(*) AS EXPECT_1000 FROM t8; +EXPECT_1000 +1000 +connection node_1; +DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; +CREATE TABLE t1(pk int not null primary key) engine=innodb; +INSERT INTO t1 values (1),(2),(3),(4); +CREATE VIEW view_t1 AS SELECT * FROM t1; +INSERT INTO view_t1 VALUES (5); +SELECT * FROM t1; +pk +1 +2 +3 +4 +5 +DROP TABLE t1; +DROP VIEW view_t1; +CREATE TABLE t1(pk int not null primary key) engine=myisam; +INSERT INTO t1 values (1),(2),(3),(4); +CREATE VIEW view_t1 AS SELECT * FROM t1; +INSERT INTO view_t1 VALUES (5); +SELECT * FROM t1; +pk +1 +2 +3 +4 +5 +DROP TABLE t1; +DROP VIEW view_t1; +CREATE TABLE t1(pk int not null primary key) engine=aria; +INSERT INTO t1 values (1),(2),(3),(4); +CREATE VIEW view_t1 AS SELECT * FROM t1; +INSERT INTO view_t1 VALUES (5); +SELECT * FROM t1; +pk +1 +2 +3 +4 +5 +DROP TABLE t1; +DROP VIEW view_t1; +SET GLOBAL wsrep_mode=DEFAULT; diff --git a/mysql-test/suite/galera/r/mdev-31285.result b/mysql-test/suite/galera/r/mdev-31285.result index 228f62fa305..58fcb385b1a 100644 --- a/mysql-test/suite/galera/r/mdev-31285.result +++ b/mysql-test/suite/galera/r/mdev-31285.result @@ -1,23 +1,8 @@ connection node_2; connection node_1; connection node_1; -connection node_2; -connection node_1; CREATE TABLE t ENGINE=InnoDB WITH SYSTEM VERSIONING AS SELECT 1 AS i; +ERROR 42000: This version of MariaDB doesn't yet support 'SYSTEM VERSIONING AS SELECT in Galera cluster' +connection node_2; SHOW CREATE TABLE t; -Table Create Table -t CREATE TABLE `t` ( - `i` int(1) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING -SELECT * from t; -i -1 -DROP TABLE IF EXISTS t; -COMMIT; -connection node_2; -SET SESSION wsrep_sync_wait=0; -Killing server ... -Starting server ... -connection node_2; -call mtr.add_suppression("WSREP: Event .*Write_rows_v1 apply failed:.*"); -call mtr.add_suppression("SREP: Failed to apply write set: gtid:.*"); +ERROR 42S02: Table 'test.t' doesn't exist diff --git a/mysql-test/suite/galera/r/mysql-wsrep#332.result b/mysql-test/suite/galera/r/mysql-wsrep#332.result index 565979a93ae..16b078175bb 100644 --- a/mysql-test/suite/galera/r/mysql-wsrep#332.result +++ b/mysql-test/suite/galera/r/mysql-wsrep#332.result @@ -21,14 +21,10 @@ connection node_1a; SET SESSION wsrep_on = 0; SET SESSION wsrep_on = 1; SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; connection node_1; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; SET GLOBAL wsrep_provider_options = 'dbug='; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction @@ -64,14 +60,10 @@ connection node_1a; SET SESSION wsrep_on = 0; SET SESSION wsrep_on = 1; SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; connection node_1; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; SET GLOBAL wsrep_provider_options = 'dbug='; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction @@ -112,14 +104,10 @@ connection node_1a; SET SESSION wsrep_on = 0; SET SESSION wsrep_on = 1; SET GLOBAL wsrep_provider_options = 'dbug='; -SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_master_enter_sync'; connection node_1; COMMIT; connection node_1a; -SET SESSION wsrep_on = 0; -SET SESSION wsrep_on = 1; SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; -SET GLOBAL wsrep_provider_options = 'signal=local_monitor_master_enter_sync'; SET GLOBAL wsrep_provider_options = 'dbug='; connection node_1; ERROR 40001: Deadlock found when trying to get lock; try restarting transaction diff --git a/mysql-test/suite/galera/r/rpl_galera_to_mariadb_clone_slave_using_mariadb-backup.result b/mysql-test/suite/galera/r/rpl_galera_to_mariadb_clone_slave_using_mariadb-backup.result new file mode 100644 index 00000000000..71c84d01a89 --- /dev/null +++ b/mysql-test/suite/galera/r/rpl_galera_to_mariadb_clone_slave_using_mariadb-backup.result @@ -0,0 +1,211 @@ +connection node_2; +connection node_1; +# +# MDEV-33355 Add a Galera-2-node-to-MariaDB replication MTR test cloning the slave with mariadb-backup +# +connect master, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connect slave, 127.0.0.1, root, , test, $NODE_MYPORT_3; +START SLAVE; +include/wait_for_slave_to_start.inc +connection master; +connection slave; +############################################################## +### Initial block with some transactions +### Slave: Make sure replication is not using GTID +connection slave; +# Using_Gtid=No +### Master: Create and populate t1 +connection master; +CREATE TABLE t1(a TEXT) ENGINE=InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#00:stmt#00 - slave run#0, before backup'); +INSERT INTO t1 VALUES ('tr#00:stmt#01 - slave run#0, before backup'); +INSERT INTO t1 VALUES ('tr#00:stmt#02 - slave run#0, before backup'); +COMMIT; +connection slave; +############################################################## +### Run the last transaction before mariadb-backup --backup +### Remember SHOW MASTER STATUS and @@gtid_binlog_pos +### before and after the transaction. +### Master: Rember MASTER STATUS and @@gtid_binlog_pos before tr#01 +connection master; +### Slave: Remember MASTER STATUS and @@gtid_binlog_pos before tr#01 +connection slave; +### Master: Run the actual last transaction before the backup +connection master; +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#01:stmt#00 - slave run#0, before backup'); +INSERT INTO t1 VALUES ('tr#01:stmt#01 - slave run#0, before backup'); +INSERT INTO t1 VALUES ('tr#01:stmt#02 - slave run#0, before backup'); +COMMIT; +connection slave; +### Master: Remember MASTER STATUS and @@gtid_binlog_pos after tr#01 +connection master; +### Slave: Remember MASTER STATUS and @@gtid_binlog_pos after tr#01 +connection slave; +############################################################## +### Running `mariadb-backup --backup,--prepare` and checking +### that mariadb_backup_slave_info and mariadb_backup_binlog_info are OK +### Slave: Create a backup +### Slave: Prepare the backup +### Slave: xtrabackup files: +############################ mariadb_backup_slave_info +CHANGE MASTER TO MASTER_LOG_FILE='master_after_tr01_show_master_status_file', MASTER_LOG_POS=master_after_tr01_show_master_status_position; +############################ mariadb_backup_binlog_info +slave_after_tr01_show_master_status_file slave_after_tr01_show_master_status_position slave_after_tr01_gtid_binlog_pos +############################ +############################################################## +### Run more transactions after the backup: +### - while the slave is still running, then +### - while the slave is shut down +### Master: Run another transaction while the slave is still running +connection master; +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup'); +INSERT INTO t1 VALUES ('tr#02:stmt#01 - slave run#0, after backup'); +INSERT INTO t1 VALUES ('tr#02:stmt@02 - slave run#0, after backup'); +COMMIT; +connection slave; +### Master: Remember MASTER STATUS and @@gtid_binlog_pos after tr#02 +connection master; +### Slave: Remember MASTER STATUS and @@gtid_binlog_pos after tr#02 +connection slave; +### Master: Checking SHOW BINLOG EVENTS +connection master; +SHOW BINLOG EVENTS IN 'master_after_tr01_show_master_status_file' FROM master_after_tr01_show_master_status_position LIMIT 0,1; +Log_name master_after_tr01_show_master_status_file +Pos master_after_tr01_show_master_status_position +Event_type Gtid +Server_id # +End_log_pos # +Info BEGIN GTID master_after_tr02_gtid_binlog_pos +SHOW BINLOG EVENTS IN 'master_after_tr01_show_master_status_file' FROM master_after_tr01_show_master_status_position LIMIT 1,1; +Log_name master_after_tr01_show_master_status_file +Pos # +Event_type Query_or_Annotate_rows +Server_id # +End_log_pos # +Info INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup') +### Slave: Checking SHOW BINLOG EVENTS +connection slave; +SHOW BINLOG EVENTS IN 'slave_after_tr01_show_master_status_file' FROM slave_after_tr01_show_master_status_position LIMIT 0,1; +Log_name slave_after_tr01_show_master_status_file +Pos # +Event_type Gtid +Server_id 1 +End_log_pos # +Info BEGIN GTID slave_after_tr02_gtid_binlog_pos +SHOW BINLOG EVENTS IN 'slave_after_tr01_show_master_status_file' FROM slave_after_tr01_show_master_status_position LIMIT 1,1; +Log_name slave_after_tr01_show_master_status_file +Pos # +Event_type Query_or_Annotate_rows +Server_id # +End_log_pos # +Info INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup') +### Slave: Stop replication +connection slave; +STOP SLAVE; +include/wait_for_slave_to_stop.inc +RESET SLAVE; +Warnings: +Note 4190 RESET SLAVE is implicitly changing the value of 'Using_Gtid' from 'No' to 'Slave_Pos' +### Slave: Shutdown the server +connection slave; +### Master: Run a transaction while the slave is shut down +connection master; +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#03:stmt#00 - after slave run#0, slave is shut down, after backup'); +INSERT INTO t1 VALUES ('tr#03:stmt#01 - after slave run#0, slave is shut down, after backup'); +INSERT INTO t1 VALUES ('tr#03:stmt#02 - after slave run#0, slave is shut down, after backup'); +COMMIT; +############################################################## +### Emulate starting a new virgin slave +### Slave: Remove the data directory +### Slave: Copy back the backup +### Slave: Restart the server +connection slave; +# restart +### Slave: Display the restored data before START SLAVE +connection slave; +SELECT * FROM t1 ORDER BY a; +a +tr#00:stmt#00 - slave run#0, before backup +tr#00:stmt#01 - slave run#0, before backup +tr#00:stmt#02 - slave run#0, before backup +tr#01:stmt#00 - slave run#0, before backup +tr#01:stmt#01 - slave run#0, before backup +tr#01:stmt#02 - slave run#0, before backup +### Slave: Execute the CHANGE MASTER statement to set up the host and port +CHANGE MASTER '' TO MASTER_USER='root', MASTER_HOST='127.0.0.1', MASTER_PORT=###, MASTER_CONNECT_RETRY=1, MASTER_SSL_VERIFY_SERVER_CERT=0; +### Slave: Execute the CHANGE MASTER statement from mariadb_backup_slave_info +CHANGE MASTER TO MASTER_LOG_FILE='master_after_tr01_show_master_status_file', MASTER_LOG_POS=master_after_tr01_show_master_status_position; +Warnings: +Note 4190 CHANGE MASTER TO is implicitly changing the value of 'Using_Gtid' from 'Slave_Pos' to 'No' +### Slave: Execute START SLAVE +include/start_slave.inc +### Master: Wait for the slave to apply all master events +connection master; +connection slave; +### Slave: Make sure replication is not using GTID after the slave restart +connection slave; +# Using_Gtid=No +### Slave: Display the restored data after START SLAVE +connection slave; +SELECT * FROM t1 ORDER BY a; +a +tr#00:stmt#00 - slave run#0, before backup +tr#00:stmt#01 - slave run#0, before backup +tr#00:stmt#02 - slave run#0, before backup +tr#01:stmt#00 - slave run#0, before backup +tr#01:stmt#01 - slave run#0, before backup +tr#01:stmt#02 - slave run#0, before backup +tr#02:stmt#00 - slave run#0, after backup +tr#02:stmt#01 - slave run#0, after backup +tr#02:stmt@02 - slave run#0, after backup +tr#03:stmt#00 - after slave run#0, slave is shut down, after backup +tr#03:stmt#01 - after slave run#0, slave is shut down, after backup +tr#03:stmt#02 - after slave run#0, slave is shut down, after backup +############################################################## +### Continue master transactions, check the new slave replicates well. +### Master: Run a transaction after restarting replication +connection master; +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#04:stmt#00 - slave run#1'); +INSERT INTO t1 VALUES ('tr#04:stmt#01 - slave run#1'); +INSERT INTO t1 VALUES ('tr#04:stmt#02 - slave run#1'); +COMMIT; +connection slave; +### Slave: Display the restored data + new transactions +connection slave; +SELECT * FROM t1 ORDER BY a; +a +tr#00:stmt#00 - slave run#0, before backup +tr#00:stmt#01 - slave run#0, before backup +tr#00:stmt#02 - slave run#0, before backup +tr#01:stmt#00 - slave run#0, before backup +tr#01:stmt#01 - slave run#0, before backup +tr#01:stmt#02 - slave run#0, before backup +tr#02:stmt#00 - slave run#0, after backup +tr#02:stmt#01 - slave run#0, after backup +tr#02:stmt@02 - slave run#0, after backup +tr#03:stmt#00 - after slave run#0, slave is shut down, after backup +tr#03:stmt#01 - after slave run#0, slave is shut down, after backup +tr#03:stmt#02 - after slave run#0, slave is shut down, after backup +tr#04:stmt#00 - slave run#1 +tr#04:stmt#01 - slave run#1 +tr#04:stmt#02 - slave run#1 +############################################################## +### Cleanup +### Removing the backup directory +connection master; +DROP TABLE t1; +connection slave; +STOP SLAVE; +include/wait_for_slave_to_stop.inc +RESET SLAVE ALL; +Warnings: +Note 4190 RESET SLAVE is implicitly changing the value of 'Using_Gtid' from 'No' to 'Slave_Pos' +connection master; +set global wsrep_on=OFF; +RESET MASTER; +set global wsrep_on=ON; diff --git a/mysql-test/suite/galera/r/versioning_trx_id.result b/mysql-test/suite/galera/r/versioning_trx_id.result index df92d088834..c28662dcfe6 100644 --- a/mysql-test/suite/galera/r/versioning_trx_id.result +++ b/mysql-test/suite/galera/r/versioning_trx_id.result @@ -17,7 +17,7 @@ a select count(*) from mysql.transaction_registry where begin_timestamp='0-0-0'; count(*) 0 -select count(*) from mysql.transaction_registry where begin_timestamp>=commit_timestamp; +select count(*) from mysql.transaction_registry where begin_timestamp>commit_timestamp; count(*) 0 connection node_3; @@ -34,7 +34,7 @@ a select count(*) from mysql.transaction_registry where begin_timestamp='0-0-0'; count(*) 0 -select count(*) from mysql.transaction_registry where begin_timestamp>=commit_timestamp; +select count(*) from mysql.transaction_registry where begin_timestamp>commit_timestamp; count(*) 0 connection node_1; @@ -50,7 +50,7 @@ a select count(*) from mysql.transaction_registry where begin_timestamp='0-0-0'; count(*) 0 -select count(*) from mysql.transaction_registry where begin_timestamp>=commit_timestamp; +select count(*) from mysql.transaction_registry where begin_timestamp>commit_timestamp; count(*) 0 drop table t1; diff --git a/mysql-test/suite/galera/suite.pm b/mysql-test/suite/galera/suite.pm index f6caecdc36a..4c4d26db4c5 100644 --- a/mysql-test/suite/galera/suite.pm +++ b/mysql-test/suite/galera/suite.pm @@ -1,5 +1,6 @@ package My::Suite::Galera; +use warnings; use lib 'suite'; use wsrep::common; @@ -63,6 +64,7 @@ push @::global_suppressions, qr(WSREP: Failed to remove page file .*), qr(WSREP: wsrep_sst_method is set to 'mysqldump' yet mysqld bind_address is set to .*), qr|WSREP: Sending JOIN failed: -107 \(Transport endpoint is not connected\). Will retry in new primary component.|, + qr|WSREP: Send action \{.* STATE_REQUEST} returned -107 \(Transport endpoint is not connected\)|, qr|WSREP: Trying to continue unpaused monitor|, qr|WSREP: Wait for gtid returned error 3 while waiting for prior transactions to commit before setting position|, qr|WSREP: Failed to report last committed|, diff --git a/mysql-test/suite/galera/t/MDEV-22232.test b/mysql-test/suite/galera/t/MDEV-22232.test index dbd9ed1e9c7..087d6417b01 100644 --- a/mysql-test/suite/galera/t/MDEV-22232.test +++ b/mysql-test/suite/galera/t/MDEV-22232.test @@ -18,19 +18,16 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB; # Run CTAS until the resulting table gets created, -# then it gets BF aborted by ALTER. -SET DEBUG_SYNC = 'create_table_select_before_create SIGNAL may_alter WAIT_FOR bf_abort'; +# then it gets BF aborted by other DDL. +SET DEBUG_SYNC = 'create_table_select_before_create SIGNAL may_run WAIT_FOR bf_abort'; --send CREATE TABLE t2 SELECT * FROM t1; # Wait for CTAS to reach the table create point, -# start executing ALTER and BF abort CTAS. +# start executing other DDL and BF abort CTAS. --connection node_1 -SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; ---disable_result_log ---error ER_CANT_DROP_FIELD_OR_KEY -ALTER TABLE t1 DROP FOREIGN KEY b, ALGORITHM=COPY; ---enable_result_log +SET DEBUG_SYNC = 'now WAIT_FOR may_run'; +TRUNCATE TABLE t1; --connection con1 # CTAS gets BF aborted. @@ -46,19 +43,16 @@ SET DEBUG_SYNC = 'RESET'; INSERT INTO t1 VALUES (10), (20), (30); # Run CTAS until the resulting table gets created, -# then it gets BF aborted by ALTER. -SET DEBUG_SYNC = 'create_table_select_before_create SIGNAL may_alter WAIT_FOR bf_abort'; +# then it gets BF aborted by other DDL. +SET DEBUG_SYNC = 'create_table_select_before_create SIGNAL may_run WAIT_FOR bf_abort'; --send CREATE TABLE t2 SELECT * FROM t1; # Wait for CTAS to reach the table create point, -# start executing ALTER and BF abort CTAS. +# start executing other DDL and BF abort CTAS. --connection node_1 -SET DEBUG_SYNC = 'now WAIT_FOR may_alter'; ---disable_result_log ---error ER_ERROR_ON_RENAME -ALTER TABLE t1 DROP FOREIGN KEY b, ALGORITHM=COPY; ---enable_result_log +SET DEBUG_SYNC = 'now WAIT_FOR may_run'; +TRUNCATE TABLE t1; --connection con1 # CTAS gets BF aborted. diff --git a/mysql-test/suite/galera/t/MDEV-24143.test b/mysql-test/suite/galera/t/MDEV-24143.test index e58f147cb7c..3aecac8cb07 100644 --- a/mysql-test/suite/galera/t/MDEV-24143.test +++ b/mysql-test/suite/galera/t/MDEV-24143.test @@ -11,7 +11,11 @@ SET SESSION autocommit=0; SELECT * FROM t1 WHERE c1 <=0 ORDER BY c1 DESC; --error ER_LOCK_DEADLOCK INSERT INTO t1 VALUES (4),(3),(1),(2); ---error ER_TABLE_EXISTS_ERROR +# +# This is because support for CREATE TABLE ENGINE=SEQUENCE +# is done before we check does table exists already. +# +--error ER_NOT_SUPPORTED_YET CREATE TABLE t1 (pk INT PRIMARY KEY, b INT) ENGINE=SEQUENCE; --error ER_CANT_DROP_FIELD_OR_KEY ALTER TABLE t1 DROP COLUMN c2; diff --git a/mysql-test/suite/galera/t/MDEV-25731.test b/mysql-test/suite/galera/t/MDEV-25731.test new file mode 100644 index 00000000000..893cccbb2bd --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-25731.test @@ -0,0 +1,34 @@ +--source include/galera_cluster.inc +--source include/have_aria.inc + +--connection node_1 +SET GLOBAL wsrep_load_data_splitting=ON; +SET GLOBAL wsrep_mode=REPLICATE_MYISAM; +CREATE TABLE t1 (c1 int) ENGINE=MYISAM; +LOAD DATA INFILE '../../std_data/mdev-25731.dat' IGNORE INTO TABLE t1 LINES TERMINATED BY '\n'; +SELECT COUNT(*) AS EXPECT_6 FROM t1; + +--connection node_2 +SELECT COUNT(*) AS EXPECT_6 FROM t1; + +--connection node_1 +ALTER TABLE t1 ENGINE=Aria; +SET GLOBAL wsrep_mode=REPLICATE_ARIA; +LOAD DATA INFILE '../../std_data/mdev-25731.dat' IGNORE INTO TABLE t1 LINES TERMINATED BY '\n'; +SELECT COUNT(*) AS EXPECT_12 FROM t1; + +--connection node_2 +SELECT COUNT(*) AS EXPECT_12 FROM t1; + +--connection node_1 +ALTER TABLE t1 ENGINE=InnoDB; +LOAD DATA INFILE '../../std_data/mdev-25731.dat' IGNORE INTO TABLE t1 LINES TERMINATED BY '\n'; +SELECT COUNT(*) AS EXPECT_18 FROM t1; + +--connection node_2 +SELECT COUNT(*) AS EXPECT_18 FROM t1; + +--connection node_1 +DROP TABLE t1; +SET GLOBAL wsrep_load_data_splitting=OFF; +SET GLOBAL wsrep_mode=DEFAULT; diff --git a/mysql-test/suite/galera/t/MDEV-26499.test b/mysql-test/suite/galera/t/MDEV-26499.test new file mode 100644 index 00000000000..824b28c14f3 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-26499.test @@ -0,0 +1,20 @@ +# +# MDEV-26499 +# +# This test reproduces some failure on mysql_shutdown() call +# which manifests sporadically in some galera MTR tests during +# restart of a node. +# + +--source include/galera_cluster.inc +--source include/have_debug_sync.inc + +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + +--connection node_2 +SET GLOBAL debug_dbug="+d,simulate_slow_client_at_shutdown"; +--source include/restart_mysqld.inc + +--source include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera/t/MDEV-26597.test b/mysql-test/suite/galera/t/MDEV-26597.test index 783a52cad50..465f1130443 100644 --- a/mysql-test/suite/galera/t/MDEV-26597.test +++ b/mysql-test/suite/galera/t/MDEV-26597.test @@ -18,7 +18,7 @@ SHOW WARNINGS; SET SESSION wsrep_sync_wait = 0; --source include/kill_galera.inc ---let $start_mysqld_params = "" +--let $start_mysqld_params = --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect --source include/start_mysqld.inc diff --git a/mysql-test/suite/galera/t/MDEV-27276.test b/mysql-test/suite/galera/t/MDEV-27276.test index 1c589c9e85b..bdce0d91373 100644 --- a/mysql-test/suite/galera/t/MDEV-27276.test +++ b/mysql-test/suite/galera/t/MDEV-27276.test @@ -17,7 +17,7 @@ # We use concurrency facility of test MW-369 to setup the conflict between DDL and DML # -# Open connection node_1a here, MW-369.inc will use it later +# Open connection node_1a here, we will use it later --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 # create FK parent table @@ -28,14 +28,51 @@ CREATE TABLE p (id INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; --let $mw_369_parent_query = INSERT INTO p VALUES(1,0) --let $mw_369_child_query = CREATE TABLE c(id INT NOT NULL PRIMARY KEY, p_id INT, FOREIGN KEY (p_id) REFERENCES p(id) ON DELETE CASCADE) ENGINE=InnoDB -# execute above queries through separate nodes ---source MW-369.inc +--connection node_1 +SET AUTOCOMMIT=ON; +START TRANSACTION; +--eval $mw_369_parent_query + +# +# Block the $mw_369_child_query from node_2 +# +# --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1a +SET SESSION wsrep_sync_wait = 0; +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_set_sync_point.inc + +# +# insert client row, which will make it impossible to replay the +# delete on parent +# +--connection node_2 +--eval $mw_369_child_query + +# +# Wait until $mw_369_child_query from node_2 reaches the sync point and +# block the 'COMMIT' from node_1 before it certifies. +# +--connection node_1a +--source include/galera_wait_sync_point.inc +--source include/galera_clear_sync_point.inc + +--connection node_1 +--send COMMIT + +--connection node_1a +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_signal_sync_point.inc +--source include/galera_clear_sync_point.inc # Expect certification failure --connection node_1 --error ER_LOCK_DEADLOCK --reap +--connection node_1a +SET SESSION DEBUG_SYNC = "RESET"; + --connection node_2 SELECT * FROM p; SELECT * FROM c; diff --git a/mysql-test/suite/galera/t/MDEV-29142.test b/mysql-test/suite/galera/t/MDEV-29142.test index 316b7f26000..c41302f9e27 100644 --- a/mysql-test/suite/galera/t/MDEV-29142.test +++ b/mysql-test/suite/galera/t/MDEV-29142.test @@ -50,12 +50,12 @@ SET SESSION wsrep_sync_wait = 0; --source include/kill_galera.inc --remove_file $MYSQLTEST_VARDIR/mysqld.1/data/grastate.dat ---let $start_mysqld_params = "--wsrep-new-cluster" +--let $start_mysqld_params =--wsrep-new-cluster --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --source include/start_mysqld.inc --connection node_2 ---let $start_mysqld_params = "" +--let $start_mysqld_params = --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect --source include/start_mysqld.inc diff --git a/mysql-test/suite/galera/t/MDEV-33136.test b/mysql-test/suite/galera/t/MDEV-33136.test new file mode 100644 index 00000000000..12765ef6dfb --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-33136.test @@ -0,0 +1,44 @@ +# +# MDEV-33136: Properly BF-abort user transactions with explicit locks +# +# User transactions may acquire explicit MDL locks from InnoDB level +# when persistent statistics is re-read for a table. +# If such a transaction would be subject to BF-abort, it was improperly +# detected as a system transaction and wouldn't get aborted. +# +# The fix: Check if a transaction holding explicit MDL locks is a user +# transaction in the MDL conflict handling code. + +--source include/galera_cluster.inc +--source include/have_debug_sync.inc +--source include/have_debug.inc + +--connect node_1a,127.0.0.1,root,,test,$NODE_MYPORT_1 + +--connection node_1 +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; + +--connection node_1a +TRUNCATE TABLE t1; +# TRUNCATE forces the next statement to re-read statistics from persistent storage, +# which will acquire MDL locks on the statistics tables in InnoDB. +SET SESSION wsrep_retry_autocommit = 0; +SET DEBUG_SYNC = 'dict_stats_mdl_acquired SIGNAL may_toi WAIT_FOR bf_abort'; +--send + INSERT INTO t1 VALUES (1); + +--connection node_1 +SET DEBUG_SYNC = 'now WAIT_FOR may_toi'; +TRUNCATE TABLE t1; + +--connection node_1a +# Local INSERT gets aborted. +--error ER_LOCK_DEADLOCK +--reap + +# Cleanup +--connection node_1 +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t1; +--disconnect node_1a +--source include/galera_end.inc diff --git a/mysql-test/suite/galera/t/MDEV-33828.cnf b/mysql-test/suite/galera/t/MDEV-33828.cnf new file mode 100644 index 00000000000..4c62448fe3d --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-33828.cnf @@ -0,0 +1,4 @@ +!include ../galera_2nodes.cnf + +[mysqld] +log-bin diff --git a/mysql-test/suite/galera/t/MDEV-33828.test b/mysql-test/suite/galera/t/MDEV-33828.test new file mode 100644 index 00000000000..8e30481beee --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-33828.test @@ -0,0 +1,45 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_aria.inc + +SET AUTOCOMMIT=ON; +SELECT @@autocommit; + +SET LOCAL enforce_storage_engine=InnoDB; + +CREATE TABLE t1(id int not null primary key auto_increment, name varchar(64)) ENGINE=InnoDB; +INSERT INTO t1(name) VALUES ('name1'),('name3'),('name6'),('name2'); + +DELIMITER |; +CREATE PROCEDURE sel_proc() +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + SELECT * FROM t1; +END| + +CREATE PROCEDURE ins_proc() +BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + INSERT INTO t1 VALUES ('name_proc'); +END| +DELIMITER ;| + +SET AUTOCOMMIT=OFF; +SELECT @@autocommit; + +START TRANSACTION; + +insert into t1(name) values('name10'); + +select param_list, returns, db, type from mysql.proc where name='sel_proc'; + +call ins_proc(); + +COMMIT; + +SET AUTOCOMMIT=ON; + +SELECT * FROM t1; +DROP TABLE t1; +DROP PROCEDURE sel_proc; +DROP PROCEDURE ins_proc; diff --git a/mysql-test/suite/galera/t/MW-336.cnf b/mysql-test/suite/galera/t/MW-336.cnf index e68f891792c..da97be5f86d 100644 --- a/mysql-test/suite/galera/t/MW-336.cnf +++ b/mysql-test/suite/galera/t/MW-336.cnf @@ -2,6 +2,8 @@ [mysqld.1] wsrep-debug=SERVER +loose-wsrep-mw-336=1 [mysqld.2] wsrep-debug=SERVER +loose-wsrep-mw-336=2 diff --git a/mysql-test/suite/galera/t/MW-336.test b/mysql-test/suite/galera/t/MW-336.test index 83943c7d8ea..29a70978e5e 100644 --- a/mysql-test/suite/galera/t/MW-336.test +++ b/mysql-test/suite/galera/t/MW-336.test @@ -3,11 +3,12 @@ # --source include/galera_cluster.inc ---source include/have_innodb.inc --source include/force_restart.inc +--source include/have_sequence.inc --connection node_1 -CREATE TABLE t1 (f1 INTEGER) Engine=InnoDB; +SET @wsrep_slave_threads_orig = @@wsrep_slave_threads; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT) Engine=InnoDB; SET GLOBAL wsrep_slave_threads = 10; @@ -22,7 +23,7 @@ SELECT VARIABLE_VALUE AS EXPECT_10 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE V SET GLOBAL wsrep_slave_threads = 1; --connection node_2 -INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (NULL); --connection node_1 --echo # Wait until one of the appliers has exited @@ -54,27 +55,19 @@ SELECT VARIABLE_VALUE AS EXPECT_20 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE V SET GLOBAL wsrep_slave_threads = 1; --connection node_2 -INSERT INTO t1 VALUES (1); -INSERT INTO t1 VALUES (2); -INSERT INTO t1 VALUES (3); -INSERT INTO t1 VALUES (4); -INSERT INTO t1 VALUES (5); -INSERT INTO t1 VALUES (6); -INSERT INTO t1 VALUES (7); -INSERT INTO t1 VALUES (8); -INSERT INTO t1 VALUES (9); -INSERT INTO t1 VALUES (10); -INSERT INTO t1 VALUES (11); -INSERT INTO t1 VALUES (12); -INSERT INTO t1 VALUES (13); -INSERT INTO t1 VALUES (14); -INSERT INTO t1 VALUES (16); -INSERT INTO t1 VALUES (17); -INSERT INTO t1 VALUES (18); -INSERT INTO t1 VALUES (19); -INSERT INTO t1 VALUES (20); +--disable_query_log +let $c = 50; +while ($c) { +INSERT INTO t1 VALUES(NULL); COMMIT; +dec $c; +} +--enable_query_log --connection node_1 +--let $wait_condition = SELECT COUNT(*) = 51 FROM t1; +--let $wait_condition_on_error_output = SELECT COUNT(*) FROM t1; +--source include/wait_condition_with_debug.inc + --echo # Wait until 19 of the appliers has exited --let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; --let $wait_condition_on_error_output = SELECT COUNT(*), 1 as EXPECTED_VALUE FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE = 'wsrep applier idle'; show processlist @@ -82,7 +75,7 @@ INSERT INTO t1 VALUES (20); SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; -SELECT COUNT(*) FROM t1; +SELECT COUNT(*) AS EXPECT_51 FROM t1; SET GLOBAL wsrep_slave_threads = 10; --echo # Set slave threads to 10 step 3 @@ -96,16 +89,13 @@ SELECT VARIABLE_VALUE AS EXPECT_10 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE V SET GLOBAL wsrep_slave_threads = 1; --connection node_2 -INSERT INTO t1 VALUES (21); -INSERT INTO t1 VALUES (22); -INSERT INTO t1 VALUES (23); -INSERT INTO t1 VALUES (24); -INSERT INTO t1 VALUES (25); -INSERT INTO t1 VALUES (26); -INSERT INTO t1 VALUES (27); -INSERT INTO t1 VALUES (28); -INSERT INTO t1 VALUES (29); -INSERT INTO t1 VALUES (30); +--disable_query_log +let $c = 50; +while ($c) { +INSERT INTO t1 VALUES(NULL); COMMIT; +dec $c; +} +--enable_query_log --connection node_1 --echo # Wait until slave threads back to 1 @@ -115,6 +105,10 @@ INSERT INTO t1 VALUES (30); SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count'; -SELECT COUNT(*) FROM t1; +SELECT COUNT(*) AS EXPECT_101 FROM t1; DROP TABLE t1; + +--disable_query_log +SET GLOBAL wsrep_slave_threads = @wsrep_slave_threads_orig; +--enable_query_log diff --git a/mysql-test/suite/galera/t/MW-369.inc b/mysql-test/suite/galera/t/MW-369.inc index 71df979d6ba..f080d99fe7e 100644 --- a/mysql-test/suite/galera/t/MW-369.inc +++ b/mysql-test/suite/galera/t/MW-369.inc @@ -12,9 +12,9 @@ # START TRANSACTION; # $mw_369_parent_query # node_2 -# $mw_369_child_query - will be blocked on node_1 in apply monitor +# $mw_369_child_query - will be blocked on node_1 in wsrep_apply_cb # node_1: -# COMMIT; - will be blocked on node_1 in local monitor +# COMMIT; - will be blocked on node_1 in wsrep_after_certification # # The $mw_369_child_query is always expected to succeed. The caller is # responsible for checking if the final COMMIT on connection node_1 @@ -32,8 +32,7 @@ START TRANSACTION; # --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 --connection node_1a SET SESSION wsrep_sync_wait = 0; ---let $galera_sync_point = apply_monitor_slave_enter_sync ---source include/galera_set_sync_point.inc +SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb"; # # insert client row, which will make it impossible to replay the @@ -47,28 +46,37 @@ SET SESSION wsrep_sync_wait = 0; # block the 'COMMIT' from node_1 before it certifies. # --connection node_1a ---source include/galera_wait_sync_point.inc ---source include/galera_clear_sync_point.inc - ---let $galera_sync_point = local_monitor_master_enter_sync ---source include/galera_set_sync_point.inc +SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached"; --connection node_1 +SET DEBUG_SYNC = "wsrep_after_certification SIGNAL after_certification_reached WAIT_FOR continue_after_certification"; --send COMMIT # # Wait until both sync points have been reached # --connection node_1a ---let $galera_sync_point = apply_monitor_slave_enter_sync local_monitor_master_enter_sync ---source include/galera_wait_sync_point.inc +SET SESSION DEBUG_SYNC = "now WAIT_FOR after_certification_reached"; # # both threads are now parked in sync points, signal them to continue # ---let $galera_sync_point = apply_monitor_slave_enter_sync ---source include/galera_signal_sync_point.inc ---let $galera_sync_point = local_monitor_master_enter_sync ---source include/galera_signal_sync_point.inc ---source include/galera_clear_sync_point.inc +--let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'debug sync point:%' +--let $wait_condition_on_error_output = SELECT STATE FROM INFORMATION_SCHEMA.PROCESSLIST +--source include/wait_condition_with_debug.inc + +SET DEBUG_SYNC = 'now SIGNAL continue_after_certification'; + +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'debug sync point:%' +--let $wait_condition_on_error_output = SELECT STATE FROM INFORMATION_SCHEMA.PROCESSLIST +--source include/wait_condition_with_debug.inc + +SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; + +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'debug sync point:%' +--let $wait_condition_on_error_output = SELECT STATE FROM INFORMATION_SCHEMA.PROCESSLIST +--source include/wait_condition_with_debug.inc + +SET GLOBAL DEBUG_DBUG = ""; +SET DEBUG_SYNC = 'RESET'; diff --git a/mysql-test/suite/galera/t/MW-369.test b/mysql-test/suite/galera/t/MW-369.test index c8f8c974019..0efac20dbe0 100644 --- a/mysql-test/suite/galera/t/MW-369.test +++ b/mysql-test/suite/galera/t/MW-369.test @@ -24,7 +24,6 @@ --source include/galera_cluster.inc --source include/have_innodb.inc --source include/have_debug_sync.inc ---source include/galera_have_debug_sync.inc CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, diff --git a/mysql-test/suite/galera/t/galera_bf_abort_mariabackup.test b/mysql-test/suite/galera/t/galera_bf_abort_mariabackup.test index 34c3f5d3621..ed16ac3926c 100644 --- a/mysql-test/suite/galera/t/galera_bf_abort_mariabackup.test +++ b/mysql-test/suite/galera/t/galera_bf_abort_mariabackup.test @@ -13,7 +13,7 @@ CREATE TABLE t(i INT NOT NULL PRIMARY KEY) ENGINE INNODB; INSERT INTO t VALUES(1); # -# In default settings donor should desync +# In default settings donor should not desync # --echo # Restart node_2, force SST. --connection node_2 @@ -37,7 +37,7 @@ let $restart_noprint=2; --connection node_1 let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err; ---echo # Both should return FOUND 2 as we have bootstrap and SST +--echo # Both should return NOT FOUND as we have mariabackup with backup locks let SEARCH_PATTERN = Desyncing and pausing the provider; --source include/search_pattern_in_file.inc let SEARCH_PATTERN = Resuming and resyncing the provider; @@ -76,7 +76,7 @@ let $restart_noprint=2; --connection node_1 let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err; ---echo # Both should return FOUND 3 as we have 1 new SST +--echo # Both should return NOT FOUND as we have mariabackup with backup locks let SEARCH_PATTERN = Desyncing and pausing the provider; --source include/search_pattern_in_file.inc let SEARCH_PATTERN = Resuming and resyncing the provider; @@ -117,13 +117,16 @@ let $targetdir=$MYSQLTEST_VARDIR/tmp/backup2; --enable_result_log let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.2.err; ---echo # Both should return FOUND 1 as node should not desync +--echo # Both should return FOUND 2 because both backups do desync but on different points let SEARCH_PATTERN = Desyncing and pausing the provider; --source include/search_pattern_in_file.inc let SEARCH_PATTERN = Resuming and resyncing the provider; --source include/search_pattern_in_file.inc ---echo # Should return FOUND 1 because only last backup does not desync -let SEARCH_PATTERN = Server not desynched from group because WSREP_MODE_BF_MARIABACKUP used.; +--echo # Should return FOUND 1 as server did not desync at BLOCK_DDL +let SEARCH_PATTERN = Server not desynched from group at BLOCK_DDL because WSREP_MODE_BF_MARIABACKUP is used.; +--source include/search_pattern_in_file.inc +--echo # Should return FOUND 1 as server did desync and pause at BLOCK_COMMIT +let SEARCH_PATTERN = Server desynched from group during BACKUP STAGE BLOCK_COMMIT.; --source include/search_pattern_in_file.inc SET GLOBAL wsrep_mode = ""; diff --git a/mysql-test/suite/galera/t/galera_ist_mariabackup_verify_ca.cnf b/mysql-test/suite/galera/t/galera_ist_mariabackup_verify_ca.cnf index f2187b83486..ffd2306bfb3 100644 --- a/mysql-test/suite/galera/t/galera_ist_mariabackup_verify_ca.cnf +++ b/mysql-test/suite/galera/t/galera_ist_mariabackup_verify_ca.cnf @@ -10,9 +10,11 @@ ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem [mysqld.1] wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true' +innodb-log-file-buffering [mysqld.2] wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true' +innodb-log-file-buffering [sst] ssl-mode=VERIFY_CA diff --git a/mysql-test/suite/galera/t/galera_ist_restart_joiner.test b/mysql-test/suite/galera/t/galera_ist_restart_joiner.test index b36a0de57b6..940b511f752 100644 --- a/mysql-test/suite/galera/t/galera_ist_restart_joiner.test +++ b/mysql-test/suite/galera/t/galera_ist_restart_joiner.test @@ -37,7 +37,7 @@ UPDATE t1 SET f2 = 'c' WHERE f1 > 2; # Write file to make mysql-test-run.pl expect the crash, but don't start it --let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')` --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect ---exec echo "wait" > $_expect_file_name +--write_line wait $_expect_file_name --let KILL_NODE_PIDFILE = `SELECT @@pid_file` diff --git a/mysql-test/suite/galera/t/galera_load_data.test b/mysql-test/suite/galera/t/galera_load_data.test index c37920a43c4..252580f9426 100644 --- a/mysql-test/suite/galera/t/galera_load_data.test +++ b/mysql-test/suite/galera/t/galera_load_data.test @@ -30,8 +30,308 @@ CREATE TABLE cardtest_tbl ( LOCK TABLES cardtest_tbl WRITE; ALTER TABLE cardtest_tbl DISABLE KEYS; -INSERT INTO cardtest_tbl VALUES (1,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(2,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(3,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(4,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(5,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(6,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(7,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(8,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(9,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(10,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(11,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(12,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(13,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(14,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(15,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(16,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(17,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(18,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(19,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(20,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(21,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(22,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(23,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(24,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(25,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(26,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(27,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(28,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(29,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(30,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(31,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(32,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(33,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(34,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(35,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(36,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(37,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(38,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(39,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(40,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(41,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(42,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(43,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(44,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(45,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(46,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(47,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(48,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(49,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(50,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(51,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(52,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(53,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(54,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(55,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(56,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(57,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(58,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(59,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(60,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(61,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(62,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(63,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(64,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(65,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(66,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(67,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(68,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(69,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(70,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(71,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(72,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(73,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(74,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(75,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(76,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(77,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(78,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(79,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(80,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(81,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(82,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(83,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(84,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(85,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(86,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(87,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(88,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(89,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(90,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(91,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(92,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(93,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(94,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(95,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(96,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(97,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(98,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(99,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(100,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(101,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(102,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(103,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(104,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(105,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(106,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(107,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(108,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(109,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(110,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(111,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(112,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(113,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(114,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(115,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(116,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(117,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(118,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(119,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(120,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(121,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(122,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(123,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(124,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(125,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(126,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(127,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(128,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(129,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(130,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(131,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(132,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(133,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(134,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(135,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(136,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(137,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(138,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(139,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(140,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(141,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(142,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(143,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(144,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(145,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(146,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(147,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(148,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(149,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(150,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(151,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(152,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(153,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(154,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(155,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(156,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(157,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(158,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(159,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(160,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(161,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(162,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(163,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(164,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(165,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(166,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(167,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(168,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(169,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(170,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(171,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(172,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(173,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(174,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(175,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(176,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(177,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(178,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(179,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(180,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(181,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(182,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(183,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(184,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(185,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(186,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(187,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(188,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(189,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(190,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(191,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(192,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(193,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(194,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(195,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(196,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(197,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(198,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(199,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(200,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(201,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(202,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(203,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(204,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(205,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(206,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(207,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(208,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(209,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(210,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(211,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(212,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(213,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(214,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(215,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(216,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(217,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(218,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(219,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(220,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(221,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(222,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(223,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(224,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(225,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(226,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(227,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(228,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(229,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(230,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(231,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(232,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(233,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(234,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(235,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(236,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(237,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(238,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(239,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(240,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(241,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(242,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(243,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(244,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(245,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(246,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(247,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(248,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(249,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(250,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(251,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(252,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(253,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(254,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(255,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(256,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(257,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(258,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(259,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(260,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(261,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(262,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(263,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(264,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(265,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(266,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(267,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(268,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(269,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(270,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(271,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(272,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(273,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(274,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(275,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(276,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(277,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(278,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(279,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(280,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(281,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(282,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(283,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(284,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(285,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(286,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(287,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(288,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(289,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(290,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(291,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(292,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(293,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(294,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(295,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(296,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(297,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(298,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(299,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(300,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL),(301,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL); - +INSERT INTO cardtest_tbl VALUES + (1,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (2,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (3,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (4,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (5,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (6,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (7,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (8,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (9,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (10,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (11,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (12,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (13,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (14,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (15,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (16,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (17,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (18,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (19,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (20,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (21,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (22,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (23,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (24,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (25,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (26,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (27,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (28,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (29,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (30,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (31,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (32,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (33,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (34,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (35,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (36,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (37,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (38,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (39,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (40,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (41,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (42,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (43,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (44,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (45,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (46,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (47,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (48,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (49,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (50,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (51,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (52,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (53,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (54,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (55,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (56,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (57,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (58,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (59,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (60,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (61,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (62,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (63,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (64,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (65,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (66,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (67,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (68,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (69,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (70,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (71,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (72,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (73,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (74,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (75,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (76,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (77,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (78,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (79,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (80,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (81,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (82,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (83,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (84,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (85,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (86,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (87,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (88,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (89,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (90,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (91,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (92,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (93,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (94,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (95,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (96,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (97,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (98,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (99,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (100,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (101,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (102,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (103,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (104,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (105,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (106,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (107,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (108,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (109,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (110,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (111,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (112,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (113,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (114,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (115,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (116,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (117,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (118,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (119,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (120,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (121,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (122,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (123,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (124,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (125,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (126,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (127,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (128,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (129,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (130,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (131,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (132,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (133,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (134,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (135,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (136,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (137,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (138,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (139,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (140,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (141,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (142,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (143,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (144,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (145,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (146,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (147,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (148,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (149,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (150,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (151,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (152,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (153,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (154,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (155,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (156,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (157,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (158,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (159,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (160,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (161,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (162,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (163,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (164,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (165,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (166,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (167,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (168,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (169,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (170,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (171,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (172,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (173,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (174,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (175,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (176,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (177,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (178,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (179,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (180,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (181,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (182,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (183,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (184,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (185,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (186,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (187,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (188,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (189,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (190,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (191,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (192,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (193,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (194,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (195,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (196,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (197,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (198,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (199,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (200,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (201,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (202,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (203,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (204,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (205,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (206,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (207,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (208,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (209,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (210,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (211,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (212,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (213,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (214,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (215,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (216,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (217,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (218,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (219,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (220,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (221,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (222,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (223,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (224,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (225,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (226,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (227,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (228,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (229,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (230,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (231,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (232,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (233,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (234,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (235,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (236,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (237,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (238,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (239,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (240,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (241,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (242,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (243,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (244,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (245,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (246,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (247,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (248,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (249,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (250,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (251,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (252,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (253,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (254,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (255,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (256,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (257,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (258,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (259,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (260,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (261,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (262,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (263,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (264,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (265,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (266,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (267,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (268,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (269,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (270,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (271,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (272,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (273,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (274,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (275,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (276,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (277,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (278,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (279,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (280,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (281,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (282,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (283,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (284,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (285,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (286,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (287,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (288,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (289,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (290,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (291,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (292,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (293,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (294,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (295,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (296,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (297,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (298,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (299,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (300,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL), + (301,1,'','',1,1466430455,1471454450,NULL,10.00000,1,NULL,'','',NULL,NULL,1,NULL,NULL); ALTER TABLE cardtest_tbl ENABLE KEYS; UNLOCK TABLES; diff --git a/mysql-test/suite/galera/t/galera_mdl_race.test b/mysql-test/suite/galera/t/galera_mdl_race.test index ad6770f9991..3341a3792f1 100644 --- a/mysql-test/suite/galera/t/galera_mdl_race.test +++ b/mysql-test/suite/galera/t/galera_mdl_race.test @@ -3,70 +3,92 @@ # --source include/galera_cluster.inc +--source include/have_debug.inc --source include/have_debug_sync.inc +--connection node_1 CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)) engine=innodb; CREATE TABLE t2 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)) engine=innodb; INSERT INTO t1 VALUES (1, 'a'); INSERT INTO t1 VALUES (2, 'a'); ---connection node_1 SET AUTOCOMMIT=ON; START TRANSACTION; - UPDATE t1 SET f2 = 'b' WHERE f1 = 1; # block access to t2 --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 --connection node_1a +SET SESSION wsrep_sync_wait=0; +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2' +--let $wait_condition_on_error_output = SELECT * FROM INFORMATION_SCHEMA.TABLES +--source include/wait_condition_with_debug.inc LOCK TABLE t2 WRITE; -# Block before MLD lock wait +# Block before MDL lock wait --connection node_1 - SET @@debug_dbug = "d,sync.wsrep_before_mdl_wait"; +SET DEBUG_SYNC= 'wsrep_before_mdl_wait SIGNAL before_mdl_wait WAIT_FOR mdl_wait_continue'; --send SELECT * FROM t2; -# Wait for SELECT to be blocked --connection node_1a -#--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIS WHERE STATE = 'System lock'; -#--source include/wait_condition.inc -#--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'init' AND INFO = 'COMMIT'; -#--source include/wait_condition.inc +--echo # Wait until select is blocked before MDL lock wait +SET DEBUG_SYNC= 'now WAIT_FOR before_mdl_wait'; # block applier to wait after BF victim is locked +--connection node_1a SET @@debug_dbug = "d,sync.wsrep_after_BF_victim_lock"; # Issue a conflicting update on node #2 --connection node_2 UPDATE t1 SET f2 = 'c' WHERE f1 = 1; -# Unblock the SELECT, to enter wsrep_thd_is_BF ---connection node_1a -SET @@debug_dbug = ""; -SET DEBUG_SYNC = "now SIGNAL signal.wsrep_before_mdl_wait"; +--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1b +SET SESSION wsrep_sync_wait=0; +--echo # Wait for conflicting update to block +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'Update_rows_log_event:%'; +--source include/wait_condition.inc -# unblock applier to try to BF the SELECT +# Unblock the SELECT, to enter wsrep_thd_is_BF SET DEBUG_SYNC = "now SIGNAL signal.wsrep_after_BF_victim_lock"; +--connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1c +--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'Update_rows_log_event:%'; +--source include/wait_condition.inc + +--connection node_1a +# unblock applier to try to BF the SELECT +SET DEBUG_SYNC = "now SIGNAL BF_victim_continue"; + # table lock is not needed anymore UNLOCK TABLES; -# SELECT succeeds +# SELECT returns deadlock --connection node_1 - --error ER_LOCK_DEADLOCK --reap -SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'a'; -SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'c'; +--connection node_1 +SELECT COUNT(*) AS EXPECT_1 FROM t1 WHERE f2 = 'a'; +SELECT COUNT(*) AS EXPECT_1 FROM t1 WHERE f2 = 'c'; +SELECT * FROM t1; --connection node_2 -SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'a'; -SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'c'; +SELECT COUNT(*) AS EXPECT_1 FROM t1 WHERE f2 = 'a'; +SELECT COUNT(*) AS EXPECT_1 FROM t1 WHERE f2 = 'c'; +SELECT * FROM t1; DROP TABLE t1; DROP TABLE t2; --connection node_1a SET DEBUG_SYNC = "RESET"; +--connection node_1b +SET DEBUG_SYNC = "RESET"; + +--connection node_1 +--disconnect node_1a +--disconnect node_1b +--disconnect node_1c diff --git a/mysql-test/suite/galera/t/galera_myisam_autocommit.test b/mysql-test/suite/galera/t/galera_myisam_autocommit.test index 3452a06a16c..0612aabb233 100644 --- a/mysql-test/suite/galera/t/galera_myisam_autocommit.test +++ b/mysql-test/suite/galera/t/galera_myisam_autocommit.test @@ -2,22 +2,24 @@ --source include/have_innodb.inc # -# This tests simple autocommit replication of MyISAM tables. No updates arrive on the slave. +# This tests simple autocommit replication of MyISAM tables. # -# Without a PK - SET GLOBAL wsrep_mode=REPLICATE_MYISAM; +# Without a PK + CREATE TABLE t1 (f1 INTEGER) ENGINE=MyISAM; INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (2), (3); +# This is TOI INSERT INTO t1 SELECT 4 FROM DUAL UNION ALL SELECT 5 FROM DUAL; CREATE TABLE t2 (f1 INTEGER PRIMARY KEY) ENGINE=MyISAM; INSERT INTO t2 VALUES (1); INSERT INTO t2 VALUES (2), (3); +# This is TOI INSERT INTO t2 SELECT 4 FROM DUAL UNION ALL SELECT 5 FROM DUAL; # Error @@ -34,16 +36,26 @@ UPDATE t2 SET f1 = 9 WHERE f1 = 1; DELETE FROM t1 WHERE f1 = 9; DELETE FROM t2 WHERE f1 = 9; +SELECT * FROM t1 ORDER BY f1; +SELECT * FROM t2 ORDER BY f1; + +--connection node_2 +SELECT * FROM t1 ORDER BY f1; +SELECT * FROM t2 ORDER BY f1; + # TRUNCATE TRUNCATE TABLE t1; -TRUNCATE TABLE t1; +TRUNCATE TABLE t2; + +SELECT * FROM t1 ORDER BY f1; +SELECT * FROM t2 ORDER BY f1; --connection node_2 -SELECT COUNT(*) = 0 FROM t1; -SELECT COUNT(*) = 0 FROM t2; +SELECT * FROM t1 ORDER BY f1; +SELECT * FROM t2 ORDER BY f1; --connection node_1 +SET GLOBAL wsrep_mode=DEFAULT; DROP TABLE t1; DROP TABLE t2; -SET GLOBAL wsrep_mode=DEFAULT; diff --git a/mysql-test/suite/galera/t/galera_parallel_apply_lock_table.test b/mysql-test/suite/galera/t/galera_parallel_apply_lock_table.test index 2e9f05cb4af..b49253efc02 100644 --- a/mysql-test/suite/galera/t/galera_parallel_apply_lock_table.test +++ b/mysql-test/suite/galera/t/galera_parallel_apply_lock_table.test @@ -32,7 +32,7 @@ INSERT INTO t2 VALUES (1); --connection node_2a --sleep 1 SET SESSION wsrep_sync_wait=0; -SELECT COUNT(*) AS EXPECT_1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE (STATE LIKE '%committing%' or STATE = 'Waiting for certification'); +SELECT COUNT(*) AS EXPECT_1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE (STATE LIKE 'Commit' or STATE = 'Waiting for certification'); SELECT COUNT(*) AS EXPECT_1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%Waiting for table metadata lock%'; SELECT COUNT(*) AS EXPECT_0 FROM t1; SELECT COUNT(*) AS EXPECT_0 FROM t2; diff --git a/mysql-test/suite/galera/t/galera_parallel_simple.test b/mysql-test/suite/galera/t/galera_parallel_simple.test index d49dc0ae876..89adaf8cbd2 100644 --- a/mysql-test/suite/galera/t/galera_parallel_simple.test +++ b/mysql-test/suite/galera/t/galera_parallel_simple.test @@ -51,7 +51,7 @@ SET SESSION wsrep_sync_wait = 0; --let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'Waiting for table metadata lock%'; --source include/wait_condition.inc ---let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'committing%'; +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'Commit'; --source include/wait_condition.inc UNLOCK TABLES; diff --git a/mysql-test/suite/galera/t/galera_pc_recovery.test b/mysql-test/suite/galera/t/galera_pc_recovery.test index 1621414aff5..16abe6fc9ba 100644 --- a/mysql-test/suite/galera/t/galera_pc_recovery.test +++ b/mysql-test/suite/galera/t/galera_pc_recovery.test @@ -27,8 +27,8 @@ INSERT INTO t1 VALUES (1); SELECT COUNT(*) = 1 FROM t1; --let $NODE_2_PIDFILE = `SELECT @@pid_file` ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.2.expect --exec kill -9 `cat $NODE_1_PIDFILE` `cat $NODE_2_PIDFILE` # Perform --wsrep-recover and preserve the positions into variables by placing them in $MYSQL_TMP_DIR/galera_wsrep_start_position.inc and then --source'ing it @@ -66,8 +66,8 @@ if ($galera_wsrep_start_position2 == '') { # Instruct MTR to perform the actual restart using --wsrep-start-position . Proper --wsrep_cluster_address is used as my.cnf only contains 'gcomm://' for node #1 ---exec echo "restart: --wsrep-start-position=$galera_wsrep_start_position1 --wsrep_cluster_address=gcomm://127.0.0.1:$NODE_GALERAPORT_1,127.0.0.1:$NODE_GALERAPORT_2" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect ---exec echo "restart: --wsrep-start-position=$galera_wsrep_start_position2 --wsrep_cluster_address=gcomm://127.0.0.1:$NODE_GALERAPORT_1,127.0.0.1:$NODE_GALERAPORT_2" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--write_line "restart: --wsrep-start-position=$galera_wsrep_start_position1 --wsrep_cluster_address=gcomm://127.0.0.1:$NODE_GALERAPORT_1,127.0.0.1:$NODE_GALERAPORT_2" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart: --wsrep-start-position=$galera_wsrep_start_position2 --wsrep_cluster_address=gcomm://127.0.0.1:$NODE_GALERAPORT_1,127.0.0.1:$NODE_GALERAPORT_2" $MYSQLTEST_VARDIR/tmp/mysqld.2.expect --sleep 5 --connection node_1 diff --git a/mysql-test/suite/galera/t/galera_restart_on_unknown_option.test b/mysql-test/suite/galera/t/galera_restart_on_unknown_option.test index 6a0f24dbaae..e3a8b749cb4 100644 --- a/mysql-test/suite/galera/t/galera_restart_on_unknown_option.test +++ b/mysql-test/suite/galera/t/galera_restart_on_unknown_option.test @@ -62,7 +62,7 @@ SELECT * FROM t1; --let $start_mysqld_params=--galera-unknown-option --echo Starting server ... ---exec echo "try:$start_mysqld_params" > $_expect_file_name +--write_line "try:$start_mysqld_params" $_expect_file_name # Sleep to ensure that server exited... @@ -107,7 +107,7 @@ SELECT * FROM t1; --let $start_mysqld_params=--galera-unknown-option --echo Starting server ... ---exec echo "try:$start_mysqld_params" > $_expect_file_name +--write_line "try:$start_mysqld_params" $_expect_file_name # Sleep to ensure that server exited... diff --git a/mysql-test/suite/galera/t/galera_sequence_engine.test b/mysql-test/suite/galera/t/galera_sequence_engine.test new file mode 100644 index 00000000000..47107dcce84 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sequence_engine.test @@ -0,0 +1,16 @@ +--source include/galera_cluster.inc +--source include/have_sequence.inc + +SET GLOBAL wsrep_ignore_apply_errors=0; +SET SESSION AUTOCOMMIT=0; +SET SESSION max_error_count=0; +--error ER_NOT_SUPPORTED_YET +CREATE TABLE t0 (id GEOMETRY,parent_id GEOMETRY)ENGINE=SEQUENCE; + +--connection node_2 +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE t0; + +--connection node_1 +SET GLOBAL wsrep_ignore_apply_errors=DEFAULT; + diff --git a/mysql-test/suite/galera/t/galera_shutdown_nonprim.test b/mysql-test/suite/galera/t/galera_shutdown_nonprim.test index cf7018cd751..d1a1c91456b 100644 --- a/mysql-test/suite/galera/t/galera_shutdown_nonprim.test +++ b/mysql-test/suite/galera/t/galera_shutdown_nonprim.test @@ -16,21 +16,27 @@ SET GLOBAL wsrep_provider_options = 'pc.weight=2'; --connection node_2 # Isolate node_2 from the group and wait until wsrep_ready becomes OFF. -SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; SET SESSION wsrep_sync_wait = 0; ---let $wait_condition = SELECT VARIABLE_VALUE = 'OFF' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready' ---source include/wait_condition.inc - -# Verify that graceful shutdown succeeds. ---source include/shutdown_mysqld.inc ---source include/start_mysqld.inc - ---let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; ---source include/wait_condition.inc +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; --connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--connection node_2 +--let $wait_condition = SELECT VARIABLE_VALUE = 'OFF' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready' +--source include/wait_condition.inc +SHOW STATUS LIKE 'wsrep_cluster_status'; +# Verify that graceful shutdown succeeds. +--source include/shutdown_mysqld.inc + +--source include/start_mysqld.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --source include/wait_condition.inc # Restore original settings. SET GLOBAL wsrep_provider_options = 'pc.weight = 1'; + --source include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup.cnf b/mysql-test/suite/galera/t/galera_sst_mariabackup.cnf index 857a4101406..6cb80831d1f 100644 --- a/mysql-test/suite/galera/t/galera_sst_mariabackup.cnf +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup.cnf @@ -7,9 +7,14 @@ wsrep_debug=1 [mysqld.1] wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' +innodb_fast_shutdown=0 +innodb_undo_tablespaces=0 [mysqld.2] wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true' +innodb_fast_shutdown=0 +innodb_undo_tablespaces=3 +innodb_log_file_buffering [sst] transferfmt=@ENV.MTR_GALERA_TFMT diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup.test b/mysql-test/suite/galera/t/galera_sst_mariabackup.test index bcb9ade3a25..96f8b4dca55 100644 --- a/mysql-test/suite/galera/t/galera_sst_mariabackup.test +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup.test @@ -1,6 +1,5 @@ --source include/big_test.inc --source include/galera_cluster.inc ---source include/have_innodb.inc --source include/have_mariabackup.inc # Save original auto_increment_offset values. @@ -8,12 +7,39 @@ --let $node_2=node_2 --source include/auto_increment_offset_save.inc +--connection node_1 +select @@innodb_undo_tablespaces; + +--connection node_2 +select @@innodb_undo_tablespaces; + --source suite/galera/include/galera_st_shutdown_slave.inc --source suite/galera/include/galera_st_clean_slave.inc --source suite/galera/include/galera_st_kill_slave.inc --source suite/galera/include/galera_st_kill_slave_ddl.inc +--connection node_2 +--echo Shutting down server ... +--source include/shutdown_mysqld.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +--connection node_2 +--echo Starting server ... +--source include/start_mysqld.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +--connection node_2 +select @@innodb_undo_tablespaces; + +call mtr.add_suppression("InnoDB: Cannot change innodb_undo_tablespaces=3 because previous shutdown was not with innodb_fast_shutdown=0"); + # Restore original auto_increment_offset values. --source include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera/t/galera_table_with_hyphen.inc b/mysql-test/suite/galera/t/galera_table_with_hyphen.inc new file mode 100644 index 00000000000..ac79d864e82 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_table_with_hyphen.inc @@ -0,0 +1,48 @@ +# +# parameters: +# $fk_child - child table name +# $fk_parent - parent table name +# +--connection node_1 +SET GLOBAL wsrep_slave_threads=2; + +--eval CREATE TABLE `$fk_parent` ( id INT AUTO_INCREMENT PRIMARY KEY, j INT) ENGINE=InnoDB + +--eval CREATE TABLE `$fk_child` (id INT AUTO_INCREMENT PRIMARY KEY, parent_id INT, j INT, FOREIGN KEY (parent_id) REFERENCES `$fk_parent`(id)) ENGINE=InnoDB + +--eval INSERT INTO `$fk_parent` VALUES (23,0) + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM `$fk_parent`; +--source include/wait_condition.inc + +--connection node_1a +SET GLOBAL DEBUG_DBUG='+d,wsrep_ha_write_row'; + +--connection node_2 +--eval INSERT INTO `$fk_child` VALUES (21,23,0),(22,23,0),(23,23,0) + +--connection node_1a +SET DEBUG_SYNC='now WAIT_FOR wsrep_ha_write_row_reached'; + +--let $wsrep_received_before = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME = 'wsrep_received'` + +--connection node_2 +--eval UPDATE `$fk_parent` SET j=2 WHERE id=23 + +--connection node_1a +--let $wait_condition = SELECT VARIABLE_VALUE = $wsrep_received_before + 1 FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME = 'wsrep_received' +--source include/wait_condition.inc + +SET GLOBAL DEBUG_DBUG='-d,wsrep_ha_write_row'; +SET DEBUG_SYNC='now SIGNAL wsrep_ha_write_row_continue'; + +SET GLOBAL DEBUG_DBUG="RESET"; +SET DEBUG_SYNC = 'RESET'; + +SET GLOBAL wsrep_slave_threads=DEFAULT; + +--connection node_2 +--eval drop table `$fk_child` +--eval drop table `$fk_parent` + diff --git a/mysql-test/suite/galera/t/galera_table_with_hyphen.test b/mysql-test/suite/galera/t/galera_table_with_hyphen.test new file mode 100644 index 00000000000..1b28bdeb3ca --- /dev/null +++ b/mysql-test/suite/galera/t/galera_table_with_hyphen.test @@ -0,0 +1,34 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +# +# Testing how tables and databases with special characters +# are treated in certification +# +# The test creates two tables having foreign key constraint +# reference and executes two transactions which modify +# same rows. The same test is executed with different names +# containin special characters to see if the certification +# can detect the conflicts +# +# Actual test is in include file galera_table_with_hyphen.inc +# It create the test tables from parameters $fk_child and +# $fk_parent +# +--connection node_1 +set wsrep_sync_wait=0; + +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +SET SESSION wsrep_sync_wait = 0; + +--let $fk_child = child +--let $fk_parent = par-ent + +--source galera_table_with_hyphen.inc + +--let $fk_child = c-hild +--let $fk_parent = p-arent- + +--source galera_table_with_hyphen.inc diff --git a/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.cnf b/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.cnf index 022cfcdc0b0..b2cba42c0bd 100644 --- a/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.cnf +++ b/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.cnf @@ -2,9 +2,3 @@ [mysqld] wsrep-ignore-apply-errors=0 - -[mysqld.3] -auto_increment_offset=3 - -[mysqld.4] -auto_increment_offset=4 diff --git a/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.test b/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.test index 5e74af4ab2e..e21c271cba0 100644 --- a/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.test +++ b/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.test @@ -6,25 +6,15 @@ --source include/galera_cluster.inc --source include/big_test.inc -# Save original auto_increment_offset values. ---let $node_1=node_1 ---let $node_2=node_2 ---source include/auto_increment_offset_save.inc -# The following has to be set hard as these connection doesn't yet exists and -# the auto_increment_offset value changes during the lifetime of the servers. ---let $node_3=node_3 ---let $auto_increment_offset_node_3 = 3; ---let $node_4=node_4 ---let $auto_increment_offset_node_4 = 4; - --connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 --connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4 +# Save original auto_increment_offset values. --let $node_1=node_1 --let $node_2=node_2 --let $node_3=node_3 --let $node_4=node_4 ---source suite/galera/include/auto_increment_offset_save.inc +--source include/auto_increment_offset_save.inc --connection node_3 # Isolate node #3 @@ -92,6 +82,7 @@ CALL mtr.add_suppression("Slave SQL: Error 'Unknown table"); --connection node_3 SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; SELECT COUNT(*) AS expect_1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; +CALL mtr.add_suppression("WSREP: Vote 0 \\(success\\) on .* is inconsistent with group. Leaving cluster."); --connection node_4 SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; @@ -105,3 +96,6 @@ DROP TABLE t2; --let $node_4=node_4 --let $auto_increment_offset_node_4 = 4; --source suite/galera/include/auto_increment_offset_restore.inc + +--disconnect node_3 +--disconnect node_4 diff --git a/mysql-test/suite/galera/t/galera_wan_restart_sst.test b/mysql-test/suite/galera/t/galera_wan_restart_sst.test index 7a8c0df4946..e904f46c06a 100644 --- a/mysql-test/suite/galera/t/galera_wan_restart_sst.test +++ b/mysql-test/suite/galera/t/galera_wan_restart_sst.test @@ -11,6 +11,7 @@ --source include/big_test.inc --source include/galera_cluster.inc --source include/have_innodb.inc +--source include/force_restart.inc --connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 --connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4 @@ -27,7 +28,7 @@ SELECT VARIABLE_VALUE AS EXPECT_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --connection node_1 -CREATE TABLE t1 (f1 INTEGER); +CREATE TABLE t1 (f1 INTEGER NOT NULL PRIMARY KEY) ENGINE=INNODB; INSERT INTO t1 VALUES (1); --connection node_2 @@ -45,10 +46,20 @@ INSERT INTO t1 VALUES (4); --connection node_3 INSERT INTO t1 VALUES (13); - ---source include/kill_galera.inc +--let $wait_condition = SELECT COUNT(*) = 5 FROM t1; +--source include/wait_condition.inc --connection node_1 +--let $wait_condition = SELECT COUNT(*) = 5 FROM t1; +--source include/wait_condition.inc + +--connection node_3 +--source include/kill_galera.inc +--remove_file $MYSQLTEST_VARDIR/mysqld.3/data/grastate.dat + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc INSERT INTO t1 VALUES (11); --connection node_2 @@ -62,6 +73,10 @@ INSERT INTO t1 VALUES (14); INSERT INTO t1 VALUES (131); +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + # # Restart node #2 # @@ -69,9 +84,17 @@ INSERT INTO t1 VALUES (131); --connection node_2 INSERT INTO t1 VALUES (22); +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 10 FROM t1; +--source include/wait_condition.inc + +--connection node_2 --source include/kill_galera.inc +--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat --connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc INSERT INTO t1 VALUES (21); --connection node_3 @@ -90,11 +113,21 @@ INSERT INTO t1 VALUES (221); # --connection node_4 +--let $wait_condition = SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc INSERT INTO t1 VALUES (34); +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 15 FROM t1; +--source include/wait_condition.inc + +--connection node_4 --source include/kill_galera.inc +--remove_file $MYSQLTEST_VARDIR/mysqld.4/data/grastate.dat --connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc INSERT INTO t1 VALUES (31); --connection node_2 @@ -105,6 +138,7 @@ INSERT INTO t1 VALUES (33); --connection node_4 --source include/start_mysqld.inc +--remove_file $MYSQLTEST_VARDIR/mysqld.4/data/grastate.dat INSERT INTO t1 VALUES (341); diff --git a/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test b/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test index 94ea008cb16..cfa5f8bcead 100644 --- a/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test +++ b/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test @@ -30,7 +30,7 @@ --echo Starting server ... --let $restart_noprint=2 ---let $start_mysqld_params="--wsrep-new-cluster" +--let $start_mysqld_params=--wsrep-new-cluster --source include/start_mysqld.inc --source include/wait_until_ready.inc diff --git a/mysql-test/suite/galera/t/mdev-22063.test b/mysql-test/suite/galera/t/mdev-22063.test new file mode 100644 index 00000000000..d0f3e3bc4b4 --- /dev/null +++ b/mysql-test/suite/galera/t/mdev-22063.test @@ -0,0 +1,184 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_log_bin.inc +--source include/have_sequence.inc +--source include/have_aria.inc + +--echo # Case 1 CREATE SEQUENCE with no NOCACHE +--error ER_NOT_SUPPORTED_YET +CREATE SEQUENCE s ENGINE=InnoDB; +CREATE SEQUENCE s NOCACHE ENGINE=InnoDB; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +START TRANSACTION; +REPLACE INTO s VALUES (1,1,9223372036854775806,1,1,1000,0,0); +OPTIMIZE TABLE t1; +SELECT * FROM t1; +SELECT * FROM s; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1' +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 's' +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1 FROM test.s; +--source include/wait_condition.inc + +SELECT * FROM t1; +SELECT * FROM s; + +--connection node_1 +DROP TABLE t1; +DROP SEQUENCE s; + +--echo # Case 2 REPLACE INTO ... SELECT with error +CREATE TABLE t (id INT KEY,a YEAR,INDEX (id,a)) engine=innodb; +--error ER_WRONG_VALUE_COUNT_ON_ROW +REPLACE INTO t (id,a)SELECT /*!99997 */ 1; +REPLACE INTO t (id,a)SELECT /*!99997 */ 1,2; +SELECT * FROM t; + +CREATE TABLE t2 (id INT KEY,a YEAR,INDEX (id,a)) engine=myisam; +--error ER_WRONG_VALUE_COUNT_ON_ROW +REPLACE INTO t2 (id,a)SELECT /*!99997 */ 1; +REPLACE INTO t2 (id,a)SELECT /*!99997 */ 1,2; +SELECT * FROM t2; + +CREATE TABLE t3 (id INT KEY,a YEAR,INDEX (id,a)) engine=aria; +--error ER_WRONG_VALUE_COUNT_ON_ROW +REPLACE INTO t3 (id,a)SELECT /*!99997 */ 1; +REPLACE INTO t3 (id,a)SELECT /*!99997 */ 1,2; +SELECT * FROM t3; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't3' +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1 FROM test.t3; +--source include/wait_condition.inc + +SELECT * FROM t; +SELECT * FROM t2; +SELECT * FROM t3; + +--connection node_1 +DROP TABLE t,t2,t3; + +--echo # Bigger REPLACE ... AS SELECT test + +CREATE TABLE t1(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t2(id int not null primary key ,b int) ENGINE=MyISAM; +CREATE TABLE t3(id int not null primary key ,b int) ENGINE=Aria; +CREATE TABLE t4(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t5(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t6(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t7(id int not null primary key ,b int) ENGINE=MyISAM; +CREATE TABLE t8(id int not null primary key ,b int) ENGINE=Aria; + +INSERT INTO t1(id) SELECT seq FROM seq_1_to_1000; +INSERT INTO t2(id) SELECT seq FROM seq_1_to_1000; +INSERT INTO t3(id) SELECT seq FROM seq_1_to_1000; + +REPLACE INTO t4 SELECT * FROM t1; +REPLACE INTO t5 SELECT * FROM t2; +REPLACE INTO t6 SELECT * FROM t3; +REPLACE INTO t7 SELECT * FROM t2; +REPLACE INTO t8 SELECT * FROM t3; + +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +SELECT COUNT(*) AS EXPECT_1000 FROM t2; +SELECT COUNT(*) AS EXPECT_1000 FROM t3; +SELECT COUNT(*) AS EXPECT_1000 FROM t4; +SELECT COUNT(*) AS EXPECT_1000 FROM t5; +SELECT COUNT(*) AS EXPECT_1000 FROM t6; +SELECT COUNT(*) AS EXPECT_1000 FROM t7; +SELECT COUNT(*) AS EXPECT_1000 FROM t8; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 8 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't_' +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1000 FROM test.t8; +--source include/wait_condition.inc + +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +SELECT COUNT(*) AS EXPECT_1000 FROM t2; +SELECT COUNT(*) AS EXPECT_1000 FROM t3; +SELECT COUNT(*) AS EXPECT_1000 FROM t4; +SELECT COUNT(*) AS EXPECT_1000 FROM t5; +SELECT COUNT(*) AS EXPECT_1000 FROM t6; +SELECT COUNT(*) AS EXPECT_1000 FROM t7; +SELECT COUNT(*) AS EXPECT_1000 FROM t8; + +--connection node_1 +DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; + +--echo # Bigger INSERT INTO ... SELECT test + +CREATE TABLE t1(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t2(id int not null primary key ,b int) ENGINE=MyISAM; +CREATE TABLE t3(id int not null primary key ,b int) ENGINE=Aria; +CREATE TABLE t4(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t5(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t6(id int not null primary key ,b int) ENGINE=InnoDB; +CREATE TABLE t7(id int not null primary key ,b int) ENGINE=MyISAM; +CREATE TABLE t8(id int not null primary key ,b int) ENGINE=Aria; + +INSERT INTO t1(id) SELECT seq FROM seq_1_to_1000; +INSERT INTO t2(id) SELECT seq FROM seq_1_to_1000; +INSERT INTO t3(id) SELECT seq FROM seq_1_to_1000; + +INSERT INTO t4 SELECT * FROM t1; +INSERT INTO t5 SELECT * FROM t2; +INSERT INTO t6 SELECT * FROM t3; +INSERT INTO t7 SELECT * FROM t2; +INSERT INTO t8 SELECT * FROM t3; + +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +SELECT COUNT(*) AS EXPECT_1000 FROM t2; +SELECT COUNT(*) AS EXPECT_1000 FROM t3; +SELECT COUNT(*) AS EXPECT_1000 FROM t4; +SELECT COUNT(*) AS EXPECT_1000 FROM t5; +SELECT COUNT(*) AS EXPECT_1000 FROM t6; +SELECT COUNT(*) AS EXPECT_1000 FROM t7; +SELECT COUNT(*) AS EXPECT_1000 FROM t8; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 8 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME LIKE 't_' +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1000 FROM test.t8; +--source include/wait_condition.inc + +SELECT COUNT(*) AS EXPECT_1000 FROM t1; +SELECT COUNT(*) AS EXPECT_1000 FROM t2; +SELECT COUNT(*) AS EXPECT_1000 FROM t3; +SELECT COUNT(*) AS EXPECT_1000 FROM t4; +SELECT COUNT(*) AS EXPECT_1000 FROM t5; +SELECT COUNT(*) AS EXPECT_1000 FROM t6; +SELECT COUNT(*) AS EXPECT_1000 FROM t7; +SELECT COUNT(*) AS EXPECT_1000 FROM t8; + +--connection node_1 +DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; +# +# View +# +CREATE TABLE t1(pk int not null primary key) engine=innodb; +INSERT INTO t1 values (1),(2),(3),(4); +CREATE VIEW view_t1 AS SELECT * FROM t1; +INSERT INTO view_t1 VALUES (5); +SELECT * FROM t1; +DROP TABLE t1; +DROP VIEW view_t1; +CREATE TABLE t1(pk int not null primary key) engine=myisam; +INSERT INTO t1 values (1),(2),(3),(4); +CREATE VIEW view_t1 AS SELECT * FROM t1; +INSERT INTO view_t1 VALUES (5); +SELECT * FROM t1; +DROP TABLE t1; +DROP VIEW view_t1; +CREATE TABLE t1(pk int not null primary key) engine=aria; +INSERT INTO t1 values (1),(2),(3),(4); +CREATE VIEW view_t1 AS SELECT * FROM t1; +INSERT INTO view_t1 VALUES (5); +SELECT * FROM t1; +DROP TABLE t1; +DROP VIEW view_t1; +SET GLOBAL wsrep_mode=DEFAULT; diff --git a/mysql-test/suite/galera/t/mdev-22543.test b/mysql-test/suite/galera/t/mdev-22543.test index 1e7d3712639..26257b28814 100644 --- a/mysql-test/suite/galera/t/mdev-22543.test +++ b/mysql-test/suite/galera/t/mdev-22543.test @@ -36,7 +36,7 @@ SET DEBUG_SYNC = "now WAIT_FOR sync_point_reached"; # Restart without waiting. The UPDATE should block FTWRL on node_1, # so the SST cannot be completed and node_2 cannot join before # UPDATE connection is signalled to continue. ---exec echo "restart:$start_mysqld_params" > $_expect_file_name +--write_line "restart:$start_mysqld_params" $_expect_file_name # If the bug is present, FTWRL times out on node_1 in couple of # seconds and node_2 fails to join. --sleep 10 diff --git a/mysql-test/suite/galera/t/mdev-30013.test b/mysql-test/suite/galera/t/mdev-30013.test index 038b66600ce..3795dd32306 100644 --- a/mysql-test/suite/galera/t/mdev-30013.test +++ b/mysql-test/suite/galera/t/mdev-30013.test @@ -1,4 +1,5 @@ --source include/galera_cluster.inc +--source include/force_restart.inc # ARCHIVE plugin must be uninstalled if (!$HA_ARCHIVE_SO) { skip Needs Archive loadable plugin; diff --git a/mysql-test/suite/galera/t/mdev-31285.test b/mysql-test/suite/galera/t/mdev-31285.test index d2749165ef7..5abef37cccd 100644 --- a/mysql-test/suite/galera/t/mdev-31285.test +++ b/mysql-test/suite/galera/t/mdev-31285.test @@ -1,34 +1,15 @@ --source include/galera_cluster.inc ---let $node_1 = node_1 ---let $node_2 = node_2 ---source include/auto_increment_offset_save.inc - --connection node_1 +# +# Below should not cause nodes to be inconsistent (they could if we +# allow TOI as some error are ignored on applier +# +--error ER_NOT_SUPPORTED_YET CREATE TABLE t ENGINE=InnoDB WITH SYSTEM VERSIONING AS SELECT 1 AS i; + +--connection node_2 +--error ER_NO_SUCH_TABLE SHOW CREATE TABLE t; -SELECT * from t; -DROP TABLE IF EXISTS t; -COMMIT; -# -# Restart node_2, force SST because database is inconsistent compared to node_1 -# ---connection node_2 -SET SESSION wsrep_sync_wait=0; ---source include/kill_galera.inc ---remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat ---echo Starting server ... -let $restart_noprint=2; ---source include/start_mysqld.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; ---source include/wait_condition.inc ---let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; ---source include/wait_condition.inc - ---connection node_2 -call mtr.add_suppression("WSREP: Event .*Write_rows_v1 apply failed:.*"); -call mtr.add_suppression("SREP: Failed to apply write set: gtid:.*"); - ---source include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera/t/mysql-wsrep#332.test b/mysql-test/suite/galera/t/mysql-wsrep#332.test index e216dfe79d4..464156e832e 100644 --- a/mysql-test/suite/galera/t/mysql-wsrep#332.test +++ b/mysql-test/suite/galera/t/mysql-wsrep#332.test @@ -3,7 +3,7 @@ --source include/have_debug_sync.inc --source include/galera_have_debug_sync.inc -# Open connection node_1a here, MW-369.inc will use it later +# Open connection node_1a here, will use it later --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 # @@ -27,7 +27,42 @@ INSERT INTO c VALUES (2, 2); --let $mw_369_parent_query = UPDATE p SET f1 = f1 + 100 --let $mw_369_child_query = ALTER TABLE c ADD FOREIGN KEY (p_id) REFERENCES p(f1) ---source MW-369.inc +--connection node_1 +SET AUTOCOMMIT=ON; +START TRANSACTION; +--eval $mw_369_parent_query + +# +# Block the $mw_369_child_query from node_2 +# +# --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1a +SET SESSION wsrep_sync_wait = 0; +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_set_sync_point.inc + +# +# insert client row, which will make it impossible to replay the +# delete on parent +# +--connection node_2 +--eval $mw_369_child_query + +# +# Wait until $mw_369_child_query from node_2 reaches the sync point and +# block the 'COMMIT' from node_1 before it certifies. +# +--connection node_1a +--source include/galera_wait_sync_point.inc +--source include/galera_clear_sync_point.inc + +--connection node_1 +--send COMMIT + +--connection node_1a +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_signal_sync_point.inc +--source include/galera_clear_sync_point.inc # Expect certification failure --connection node_1 @@ -62,7 +97,42 @@ INSERT INTO c VALUES (2, 2, 2); --let $mw_369_parent_query = UPDATE p1 SET f1 = f1 + 100 --let $mw_369_child_query = ALTER TABLE c ADD FOREIGN KEY (p_id1) REFERENCES p1(f1), ADD FOREIGN KEY (p_id2) REFERENCES p2(f1) ---source MW-369.inc +--connection node_1 +SET AUTOCOMMIT=ON; +START TRANSACTION; +--eval $mw_369_parent_query + +# +# Block the $mw_369_child_query from node_2 +# +# --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1a +SET SESSION wsrep_sync_wait = 0; +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_set_sync_point.inc + +# +# insert client row, which will make it impossible to replay the +# delete on parent +# +--connection node_2 +--eval $mw_369_child_query + +# +# Wait until $mw_369_child_query from node_2 reaches the sync point and +# block the 'COMMIT' from node_1 before it certifies. +# +--connection node_1a +--source include/galera_wait_sync_point.inc +--source include/galera_clear_sync_point.inc + +--connection node_1 +--send COMMIT + +--connection node_1a +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_signal_sync_point.inc +--source include/galera_clear_sync_point.inc # Expect certification failure --connection node_1 @@ -96,7 +166,42 @@ INSERT INTO c VALUES (2, 2, 2); --let $mw_369_parent_query = UPDATE p2 SET f1 = f1 + 100 --let $mw_369_child_query = ALTER TABLE c ADD FOREIGN KEY (p_id1) REFERENCES p1(f1), ADD FOREIGN KEY (p_id2) REFERENCES p2(f1) ---source MW-369.inc +--connection node_1 +SET AUTOCOMMIT=ON; +START TRANSACTION; +--eval $mw_369_parent_query + +# +# Block the $mw_369_child_query from node_2 +# +# --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 +--connection node_1a +SET SESSION wsrep_sync_wait = 0; +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_set_sync_point.inc + +# +# insert client row, which will make it impossible to replay the +# delete on parent +# +--connection node_2 +--eval $mw_369_child_query + +# +# Wait until $mw_369_child_query from node_2 reaches the sync point and +# block the 'COMMIT' from node_1 before it certifies. +# +--connection node_1a +--source include/galera_wait_sync_point.inc +--source include/galera_clear_sync_point.inc + +--connection node_1 +--send COMMIT + +--connection node_1a +--let $galera_sync_point = apply_monitor_slave_enter_sync +--source include/galera_signal_sync_point.inc +--source include/galera_clear_sync_point.inc # Expect certification failure --connection node_1 diff --git a/mysql-test/suite/galera/t/rpl_galera_to_mariadb_clone_slave_using_mariadb-backup.cnf b/mysql-test/suite/galera/t/rpl_galera_to_mariadb_clone_slave_using_mariadb-backup.cnf new file mode 100644 index 00000000000..ebe1d47f200 --- /dev/null +++ b/mysql-test/suite/galera/t/rpl_galera_to_mariadb_clone_slave_using_mariadb-backup.cnf @@ -0,0 +1,10 @@ +!include ../galera_2nodes_as_master.cnf + +[mysqld.1] +innodb-log-file-buffering + +[mysqld.2] +innodb-log-file-buffering + +[mysqld.3] +innodb-log-file-buffering diff --git a/mysql-test/suite/galera/t/rpl_galera_to_mariadb_clone_slave_using_mariadb-backup.test b/mysql-test/suite/galera/t/rpl_galera_to_mariadb_clone_slave_using_mariadb-backup.test new file mode 100644 index 00000000000..29590e327fd --- /dev/null +++ b/mysql-test/suite/galera/t/rpl_galera_to_mariadb_clone_slave_using_mariadb-backup.test @@ -0,0 +1,9 @@ +--source include/have_innodb.inc +--source include/galera_cluster.inc + +--echo # +--echo # MDEV-33355 Add a Galera-2-node-to-MariaDB replication MTR test cloning the slave with mariadb-backup +--echo # + +--let cnf=galera2_to_mariadb +--source include/rpl_clone_slave_using_mariadb-backup.inc diff --git a/mysql-test/suite/galera/t/versioning_trx_id.test b/mysql-test/suite/galera/t/versioning_trx_id.test index 017379c32c4..fc9ea18eeb4 100644 --- a/mysql-test/suite/galera/t/versioning_trx_id.test +++ b/mysql-test/suite/galera/t/versioning_trx_id.test @@ -13,29 +13,29 @@ set session wsrep_sync_wait=15; insert into t1 (a) values (3),(4); select a from t1; select count(*) from mysql.transaction_registry where begin_timestamp='0-0-0'; -if (`SELECT count(*) from mysql.transaction_registry where begin_timestamp>=commit_timestamp`) { +if (`SELECT count(*) from mysql.transaction_registry where begin_timestamp>commit_timestamp`) { select * from mysql.transaction_registry; } -select count(*) from mysql.transaction_registry where begin_timestamp>=commit_timestamp; +select count(*) from mysql.transaction_registry where begin_timestamp>commit_timestamp; --connection node_3 set session wsrep_sync_wait=15; insert into t1 (a) values (5),(6); select a from t1; select count(*) from mysql.transaction_registry where begin_timestamp='0-0-0'; -if (`SELECT count(*) from mysql.transaction_registry where begin_timestamp>=commit_timestamp`) { +if (`SELECT count(*) from mysql.transaction_registry where begin_timestamp>commit_timestamp`) { select * from mysql.transaction_registry; } -select count(*) from mysql.transaction_registry where begin_timestamp>=commit_timestamp; +select count(*) from mysql.transaction_registry where begin_timestamp>commit_timestamp; --connection node_1 set session wsrep_sync_wait=15; select a from t1; select count(*) from mysql.transaction_registry where begin_timestamp='0-0-0'; -if (`SELECT count(*) from mysql.transaction_registry where begin_timestamp>=commit_timestamp`) { +if (`SELECT count(*) from mysql.transaction_registry where begin_timestamp>commit_timestamp`) { select * from mysql.transaction_registry; } -select count(*) from mysql.transaction_registry where begin_timestamp>=commit_timestamp; +select count(*) from mysql.transaction_registry where begin_timestamp>commit_timestamp; drop table t1; diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def index 728500f45fc..f71f726c4f9 100644 --- a/mysql-test/suite/galera_3nodes/disabled.def +++ b/mysql-test/suite/galera_3nodes/disabled.def @@ -19,3 +19,4 @@ galera_ipv6_mariabackup_section : temporarily disabled at the request of Codersh # Opensuse/suse/rocky9/rocky84/rhel9/rhel8-ppc64le .. - all same IPv6 isn't configured right or skipping or galera galera_ipv6_rsync : Can't connect to server on '::1' (115) galera_ipv6_rsync_section : Can't connect to server on '::1' (115) +GCF-354 : MDEV-25614 Galera test failure on GCF-354 diff --git a/mysql-test/suite/galera_3nodes/r/MDEV-29171.result b/mysql-test/suite/galera_3nodes/r/MDEV-29171.result index 371ce006dd3..55513ff53af 100644 --- a/mysql-test/suite/galera_3nodes/r/MDEV-29171.result +++ b/mysql-test/suite/galera_3nodes/r/MDEV-29171.result @@ -19,20 +19,40 @@ connection node_2; connection node_1; connection node_1; # restart: --wsrep_new_cluster --wsrep_gtid_domain_id=200 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +VARIABLE_VALUE +Primary +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +VARIABLE_VALUE +Synced show variables like 'wsrep_gtid_domain_id'; Variable_name Value wsrep_gtid_domain_id 200 connection node_2; # restart +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +VARIABLE_VALUE +Primary +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +VARIABLE_VALUE +Synced show variables like 'wsrep_gtid_domain_id'; Variable_name Value wsrep_gtid_domain_id 200 +connection node_1; connection node_3; # restart: --wsrep_sst_donor=node2 +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +VARIABLE_VALUE +Primary +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +VARIABLE_VALUE +Synced show variables like 'wsrep_gtid_domain_id'; Variable_name Value wsrep_gtid_domain_id 200 connection node_1; +connection node_1; set global wsrep_gtid_domain_id=100; connection node_2; set global wsrep_gtid_domain_id=100; diff --git a/mysql-test/suite/galera_3nodes/r/galera_allowlist.result b/mysql-test/suite/galera_3nodes/r/galera_allowlist.result index 471444d8c08..a3fb6cf7db5 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_allowlist.result +++ b/mysql-test/suite/galera_3nodes/r/galera_allowlist.result @@ -7,6 +7,9 @@ connection node_2; SELECT COUNT(*) = 3 FROM mysql.wsrep_allowlist; COUNT(*) = 3 1 +connection node_1; +connection node_2; +connection node_3; connection node_3; SET @@global.wsrep_desync = 1; SET SESSION wsrep_sync_wait = 0; diff --git a/mysql-test/suite/galera_3nodes/r/galera_ist_gcache_rollover.result b/mysql-test/suite/galera_3nodes/r/galera_ist_gcache_rollover.result index 9f1d3fec16e..a69cef11358 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_ist_gcache_rollover.result +++ b/mysql-test/suite/galera_3nodes/r/galera_ist_gcache_rollover.result @@ -9,6 +9,7 @@ INSERT INTO t1 VALUES (01), (02), (03), (04), (05); connection node_2; Unloading wsrep provider ... SET GLOBAL wsrep_cluster_address = ''; +connection node_1; connection node_3; Unloading wsrep provider ... SET GLOBAL wsrep_cluster_address = ''; @@ -33,14 +34,16 @@ SET GLOBAL wsrep_provider_options = 'dbug='; SET GLOBAL wsrep_provider_options = 'signal=ist_sender_send_after_get_buffers'; INSERT INTO t1 VALUES (51), (52), (53), (54), (55); connection node_2; +connection node_1; connection node_3; +connection node_1; connection node_2; -SELECT COUNT(*) = 30 FROM t1; -COUNT(*) = 30 -1 -SELECT COUNT(*) = 3 FROM t2; -COUNT(*) = 3 -1 +SELECT COUNT(*) AS EXPECT_30 FROM t1; +EXPECT_30 +30 +SELECT COUNT(*) AS EXPECT_3 FROM t2; +EXPECT_3 +3 SELECT LENGTH(f1) = 512 * 1024 FROM t2; LENGTH(f1) = 512 * 1024 1 @@ -48,12 +51,12 @@ LENGTH(f1) = 512 * 1024 1 CALL mtr.add_suppression("WSREP: Unsupported protocol downgrade: incremental data collection disabled"); connection node_3; -SELECT COUNT(*) = 30 FROM t1; -COUNT(*) = 30 -1 -SELECT COUNT(*) = 3 FROM t2; -COUNT(*) = 3 -1 +SELECT COUNT(*) AS EXPECT_30 FROM t1; +EXPECT_30 +30 +SELECT COUNT(*) AS EXPECT_3 FROM t2; +EXPECT_3 +3 SELECT LENGTH(f1) = 512 * 1024 FROM t2; LENGTH(f1) = 512 * 1024 1 diff --git a/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result index 732385a3966..a88909f4bfb 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result +++ b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result @@ -92,3 +92,7 @@ connection node_2; call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required."); connection node_3; call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required."); +disconnect node_1a; +disconnect node_3; +disconnect node_2; +disconnect node_1; diff --git a/mysql-test/suite/galera_3nodes/t/MDEV-29171.test b/mysql-test/suite/galera_3nodes/t/MDEV-29171.test index bfb7abf9a8b..1ce33bee974 100644 --- a/mysql-test/suite/galera_3nodes/t/MDEV-29171.test +++ b/mysql-test/suite/galera_3nodes/t/MDEV-29171.test @@ -50,6 +50,16 @@ select @@wsrep_gtid_domain_id,@@wsrep_node_name; --connection node_1 --let $restart_parameters = --wsrep_new_cluster --wsrep_gtid_domain_id=200 --source include/start_mysqld.inc + +--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +--source include/wait_condition.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +--source include/wait_condition.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment' +--source include/wait_condition.inc + +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; show variables like 'wsrep_gtid_domain_id'; # @@ -59,8 +69,21 @@ show variables like 'wsrep_gtid_domain_id'; --let $restart_parameters = --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect --source include/start_mysqld.inc + +--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +--source include/wait_condition.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +--source include/wait_condition.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment' +--source include/wait_condition.inc + +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; show variables like 'wsrep_gtid_domain_id'; +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc # # Restart node_3, select node_2 as donor @@ -70,9 +93,23 @@ show variables like 'wsrep_gtid_domain_id'; --let $restart_parameters = --wsrep_sst_donor="node2" --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.3.expect --source include/start_mysqld.inc + +--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +--source include/wait_condition.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +--source include/wait_condition.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment' +--source include/wait_condition.inc + +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; + # Expect domain id 200 show variables like 'wsrep_gtid_domain_id'; +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc # # Cleanup diff --git a/mysql-test/suite/galera_3nodes/t/galera_allowlist.test b/mysql-test/suite/galera_3nodes/t/galera_allowlist.test index 74fff61c4f8..de80965a584 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_allowlist.test +++ b/mysql-test/suite/galera_3nodes/t/galera_allowlist.test @@ -12,6 +12,12 @@ SELECT COUNT(*) = 3 FROM mysql.wsrep_allowlist; --let $galera_server_number = 3 --source include/galera_connect.inc +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + --connection node_3 # Desync and disconnect node 3 from the PC: SET @@global.wsrep_desync = 1; @@ -64,3 +70,6 @@ CALL mtr.add_suppression('WSREP: Connection not allowed'); --connection node_3 CALL mtr.add_suppression('WSREP: Ignoring lack of quorum'); + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_gtid_consistency.cnf b/mysql-test/suite/galera_3nodes/t/galera_gtid_consistency.cnf index 5bd03178d1f..c27490faf36 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_gtid_consistency.cnf +++ b/mysql-test/suite/galera_3nodes/t/galera_gtid_consistency.cnf @@ -33,3 +33,6 @@ log_slave_updates=ON log_bin=mariadb-bin-log binlog-format=row wsrep-gtid-mode=ON + +[sst] +transferfmt=@ENV.MTR_GALERA_TFMT diff --git a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.cnf b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.cnf index 303087dffbb..29563657262 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.cnf +++ b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.cnf @@ -2,10 +2,22 @@ [mysqld.1] wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.ignore_sb=true;gcache.size=1M' +auto_increment_increment=1 +auto_increment_offset=1 +# this will force server restarts before this test +loose-galera-ist-gcache-rollover=1 +wsrep-debug=1 [mysqld.2] wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.ignore_sb=true;gcache.size=1M' +auto_increment_increment=2 +auto_increment_offset=2 +loose-galera-ist-gcache-rollover=2 +wsrep-debug=1 [mysqld.3] wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.ignore_sb=true;gcache.size=1M' - +auto_increment_increment=3 +auto_increment_offset=3 +loose-galera-ist-gcache-rollover=3 +wsrep-debug=1 diff --git a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test index 210a4c2331e..16b9bdb2d02 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test +++ b/mysql-test/suite/galera_3nodes/t/galera_ist_gcache_rollover.test @@ -12,6 +12,7 @@ --source include/have_innodb.inc --source include/have_debug_sync.inc --source include/galera_have_debug_sync.inc +--source include/force_restart.inc --let $galera_connection_name = node_3 --let $galera_server_number = 3 @@ -24,6 +25,9 @@ --source ../galera/include/auto_increment_offset_save.inc --connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--let $wait_condition_on_error_output = SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME LIKE 'wsrep%'; show processlist +--source include/wait_condition_with_debug.inc CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); INSERT INTO t1 VALUES (01), (02), (03), (04), (05); @@ -32,12 +36,15 @@ INSERT INTO t1 VALUES (01), (02), (03), (04), (05); --let $wsrep_cluster_address_orig2 = `select @@wsrep_cluster_address` --source suite/galera/include/galera_stop_replication.inc +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + --connection node_3 --let $wsrep_cluster_address_orig3 = `select @@wsrep_cluster_address` --source suite/galera/include/galera_stop_replication.inc --connection node_1 ---source include/wait_until_connected_again.inc INSERT INTO t1 VALUES (11), (12), (13), (14), (15); # Wait until nodes #2 and #3 have left @@ -88,29 +95,39 @@ INSERT INTO t1 VALUES (51), (52), (53), (54), (55); --connection node_2 --source include/wait_until_connected_again.inc +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 OR VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + --connection node_3 --source include/wait_until_connected_again.inc -sleep 5; +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc # Final checks --connection node_2 -SELECT COUNT(*) = 30 FROM t1; -SELECT COUNT(*) = 3 FROM t2; +--let $wait_condition = SELECT COUNT(*) = 30 FROM t1 +--source include/wait_condition.inc + +SELECT COUNT(*) AS EXPECT_30 FROM t1; +SELECT COUNT(*) AS EXPECT_3 FROM t2; SELECT LENGTH(f1) = 512 * 1024 FROM t2; CALL mtr.add_suppression("WSREP: Unsupported protocol downgrade: incremental data collection disabled"); # Final checks --connection node_3 -SELECT COUNT(*) = 30 FROM t1; -SELECT COUNT(*) = 3 FROM t2; +--let $wait_condition = SELECT COUNT(*) = 30 FROM t1 +--source include/wait_condition.inc +SELECT COUNT(*) AS EXPECT_30 FROM t1; +SELECT COUNT(*) AS EXPECT_3 FROM t2; SELECT LENGTH(f1) = 512 * 1024 FROM t2; CALL mtr.add_suppression("WSREP: Unsupported protocol downgrade: incremental data collection disabled"); DROP TABLE t1, t2; # Restore original auto_increment_offset values. ---source ../galera/include/auto_increment_offset_restore.inc - --let $galera_cluster_size=3 +--source ../galera/include/auto_increment_offset_restore.inc --source include/galera_end.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_B.test b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_B.test index 55d6b458849..d06cdcc8ae4 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_B.test +++ b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_B.test @@ -278,4 +278,9 @@ call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State T --connection node_3 call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required."); +--disconnect node_1a + +# Restore original auto_increment_offset values. +--let $galera_cluster_size=3 --source ../galera/include/auto_increment_offset_restore.inc +--source include/galera_end.inc diff --git a/mysql-test/suite/galera_3nodes_sr/r/GCF-336.result b/mysql-test/suite/galera_3nodes_sr/r/GCF-336.result index eeccfa3b5a3..8fc853f8425 100644 --- a/mysql-test/suite/galera_3nodes_sr/r/GCF-336.result +++ b/mysql-test/suite/galera_3nodes_sr/r/GCF-336.result @@ -25,6 +25,8 @@ SET SESSION wsrep_sync_wait=0; connection node_2; INSERT INTO t1 VALUES (2); ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +connection node_2a; +connection node_2; COMMIT; ERROR 08S01: WSREP has not yet prepared node for application use connection node_2a; diff --git a/mysql-test/suite/galera_3nodes_sr/r/GCF-832.result b/mysql-test/suite/galera_3nodes_sr/r/GCF-832.result index 9043c66840d..ef21e4ca347 100644 --- a/mysql-test/suite/galera_3nodes_sr/r/GCF-832.result +++ b/mysql-test/suite/galera_3nodes_sr/r/GCF-832.result @@ -6,20 +6,26 @@ connection node_2; connection node_3; connection node_2; SET GLOBAL debug_dbug="d,crash_last_fragment_commit_after_fragment_removal"; -CREATE TABLE t1 (f1 VARCHAR(30)) ENGINE=InnoDB; +CREATE TABLE t1 (f1 VARCHAR(30) not null primary key) ENGINE=InnoDB; SET AUTOCOMMIT=OFF; SET SESSION wsrep_trx_fragment_size=1; START TRANSACTION; -INSERT INTO t1 VALUES ('primary'),('primary'),('primary'),('primary'),('primary'); +INSERT INTO t1 VALUES ('primary1'),('primary2'),('primary3'),('primary4'),('primary5'); COMMIT; Got one of the listed errors +connection node_1; +connection node_2; # restart connection node_1; SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; COUNT(*) = 0 1 +SELECT * FROM t1; +f1 connection node_2; SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; COUNT(*) = 0 1 +SELECT * FROM t1; +f1 DROP TABLE t1; diff --git a/mysql-test/suite/galera_3nodes_sr/r/galera_sr_kill_slave_before_apply.result b/mysql-test/suite/galera_3nodes_sr/r/galera_sr_kill_slave_before_apply.result index 933038e00f1..08e3fc6c3e3 100644 --- a/mysql-test/suite/galera_3nodes_sr/r/galera_sr_kill_slave_before_apply.result +++ b/mysql-test/suite/galera_3nodes_sr/r/galera_sr_kill_slave_before_apply.result @@ -7,11 +7,11 @@ connection node_3; connection node_1; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; connection node_2; -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) AS EXPECT_0 FROM t1; +EXPECT_0 +0 connection node_1; -CREATE TABLE t2 (f1 INTEGER); +CREATE TABLE t2 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; LOCK TABLE t2 WRITE; connection node_1; @@ -37,13 +37,14 @@ count_match count_match 1 connection node_1; -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; -COUNT(*) +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +EXPECT_0 0 connection node_2; -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; -COUNT(*) +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +EXPECT_0 0 +call mtr.add_suppression("WSREP: node uuid:.*"); connection node_1; DROP TABLE t1; DROP TABLE t2; diff --git a/mysql-test/suite/galera_3nodes_sr/t/GCF-336.test b/mysql-test/suite/galera_3nodes_sr/t/GCF-336.test index ba85aa5291c..20d5955e4fc 100644 --- a/mysql-test/suite/galera_3nodes_sr/t/GCF-336.test +++ b/mysql-test/suite/galera_3nodes_sr/t/GCF-336.test @@ -27,6 +27,12 @@ SET SESSION wsrep_sync_wait=0; --connection node_2 --error ER_LOCK_DEADLOCK INSERT INTO t1 VALUES (2); + +--connection node_2a +--let $wait_condition = SELECT VARIABLE_VALUE = 'non-Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +--source include/wait_condition.inc + +--connection node_2 --error ER_UNKNOWN_COM_ERROR COMMIT; diff --git a/mysql-test/suite/galera_3nodes_sr/t/GCF-832.test b/mysql-test/suite/galera_3nodes_sr/t/GCF-832.test index 5da080a6c2c..700b3c38b6b 100644 --- a/mysql-test/suite/galera_3nodes_sr/t/GCF-832.test +++ b/mysql-test/suite/galera_3nodes_sr/t/GCF-832.test @@ -4,6 +4,7 @@ # --source include/galera_cluster.inc --source include/have_debug_sync.inc +--source include/force_restart.inc --connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 # Save original auto_increment_offset values. @@ -13,30 +14,42 @@ --source ../galera/include/auto_increment_offset_save.inc --connection node_2 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + SET GLOBAL debug_dbug="d,crash_last_fragment_commit_after_fragment_removal"; --let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')` --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect ---exec echo "wait" > $_expect_file_name +--write_line wait $_expect_file_name -CREATE TABLE t1 (f1 VARCHAR(30)) ENGINE=InnoDB; +CREATE TABLE t1 (f1 VARCHAR(30) not null primary key) ENGINE=InnoDB; SET AUTOCOMMIT=OFF; SET SESSION wsrep_trx_fragment_size=1; START TRANSACTION; -INSERT INTO t1 VALUES ('primary'),('primary'),('primary'),('primary'),('primary'); +INSERT INTO t1 VALUES ('primary1'),('primary2'),('primary3'),('primary4'),('primary5'); --error 2013,2026 COMMIT; +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--connection node_2 --source include/start_mysqld.inc --connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; +SELECT * FROM t1; --connection node_2 --enable_reconnect SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; +SELECT * FROM t1; DROP TABLE t1; diff --git a/mysql-test/suite/galera_3nodes_sr/t/galera_sr_kill_slave_before_apply.test b/mysql-test/suite/galera_3nodes_sr/t/galera_sr_kill_slave_before_apply.test index 08a59296e41..58d744e704d 100644 --- a/mysql-test/suite/galera_3nodes_sr/t/galera_sr_kill_slave_before_apply.test +++ b/mysql-test/suite/galera_3nodes_sr/t/galera_sr_kill_slave_before_apply.test @@ -6,6 +6,7 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +--source include/force_restart.inc --connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 # Save original auto_increment_offset values. @@ -15,18 +16,23 @@ --source ../galera/include/auto_increment_offset_save.inc --connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; # Block node #2's applier before table t1's inserts have come into play --connection node_2 -SELECT COUNT(*) = 0 FROM t1; +SELECT COUNT(*) AS EXPECT_0 FROM t1; --connection node_1 -CREATE TABLE t2 (f1 INTEGER); +CREATE TABLE t2 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; --connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2' +--source include/wait_condition.inc LOCK TABLE t2 WRITE; --connection node_1 @@ -77,10 +83,12 @@ if ($mysql_errno == 1213) { --enable_query_log --connection node_1 -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; --connection node_2 -SELECT COUNT(*) FROM mysql.wsrep_streaming_log; +SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log; +# As noted above sometimes node delivers the same view twice +call mtr.add_suppression("WSREP: node uuid:.*"); --connection node_1 DROP TABLE t1; diff --git a/mysql-test/suite/galera_sr/r/galera_sr_bf_abort_idle.result b/mysql-test/suite/galera_sr/r/galera_sr_bf_abort_idle.result new file mode 100644 index 00000000000..a1495f1c138 --- /dev/null +++ b/mysql-test/suite/galera_sr/r/galera_sr_bf_abort_idle.result @@ -0,0 +1,33 @@ +connection node_2; +connection node_1; +connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INTEGER); +INSERT INTO t1 VALUES (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1); +SET SESSION wsrep_trx_fragment_size=10; +SET SESSION wsrep_trx_fragment_unit='rows'; +START TRANSACTION; +UPDATE t1 SET f2 = f2 + 10; +connection node_2; +INSERT INTO t1 VALUES (10,2); +connection node_1a; +connection node_1; +INSERT INTO t1 VALUES (9,1); +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +ROLLBACK; +DROP TABLE t1; +connection node_1; +CREATE TABLE t1(f1 INTEGER PRIMARY KEY, f2 INTEGER); +INSERT INTO t1 VALUES (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1); +SET SESSION wsrep_trx_fragment_size=5; +SET SESSION wsrep_trx_fragment_unit='rows'; +START TRANSACTION; +UPDATE t1 SET f2 = f2 + 10; +connection node_2; +INSERT INTO t1 VALUES (10,2); +connection node_1a; +connection node_1; +INSERT INTO t1 VALUES (9,1); +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +ROLLBACK; +DROP TABLE t1; diff --git a/mysql-test/suite/galera_sr/t/MDEV-25718.test b/mysql-test/suite/galera_sr/t/MDEV-25718.test index 9aebbdc7c5c..037cd300709 100644 --- a/mysql-test/suite/galera_sr/t/MDEV-25718.test +++ b/mysql-test/suite/galera_sr/t/MDEV-25718.test @@ -43,8 +43,9 @@ SET SESSION wsrep_sync_wait = 0; SET debug_sync = "now SIGNAL write_row_continue"; # Let's give the INSERT some time, to make sure it does rollback ---let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO = "INSERT INTO t1 VALUES (1)" AND STATE = "Freeing items"; ---source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO = "INSERT INTO t1 VALUES (1)" AND (STATE = "Freeing items" OR STATE = 'Rollback'); +--let $wait_condition_on_error_output = SELECT INFO, STATE FROM INFORMATION_SCHEMA.PROCESSLIST +--source include/wait_condition_with_debug.inc # Resume the DDL in streaming_rollback SET SESSION debug_sync = "now SIGNAL wsrep_streaming_rollback_continue"; diff --git a/mysql-test/suite/galera_sr/t/galera_sr_bf_abort_idle.test b/mysql-test/suite/galera_sr/t/galera_sr_bf_abort_idle.test new file mode 100644 index 00000000000..66259b790cc --- /dev/null +++ b/mysql-test/suite/galera_sr/t/galera_sr_bf_abort_idle.test @@ -0,0 +1,68 @@ +# +# Test BF abort for idle SR transactions +# + +--source include/galera_cluster.inc + +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 + +# +# Case 1: BF abort idle SR transaction that has not yet replicated any fragments +# +--connection node_1 +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INTEGER); +INSERT INTO t1 VALUES (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1); + +--let $bf_count = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.global_status WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'` + +SET SESSION wsrep_trx_fragment_size=10; +SET SESSION wsrep_trx_fragment_unit='rows'; +START TRANSACTION; +UPDATE t1 SET f2 = f2 + 10; + +--connection node_2 +INSERT INTO t1 VALUES (10,2); + +# Wait for SR transaction to be BF aborted +--connection node_1a +--let $wait_condition = SELECT VARIABLE_VALUE = $bf_count + 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts' +--source include/wait_condition.inc + + +--connection node_1 +--error ER_LOCK_DEADLOCK +INSERT INTO t1 VALUES (9,1); +ROLLBACK; + +DROP TABLE t1; + + +# +# Case 2: BF abort idle SR transaction that has already replicated a fragment +# +--connection node_1 +CREATE TABLE t1(f1 INTEGER PRIMARY KEY, f2 INTEGER); +INSERT INTO t1 VALUES (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1); + +--let $bf_count = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.global_status WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'` + + +SET SESSION wsrep_trx_fragment_size=5; +SET SESSION wsrep_trx_fragment_unit='rows'; +START TRANSACTION; +UPDATE t1 SET f2 = f2 + 10; + +--connection node_2 +INSERT INTO t1 VALUES (10,2); + +# Wait for SR transaction to be BF aborted +--connection node_1a +--let $wait_condition = SELECT VARIABLE_VALUE = $bf_count + 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts' +--source include/wait_condition.inc + +--connection node_1 +--error ER_LOCK_DEADLOCK +INSERT INTO t1 VALUES (9,1); +ROLLBACK; + +DROP TABLE t1; diff --git a/mysql-test/suite/galera_sr/t/galera_sr_kill_all_norecovery.test b/mysql-test/suite/galera_sr/t/galera_sr_kill_all_norecovery.test index 5332b1a1579..f6f50fd50c9 100644 --- a/mysql-test/suite/galera_sr/t/galera_sr_kill_all_norecovery.test +++ b/mysql-test/suite/galera_sr/t/galera_sr_kill_all_norecovery.test @@ -38,12 +38,12 @@ SET SESSION wsrep_sync_wait = 0; --source include/kill_galera.inc --remove_file $MYSQLTEST_VARDIR/mysqld.1/data/grastate.dat ---let $start_mysqld_params = "--wsrep-new-cluster" +--let $start_mysqld_params =--wsrep-new-cluster --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --source include/start_mysqld.inc --connection node_2 ---let $start_mysqld_params = "" +--let $start_mysqld_params = --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect --source include/start_mysqld.inc diff --git a/mysql-test/suite/gcol/inc/innodb_v_large_col.inc b/mysql-test/suite/gcol/inc/innodb_v_large_col.inc index 70e188635fa..8ba6920fea4 100644 --- a/mysql-test/suite/gcol/inc/innodb_v_large_col.inc +++ b/mysql-test/suite/gcol/inc/innodb_v_large_col.inc @@ -1,5 +1,3 @@ ---source include/have_innodb.inc - eval CREATE TABLE `t` ( `a` VARCHAR(10000), `b` VARCHAR(3000), `c` VARCHAR(14000) GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, diff --git a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result index 63ea5b1d418..505afb9b923 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result @@ -96,11 +96,8 @@ a b c DROP TABLE t1; CREATE TABLE t1 (a INT, b INT, c INT GENERATED ALWAYS AS(a+b)); INSERT INTO t1(a, b) VALUES (1, 1), (2, 2), (3, 3), (4, 4); -connection con1; -# disable purge -BEGIN; -SELECT * FROM t0; -a +connect stop_purge,localhost,root,,; +START TRANSACTION WITH CONSISTENT SNAPSHOT; connection default; DELETE FROM t1 WHERE a = 1; UPDATE t1 SET a = 2, b = 2 WHERE a = 5; @@ -109,10 +106,11 @@ SET DEBUG_SYNC= 'inplace_after_index_build SIGNAL uncommitted WAIT_FOR purged'; ALTER TABLE t1 ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=NONE; connection con1; SET DEBUG_SYNC= 'now WAIT_FOR uncommitted'; +BEGIN; DELETE FROM t1 WHERE a = 3; UPDATE t1 SET a = 7, b = 7 WHERE a = 4; INSERT INTO t1(a, b) VALUES (8, 8); -# enable purge +disconnect stop_purge; COMMIT; # wait for purge to process the deleted/updated records. InnoDB 2 transactions not purged diff --git a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test index 09fba0285c7..7966953535c 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test @@ -131,9 +131,8 @@ CREATE TABLE t1 (a INT, b INT, c INT GENERATED ALWAYS AS(a+b)); INSERT INTO t1(a, b) VALUES (1, 1), (2, 2), (3, 3), (4, 4); -connection con1; ---echo # disable purge -BEGIN; SELECT * FROM t0; +connect (stop_purge,localhost,root,,); +START TRANSACTION WITH CONSISTENT SNAPSHOT; connection default; DELETE FROM t1 WHERE a = 1; @@ -148,13 +147,14 @@ send ALTER TABLE t1 ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=NONE; connection con1; SET DEBUG_SYNC= 'now WAIT_FOR uncommitted'; +BEGIN; DELETE FROM t1 WHERE a = 3; UPDATE t1 SET a = 7, b = 7 WHERE a = 4; INSERT INTO t1(a, b) VALUES (8, 8); ---echo # enable purge +disconnect stop_purge; COMMIT; --echo # wait for purge to process the deleted/updated records. diff --git a/mysql-test/suite/innodb/include/innodb_merge_threshold_delete.inc b/mysql-test/suite/innodb/include/innodb_merge_threshold_delete.inc index 68f34978f23..2431d207c3d 100644 --- a/mysql-test/suite/innodb/include/innodb_merge_threshold_delete.inc +++ b/mysql-test/suite/innodb/include/innodb_merge_threshold_delete.inc @@ -5,9 +5,6 @@ # "create table tab1 (a bigint primary key, b varchar(2048)) engine=InnoDB;" # ---source include/have_innodb.inc ---source include/have_innodb_16k.inc - # turn on flags --disable_query_log SET GLOBAL innodb_monitor_enable=index_page_merge_attempts; diff --git a/mysql-test/suite/innodb/include/innodb_merge_threshold_secondary.inc b/mysql-test/suite/innodb/include/innodb_merge_threshold_secondary.inc index d49272c4087..2ffe1085ccf 100644 --- a/mysql-test/suite/innodb/include/innodb_merge_threshold_secondary.inc +++ b/mysql-test/suite/innodb/include/innodb_merge_threshold_secondary.inc @@ -6,9 +6,6 @@ # "create index index1 on tab1(b(750));" # ---source include/have_innodb.inc ---source include/have_innodb_16k.inc - # turn on flags --disable_query_log SET GLOBAL innodb_monitor_enable=index_page_merge_attempts; diff --git a/mysql-test/suite/innodb/include/innodb_merge_threshold_update.inc b/mysql-test/suite/innodb/include/innodb_merge_threshold_update.inc index ae720e0488d..a7537d60ee2 100644 --- a/mysql-test/suite/innodb/include/innodb_merge_threshold_update.inc +++ b/mysql-test/suite/innodb/include/innodb_merge_threshold_update.inc @@ -5,9 +5,6 @@ # "create table tab1 (a bigint primary key, b varchar(2048)) engine=InnoDB;" # ---source include/have_innodb.inc ---source include/have_innodb_16k.inc - # turn on flags --disable_query_log SET GLOBAL innodb_monitor_enable=index_page_merge_attempts; diff --git a/mysql-test/suite/innodb/include/no_checkpoint_start.inc b/mysql-test/suite/innodb/include/no_checkpoint_start.inc index a903fee67d4..69823dd0a03 100644 --- a/mysql-test/suite/innodb/include/no_checkpoint_start.inc +++ b/mysql-test/suite/innodb/include/no_checkpoint_start.inc @@ -1,5 +1,28 @@ # Preparation for using no_checkpoint_end.inc +# no_checkpoint_flush: Set to trigger flushing the dirty pages from buffer pool +# and checkpoint before the "no checkpoint" block. + +if ($no_checkpoint_flush) { + --echo + --echo # Flush all dirty pages from buffer pool + SET @no_checkpoint_save_pct= @@GLOBAL.innodb_max_dirty_pages_pct; + SET @no_checkpoint_save_pct_lwm= @@GLOBAL.innodb_max_dirty_pages_pct_lwm; + + SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0; + SET GLOBAL innodb_max_dirty_pages_pct=0.0; + + let $wait_condition = + SELECT variable_value = 0 + FROM information_schema.global_status + WHERE variable_name = 'INNODB_BUFFER_POOL_PAGES_DIRTY'; + --source include/wait_condition.inc + + SET GLOBAL innodb_max_dirty_pages_pct= @no_checkpoint_save_pct; + SET GLOBAL innodb_max_dirty_pages_pct_lwm= @no_checkpoint_save_pct_lwm; + --echo +} + let MYSQLD_DATADIR= `select @@datadir`; --replace_regex /.*Last checkpoint at[ ]*([0-9]+).*/\1/ let CHECKPOINT_LSN=`SHOW ENGINE INNODB STATUS`; diff --git a/mysql-test/suite/innodb/r/alter_copy.result b/mysql-test/suite/innodb/r/alter_copy.result index 8c9e5966b2e..72ae28e9652 100644 --- a/mysql-test/suite/innodb/r/alter_copy.result +++ b/mysql-test/suite/innodb/r/alter_copy.result @@ -51,7 +51,7 @@ ADD INDEX(a,b,d), ADD INDEX(a,d,b), ADD INDEX(b,c,d), ADD INDEX(b,d,c), ALGORITHM=COPY; connection default; SET DEBUG_SYNC='now WAIT_FOR hung'; -# restart: --innodb-force-recovery=3 --debug_dbug=+d,recv_ran_out_of_buffer +# restart: --innodb-force-recovery=3 disconnect hang; FTS_INDEX_1.ibd FTS_INDEX_2.ibd diff --git a/mysql-test/suite/innodb/r/alter_kill.result b/mysql-test/suite/innodb/r/alter_kill.result index a0d95154ab9..af23efe9790 100644 --- a/mysql-test/suite/innodb/r/alter_kill.result +++ b/mysql-test/suite/innodb/r/alter_kill.result @@ -1,3 +1,7 @@ +SELECT @@innodb_doublewrite; +@@innodb_doublewrite +OFF +SET GLOBAL innodb_doublewrite=fast; # # Bug#16720368 INNODB CRASHES ON BROKEN #SQL*.IBD FILE AT STARTUP # @@ -12,11 +16,14 @@ connection default; disconnect con1; # Corrupt FIL_PAGE_TYPE in bug16720368.ibd, # and recompute innodb_checksum_algorithm=crc32 -# restart +# restart: --innodb-flush-method=O_DIRECT +SELECT @@innodb_doublewrite; +@@innodb_doublewrite +OFF SELECT COUNT(*) FROM bug16720368; -ERROR 42S02: Table 'test.bug16720368' doesn't exist in engine +ERROR HY000: Table `test`.`bug16720368` is corrupted. Please drop the table and recreate. INSERT INTO bug16720368 VALUES(1); -ERROR HY000: Table test/bug16720368 is corrupted. Please drop the table and recreate. +ERROR HY000: Table `test`.`bug16720368` is corrupted. Please drop the table and recreate. INSERT INTO bug16720368_1 VALUES(1); # Shut down the server to uncorrupt the data. # restart diff --git a/mysql-test/suite/innodb/r/alter_not_null,COPY,NON-STRICT.rdiff b/mysql-test/suite/innodb/r/alter_not_null,COPY,NON-STRICT.rdiff index 01db97e59f8..7c32d38a1d9 100644 --- a/mysql-test/suite/innodb/r/alter_not_null,COPY,NON-STRICT.rdiff +++ b/mysql-test/suite/innodb/r/alter_not_null,COPY,NON-STRICT.rdiff @@ -1,42 +1,79 @@ -7,8c7,8 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 ---- -> affected rows: 1 -> info: Records: 1 Duplicates: 0 Warnings: 1 -21,22c21,22 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 ---- -> affected rows: 1 -> info: Records: 1 Duplicates: 0 Warnings: 1 -35,36c35,36 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 ---- -> affected rows: 1 -> info: Records: 1 Duplicates: 0 Warnings: 1 -49,50c49,50 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 ---- -> affected rows: 1 -> info: Records: 1 Duplicates: 0 Warnings: 1 -63,64c63,64 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 ---- -> affected rows: 1 -> info: Records: 1 Duplicates: 0 Warnings: 1 -77,78c77,78 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 ---- -> affected rows: 1 -> info: Records: 1 Duplicates: 0 Warnings: 1 -98,99c98,99 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 ---- -> affected rows: 1 -> info: Records: 1 Duplicates: 0 Warnings: 1 +--- alter_not_null.result ++++ alter_not_null,COPY,NON-STRICT.result~ +@@ -4,8 +4,8 @@ + f1 + NULL + ALTER TABLE t1 CHANGE f1 f1 INT NOT NULL; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 ++affected rows: 1 ++info: Records: 1 Duplicates: 0 Warnings: 1 + Warnings: + Warning 1265 Data truncated for column 'f1' at row 1 + SELECT * FROM t1; +@@ -18,8 +18,8 @@ + f1 + NULL + ALTER TABLE t1 CHANGE f1 f1 CHAR(10) NOT NULL; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 ++affected rows: 1 ++info: Records: 1 Duplicates: 0 Warnings: 1 + Warnings: + Warning 1265 Data truncated for column 'f1' at row 1 + SELECT * FROM t1; +@@ -32,8 +32,8 @@ + f1 + NULL + ALTER TABLE t1 CHANGE f1 f1 VARCHAR(20) NOT NULL; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 ++affected rows: 1 ++info: Records: 1 Duplicates: 0 Warnings: 1 + Warnings: + Warning 1265 Data truncated for column 'f1' at row 1 + SELECT * FROM t1; +@@ -46,8 +46,8 @@ + f1 + NULL + ALTER TABLE t1 CHANGE f1 f1 TEXT NOT NULL DEFAULT 'abc'; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 ++affected rows: 1 ++info: Records: 1 Duplicates: 0 Warnings: 1 + Warnings: + Warning 1265 Data truncated for column 'f1' at row 1 + SELECT * FROM t1; +@@ -60,8 +60,8 @@ + f1 f2 f3 + 2 2 NULL + ALTER TABLE t1 CHANGE f3 f3 INT NOT NULL DEFAULT (f1 + f2); +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 ++affected rows: 1 ++info: Records: 1 Duplicates: 0 Warnings: 1 + Warnings: + Warning 1265 Data truncated for column 'f3' at row 1 + SELECT * FROM t1; +@@ -74,8 +74,8 @@ + f1 b + 10 NULL + ALTER TABLE t1 CHANGE b b TINYINT NOT NULL DEFAULT if(unix_timestamp()>1,1000,0); +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 ++affected rows: 1 ++info: Records: 1 Duplicates: 0 Warnings: 1 + Warnings: + Warning 1265 Data truncated for column 'b' at row 1 + SELECT * FROM t1; +@@ -95,8 +95,8 @@ + CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1))ENGINE=INNODB; + INSERT INTO t1 VALUES(1, NULL); + ALTER IGNORE TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 ++affected rows: 1 ++info: Records: 1 Duplicates: 0 Warnings: 1 + Warnings: + Warning 1265 Data truncated for column 'c2' at row 1 + SELECT * FROM t1; diff --git a/mysql-test/suite/innodb/r/alter_not_null,COPY,STRICT.rdiff b/mysql-test/suite/innodb/r/alter_not_null,COPY,STRICT.rdiff index e02d235cb72..37e97169a11 100644 --- a/mysql-test/suite/innodb/r/alter_not_null,COPY,STRICT.rdiff +++ b/mysql-test/suite/innodb/r/alter_not_null,COPY,STRICT.rdiff @@ -1,72 +1,109 @@ -7,10c7 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 -< Warnings: -< Warning 1265 Data truncated for column 'f1' at row 1 ---- -> ERROR 01000: Data truncated for column 'f1' at row 1 -13c10 -< 0 ---- -> NULL -21,24c18 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 -< Warnings: -< Warning 1265 Data truncated for column 'f1' at row 1 ---- -> ERROR 01000: Data truncated for column 'f1' at row 1 -27c21 -< ---- -> NULL -35,38c29 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 -< Warnings: -< Warning 1265 Data truncated for column 'f1' at row 1 ---- -> ERROR 01000: Data truncated for column 'f1' at row 1 -41c32 -< ---- -> NULL -49,52c40 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 -< Warnings: -< Warning 1265 Data truncated for column 'f1' at row 1 ---- -> ERROR 01000: Data truncated for column 'f1' at row 1 -55c43 -< ---- -> NULL -63,66c51 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 -< Warnings: -< Warning 1265 Data truncated for column 'f3' at row 1 ---- -> ERROR 01000: Data truncated for column 'f3' at row 1 -69c54 -< 2 2 0 ---- -> 2 2 NULL -77,80c62 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 -< Warnings: -< Warning 1265 Data truncated for column 'b' at row 1 ---- -> ERROR 01000: Data truncated for column 'b' at row 1 -83c65 -< 10 0 ---- -> 10 NULL -98,99c80,81 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 ---- -> affected rows: 1 -> info: Records: 1 Duplicates: 0 Warnings: 1 +--- alter_not_null.result ++++ alter_not_null,COPY,STRICT.result~ +@@ -4,13 +4,10 @@ + f1 + NULL + ALTER TABLE t1 CHANGE f1 f1 INT NOT NULL; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 +-Warnings: +-Warning 1265 Data truncated for column 'f1' at row 1 ++ERROR 01000: Data truncated for column 'f1' at row 1 + SELECT * FROM t1; + f1 +-0 ++NULL + DROP TABLE t1; + CREATE TABLE t1(f1 CHAR(10))ENGINE=INNODB; + INSERT INTO t1 VALUES(NULL); +@@ -18,13 +15,10 @@ + f1 + NULL + ALTER TABLE t1 CHANGE f1 f1 CHAR(10) NOT NULL; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 +-Warnings: +-Warning 1265 Data truncated for column 'f1' at row 1 ++ERROR 01000: Data truncated for column 'f1' at row 1 + SELECT * FROM t1; + f1 +- ++NULL + DROP TABLE t1; + CREATE TABLE t1(f1 VARCHAR(10))ENGINE=INNODB; + INSERT INTO t1 VALUES(NULL); +@@ -32,13 +26,10 @@ + f1 + NULL + ALTER TABLE t1 CHANGE f1 f1 VARCHAR(20) NOT NULL; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 +-Warnings: +-Warning 1265 Data truncated for column 'f1' at row 1 ++ERROR 01000: Data truncated for column 'f1' at row 1 + SELECT * FROM t1; + f1 +- ++NULL + DROP TABLE t1; + CREATE TABLE t1(f1 TEXT)ENGINE=INNODB; + INSERT INTO t1 VALUES(NULL); +@@ -46,13 +37,10 @@ + f1 + NULL + ALTER TABLE t1 CHANGE f1 f1 TEXT NOT NULL DEFAULT 'abc'; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 +-Warnings: +-Warning 1265 Data truncated for column 'f1' at row 1 ++ERROR 01000: Data truncated for column 'f1' at row 1 + SELECT * FROM t1; + f1 +- ++NULL + DROP TABLE t1; + CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, f3 INT)ENGINE=INNODB; + INSERT INTO t1 VALUES(2, 2, NULL); +@@ -60,13 +48,10 @@ + f1 f2 f3 + 2 2 NULL + ALTER TABLE t1 CHANGE f3 f3 INT NOT NULL DEFAULT (f1 + f2); +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 +-Warnings: +-Warning 1265 Data truncated for column 'f3' at row 1 ++ERROR 01000: Data truncated for column 'f3' at row 1 + SELECT * FROM t1; + f1 f2 f3 +-2 2 0 ++2 2 NULL + DROP TABLE t1; + CREATE TABLE t1(f1 INT NOT NULL DEFAULT 0, b TINYINT)ENGINE=InnoDB; + INSERT INTO t1 VALUES(10, NULL); +@@ -74,13 +59,10 @@ + f1 b + 10 NULL + ALTER TABLE t1 CHANGE b b TINYINT NOT NULL DEFAULT if(unix_timestamp()>1,1000,0); +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 +-Warnings: +-Warning 1265 Data truncated for column 'b' at row 1 ++ERROR 01000: Data truncated for column 'b' at row 1 + SELECT * FROM t1; + f1 b +-10 0 ++10 NULL + DROP TABLE t1; + CREATE TABLE t1(a INT, v INT AS (a), c INT, d INT NOT NULL, e INT) ENGINE=InnoDB; + ALTER TABLE t1 DROP COLUMN c, CHANGE COLUMN e e INT NOT NULL; +@@ -95,8 +77,8 @@ + CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1))ENGINE=INNODB; + INSERT INTO t1 VALUES(1, NULL); + ALTER IGNORE TABLE t1 CHANGE c2 c2 INT NOT NULL DEFAULT 2; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 ++affected rows: 1 ++info: Records: 1 Duplicates: 0 Warnings: 1 + Warnings: + Warning 1265 Data truncated for column 'c2' at row 1 + SELECT * FROM t1; diff --git a/mysql-test/suite/innodb/r/alter_not_null,INPLACE,STRICT.rdiff b/mysql-test/suite/innodb/r/alter_not_null,INPLACE,STRICT.rdiff index ec97b174bdf..555f4cdb1df 100644 --- a/mysql-test/suite/innodb/r/alter_not_null,INPLACE,STRICT.rdiff +++ b/mysql-test/suite/innodb/r/alter_not_null,INPLACE,STRICT.rdiff @@ -1,66 +1,98 @@ -7,10c7 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 -< Warnings: -< Warning 1265 Data truncated for column 'f1' at row 1 ---- -> ERROR 01000: Data truncated for column 'f1' at row 1 -13c10 -< 0 ---- -> NULL -21,24c18 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 -< Warnings: -< Warning 1265 Data truncated for column 'f1' at row 1 ---- -> ERROR 01000: Data truncated for column 'f1' at row 1 -27c21 -< ---- -> NULL -35,38c29 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 -< Warnings: -< Warning 1265 Data truncated for column 'f1' at row 1 ---- -> ERROR 01000: Data truncated for column 'f1' at row 1 -41c32 -< ---- -> NULL -49,52c40 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 -< Warnings: -< Warning 1265 Data truncated for column 'f1' at row 1 ---- -> ERROR 01000: Data truncated for column 'f1' at row 1 -55c43 -< ---- -> NULL -63,66c51 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 -< Warnings: -< Warning 1265 Data truncated for column 'f3' at row 1 ---- -> ERROR 01000: Data truncated for column 'f3' at row 1 -69c54 -< 2 2 0 ---- -> 2 2 NULL -77,80c62 -< affected rows: 0 -< info: Records: 0 Duplicates: 0 Warnings: 1 -< Warnings: -< Warning 1265 Data truncated for column 'b' at row 1 ---- -> ERROR 01000: Data truncated for column 'b' at row 1 -83c65 -< 10 0 ---- -> 10 NULL +--- alter_not_null.result ++++ alter_not_null,INPLACE,STRICT.result~ +@@ -4,13 +4,10 @@ + f1 + NULL + ALTER TABLE t1 CHANGE f1 f1 INT NOT NULL; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 +-Warnings: +-Warning 1265 Data truncated for column 'f1' at row 1 ++ERROR 01000: Data truncated for column 'f1' at row 1 + SELECT * FROM t1; + f1 +-0 ++NULL + DROP TABLE t1; + CREATE TABLE t1(f1 CHAR(10))ENGINE=INNODB; + INSERT INTO t1 VALUES(NULL); +@@ -18,13 +15,10 @@ + f1 + NULL + ALTER TABLE t1 CHANGE f1 f1 CHAR(10) NOT NULL; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 +-Warnings: +-Warning 1265 Data truncated for column 'f1' at row 1 ++ERROR 01000: Data truncated for column 'f1' at row 1 + SELECT * FROM t1; + f1 +- ++NULL + DROP TABLE t1; + CREATE TABLE t1(f1 VARCHAR(10))ENGINE=INNODB; + INSERT INTO t1 VALUES(NULL); +@@ -32,13 +26,10 @@ + f1 + NULL + ALTER TABLE t1 CHANGE f1 f1 VARCHAR(20) NOT NULL; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 +-Warnings: +-Warning 1265 Data truncated for column 'f1' at row 1 ++ERROR 01000: Data truncated for column 'f1' at row 1 + SELECT * FROM t1; + f1 +- ++NULL + DROP TABLE t1; + CREATE TABLE t1(f1 TEXT)ENGINE=INNODB; + INSERT INTO t1 VALUES(NULL); +@@ -46,13 +37,10 @@ + f1 + NULL + ALTER TABLE t1 CHANGE f1 f1 TEXT NOT NULL DEFAULT 'abc'; +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 +-Warnings: +-Warning 1265 Data truncated for column 'f1' at row 1 ++ERROR 01000: Data truncated for column 'f1' at row 1 + SELECT * FROM t1; + f1 +- ++NULL + DROP TABLE t1; + CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, f3 INT)ENGINE=INNODB; + INSERT INTO t1 VALUES(2, 2, NULL); +@@ -60,13 +48,10 @@ + f1 f2 f3 + 2 2 NULL + ALTER TABLE t1 CHANGE f3 f3 INT NOT NULL DEFAULT (f1 + f2); +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 +-Warnings: +-Warning 1265 Data truncated for column 'f3' at row 1 ++ERROR 01000: Data truncated for column 'f3' at row 1 + SELECT * FROM t1; + f1 f2 f3 +-2 2 0 ++2 2 NULL + DROP TABLE t1; + CREATE TABLE t1(f1 INT NOT NULL DEFAULT 0, b TINYINT)ENGINE=InnoDB; + INSERT INTO t1 VALUES(10, NULL); +@@ -74,13 +59,10 @@ + f1 b + 10 NULL + ALTER TABLE t1 CHANGE b b TINYINT NOT NULL DEFAULT if(unix_timestamp()>1,1000,0); +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 1 +-Warnings: +-Warning 1265 Data truncated for column 'b' at row 1 ++ERROR 01000: Data truncated for column 'b' at row 1 + SELECT * FROM t1; + f1 b +-10 0 ++10 NULL + DROP TABLE t1; + CREATE TABLE t1(a INT, v INT AS (a), c INT, d INT NOT NULL, e INT) ENGINE=InnoDB; + ALTER TABLE t1 DROP COLUMN c, CHANGE COLUMN e e INT NOT NULL; diff --git a/mysql-test/suite/innodb/r/autoinc_debug.result b/mysql-test/suite/innodb/r/autoinc_debug.result index b3b7a469ada..59740e43163 100644 --- a/mysql-test/suite/innodb/r/autoinc_debug.result +++ b/mysql-test/suite/innodb/r/autoinc_debug.result @@ -105,3 +105,60 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci DROP TABLE t1; SET DEBUG_SYNC='RESET'; +# +# MDEV-33593: Auto increment deadlock error causes ASSERT in subsequent save point +# +CREATE TABLE t1(col1 INT PRIMARY KEY AUTO_INCREMENT, col2 INT) ENGINE=InnoDB; +CREATE TABLE t2(col1 INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1(col2) values(100); +connect con1, localhost, root,,; +START TRANSACTION; +# T1: Acquiring Row X lock on table t2 +INSERT INTO t2 values(100); +connect con2, localhost, root,,; +START TRANSACTION; +# T2: Wait for (T1) row lock on t2 after acquiring GAP Lock on t1 +UPDATE t1 SET col2 = 20 where col1 = 10; +SET DEBUG_SYNC='lock_wait_before_suspend SIGNAL t2_waiting'; +INSERT INTO t2 values(100); +connection default; +SET DEBUG_SYNC='now WAIT_FOR t2_waiting'; +# T3: Wait for (T2) II row Lock on t1 after acquiring Auto Increment Lock on t1 +SET DEBUG_SYNC='lock_wait_before_suspend SIGNAL t3_waiting'; +INSERT INTO t1(col2) SELECT col2 from t1; +connection con1; +SAVEPOINT s1; +SET DEBUG_SYNC='now WAIT_FOR t3_waiting'; +# T1: Wait for (T3) auto increment lock on t1 causing T1 -> T3 -> T2 -> T1 deadlock +SET debug_dbug = '+d,innodb_deadlock_victim_self'; +INSERT INTO t1(col2) VALUES(200); +ERROR HY000: Failed to read auto-increment value from storage engine +# The transaction should have been rolled back +SELECT * FROM t1; +col1 col2 +1 100 +SELECT * FROM t2; +col1 +# Release the previous savepoint using the same name +SAVEPOINT s1; +COMMIT; +connection con2; +COMMIT; +connection default; +COMMIT; +disconnect con1; +disconnect con2; +# Cleanup +SELECT * FROM t1; +col1 col2 +1 100 +2 100 +DROP TABLE t1; +SELECT * FROM t2; +col1 +100 +DROP TABLE t2; +SET DEBUG_SYNC='RESET'; +# +# End of 10.5 tests +# diff --git a/mysql-test/suite/innodb/r/autoinc_import.result b/mysql-test/suite/innodb/r/autoinc_import.result new file mode 100644 index 00000000000..4a8ddd02e3d --- /dev/null +++ b/mysql-test/suite/innodb/r/autoinc_import.result @@ -0,0 +1,232 @@ +CREATE TABLE t1 (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES(42); +CREATE TABLE t1b LIKE t1; +INSERT INTO t1b VALUES(3); +CREATE TABLE t1z LIKE t1; +CREATE TABLE t1t (id TINYINT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t0t LIKE t1t; +INSERT INTO t1t VALUES(123); +FLUSH TABLES t1,t1b,t1t FOR EXPORT; +UNLOCK TABLES; +CREATE TABLE t5_7 LIKE t1; +CREATE TABLE t5_7b LIKE t1b; +CREATE TABLE t10_1 LIKE t1; +CREATE TABLE t10_1b LIKE t1b; +ALTER TABLE t1 DISCARD TABLESPACE; +ALTER TABLE t1b DISCARD TABLESPACE; +ALTER TABLE t1z DISCARD TABLESPACE; +ALTER TABLE t1t DISCARD TABLESPACE; +ALTER TABLE t0t DISCARD TABLESPACE; +ALTER TABLE t5_7 DISCARD TABLESPACE; +ALTER TABLE t5_7b DISCARD TABLESPACE; +ALTER TABLE t10_1 DISCARD TABLESPACE; +ALTER TABLE t10_1b DISCARD TABLESPACE; +FLUSH TABLES; +ALTER TABLE t0t IMPORT TABLESPACE; +Warnings: +Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t0t.cfg', will attempt to import without schema verification +INSERT INTO t0t VALUES(NULL); +SELECT * FROM t0t; +id +123 +124 +DROP TABLE t0t; +ALTER TABLE t1 IMPORT TABLESPACE; +Warnings: +Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t1.cfg', will attempt to import without schema verification +ALTER TABLE t1b IMPORT TABLESPACE; +Warnings: +Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t1b.cfg', will attempt to import without schema verification +ALTER TABLE t1z IMPORT TABLESPACE; +Warnings: +Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t1z.cfg', will attempt to import without schema verification +ALTER TABLE t1t IMPORT TABLESPACE; +Warnings: +Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t1t.cfg', will attempt to import without schema verification +ALTER TABLE t5_7 IMPORT TABLESPACE; +Warnings: +Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t5_7.cfg', will attempt to import without schema verification +ALTER TABLE t5_7b IMPORT TABLESPACE; +Warnings: +Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t5_7b.cfg', will attempt to import without schema verification +ALTER TABLE t10_1 IMPORT TABLESPACE; +Warnings: +Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t10_1.cfg', will attempt to import without schema verification +ALTER TABLE t10_1b IMPORT TABLESPACE; +Warnings: +Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t10_1b.cfg', will attempt to import without schema verification +FOUND 1 /InnoDB: Resetting PAGE_ROOT_AUTO_INC from 128 to 123 on table `test`\.`t0t`/ in mysqld.1.err +FOUND 1 /InnoDB: Resetting PAGE_ROOT_AUTO_INC from 0 to 42 on table `test`\.`t1z`/ in mysqld.1.err +FOUND 1 /InnoDB: Resetting PAGE_ROOT_AUTO_INC from 128 to 123 on table `test`\.`t1t`/ in mysqld.1.err +FOUND 1 /InnoDB: Resetting PAGE_ROOT_AUTO_INC from 3 to 42 on table `test`\.`t5_7` \(created with version 50744\)/ in mysqld.1.err +FOUND 1 /InnoDB: Resetting PAGE_ROOT_AUTO_INC from 3 to 42 on table `test`\.`t10_1` \(created with version 100149\)/ in mysqld.1.err +FOUND 5 /InnoDB: Resetting PAGE_ROOT_AUTO_INC/ in mysqld.1.err +# restart: --read-only +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b; +Table Op Msg_type Msg_text +test.t1 check status OK +test.t1b check status OK +test.t1t check status OK +test.t1z check status OK +test.t5_7 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t5_7 check status OK +test.t5_7b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t5_7b check status OK +test.t10_1 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t10_1 check status OK +test.t10_1b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t10_1b check status OK +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check status OK +test.t1b check status OK +test.t1t check status OK +test.t1z check status OK +test.t5_7 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t5_7 check status OK +test.t5_7b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t5_7b check status OK +test.t10_1 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t10_1 check status OK +test.t10_1b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t10_1b check status OK +# restart: --innodb-read-only --read-only +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b; +Table Op Msg_type Msg_text +test.t1 check status OK +test.t1b check status OK +test.t1t check status OK +test.t1z check status OK +test.t5_7 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t5_7 check status OK +test.t5_7b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t5_7b check status OK +test.t10_1 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t10_1 check status OK +test.t10_1b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t10_1b check status OK +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check status OK +test.t1b check status OK +test.t1t check status OK +test.t1z check status OK +test.t5_7 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t5_7 check status OK +test.t5_7b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t5_7b check status OK +test.t10_1 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t10_1 check status OK +test.t10_1b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed +test.t10_1b check status OK +# restart: --innodb-read-only +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b; +Table Op Msg_type Msg_text +test.t1 check status OK +test.t1b check status OK +test.t1t check status OK +test.t1z check status OK +test.t5_7 check status Operation failed +test.t5_7b check status Operation failed +test.t10_1 check status Operation failed +test.t10_1b check status Operation failed +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check status OK +test.t1b check status OK +test.t1t check status OK +test.t1z check status OK +test.t5_7 check status Operation failed +test.t5_7b check status Operation failed +test.t10_1 check status Operation failed +test.t10_1b check status Operation failed +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +SELECT COUNT(*) FROM t1b; +COUNT(*) +1 +SELECT COUNT(*) FROM t1t; +COUNT(*) +1 +SELECT COUNT(*) FROM t1z; +COUNT(*) +1 +SELECT COUNT(*) FROM t5_7; +COUNT(*) +1 +SELECT COUNT(*) FROM t5_7b; +COUNT(*) +1 +SELECT COUNT(*) FROM t10_1; +COUNT(*) +1 +SELECT COUNT(*) FROM t10_1b; +COUNT(*) +1 +# restart +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check status OK +test.t1b check status OK +test.t1t check status OK +test.t1z check status OK +test.t5_7 check note Auto_increment checked and .frm file version updated +test.t5_7 check status OK +test.t5_7b check note Auto_increment checked and .frm file version updated +test.t5_7b check status OK +test.t10_1 check note Auto_increment checked and .frm file version updated +test.t10_1 check status OK +test.t10_1b check note Auto_increment checked and .frm file version updated +test.t10_1b check status OK +INSERT INTO t1 VALUES(NULL); +INSERT INTO t1b VALUES(NULL); +INSERT INTO t1t VALUES(NULL); +INSERT INTO t1z VALUES(NULL); +INSERT INTO t5_7 VALUES(NULL); +INSERT INTO t5_7b VALUES(NULL); +INSERT INTO t10_1 VALUES(NULL); +INSERT INTO t10_1b VALUES(NULL); +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check status OK +test.t1b check status OK +test.t1t check status OK +test.t1z check status OK +test.t5_7 check status OK +test.t5_7b check status OK +test.t10_1 check status OK +test.t10_1b check status OK +SELECT * FROM t1; +id +4 +42 +SELECT * FROM t1b; +id +3 +347 +SELECT * FROM t1t; +id +123 +124 +SELECT * FROM t1z; +id +42 +43 +SELECT * FROM t5_7; +id +42 +43 +SELECT * FROM t5_7b; +id +3 +347 +SELECT * FROM t10_1; +id +42 +43 +SELECT * FROM t10_1b; +id +3 +347 +DROP TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b; diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff index b19abb449ad..ad1f3a447c2 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff +++ b/mysql-test/suite/innodb/r/check_ibd_filesize,32k.rdiff @@ -14,7 +14,7 @@ -# bytes: 65536 +# bytes: 131072 INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20; --# bytes: 4194304 +-# bytes: 2097152 -DROP TABLE t1; -CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff index a1011a1cb90..1412df393ff 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff +++ b/mysql-test/suite/innodb/r/check_ibd_filesize,4k.rdiff @@ -13,7 +13,7 @@ -# bytes: 65536 +# bytes: 16384 INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20; - # bytes: 4194304 + # bytes: 2097152 DROP TABLE t1; CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff index 010eb8a284d..156925597ab 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff +++ b/mysql-test/suite/innodb/r/check_ibd_filesize,64k.rdiff @@ -14,7 +14,7 @@ -# bytes: 65536 +# bytes: 262144 INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20; --# bytes: 4194304 +-# bytes: 2097152 -DROP TABLE t1; -CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) -ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff b/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff index 0e1e64724b0..55cf59737d3 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff +++ b/mysql-test/suite/innodb/r/check_ibd_filesize,8k.rdiff @@ -13,7 +13,7 @@ -# bytes: 65536 +# bytes: 32768 INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20; - # bytes: 4194304 + # bytes: 2097152 DROP TABLE t1; CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; diff --git a/mysql-test/suite/innodb/r/check_ibd_filesize.result b/mysql-test/suite/innodb/r/check_ibd_filesize.result index 0d224d6ac5f..b0f376183ea 100644 --- a/mysql-test/suite/innodb/r/check_ibd_filesize.result +++ b/mysql-test/suite/innodb/r/check_ibd_filesize.result @@ -10,7 +10,7 @@ DROP TABLE t1; CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB; # bytes: 65536 INSERT INTO t1 SELECT seq,REPEAT('a',30000) FROM seq_1_to_20; -# bytes: 4194304 +# bytes: 2097152 DROP TABLE t1; CREATE TABLE t1 (a INT PRIMARY KEY, b BLOB) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; diff --git a/mysql-test/suite/innodb/r/cursor-restore-unique-null.result b/mysql-test/suite/innodb/r/cursor-restore-unique-null.result new file mode 100644 index 00000000000..29edc47a483 --- /dev/null +++ b/mysql-test/suite/innodb/r/cursor-restore-unique-null.result @@ -0,0 +1,24 @@ +CREATE TABLE t(a INT PRIMARY KEY, b INT, c INT, UNIQUE KEY `b_c` (`b`,`c`)) +ENGINE=InnoDB, STATS_PERSISTENT=0; +INSERT INTO t SET a = 1, c = 2; +connect con1,localhost,root; +BEGIN; +INSERT INTO t SET a=2, c=2; +connection default; +BEGIN; +SET DEBUG_SYNC="lock_wait_start SIGNAL select_locked"; +SELECT * FROM t FORCE INDEX(b) FOR UPDATE; +connection con1; +SET DEBUG_SYNC="now WAIT_FOR select_locked"; +ROLLBACK; +connection default; +# If the bug is not fixed, and the both unique index key fields are +# NULL, there will be two (1, NULL, 2) rows in the result, +# because cursor will be restored to (NULL, 2, 1) position for +# secondary key instead of "supremum". +a b c +1 NULL 2 +COMMIT; +SET DEBUG_SYNC="RESET"; +disconnect con1; +DROP TABLE t; diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index 808e2270e27..80a0afb8d06 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -1035,9 +1035,22 @@ BEGIN; INSERT INTO child SET a=1; ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`)) connection default; +TRUNCATE TABLE parent; +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`parent` (`a`)) +DROP TABLE parent; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails +SET innodb_lock_wait_timeout=0; +RENAME TABLE parent TO transparent; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +ALTER TABLE parent FORCE, ALGORITHM=COPY; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +ALTER TABLE parent FORCE, ALGORITHM=INPLACE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction SET innodb_lock_wait_timeout=0, foreign_key_checks=0; TRUNCATE TABLE parent; ERROR HY000: Lock wait timeout exceeded; try restarting transaction +DROP TABLE parent; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction ALTER TABLE parent FORCE, ALGORITHM=COPY; ERROR HY000: Lock wait timeout exceeded; try restarting transaction ALTER TABLE parent FORCE, ALGORITHM=INPLACE; @@ -1052,7 +1065,13 @@ TRUNCATE TABLE parent; ALTER TABLE parent FORCE, ALGORITHM=COPY; ALTER TABLE parent FORCE, ALGORITHM=INPLACE; ALTER TABLE parent ADD COLUMN b INT, ALGORITHM=INSTANT; -DROP TABLE child, parent; +SET foreign_key_checks=ON; +TRUNCATE TABLE parent; +ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`parent` (`a`)) +ALTER TABLE parent FORCE, ALGORITHM=COPY; +ALTER TABLE parent FORCE, ALGORITHM=INPLACE; +RENAME TABLE parent TO transparent; +DROP TABLE child, transparent; # # MDEV-26217 Failing assertion: list.count > 0 in ut_list_remove # or Assertion `lock->trx == this' failed in dberr_t trx_t::drop_table diff --git a/mysql-test/suite/innodb/r/full_crc32_import.result b/mysql-test/suite/innodb/r/full_crc32_import.result index 548e69c1c52..416f607cc33 100644 --- a/mysql-test/suite/innodb/r/full_crc32_import.result +++ b/mysql-test/suite/innodb/r/full_crc32_import.result @@ -50,7 +50,15 @@ t1 CREATE TABLE `t1` ( `b` blob DEFAULT NULL, `c` blob DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC +) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC +# Auto increment value must be more than maximum column value +SELECT MAX(a) FROM t1; +MAX(a) +45 +SELECT auto_increment FROM information_schema.tables +WHERE table_name like 't1'; +auto_increment +46 UPDATE t1 set b = repeat("de", 100) where b = repeat("cd", 200); explain SELECT a FROM t1 where b = repeat("de", 100); id select_type table type possible_keys key key_len ref rows Extra @@ -132,7 +140,15 @@ t1 CREATE TABLE `t1` ( `c2` point NOT NULL, `c3` linestring NOT NULL, PRIMARY KEY (`c1`) -) ENGINE=InnoDB AUTO_INCREMENT=16372 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC +) ENGINE=InnoDB AUTO_INCREMENT=14325 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC +# Auto increment value must be more than maximum column value +SELECT MAX(c1) FROM t1; +MAX(c1) +14324 +SELECT auto_increment FROM information_schema.tables +WHERE table_name like 't1'; +auto_increment +14325 UPDATE t1 SET C2 = ST_GeomFromText('POINT(0 0)'); SELECT COUNT(*) FROM t1; COUNT(*) diff --git a/mysql-test/suite/innodb/r/import_bugs.result b/mysql-test/suite/innodb/r/import_bugs.result index 98f3e76763b..26845e55567 100644 --- a/mysql-test/suite/innodb/r/import_bugs.result +++ b/mysql-test/suite/innodb/r/import_bugs.result @@ -15,6 +15,58 @@ CREATE TABLE imp_t1 (a INT PRIMARY KEY) ENGINE=InnoDB; DROP TABLE imp_t1, t1; SET GLOBAL innodb_checksum_algorithm=@save_innodb_checksum_algorithm; # +# MDEV-33400 Adaptive hash index corruption after DISCARD TABLESPACE +# +SET @save_adaptive=@@GLOBAL.innodb_adaptive_hash_index; +SET GLOBAL innodb_adaptive_hash_index=ON; +CREATE TABLE t (a INT PRIMARY KEY) ENGINE=INNODB; +INSERT INTO t SELECT * FROM seq_1_to_131; +ALTER TABLE t ADD hid INT DEFAULT 2; +INSERT INTO t VALUES (251,1); +ALTER TABLE t DISCARD TABLESPACE; +CHECK TABLE mysql.innodb_table_stats; +Table Op Msg_type Msg_text +mysql.innodb_table_stats check status OK +DROP TABLE t; +SET GLOBAL innodb_adaptive_hash_index=@save_adaptive; +# End of 10.4 tests +# +# MDEV-18288: Transportable Tablespaces leave AUTO_INCREMENT in mismatched +# state, causing INSERT errors in newly imported tables when .cfg is not used. +# +CREATE TABLE t1( +id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, +PRIMARY KEY (id) +) ENGINE=INNODB; +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; +INSERT INTO t1() VALUES(); +INSERT INTO t1() VALUES(); +FLUSH TABLES test.t1 FOR EXPORT; +# Copy data file +# Skip CFG file copy +UNLOCK TABLES; +DROP TABLE t1; +ALTER TABLE t2 IMPORT TABLESPACE; +Warnings: +Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t2.cfg', will attempt to import without schema verification +SELECT * FROM t2 ORDER BY id; +id +1 +2 +INSERT INTO t2() VALUES(); +INSERT INTO t2() VALUES(); +INSERT INTO t2() VALUES(); +SELECT * FROM t2 ORDER BY id; +id +1 +2 +3 +4 +5 +DROP TABLE t2; +# End of 10.5 tests +# # MDEV-27006 Assertion `!lock_trx_has_sys_table_locks(trx)' # failed in dberr_t row_discard_tablespace_for_mysql # (dict_table_t*, trx_t*) diff --git a/mysql-test/suite/innodb/r/import_hidden_fts.result b/mysql-test/suite/innodb/r/import_hidden_fts.result new file mode 100644 index 00000000000..69120898d4d --- /dev/null +++ b/mysql-test/suite/innodb/r/import_hidden_fts.result @@ -0,0 +1,45 @@ +call mtr.add_suppression("InnoDB: Added system generated FTS_DOC_ID and FTS_DOC_ID_INDEX while importing the tablespace"); +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, +f2 CHAR(2) not null, fulltext f_idx(f2), +f3 INT as (f1) VIRTUAL, INDEX(f3), +f4 INT as (f1) STORED, INDEX(f4), +f5 INT as (f1) VIRTUAL)ENGINE=InnoDB; +INSERT INTO t1(f1, f2) VALUES(1, "on"); +INSERT INTO t1(f1, f2) SELECT seq, "si" FROM seq_2_to_256; +ALTER TABLE t1 ADD COLUMN f6 INT NOT NULL; +ALTER TABLE t1 DROP COLUMN f6; +ALTER TABLE t1 DROP INDEX f_idx; +connect con1,localhost,root,,; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +DELETE FROM t1 WHERE f1 > 1; +FLUSH TABLE t1 FOR EXPORT; +Warnings: +Warning 1235 This version of MariaDB doesn't yet support 'FLUSH TABLES on a table that had an FTS index, created on a hidden column, the auxiliary tables haven't been dropped as yet. FTS auxiliary tables will not be flushed.' +Warning 1235 This version of MariaDB doesn't yet support 'FLUSH TABLES on a table that had an FTS index, created on a hidden column, the auxiliary tables haven't been dropped as yet. FTS auxiliary tables will not be flushed.' +backup: t1 +UNLOCK TABLES; +Warnings: +Warning 1235 This version of MariaDB doesn't yet support 'FLUSH TABLES on a table that had an FTS index, created on a hidden column, the auxiliary tables haven't been dropped as yet. FTS auxiliary tables will not be flushed.' +DROP TABLE t1; +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, +f2 CHAR(2) not null, +f3 INT as (f1) VIRTUAL, INDEX(f3), +f4 INT as (f1) STORED, INDEX(f4), +f5 INT as (f1) VIRTUAL)ENGINE=InnoDB; +ALTER TABLE t1 DISCARD TABLESPACE; +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` char(2) NOT NULL, + `f3` int(11) GENERATED ALWAYS AS (`f1`) VIRTUAL, + `f4` int(11) GENERATED ALWAYS AS (`f1`) STORED, + `f5` int(11) GENERATED ALWAYS AS (`f1`) VIRTUAL, + PRIMARY KEY (`f1`), + KEY `f3` (`f3`), + KEY `f4` (`f4`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/import_hidden_fts_debug.result b/mysql-test/suite/innodb/r/import_hidden_fts_debug.result new file mode 100644 index 00000000000..2cf1746ee25 --- /dev/null +++ b/mysql-test/suite/innodb/r/import_hidden_fts_debug.result @@ -0,0 +1,76 @@ +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, +f2 CHAR(2) NOT NULL, FULLTEXT f_idx(f2), +f3 INT as (f1) VIRTUAL, INDEX(f3))ENGINE=InnoDB; +INSERT INTO t1(f1, f2) VALUES(1, "on"); +ALTER TABLE t1 DROP INDEX f_idx; +FLUSH TABLE t1 FOR EXPORT; +Warnings: +Warning 1235 This version of MariaDB doesn't yet support 'FLUSH TABLES on a table that had an FTS index, created on a hidden column, the auxiliary tables haven't been dropped as yet. FTS auxiliary tables will not be flushed.' +Warning 1235 This version of MariaDB doesn't yet support 'FLUSH TABLES on a table that had an FTS index, created on a hidden column, the auxiliary tables haven't been dropped as yet. FTS auxiliary tables will not be flushed.' +backup: t1 +UNLOCK TABLES; +Warnings: +Warning 1235 This version of MariaDB doesn't yet support 'FLUSH TABLES on a table that had an FTS index, created on a hidden column, the auxiliary tables haven't been dropped as yet. FTS auxiliary tables will not be flushed.' +DROP TABLE t1; +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, +f2 CHAR(2) NOT NULL, +f3 CHAR(2) NOT NULL, +f4 INT AS (f1) VIRTUAL, INDEX(f4))ENGINE=InnoDB; +ALTER TABLE t1 DISCARD TABLESPACE; +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Number of indexes don't match, table has 2 indexes but the tablespace meta-data file has 3 indexes) +DROP TABLE t1; +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, +f2 CHAR(2) NOT NULL, +f3 INT as (f1) VIRTUAL, INDEX(f3))ENGINE=InnoDB; +ALTER TABLE t1 DISCARD TABLESPACE; +restore: t1 .ibd and .cfg files +SET DEBUG_DBUG="+d,ib_import_set_index_root_failure"; +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Too many active concurrent transactions +SET DEBUG_DBUG="-d,ib_import_set_index_root_failure"; +SET DEBUG_DBUG="+d,ib_import_vcol_update_fail"; +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR 23000: Can't write; duplicate key in table 't1' +SET DEBUG_DBUG="-d,ib_import_vcol_update_fail"; +restore: t1 .ibd and .cfg files +SET DEBUG_DBUG="+d,ib_import_fts_error"; +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR 23000: Can't write; duplicate key in table 't1' +SET DEBUG_DBUG="-d,ib_import_fts_error"; +unlink: t1.ibd +unlink: t1.cfg +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS +WHERE table_id IN (SELECT table_id FROM information_schema.innodb_sys_tables where name="test/t1"); +NAME +f1 +f2 +f3 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` char(2) NOT NULL, + `f3` int(11) GENERATED ALWAYS AS (`f1`) VIRTUAL, + PRIMARY KEY (`f1`), + KEY `f3` (`f3`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1; +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, +FTS_DOC_ID BIGINT SIGNED NOT NULL, +f2 CHAR(2) NOT NULL, +FULLTEXT f_idx(f2))ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, 1, "on"); +ALTER TABLE t1 DROP INDEX f_idx; +FLUSH TABLE t1 FOR EXPORT; +backup: t1 +UNLOCK TABLES; +DROP TABLE t1; +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, +f2 CHAR(2) NOT NULL)ENGINE=InnoDB; +ALTER TABLE t1 DISCARD TABLESPACE; +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Schema mismatch (Column f2 ordinal value mismatch, it's at 1 in the table and 2 in the tablespace meta-data file) +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/index_length.result b/mysql-test/suite/innodb/r/index_length.result index cc92780ac32..e0d6a735bb4 100644 --- a/mysql-test/suite/innodb/r/index_length.result +++ b/mysql-test/suite/innodb/r/index_length.result @@ -20,4 +20,12 @@ FLOOR(index_length/@@innodb_page_size) 2 disconnect stop_purge; DROP TABLE t1; +# +# MDEV-22855 Assertion (!field->prefix_len || +# field->fixed_len == field->prefix_len) +# failed in btr_node_ptr_max_size +# +CREATE TABLE t1(c CHAR(194) CHARACTER SET UTF32, KEY k1(c(193)))ENGINE=InnoDB; +INSERT INTO t1 SET c=''; +DROP TABLE t1; # End of 10.4 tests diff --git a/mysql-test/suite/innodb/r/innodb-alter-debug.result b/mysql-test/suite/innodb/r/innodb-alter-debug.result index c55b4a3ddd5..fd33581ffab 100644 --- a/mysql-test/suite/innodb/r/innodb-alter-debug.result +++ b/mysql-test/suite/innodb/r/innodb-alter-debug.result @@ -108,11 +108,11 @@ DROP TABLE t; # MDEV-26772 InnoDB DDL fails with DUPLICATE KEY error # create table t1(f1 int not null primary key, -f2 int not null, index idx(f2))engine=innodb; +f2 int not null, index idx(f2), index i(f2,f1))engine=innodb; insert into t1 values(1, 1); connect con1,localhost,root,,,; SET DEBUG_SYNC='before_delete_table_stats SIGNAL blocked WAIT_FOR go'; -SET innodb_lock_wait_timeout=0; +SET STATEMENT innodb_lock_wait_timeout=0 FOR ALTER TABLE t1 FORCE, ALGORITHM=COPY; connection default; SET DEBUG_SYNC='now WAIT_FOR blocked'; @@ -124,6 +124,17 @@ connection con1; connection default; COMMIT; SET DEBUG_SYNC=RESET; +RENAME TABLE mysql.innodb_table_stats TO mysql.innodb_table_stats_hidden; +connection con1; +SET DEBUG_SYNC='innodb_commit_inplace_before_lock SIGNAL blocked WAIT_FOR go'; +ALTER TABLE t1 DROP INDEX i; +connection default; +SET DEBUG_SYNC='now WAIT_FOR blocked'; +RENAME TABLE mysql.innodb_table_stats_hidden TO mysql.innodb_table_stats; +SET DEBUG_SYNC='now SIGNAL go'; +connection con1; +connection default; +SET DEBUG_SYNC=RESET; connection con1; ALTER TABLE t1 RENAME KEY idx TO idx1, ALGORITHM=COPY; disconnect con1; diff --git a/mysql-test/suite/innodb/r/innodb-lru-force-no-free-page.result b/mysql-test/suite/innodb/r/innodb-lru-force-no-free-page.result deleted file mode 100644 index 09e53b59d9d..00000000000 --- a/mysql-test/suite/innodb/r/innodb-lru-force-no-free-page.result +++ /dev/null @@ -1,10 +0,0 @@ -call mtr.add_suppression("InnoDB: Difficult to find free blocks in the buffer pool"); -SET @saved_debug = @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,ib_lru_force_no_free_page"; -CREATE TABLE t1 (j LONGBLOB) ENGINE = InnoDB; -BEGIN; -INSERT INTO t1 VALUES (repeat('abcdefghijklmnopqrstuvwxyz',200)); -COMMIT; -SET debug_dbug = @saved_debug; -DROP TABLE t1; -FOUND 1 /InnoDB: Difficult to find free blocks / in mysqld.1.err diff --git a/mysql-test/suite/innodb/r/innodb-wl5522,crc32.rdiff b/mysql-test/suite/innodb/r/innodb-wl5522,crc32.rdiff deleted file mode 100644 index bb902e18931..00000000000 --- a/mysql-test/suite/innodb/r/innodb-wl5522,crc32.rdiff +++ /dev/null @@ -1,5 +0,0 @@ -120,121c120 -< Warnings: -< Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t2.cfg', will attempt to import without schema verification ---- -> ERROR HY000: Schema mismatch (Expected FSP_SPACE_FLAGS=0x*, .ibd file contains 0x*.) diff --git a/mysql-test/suite/innodb/r/innodb-wl5522,strict_crc32.rdiff b/mysql-test/suite/innodb/r/innodb-wl5522,strict_crc32.rdiff index bb902e18931..283bbe96aae 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522,strict_crc32.rdiff +++ b/mysql-test/suite/innodb/r/innodb-wl5522,strict_crc32.rdiff @@ -1,5 +1,12 @@ -120,121c120 -< Warnings: -< Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t2.cfg', will attempt to import without schema verification ---- -> ERROR HY000: Schema mismatch (Expected FSP_SPACE_FLAGS=0x*, .ibd file contains 0x*.) +--- innodb-wl5522.result ++++ innodb-wl5522,strict_crc32.result~ +@@ -131,8 +131,7 @@ + ALTER TABLE t2 IMPORT TABLESPACE; + ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x1; .cfg file uses ROW_FORMAT=COMPACT) + ALTER TABLE t2 IMPORT TABLESPACE; +-Warnings: +-Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t2.cfg', will attempt to import without schema verification ++ERROR HY000: Schema mismatch (Expected FSP_SPACE_FLAGS=0x*, .ibd file contains 0x*.) + DROP TABLE t2; + SET GLOBAL innodb_file_per_table = 1; + SELECT @@innodb_file_per_table; diff --git a/mysql-test/suite/innodb/r/innodb_bug30113362.result b/mysql-test/suite/innodb/r/innodb_bug30113362.result index cb0f5091650..5d30c5c03dd 100644 --- a/mysql-test/suite/innodb/r/innodb_bug30113362.result +++ b/mysql-test/suite/innodb/r/innodb_bug30113362.result @@ -37,7 +37,7 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK SELECT CLUST_INDEX_SIZE FROM information_schema.INNODB_SYS_TABLESTATS WHERE NAME = 'test/t1'; CLUST_INDEX_SIZE -1856 +1792 connection con2; DELETE FROM t1 WHERE a00 = 'cnm'; COMMIT; @@ -80,7 +80,7 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK SELECT CLUST_INDEX_SIZE FROM information_schema.INNODB_SYS_TABLESTATS WHERE NAME = 'test/t1'; CLUST_INDEX_SIZE -1856 +1792 DELETE FROM t1 WHERE a00 = 'dpn'; COMMIT; INSERT INTO t1 SET a00 = 'dpn'; @@ -117,6 +117,6 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK SELECT CLUST_INDEX_SIZE FROM information_schema.INNODB_SYS_TABLESTATS WHERE NAME = 'test/t1'; CLUST_INDEX_SIZE -1856 +1792 SET DEBUG_SYNC = 'RESET'; DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 697ed2e36ae..99e42e67277 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -431,10 +431,6 @@ a connection con1; begin work; insert into t1 values (5); -select * from t1; -a -1 -5 insert into t1 values (2); ERROR HY000: Lock wait timeout exceeded; try restarting transaction select * from t1; @@ -509,10 +505,6 @@ a connection con1; begin work; insert into t1 values (5); -select * from t1; -a -1 -5 insert into t1 values (2); ERROR HY000: Lock wait timeout exceeded; try restarting transaction select * from t1; @@ -1217,10 +1209,6 @@ a connection con1; begin work; insert into t1 values (5); -select * from t1; -a -1 -5 insert into t1 values (2); ERROR HY000: Lock wait timeout exceeded; try restarting transaction select * from t1; diff --git a/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result b/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result index c53707d5997..4fa95934446 100644 --- a/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result +++ b/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result @@ -86,7 +86,6 @@ buffer_flush_n_to_flush_by_age buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NUL buffer_flush_adaptive_avg_time buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for adaptive flushing recently. buffer_flush_adaptive_avg_pass buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of adaptive flushes passed during the recent Avg period. buffer_LRU_get_free_loops buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Total loops in LRU get free. -buffer_LRU_get_free_waits buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Total sleep waits in LRU get free. buffer_flush_avg_page_rate buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Average number of pages at which flushing is happening buffer_flush_lsn_avg_rate buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Average redo generation rate buffer_flush_pct_for_dirty buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Percent of IO capacity used to avoid max dirty page limit @@ -106,7 +105,6 @@ buffer_LRU_batch_num_scan buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NUL buffer_LRU_batch_scanned_per_call buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Pages scanned per LRU batch call buffer_LRU_batch_flush_total_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Total pages flushed as part of LRU batches buffer_LRU_batch_evict_total_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Total pages evicted as part of LRU batches -buffer_LRU_single_flush_failure_count Buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times attempt to flush a single page from LRU failed buffer_LRU_get_free_search Buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of searches performed for a clean page buffer_LRU_search_scanned buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_owner Total pages scanned as part of LRU search buffer_LRU_search_num_scan buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Number of times LRU search is performed diff --git a/mysql-test/suite/innodb/r/innodb_stats_fetch.result b/mysql-test/suite/innodb/r/innodb_stats_fetch.result index 2a68bc4c070..ccc8d20594d 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_fetch.result +++ b/mysql-test/suite/innodb/r/innodb_stats_fetch.result @@ -174,3 +174,10 @@ SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_VIRTUAL LIMIT ROWS EXAMINED 5; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN LIMIT ROWS EXAMINED 5; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS LIMIT ROWS EXAMINED 5; DROP TABLE t1; +# +# MDEV-33462 Disallow LOCK=NONE operation on statistics table +# +ALTER TABLE mysql.innodb_table_stats FORCE, LOCK=NONE, ALGORITHM=INPLACE; +ERROR 0A000: LOCK=NONE is not supported. Reason: innodb_table_stats. Try LOCK=SHARED +ALTER TABLE mysql.innodb_index_stats FORCE, LOCK=NONE, ALGORITHM=INPLACE; +ERROR 0A000: LOCK=NONE is not supported. Reason: innodb_index_stats. Try LOCK=SHARED diff --git a/mysql-test/suite/innodb/r/innodb_timeout_rollback.result b/mysql-test/suite/innodb/r/innodb_timeout_rollback.result index 30db5a21a4d..5f99ad75a12 100644 --- a/mysql-test/suite/innodb/r/innodb_timeout_rollback.result +++ b/mysql-test/suite/innodb/r/innodb_timeout_rollback.result @@ -17,10 +17,6 @@ a connection con1; begin work; insert into t1 values (5); -select * from t1; -a -1 -5 insert into t1 values (2); ERROR HY000: Lock wait timeout exceeded; try restarting transaction select * from t1; @@ -41,4 +37,4 @@ a drop table t1; disconnect con1; disconnect con2; -End of 5.0 tests +# End of 5.0 tests diff --git a/mysql-test/suite/innodb/r/innodb_ut_format_name.result b/mysql-test/suite/innodb/r/innodb_ut_format_name.result deleted file mode 100644 index 41a5b0f7149..00000000000 --- a/mysql-test/suite/innodb/r/innodb_ut_format_name.result +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE t (c INT) ENGINE=INNODB; -SET @save_dbug = @@debug_dbug; -SET debug_dbug = '+d,test_ut_format_name'; -DROP TABLE t; -SET debug_dbug = @save_dbug; diff --git a/mysql-test/suite/innodb/r/insert_into_empty,4k.rdiff b/mysql-test/suite/innodb/r/insert_into_empty,4k.rdiff index baa017ecf86..ad3d03a7eae 100644 --- a/mysql-test/suite/innodb/r/insert_into_empty,4k.rdiff +++ b/mysql-test/suite/innodb/r/insert_into_empty,4k.rdiff @@ -1,2 +1,10 @@ -423a424 -> ERROR 42000: Row size too large (> 1982). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline. +--- a/mysql-test/suite/innodb/r/insert_into_empty.result ++++ b/mysql-test/suite/innodb/r/insert_into_empty.result +@@ -430,6 +430,7 @@ + INSERT IGNORE INTO t1 VALUES + (1, REPEAT('x',4805), REPEAT('t',2211), REPEAT('u',974), REPEAT('e',871), REPEAT('z',224), REPEAT('j',978), REPEAT('n',190), REPEAT('t',888), REPEAT('x',32768), REPEAT('e',968), REPEAT('b',913), REPEAT('x',12107)), + (2, REPEAT('x',4805), REPEAT('t',2211), REPEAT('u',974), REPEAT('e',871), REPEAT('z',224), REPEAT('j',978), REPEAT('n',190), REPEAT('t',888), REPEAT('x',32768), REPEAT('e',968), REPEAT('b',913), REPEAT('x',12107)); ++ERROR 42000: Row size too large (> 1982). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline. + CHECK TABLE t1; + Table Op Msg_type Msg_text + test.t1 check status OK diff --git a/mysql-test/suite/innodb/r/insert_into_empty.result b/mysql-test/suite/innodb/r/insert_into_empty.result index 43b812b586e..d4ffaf89a91 100644 --- a/mysql-test/suite/innodb/r/insert_into_empty.result +++ b/mysql-test/suite/innodb/r/insert_into_empty.result @@ -251,6 +251,15 @@ c1 1984 3331 DROP TABLE t1; +# +# MDEV-33979 Disallow bulk insert operation during +# partition update statement +# +CREATE TABLE t1(a INT KEY)ENGINE=InnoDB +PARTITION BY KEY(a) PARTITIONS 16; +INSERT INTO t1 VALUES(1); +UPDATE t1 SET a = 2 WHERE a = 1; +DROP TABLE t1; # End of 10.6 tests # # MDEV-26947 UNIQUE column checks fail in InnoDB resulting @@ -467,3 +476,47 @@ DROP TABLE t1; CREATE TABLE t (a CHAR CHARACTER SET utf8) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; INSERT t SELECT left(seq,1) FROM seq_1_to_43691; DROP TABLE t; +# +# MDEV-32453 Bulk insert fails to apply when trigger +# does insert operation +# +CREATE TABLE t(c INT)ENGINE=InnoDB; +CREATE TRIGGER t2_ai AFTER INSERT ON t FOR EACH ROW SET @a:=(SELECT * FROM t); +BEGIN; +INSERT INTO t VALUES (1),(1); +ERROR 21000: Subquery returns more than 1 row +COMMIT; +DROP TABLE t; +# +# MDEV-33868 Assertion `trx->bulk_insert' failed in +# innodb_prepare_commit_versioned +# +CREATE TABLE t (id INT) ENGINE=InnoDB; +select 1 into outfile "VARDIR/tmp/t.outfile"; +BEGIN; +LOAD DATA INFILE 'VARDIR/tmp/t.outfile' INTO TABLE t; +COMMIT; +DROP TABLE t; +# +# MDEV-33934 Assertion `!check_foreigns' failed in +# trx_t::bulk_insert_apply_for_table(dict_table_t*) +# +CREATE TABLE t1(f1 INT,f2 INT,KEY(f1))engine=innodb; +BEGIN; +INSERT INTO t1 VALUES(); +SET STATEMENT FOREIGN_KEY_CHECKS=1 FOR SELECT * FROM t1; +f1 f2 +NULL NULL +COMMIT; +DROP TABLE t1; +# +# MDEV-33970 Assertion `!m.first->second.is_bulk_insert()' +# failed in trx_undo_report_row_operation() +# +CREATE TABLE t1(c1 INT,c2 CHAR) ENGINE=INNODB PARTITION BY KEY(c1) PARTITIONS 2; +begin; +INSERT INTO t1 VALUES(2,0); +DELETE FROM t1; +commit; +DROP TABLE t1; +# End of 10.11 tests diff --git a/mysql-test/suite/innodb/r/instant_alter_crash.result b/mysql-test/suite/innodb/r/instant_alter_crash.result index e423afe10a8..565f7e4b34e 100644 --- a/mysql-test/suite/innodb/r/instant_alter_crash.result +++ b/mysql-test/suite/innodb/r/instant_alter_crash.result @@ -202,27 +202,3 @@ Table Op Msg_type Msg_text test.t2 check status OK DROP TABLE t1,t2; db.opt -# -# MDEV-26198 Assertion `0' failed in row_log_table_apply_op during -# ADD PRIMARY KEY or OPTIMIZE TABLE -# -CREATE TABLE t1(f1 year default null, f2 year default null, -f3 text, f4 year default null, f5 year default null, -f6 year default null, f7 year default null, -f8 year default null)ENGINE=InnoDB ROW_FORMAT=REDUNDANT; -INSERT INTO t1 VALUES(1, 1, 1, 1, 1, 1, 1, 1); -ALTER TABLE t1 ADD COLUMN f9 year default null, ALGORITHM=INPLACE; -set DEBUG_SYNC="row_log_table_apply1_before SIGNAL con1_insert WAIT_FOR con1_finish"; -ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ADD COLUMN f10 YEAR DEFAULT NULL, ALGORITHM=INPLACE; -connect con1,localhost,root,,,; -SET DEBUG_SYNC="now WAIT_FOR con1_insert"; -INSERT IGNORE INTO t1 (f3) VALUES ( 'b' ); -INSERT IGNORE INTO t1 (f3) VALUES ( 'l' ); -SET DEBUG_SYNC="now SIGNAL con1_finish"; -connection default; -disconnect con1; -SET DEBUG_SYNC=RESET; -CHECK TABLE t1; -Table Op Msg_type Msg_text -test.t1 check status OK -DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/instant_alter_debug,redundant.rdiff b/mysql-test/suite/innodb/r/instant_alter_debug,redundant.rdiff index f442e406ce4..cf72c37bde8 100644 --- a/mysql-test/suite/innodb/r/instant_alter_debug,redundant.rdiff +++ b/mysql-test/suite/innodb/r/instant_alter_debug,redundant.rdiff @@ -2,7 +2,7 @@ FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; instants --35 -+36 +-37 ++38 SET GLOBAL innodb_stats_persistent = @save_stats_persistent; # End of 10.6 tests diff --git a/mysql-test/suite/innodb/r/instant_alter_debug.result b/mysql-test/suite/innodb/r/instant_alter_debug.result index ca69cfadcfd..dd032e1d1f6 100644 --- a/mysql-test/suite/innodb/r/instant_alter_debug.result +++ b/mysql-test/suite/innodb/r/instant_alter_debug.result @@ -471,10 +471,59 @@ SET DEBUG_SYNC="now WAIT_FOR try_insert"; INSERT INTO t1 VALUES(1, 2); ERROR HY000: Lock wait timeout exceeded; try restarting transaction SET DEBUG_SYNC="now SIGNAL alter_progress"; -disconnect con1; connection default; DROP TABLE t1; +# +# MDEV-26198 Assertion `0' failed in row_log_table_apply_op during +# ADD PRIMARY KEY or OPTIMIZE TABLE +# +CREATE TABLE t1(f1 year default null, f2 year default null, +f3 text, f4 year default null, f5 year default null, +f6 year default null, f7 year default null, +f8 year default null)ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, 1, 1, 1, 1, 1, 1, 1); +ALTER TABLE t1 ADD COLUMN f9 year default null, ALGORITHM=INPLACE; +set DEBUG_SYNC="row_log_table_apply1_before SIGNAL con1_insert WAIT_FOR con1_finish"; +ALTER TABLE t1 ADD COLUMN f10 YEAR DEFAULT NULL, FORCE, ALGORITHM=INPLACE; +connection con1; +SET DEBUG_SYNC="now WAIT_FOR con1_insert"; +INSERT IGNORE INTO t1 (f3) VALUES ( 'b' ); +INSERT IGNORE INTO t1 (f3) VALUES ( 'l' ); +SET DEBUG_SYNC="now SIGNAL con1_finish"; +connection default; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +# +# MDEV-19044 Alter table corrupts while applying the +# modification log +# +CREATE TABLE t1 ( +f1 INT, +f2 INT, +f3 char(19) CHARACTER SET utf8mb3, +f4 VARCHAR(500), +f5 TEXT)ENGINE=InnoDB; +INSERT INTO t1 VALUES(3, 1, REPEAT('a', 2), REPEAT("b", 20),'a'); +ALTER TABLE t1 ADD COLUMN f6 INT NOT NULL, ALGORITHM=INSTANT; +INSERT INTO t1 VALUES(1, 2, REPEAT('InnoDB', 2), +REPEAT("MariaDB", 20), REPEAT('a', 8000), 12); +INSERT INTO t1 VALUES(1, 2, REPEAT('MYSQL', 2), +REPEAT("MariaDB", 20), REPEAT('a', 8000), 12); +SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL con1_begin WAIT_FOR con1_update'; +ALTER TABLE t1 MODIFY COLUMN f2 INT NOT NULL, FORCE, ALGORITHM=INPLACE; +connection con1; +SET DEBUG_SYNC='now WAIT_FOR con1_begin'; +UPDATE t1 SET f2=204 order by f1 limit 2; +SET DEBUG_SYNC='now SIGNAL con1_update'; +connection default; +disconnect con1; SET DEBUG_SYNC=reset; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; # End of 10.4 tests # # MDEV-22867 Assertion instant.n_core_fields == n_core_fields @@ -519,6 +568,6 @@ SELECT variable_value-@old_instant instants FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; instants -35 +37 SET GLOBAL innodb_stats_persistent = @save_stats_persistent; # End of 10.6 tests diff --git a/mysql-test/suite/innodb/r/instant_alter_extend.result b/mysql-test/suite/innodb/r/instant_alter_extend.result index 33a5f57c7b6..c22043eceb1 100644 Binary files a/mysql-test/suite/innodb/r/instant_alter_extend.result and b/mysql-test/suite/innodb/r/instant_alter_extend.result differ diff --git a/mysql-test/suite/innodb/r/instant_alter_import.result b/mysql-test/suite/innodb/r/instant_alter_import.result index 3e7ee35fdc1..6fe48fb6fab 100644 --- a/mysql-test/suite/innodb/r/instant_alter_import.result +++ b/mysql-test/suite/innodb/r/instant_alter_import.result @@ -64,6 +64,7 @@ alter table t1 discard tablespace; flush tables t2 for export; unlock tables; alter table t1 import tablespace; +# restart select * from t1; z 42 diff --git a/mysql-test/suite/innodb/r/lock_insert_into_empty.result b/mysql-test/suite/innodb/r/lock_insert_into_empty.result index c1dea2fc9af..97369b58aef 100644 --- a/mysql-test/suite/innodb/r/lock_insert_into_empty.result +++ b/mysql-test/suite/innodb/r/lock_insert_into_empty.result @@ -47,6 +47,9 @@ CREATE TABLE t1 (k INT PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t1 SET k=1; START TRANSACTION; INSERT INTO t1 SET k=2; +SELECT count(*) > 0 FROM mysql.innodb_index_stats lock in share mode; +count(*) > 0 +1 connect con1,localhost,root,,test; SET innodb_lock_wait_timeout=0; CREATE TABLE t2 (pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB @@ -54,4 +57,6 @@ AS SELECT k FROM t1; ERROR HY000: Lock wait timeout exceeded; try restarting transaction disconnect con1; connection default; +SET innodb_lock_wait_timeout=default; DROP TABLE t1; +DROP TABLE IF EXISTS t2; diff --git a/mysql-test/suite/innodb/r/lock_isolation.result b/mysql-test/suite/innodb/r/lock_isolation.result new file mode 100644 index 00000000000..31843266617 --- /dev/null +++ b/mysql-test/suite/innodb/r/lock_isolation.result @@ -0,0 +1,136 @@ +# +# MDEV-26642 Weird SELECT view when a record is +# modified to the same value by two transactions +# MDEV-32898 Phantom rows caused by updates of PRIMARY KEY +# +CREATE TABLE t(a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t VALUES (1,1),(2,2); +BEGIN; +SELECT * FROM t LOCK IN SHARE MODE; +a b +1 1 +2 2 +connect con_weird,localhost,root; +BEGIN; +SELECT * FROM t; +a b +1 1 +2 2 +connect consistent,localhost,root; +SET innodb_snapshot_isolation=ON; +BEGIN; +SELECT * FROM t; +a b +1 1 +2 2 +connection default; +UPDATE t SET a=3 WHERE b=2; +COMMIT; +connection consistent; +UPDATE t SET b=3; +ERROR HY000: Record has changed since last read in table 't' +SELECT * FROM t; +a b +1 1 +3 2 +COMMIT; +connection con_weird; +UPDATE t SET b=3; +SELECT * FROM t; +a b +1 3 +2 2 +3 3 +COMMIT; +connection default; +SELECT * FROM t; +a b +1 3 +3 3 +DROP TABLE t; +# +# MDEV-26643 Inconsistent behaviors of UPDATE under +# READ UNCOMMITTED and READ COMMITTED isolation level +# +CREATE TABLE t(a INT, b INT) ENGINE=InnoDB; +INSERT INTO t VALUES(NULL, 1), (2, 2); +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +BEGIN; +UPDATE t SET a = 10; +connection consistent; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +UPDATE t SET b = 20 WHERE a; +connection default; +COMMIT; +connection consistent; +SELECT * FROM t; +a b +10 20 +10 20 +connection default; +TRUNCATE TABLE t; +INSERT INTO t VALUES(NULL, 1), (2, 2); +BEGIN; +UPDATE t SET a = 10; +connection consistent; +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +UPDATE t SET b = 20 WHERE a; +connection default; +COMMIT; +connection consistent; +SELECT * FROM t; +a b +10 20 +10 20 +connection default; +TRUNCATE TABLE t; +INSERT INTO t VALUES(NULL, 1), (2, 2); +BEGIN; +UPDATE t SET a = 10; +connection con_weird; +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +UPDATE t SET b = 20 WHERE a; +connection default; +SELECT * FROM t; +a b +10 1 +10 2 +COMMIT; +connection con_weird; +COMMIT; +connection default; +SELECT * FROM t; +a b +10 1 +10 20 +DROP TABLE t; +# +# MDEV-33802 Weird read view after ROLLBACK of other transactions +# +CREATE TABLE t(a INT PRIMARY KEY, b INT UNIQUE) ENGINE=InnoDB; +INSERT INTO t SET a=1; +BEGIN; +INSERT INTO t SET a=2; +connection consistent; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +SELECT * FROM t FORCE INDEX (b) FOR UPDATE; +ERROR HY000: Record has changed since last read in table 't' +connection con_weird; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +SELECT * FROM t FORCE INDEX (b) FOR UPDATE; +connection default; +ROLLBACK; +connection con_weird; +a b +1 NULL +SELECT * FROM t FORCE INDEX (b) FOR UPDATE; +a b +1 NULL +disconnect con_weird; +connection consistent; +SELECT * FROM t FORCE INDEX (b) FOR UPDATE; +a b +1 NULL +disconnect consistent; +connection default; +DROP TABLE t; diff --git a/mysql-test/suite/innodb/r/log_upgrade_101_flags.result b/mysql-test/suite/innodb/r/log_upgrade_101_flags.result new file mode 100644 index 00000000000..2458c51bf23 --- /dev/null +++ b/mysql-test/suite/innodb/r/log_upgrade_101_flags.result @@ -0,0 +1,12 @@ +call mtr.add_suppression("InnoDB: The change buffer is corrupted"); +call mtr.add_suppression("InnoDB: Tablespace size stored in header is 768 pages, but the sum of data file sizes is 384 pages"); +call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS of file"); +# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_upgrade --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_upgrade --innodb-undo-directory=MYSQLTEST_VARDIR/tmp/log_upgrade --innodb-force-recovery=5 --innodb-log-file-size=4m --innodb_page_size=32k --innodb_buffer_pool_size=10M +SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +COUNT(*) +1 +FOUND 1 /InnoDB: Upgrading redo log:/ in mysqld.1.err +# restart +# End of 10.5 tests diff --git a/mysql-test/suite/innodb/r/max_record_size,16k,compact,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,16k,compact.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,16k,compact,innodb.rdiff rename to mysql-test/suite/innodb/r/max_record_size,16k,compact.rdiff diff --git a/mysql-test/suite/innodb/r/max_record_size,16k,dynamic,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,16k,dynamic.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,16k,dynamic,innodb.rdiff rename to mysql-test/suite/innodb/r/max_record_size,16k,dynamic.rdiff diff --git a/mysql-test/suite/innodb/r/max_record_size,16k,innodb,redundant.rdiff b/mysql-test/suite/innodb/r/max_record_size,16k,redundant.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,16k,innodb,redundant.rdiff rename to mysql-test/suite/innodb/r/max_record_size,16k,redundant.rdiff diff --git a/mysql-test/suite/innodb/r/max_record_size,32k,compact,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,32k,compact.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,32k,compact,innodb.rdiff rename to mysql-test/suite/innodb/r/max_record_size,32k,compact.rdiff diff --git a/mysql-test/suite/innodb/r/max_record_size,32k,dynamic,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,32k,dynamic.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,32k,dynamic,innodb.rdiff rename to mysql-test/suite/innodb/r/max_record_size,32k,dynamic.rdiff diff --git a/mysql-test/suite/innodb/r/max_record_size,32k,innodb,redundant.rdiff b/mysql-test/suite/innodb/r/max_record_size,32k,redundant.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,32k,innodb,redundant.rdiff rename to mysql-test/suite/innodb/r/max_record_size,32k,redundant.rdiff diff --git a/mysql-test/suite/innodb/r/max_record_size,4k,compact,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,4k,compact.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,4k,compact,innodb.rdiff rename to mysql-test/suite/innodb/r/max_record_size,4k,compact.rdiff diff --git a/mysql-test/suite/innodb/r/max_record_size,4k,dynamic,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,4k,dynamic.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,4k,dynamic,innodb.rdiff rename to mysql-test/suite/innodb/r/max_record_size,4k,dynamic.rdiff diff --git a/mysql-test/suite/innodb/r/max_record_size,4k,innodb,redundant.rdiff b/mysql-test/suite/innodb/r/max_record_size,4k,redundant.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,4k,innodb,redundant.rdiff rename to mysql-test/suite/innodb/r/max_record_size,4k,redundant.rdiff diff --git a/mysql-test/suite/innodb/r/max_record_size,64k,compact,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,64k,compact.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,64k,compact,innodb.rdiff rename to mysql-test/suite/innodb/r/max_record_size,64k,compact.rdiff diff --git a/mysql-test/suite/innodb/r/max_record_size,64k,dynamic,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,64k,dynamic.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,64k,dynamic,innodb.rdiff rename to mysql-test/suite/innodb/r/max_record_size,64k,dynamic.rdiff diff --git a/mysql-test/suite/innodb/r/max_record_size,64k,innodb,redundant.rdiff b/mysql-test/suite/innodb/r/max_record_size,64k,redundant.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,64k,innodb,redundant.rdiff rename to mysql-test/suite/innodb/r/max_record_size,64k,redundant.rdiff diff --git a/mysql-test/suite/innodb/r/max_record_size,8k,compact,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,8k,compact.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,8k,compact,innodb.rdiff rename to mysql-test/suite/innodb/r/max_record_size,8k,compact.rdiff diff --git a/mysql-test/suite/innodb/r/max_record_size,8k,dynamic,innodb.rdiff b/mysql-test/suite/innodb/r/max_record_size,8k,dynamic.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/max_record_size,8k,dynamic,innodb.rdiff rename to mysql-test/suite/innodb/r/max_record_size,8k,dynamic.rdiff diff --git a/mysql-test/suite/innodb/r/monitor.result b/mysql-test/suite/innodb/r/monitor.result index e4b8714768e..d97f741efdd 100644 --- a/mysql-test/suite/innodb/r/monitor.result +++ b/mysql-test/suite/innodb/r/monitor.result @@ -51,7 +51,6 @@ buffer_flush_n_to_flush_by_age disabled buffer_flush_adaptive_avg_time disabled buffer_flush_adaptive_avg_pass disabled buffer_LRU_get_free_loops disabled -buffer_LRU_get_free_waits disabled buffer_flush_avg_page_rate disabled buffer_flush_lsn_avg_rate disabled buffer_flush_pct_for_dirty disabled @@ -71,7 +70,6 @@ buffer_LRU_batch_num_scan disabled buffer_LRU_batch_scanned_per_call disabled buffer_LRU_batch_flush_total_pages enabled buffer_LRU_batch_evict_total_pages enabled -buffer_LRU_single_flush_failure_count disabled buffer_LRU_get_free_search disabled buffer_LRU_search_scanned disabled buffer_LRU_search_num_scan disabled @@ -182,6 +180,7 @@ icp_attempts disabled icp_no_match disabled icp_out_of_range disabled icp_match disabled +create temporary table orig_innodb_metrics as select name, enabled from information_schema.innodb_metrics; set global innodb_monitor_disable = All; select name from information_schema.innodb_metrics where enabled; name @@ -415,7 +414,7 @@ set global innodb_monitor_reset_all = default; # MONITORS # CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0; -SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT /*1*/ NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; NAME COUNT > 0 buffer_page_written_index_leaf 0 @@ -423,13 +422,13 @@ SET GLOBAL innodb_monitor_enable='module_buffer_page'; INSERT INTO t1 VALUES (1), (2), (3), (4); FLUSH TABLES t1 FOR EXPORT; UNLOCK TABLES; -SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT /*2*/ NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; NAME COUNT > 0 buffer_page_written_index_leaf 1 SET GLOBAL innodb_monitor_disable='module_buffer_page'; SET GLOBAL innodb_monitor_reset_all='module_buffer_page'; -SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT /*3*/ NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; NAME COUNT > 0 buffer_page_written_index_leaf 0 @@ -439,13 +438,13 @@ ERROR 42000: Variable 'innodb_compression_algorithm' can't be set to the value o INSERT INTO t1 VALUES (5), (6), (7), (8); FLUSH TABLES t1 FOR EXPORT; UNLOCK TABLES; -SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT /*4*/ NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; NAME COUNT > 0 buffer_page_written_index_leaf 1 SET GLOBAL innodb_monitor_disable='%'; SET GLOBAL innodb_monitor_reset_all='%'; -SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT /*5*/ NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; NAME COUNT > 0 buffer_page_written_index_leaf 0 @@ -453,7 +452,7 @@ SET GLOBAL innodb_monitor_enable='ALL'; INSERT INTO t1 VALUES (9), (10), (11), (12); FLUSH TABLES t1 FOR EXPORT; UNLOCK TABLES; -SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT /*6*/ NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; NAME COUNT > 0 buffer_page_written_index_leaf 1 @@ -583,6 +582,41 @@ DROP TABLE t1; DROP TABLE fl2; DROP TABLE fl1; DROP TABLE fl0; -SET GLOBAL innodb_monitor_enable=default; -SET GLOBAL innodb_monitor_disable=default; -SET GLOBAL innodb_monitor_reset_all=default; +set global innodb_monitor_disable = 'adaptive\\_hash\\_p%'; +set global innodb_monitor_disable = 'adaptive\\_hash\\_r%'; +set global innodb_monitor_disable = 'buffer\\_LRU\\_batch\\_n%'; +set global innodb_monitor_disable = 'buffer\\_LRU\\_batch\\_s%'; +set global innodb_monitor_disable = 'buffer\\_LRU\\_g%'; +set global innodb_monitor_disable = 'buffer\\_LRU\\_s%'; +set global innodb_monitor_disable = 'buffer\\_LRU\\_u%'; +set global innodb_monitor_disable = 'buffer\\_f%'; +set global innodb_monitor_disable = 'buffer\\_page\\_%'; +set global innodb_monitor_disable = 'c%'; +set global innodb_monitor_disable = 'ddl%'; +set global innodb_monitor_disable = 'icp%'; +set global innodb_monitor_disable = 'index\\_p%'; +set global innodb_monitor_disable = 'innodb\\_di%'; +set global innodb_monitor_disable = 'innodb\\_l%'; +set global innodb_monitor_disable = 'innodb\\_m%'; +set global innodb_monitor_disable = 'lock\\_re%'; +set global innodb_monitor_disable = 'lock\\_ta%'; +set global innodb_monitor_disable = 'log%'; +set global innodb_monitor_disable = 'm%'; +set global innodb_monitor_disable = 'p%'; +set global innodb_monitor_disable = 't%'; +set global innodb_monitor_enable = 'log\\_w%'; +set global innodb_monitor_enable = 'trx_rseg_history_len'; +set global innodb_monitor_enable = 'trx_undo_slots_cached'; +set global innodb_monitor_enable=default; +Warnings: +Warning 1230 Default value is not defined for this set option. Please specify correct counter or module name. +set global innodb_monitor_disable=default; +Warnings: +Warning 1230 Default value is not defined for this set option. Please specify correct counter or module name. +set global innodb_monitor_reset_all=default; +Warnings: +Warning 1230 Default value is not defined for this set option. Please specify correct counter or module name. +select name, orig.enabled, new.enabled from +orig_innodb_metrics orig join information_schema.innodb_metrics new using(name) +where orig.enabled != new.enabled; +name enabled enabled diff --git a/mysql-test/suite/innodb/r/rename_table.result b/mysql-test/suite/innodb/r/rename_table.result index 0ed56005e21..a3bf59101b3 100644 --- a/mysql-test/suite/innodb/r/rename_table.result +++ b/mysql-test/suite/innodb/r/rename_table.result @@ -21,11 +21,17 @@ path DROP DATABASE abc_def; # restart DROP DATABASE abc_def2; -call mtr.add_suppression("InnoDB: (Operating system error|Error number \\d+ means|Cannot rename file)"); +call mtr.add_suppression("InnoDB: Cannot rename '.*t1.ibd' to '.*non_existing_db.*' because the target schema directory doesn't exist"); CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES(100); RENAME TABLE t1 TO non_existing_db.t1; ERROR HY000: Error on rename of './test/t1' to './non_existing_db/t1' (errno: 168 "Unknown (generic) error from engine") -FOUND 1 /\[ERROR\] InnoDB: Cannot rename file '.*t1\.ibd' to '.*non_existing_db/ in mysqld.1.err +FOUND 1 /\[ERROR\] InnoDB: Cannot rename '.*t1\.ibd' to '.*non_existing_db/ in mysqld.1.err +SET GLOBAL innodb_fast_shutdown=2; +# restart +SELECT * FROM t1; +a +100 DROP TABLE t1; # # MDEV-25509 Atomic DDL: Assertion `err != DB_DUPLICATE_KEY' diff --git a/mysql-test/suite/innodb/r/restart,16k,innodb.rdiff b/mysql-test/suite/innodb/r/restart,16k.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/restart,16k,innodb.rdiff rename to mysql-test/suite/innodb/r/restart,16k.rdiff diff --git a/mysql-test/suite/innodb/r/restart,32k,innodb.rdiff b/mysql-test/suite/innodb/r/restart,32k.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/restart,32k,innodb.rdiff rename to mysql-test/suite/innodb/r/restart,32k.rdiff diff --git a/mysql-test/suite/innodb/r/restart,4k,innodb.rdiff b/mysql-test/suite/innodb/r/restart,4k.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/restart,4k,innodb.rdiff rename to mysql-test/suite/innodb/r/restart,4k.rdiff diff --git a/mysql-test/suite/innodb/r/restart,64k,innodb.rdiff b/mysql-test/suite/innodb/r/restart,64k.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/restart,64k,innodb.rdiff rename to mysql-test/suite/innodb/r/restart,64k.rdiff diff --git a/mysql-test/suite/innodb/r/restart,8k,innodb.rdiff b/mysql-test/suite/innodb/r/restart,8k.rdiff similarity index 100% rename from mysql-test/suite/innodb/r/restart,8k,innodb.rdiff rename to mysql-test/suite/innodb/r/restart,8k.rdiff diff --git a/mysql-test/suite/innodb/r/row_size_error_log_warnings_3,4k.rdiff b/mysql-test/suite/innodb/r/row_size_error_log_warnings_3,4k.rdiff new file mode 100644 index 00000000000..812632aceae --- /dev/null +++ b/mysql-test/suite/innodb/r/row_size_error_log_warnings_3,4k.rdiff @@ -0,0 +1,2 @@ +91a92 +> ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 1982. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs diff --git a/mysql-test/suite/innodb/r/row_size_error_log_warnings_3.result b/mysql-test/suite/innodb/r/row_size_error_log_warnings_3.result index 21085e4cd7e..1fde89ac3b5 100644 --- a/mysql-test/suite/innodb/r/row_size_error_log_warnings_3.result +++ b/mysql-test/suite/innodb/r/row_size_error_log_warnings_3.result @@ -82,3 +82,11 @@ f29(10), f30(10), f31(10), f32(10), f33(10))) ENGINE=InnoDB; ERROR 42000: Too many key parts specified; max 32 parts allowed +# +# MDEV-31161 Assertion failures upon adding a too long key +# to table with COMPRESSED row format +# +CREATE TABLE t1(pk INT PRIMARY KEY, f1 INT, f2 TEXT)ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +INSERT INTO t1 (pk) VALUES (1); +ALTER TABLE t1 ADD KEY (f1), ADD KEY (f2(1000)); +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/undo_space_dblwr.result b/mysql-test/suite/innodb/r/undo_space_dblwr.result index d6822b20eb7..4466df9857b 100644 --- a/mysql-test/suite/innodb/r/undo_space_dblwr.result +++ b/mysql-test/suite/innodb/r/undo_space_dblwr.result @@ -4,15 +4,14 @@ Variable_name Value innodb_doublewrite ON create table t1(f1 int not null, f2 int not null)engine=innodb; insert into t1 values (1, 1); -InnoDB 0 transactions not purged -set GLOBAL innodb_log_checkpoint_now=1; +SET GLOBAL innodb_fast_shutdown = 0; +# restart: --debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0 # Make the first page dirty for undo tablespace set global innodb_saved_page_number_debug = 0; set global innodb_fil_make_page_dirty_debug = 1; -SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0; -SET GLOBAL innodb_max_dirty_pages_pct=0.0; +SET GLOBAL innodb_buf_flush_list_now = 1; # Kill the server -# restart +# restart: --debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0 FOUND 1 /Checksum mismatch in the first page of file/ in mysqld.1.err check table t1; Table Op Msg_type Msg_text diff --git a/mysql-test/suite/innodb/r/undo_truncate.result b/mysql-test/suite/innodb/r/undo_truncate.result index f90bef94415..6d77baa938a 100644 --- a/mysql-test/suite/innodb/r/undo_truncate.result +++ b/mysql-test/suite/innodb/r/undo_truncate.result @@ -27,6 +27,7 @@ delete from t1; connection con2; delete from t2; connection con1; +SET GLOBAL innodb_max_undo_log_size = @@GLOBAL.innodb_page_size * 4294967296; SET GLOBAL innodb_undo_log_truncate = 1; commit; disconnect con1; @@ -35,6 +36,8 @@ commit; disconnect con2; connection default; SET GLOBAL innodb_max_purge_lag_wait=0; +SET GLOBAL innodb_max_undo_log_size=DEFAULT; +SET GLOBAL innodb_max_purge_lag_wait=0; set global innodb_fast_shutdown=0; # restart drop table t1, t2; diff --git a/mysql-test/suite/innodb/t/alter_copy.test b/mysql-test/suite/innodb/t/alter_copy.test index b62f812f4b7..90f2171d10b 100644 --- a/mysql-test/suite/innodb/t/alter_copy.test +++ b/mysql-test/suite/innodb/t/alter_copy.test @@ -57,7 +57,7 @@ ALTER TABLE t ADD INDEX(b,c,d,a),ADD INDEX(b,c,a,d),ADD INDEX(b,a,c,d),ADD INDEX connection default; SET DEBUG_SYNC='now WAIT_FOR hung'; let $shutdown_timeout=0; ---let $restart_parameters= --innodb-force-recovery=3 --debug_dbug="+d,recv_ran_out_of_buffer" +--let $restart_parameters= --innodb-force-recovery=3 --source include/restart_mysqld.inc disconnect hang; let $shutdown_timeout=; diff --git a/mysql-test/suite/innodb/t/alter_crash.test b/mysql-test/suite/innodb/t/alter_crash.test index 164ff877b62..f56dcf2c275 100644 --- a/mysql-test/suite/innodb/t/alter_crash.test +++ b/mysql-test/suite/innodb/t/alter_crash.test @@ -70,7 +70,7 @@ let $orig_table_id = `SELECT table_id WHERE name = 'test/t1'`; # Write file to make mysql-test-run.pl expect crash ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --error 2013 ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); @@ -110,7 +110,7 @@ let $orig_table_id = `SELECT table_id WHERE name = 'test/t2'`; # Write file to make mysql-test-run.pl expect crash ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --error 2013 ALTER TABLE t2 ADD PRIMARY KEY (f2, f1); @@ -150,7 +150,7 @@ let $orig_table_id = `select table_id from information_schema.innodb_sys_tables where name = 'test/t1'`; # Write file to make mysql-test-run.pl expect crash ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # --error 2013 ALTER TABLE t1 ADD INDEX (b), CHANGE c d int, ALGORITHM=INPLACE; diff --git a/mysql-test/suite/innodb/t/alter_kill-master.opt b/mysql-test/suite/innodb/t/alter_kill-master.opt index e472160c2b7..9eb72834ef6 100644 --- a/mysql-test/suite/innodb/t/alter_kill-master.opt +++ b/mysql-test/suite/innodb/t/alter_kill-master.opt @@ -1 +1 @@ ---innodb-doublewrite=false +--innodb-flush-method=O_DIRECT_NO_FSYNC --skip-innodb-doublewrite diff --git a/mysql-test/suite/innodb/t/alter_kill.test b/mysql-test/suite/innodb/t/alter_kill.test index 57ca97f003d..3936b3fd9e4 100644 --- a/mysql-test/suite/innodb/t/alter_kill.test +++ b/mysql-test/suite/innodb/t/alter_kill.test @@ -7,6 +7,9 @@ let MYSQLD_DATADIR=`select @@datadir`; let PAGE_SIZE=`select @@innodb_page_size`; +SELECT @@innodb_doublewrite; +SET GLOBAL innodb_doublewrite=fast; + -- disable_query_log call mtr.add_suppression("InnoDB: innodb_force_recovery is on."); call mtr.add_suppression("InnoDB: Ignoring tablespace for.*bug16720368"); @@ -73,9 +76,12 @@ syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n"; close(FILE) || die "Unable to close $file"; EOF +-- let $restart_parameters=--innodb-flush-method=O_DIRECT -- source include/start_mysqld.inc +-- let $restart_parameters= ---error ER_NO_SUCH_TABLE_IN_ENGINE +SELECT @@innodb_doublewrite; +--error ER_TABLE_CORRUPT SELECT COUNT(*) FROM bug16720368; --error ER_TABLE_CORRUPT INSERT INTO bug16720368 VALUES(1); diff --git a/mysql-test/suite/innodb/t/alter_rename_existing.test b/mysql-test/suite/innodb/t/alter_rename_existing.test index 556d8e660b4..f09456e747a 100644 --- a/mysql-test/suite/innodb/t/alter_rename_existing.test +++ b/mysql-test/suite/innodb/t/alter_rename_existing.test @@ -18,7 +18,7 @@ INSERT INTO t1(b) VALUES('one'), ('two'), ('three'); --echo # --echo # Create a file called MYSQLD_DATADIR/test/t1.ibd ---exec echo "This is not t1.ibd" > $MYSQLD_DATADIR/test/t1.ibd +--write_line "This is not t1.ibd" $MYSQLD_DATADIR/test/t1.ibd --echo # Directory listing of test/*.ibd --echo # diff --git a/mysql-test/suite/innodb/t/autoinc_debug.test b/mysql-test/suite/innodb/t/autoinc_debug.test index 7722b848c74..d38a70b3376 100644 --- a/mysql-test/suite/innodb/t/autoinc_debug.test +++ b/mysql-test/suite/innodb/t/autoinc_debug.test @@ -92,3 +92,69 @@ SELECT * FROM t1; SHOW CREATE TABLE t1; DROP TABLE t1; SET DEBUG_SYNC='RESET'; + +--echo # +--echo # MDEV-33593: Auto increment deadlock error causes ASSERT in subsequent save point +--echo # + +CREATE TABLE t1(col1 INT PRIMARY KEY AUTO_INCREMENT, col2 INT) ENGINE=InnoDB; +CREATE TABLE t2(col1 INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1(col2) values(100); + +--connect(con1, localhost, root,,) +START TRANSACTION; +--echo # T1: Acquiring Row X lock on table t2 +INSERT INTO t2 values(100); + +--connect(con2, localhost, root,,) +START TRANSACTION; +--echo # T2: Wait for (T1) row lock on t2 after acquiring GAP Lock on t1 +UPDATE t1 SET col2 = 20 where col1 = 10; +SET DEBUG_SYNC='lock_wait_before_suspend SIGNAL t2_waiting'; +--send INSERT INTO t2 values(100) + +--connection default +SET DEBUG_SYNC='now WAIT_FOR t2_waiting'; +--echo # T3: Wait for (T2) II row Lock on t1 after acquiring Auto Increment Lock on t1 +SET DEBUG_SYNC='lock_wait_before_suspend SIGNAL t3_waiting'; +--send INSERT INTO t1(col2) SELECT col2 from t1 + +--connection con1 +SAVEPOINT s1; +SET DEBUG_SYNC='now WAIT_FOR t3_waiting'; +--echo # T1: Wait for (T3) auto increment lock on t1 causing T1 -> T3 -> T2 -> T1 deadlock +SET debug_dbug = '+d,innodb_deadlock_victim_self'; +--error ER_AUTOINC_READ_FAILED +INSERT INTO t1(col2) VALUES(200); + +--echo # The transaction should have been rolled back +SELECT * FROM t1; +SELECT * FROM t2; + +--echo # Release the previous savepoint using the same name +SAVEPOINT s1; +COMMIT; + +--connection con2 +--reap +COMMIT; + +--connection default +--reap +COMMIT; + +--disconnect con1 +--disconnect con2 + +--echo # Cleanup +SELECT * FROM t1; +DROP TABLE t1; + +SELECT * FROM t2; +DROP TABLE t2; + +SET DEBUG_SYNC='RESET'; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/suite/innodb/t/autoinc_import.test b/mysql-test/suite/innodb/t/autoinc_import.test new file mode 100644 index 00000000000..e137413dfb5 --- /dev/null +++ b/mysql-test/suite/innodb/t/autoinc_import.test @@ -0,0 +1,168 @@ +--source include/have_innodb.inc + +CREATE TABLE t1 (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES(42); +CREATE TABLE t1b LIKE t1; +INSERT INTO t1b VALUES(3); +CREATE TABLE t1z LIKE t1; +CREATE TABLE t1t (id TINYINT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t0t LIKE t1t; +INSERT INTO t1t VALUES(123); +--let DATADIR=`select @@datadir` +--let PAGE_SIZE=`select @@innodb_page_size` +FLUSH TABLES t1,t1b,t1t FOR EXPORT; +--copy_file $DATADIR/test/t1.ibd $DATADIR/test/t.ibd +--copy_file $DATADIR/test/t1.ibd $DATADIR/test/tz.ibd +--copy_file $DATADIR/test/t1b.ibd $DATADIR/test/tb.ibd +--copy_file $DATADIR/test/t1t.ibd $DATADIR/test/tt.ibd +UNLOCK TABLES; +CREATE TABLE t5_7 LIKE t1; +CREATE TABLE t5_7b LIKE t1b; +CREATE TABLE t10_1 LIKE t1; +CREATE TABLE t10_1b LIKE t1b; +ALTER TABLE t1 DISCARD TABLESPACE; +ALTER TABLE t1b DISCARD TABLESPACE; +ALTER TABLE t1z DISCARD TABLESPACE; +ALTER TABLE t1t DISCARD TABLESPACE; +ALTER TABLE t0t DISCARD TABLESPACE; +ALTER TABLE t5_7 DISCARD TABLESPACE; +ALTER TABLE t5_7b DISCARD TABLESPACE; +ALTER TABLE t10_1 DISCARD TABLESPACE; +ALTER TABLE t10_1b DISCARD TABLESPACE; +FLUSH TABLES; + +# Update the PAGE_ROOT_AUTO_INC field of a few files. +perl; +do "$ENV{MTR_SUITE_DIR}/include/crc32.pl"; +sub update_autoinc +{ + my ($file, $value) = @_; + open(FILE, "+<$file") || die "Unable to open $file"; + binmode FILE; + my $ps= $ENV{PAGE_SIZE}; + my $page; + die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps; + my $full_crc32 = unpack("N",substr($page,54,4)) & 0x10; # FIL_SPACE_FLAGS + sysseek(FILE, 3*$ps, 0) || die "Unable to seek $file\n"; + die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps; + substr($page,56,8)=pack("NN",0,$value); + my $polynomial = 0x82f63b78; # CRC-32C + if ($full_crc32) { + my $ck = mycrc32(substr($page, 0, $ps-4), 0, $polynomial); + substr($page, $ps-4, 4) = pack("N", $ck); + } + else + { + my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^ + mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial)); + substr($page,0,4)=$ck; + substr($page,$ps-8,4)=$ck; + } + sysseek(FILE, 3*$ps, 0) || die "Unable to rewind $file\n"; + syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n"; + close(FILE) || die "Unable to close $file"; +} +update_autoinc("$ENV{DATADIR}/test/tz.ibd", 0); +update_autoinc("$ENV{DATADIR}/test/t.ibd", 3); +update_autoinc("$ENV{DATADIR}/test/tb.ibd", 346); +update_autoinc("$ENV{DATADIR}/test/tt.ibd", 128); +EOF + +--remove_file $DATADIR/test/t5_7.frm +--remove_file $DATADIR/test/t5_7b.frm +--copy_file $MYSQL_TEST_DIR/std_data/autoinc_import_57.frm $DATADIR/test/t5_7.frm +--copy_file $MYSQL_TEST_DIR/std_data/autoinc_import_57.frm $DATADIR/test/t5_7b.frm +--remove_file $DATADIR/test/t10_1.frm +--remove_file $DATADIR/test/t10_1b.frm +--copy_file $MYSQL_TEST_DIR/std_data/autoinc_import_101.frm $DATADIR/test/t10_1.frm +--copy_file $MYSQL_TEST_DIR/std_data/autoinc_import_101.frm $DATADIR/test/t10_1b.frm +--copy_file $DATADIR/test/t.ibd $DATADIR/test/t5_7.ibd +--copy_file $DATADIR/test/tb.ibd $DATADIR/test/t5_7b.ibd +--copy_file $DATADIR/test/t.ibd $DATADIR/test/t10_1.ibd +--copy_file $DATADIR/test/tb.ibd $DATADIR/test/t10_1b.ibd +--move_file $DATADIR/test/t.ibd $DATADIR/test/t1.ibd +--move_file $DATADIR/test/tb.ibd $DATADIR/test/t1b.ibd +--copy_file $DATADIR/test/tt.ibd $DATADIR/test/t0t.ibd +--move_file $DATADIR/test/tt.ibd $DATADIR/test/t1t.ibd +--move_file $DATADIR/test/tz.ibd $DATADIR/test/t1z.ibd + +ALTER TABLE t0t IMPORT TABLESPACE; +INSERT INTO t0t VALUES(NULL); +SELECT * FROM t0t; +DROP TABLE t0t; +ALTER TABLE t1 IMPORT TABLESPACE; +ALTER TABLE t1b IMPORT TABLESPACE; +ALTER TABLE t1z IMPORT TABLESPACE; +ALTER TABLE t1t IMPORT TABLESPACE; +ALTER TABLE t5_7 IMPORT TABLESPACE; +ALTER TABLE t5_7b IMPORT TABLESPACE; +ALTER TABLE t10_1 IMPORT TABLESPACE; +ALTER TABLE t10_1b IMPORT TABLESPACE; + +--let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let SEARCH_PATTERN= InnoDB: Resetting PAGE_ROOT_AUTO_INC from 128 to 123 on table `test`\.`t0t` +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN= InnoDB: Resetting PAGE_ROOT_AUTO_INC from 0 to 42 on table `test`\.`t1z` +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN= InnoDB: Resetting PAGE_ROOT_AUTO_INC from 128 to 123 on table `test`\.`t1t` +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN= InnoDB: Resetting PAGE_ROOT_AUTO_INC from 3 to 42 on table `test`\.`t5_7` \(created with version 50744\) +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN= InnoDB: Resetting PAGE_ROOT_AUTO_INC from 3 to 42 on table `test`\.`t10_1` \(created with version 100149\) +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN= InnoDB: Resetting PAGE_ROOT_AUTO_INC +--source include/search_pattern_in_file.inc + +# Restart, so that the InnoDB tables will be loaded into the data dictionary. +--let $restart_parameters=--read-only +--source include/restart_mysqld.inc + +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b; +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE; + +--let $restart_parameters=--innodb-read-only --read-only +--source include/restart_mysqld.inc + +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b; +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE; + +--let $restart_parameters=--innodb-read-only +--source include/restart_mysqld.inc + +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b; +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE; + +SELECT COUNT(*) FROM t1; +SELECT COUNT(*) FROM t1b; +SELECT COUNT(*) FROM t1t; +SELECT COUNT(*) FROM t1z; +SELECT COUNT(*) FROM t5_7; +SELECT COUNT(*) FROM t5_7b; +SELECT COUNT(*) FROM t10_1; +SELECT COUNT(*) FROM t10_1b; + +--let $restart_parameters= +--source include/restart_mysqld.inc + +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE; + +INSERT INTO t1 VALUES(NULL); +INSERT INTO t1b VALUES(NULL); +INSERT INTO t1t VALUES(NULL); +INSERT INTO t1z VALUES(NULL); +INSERT INTO t5_7 VALUES(NULL); +INSERT INTO t5_7b VALUES(NULL); +INSERT INTO t10_1 VALUES(NULL); +INSERT INTO t10_1b VALUES(NULL); + +CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE; + +SELECT * FROM t1; +SELECT * FROM t1b; +SELECT * FROM t1t; +SELECT * FROM t1z; +SELECT * FROM t5_7; +SELECT * FROM t5_7b; +SELECT * FROM t10_1; +SELECT * FROM t10_1b; +DROP TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b; diff --git a/mysql-test/suite/innodb/t/corrupted_during_recovery.test b/mysql-test/suite/innodb/t/corrupted_during_recovery.test index a6c2715015a..8324054992c 100644 --- a/mysql-test/suite/innodb/t/corrupted_during_recovery.test +++ b/mysql-test/suite/innodb/t/corrupted_during_recovery.test @@ -7,7 +7,7 @@ call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE faile call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed read of file '.*test.t1\\.ibd' page"); call mtr.add_suppression("InnoDB: Failed to read page 3 from file '.*test.t1\\.ibd': Page read from tablespace is corrupted."); call mtr.add_suppression("InnoDB: (Unable to apply log to|Discarding log for) corrupted page .*, page number=3\\]"); -call mtr.add_suppression("Table .*test.*/t1 is corrupted. Please drop the table and recreate\\."); +call mtr.add_suppression("Table `test`.`t1` is corrupted. Please drop the table and recreate."); call mtr.add_suppression("InnoDB: File '.*test/t1\\.ibd' is corrupted"); call mtr.add_suppression("InnoDB: A long wait .* was observed for dict_sys"); --enable_query_log diff --git a/mysql-test/suite/innodb/t/cursor-restore-unique-null.test b/mysql-test/suite/innodb/t/cursor-restore-unique-null.test new file mode 100644 index 00000000000..409694d695b --- /dev/null +++ b/mysql-test/suite/innodb/t/cursor-restore-unique-null.test @@ -0,0 +1,36 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/count_sessions.inc + + +CREATE TABLE t(a INT PRIMARY KEY, b INT, c INT, UNIQUE KEY `b_c` (`b`,`c`)) + ENGINE=InnoDB, STATS_PERSISTENT=0; +INSERT INTO t SET a = 1, c = 2; + +--connect con1,localhost,root +BEGIN; + INSERT INTO t SET a=2, c=2; + +--connection default +BEGIN; +SET DEBUG_SYNC="lock_wait_start SIGNAL select_locked"; +--send SELECT * FROM t FORCE INDEX(b) FOR UPDATE + +--connection con1 +SET DEBUG_SYNC="now WAIT_FOR select_locked"; +ROLLBACK; + +--connection default +--echo # If the bug is not fixed, and the both unique index key fields are +--echo # NULL, there will be two (1, NULL, 2) rows in the result, +--echo # because cursor will be restored to (NULL, 2, 1) position for +--echo # secondary key instead of "supremum". +--reap +COMMIT; + +SET DEBUG_SYNC="RESET"; + +--disconnect con1 +DROP TABLE t; +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/doublewrite_debug.test b/mysql-test/suite/innodb/t/doublewrite_debug.test index ab7fd8eba22..b8dcd5068ef 100644 --- a/mysql-test/suite/innodb/t/doublewrite_debug.test +++ b/mysql-test/suite/innodb/t/doublewrite_debug.test @@ -45,7 +45,7 @@ commit work; # Slow shutdown and restart to make sure ibuf merge is finished SET GLOBAL innodb_fast_shutdown = 0; let $shutdown_timeout=; -let $restart_parameters="--debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0"; +let $restart_parameters=--debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0; --source include/restart_mysqld.inc --source ../include/no_checkpoint_start.inc begin; @@ -95,7 +95,7 @@ select f1, f2 from t1; --echo # Test Begin: Test if recovery works if 1st page of --echo # system tablespace is corrupted and 2nd page as corrupted. -let $restart_parameters="--debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0"; +let $restart_parameters=--debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0; --source include/restart_mysqld.inc --source ../include/no_checkpoint_start.inc begin; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index 0db3a7ca377..e793e261abd 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -1077,10 +1077,23 @@ BEGIN; --error ER_NO_REFERENCED_ROW_2 INSERT INTO child SET a=1; connection default; +--error ER_TRUNCATE_ILLEGAL_FK +TRUNCATE TABLE parent; +--error ER_ROW_IS_REFERENCED_2 +DROP TABLE parent; +SET innodb_lock_wait_timeout=0; +--error ER_LOCK_WAIT_TIMEOUT +RENAME TABLE parent TO transparent; +--error ER_LOCK_WAIT_TIMEOUT +ALTER TABLE parent FORCE, ALGORITHM=COPY; +--error ER_LOCK_WAIT_TIMEOUT +ALTER TABLE parent FORCE, ALGORITHM=INPLACE; SET innodb_lock_wait_timeout=0, foreign_key_checks=0; --error ER_LOCK_WAIT_TIMEOUT TRUNCATE TABLE parent; --error ER_LOCK_WAIT_TIMEOUT +DROP TABLE parent; +--error ER_LOCK_WAIT_TIMEOUT ALTER TABLE parent FORCE, ALGORITHM=COPY; --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE parent FORCE, ALGORITHM=INPLACE; @@ -1095,7 +1108,13 @@ TRUNCATE TABLE parent; ALTER TABLE parent FORCE, ALGORITHM=COPY; ALTER TABLE parent FORCE, ALGORITHM=INPLACE; ALTER TABLE parent ADD COLUMN b INT, ALGORITHM=INSTANT; -DROP TABLE child, parent; +SET foreign_key_checks=ON; +--error ER_TRUNCATE_ILLEGAL_FK +TRUNCATE TABLE parent; +ALTER TABLE parent FORCE, ALGORITHM=COPY; +ALTER TABLE parent FORCE, ALGORITHM=INPLACE; +RENAME TABLE parent TO transparent; +DROP TABLE child, transparent; --echo # --echo # MDEV-26217 Failing assertion: list.count > 0 in ut_list_remove diff --git a/mysql-test/suite/innodb/t/full_crc32_import.test b/mysql-test/suite/innodb/t/full_crc32_import.test index 0eb31f8d63f..6f02b2ab7e8 100644 --- a/mysql-test/suite/innodb/t/full_crc32_import.test +++ b/mysql-test/suite/innodb/t/full_crc32_import.test @@ -63,6 +63,12 @@ ALTER TABLE t1 DROP INDEX b; ALTER TABLE t1 IMPORT TABLESPACE; --enable_warnings SHOW CREATE TABLE t1; + +--echo # Auto increment value must be more than maximum column value +SELECT MAX(a) FROM t1; +SELECT auto_increment FROM information_schema.tables +WHERE table_name like 't1'; + UPDATE t1 set b = repeat("de", 100) where b = repeat("cd", 200); --replace_column 9 # explain SELECT a FROM t1 where b = repeat("de", 100); @@ -145,6 +151,12 @@ ALTER TABLE t1 DROP INDEX idx1; ALTER TABLE t1 IMPORT TABLESPACE; --disable_warnings SHOW CREATE TABLE t1; + +--echo # Auto increment value must be more than maximum column value +SELECT MAX(c1) FROM t1; +SELECT auto_increment FROM information_schema.tables +WHERE table_name like 't1'; + UPDATE t1 SET C2 = ST_GeomFromText('POINT(0 0)'); SELECT COUNT(*) FROM t1; DELETE FROM t1; diff --git a/mysql-test/suite/innodb/t/group_commit_crash.test b/mysql-test/suite/innodb/t/group_commit_crash.test index 12f7ba202e3..b0ed854f4f3 100644 --- a/mysql-test/suite/innodb/t/group_commit_crash.test +++ b/mysql-test/suite/innodb/t/group_commit_crash.test @@ -51,7 +51,7 @@ while ($numtests) START TRANSACTION; insert into t1 select * from t2; # Write file to make mysql-test-run.pl expect crash - --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + --write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect eval call setcrash($numtests); diff --git a/mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test b/mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test index 6115e3f0050..9b7de7cea56 100644 --- a/mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test +++ b/mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test @@ -51,7 +51,7 @@ while ($numtests) START TRANSACTION; insert into t1 select * from t2; # Write file to make mysql-test-run.pl expect crash - --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + --write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect eval call setcrash($numtests); diff --git a/mysql-test/suite/innodb/t/import_bugs.test b/mysql-test/suite/innodb/t/import_bugs.test index 7fcab9f9abc..d22b4b67272 100644 --- a/mysql-test/suite/innodb/t/import_bugs.test +++ b/mysql-test/suite/innodb/t/import_bugs.test @@ -1,4 +1,5 @@ --source include/have_innodb.inc +--source include/have_sequence.inc call mtr.add_suppression("Index for table 'imp_t1' is corrupt; try to repair it"); @@ -22,6 +23,67 @@ DROP TABLE imp_t1, t1; SET GLOBAL innodb_checksum_algorithm=@save_innodb_checksum_algorithm; +--echo # +--echo # MDEV-33400 Adaptive hash index corruption after DISCARD TABLESPACE +--echo # + +SET @save_adaptive=@@GLOBAL.innodb_adaptive_hash_index; +SET GLOBAL innodb_adaptive_hash_index=ON; + +CREATE TABLE t (a INT PRIMARY KEY) ENGINE=INNODB; +INSERT INTO t SELECT * FROM seq_1_to_131; +ALTER TABLE t ADD hid INT DEFAULT 2; +INSERT INTO t VALUES (251,1); +ALTER TABLE t DISCARD TABLESPACE; +CHECK TABLE mysql.innodb_table_stats; +DROP TABLE t; +SET GLOBAL innodb_adaptive_hash_index=@save_adaptive; + +--echo # End of 10.4 tests + +--echo # +--echo # MDEV-18288: Transportable Tablespaces leave AUTO_INCREMENT in mismatched +--echo # state, causing INSERT errors in newly imported tables when .cfg is not used. +--echo # + +CREATE TABLE t1( + id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + PRIMARY KEY (id) +) ENGINE=INNODB; + +CREATE TABLE t2 LIKE t1; + +ALTER TABLE t2 DISCARD TABLESPACE; + +INSERT INTO t1() VALUES(); +INSERT INTO t1() VALUES(); + +FLUSH TABLES test.t1 FOR EXPORT; + +--echo # Copy data file +--copy_file $datadir/test/t1.ibd $datadir/test/t2.ibd + +--echo # Skip CFG file copy +#--copy_file $datadir/test/t1.cfg $datadir/test/t2.cfg +--remove_file $datadir/test/t1.cfg + +UNLOCK TABLES; +DROP TABLE t1; + +--replace_regex /opening '.*\/test\//opening '.\/test\// +ALTER TABLE t2 IMPORT TABLESPACE; + +SELECT * FROM t2 ORDER BY id; + +INSERT INTO t2() VALUES(); +INSERT INTO t2() VALUES(); +INSERT INTO t2() VALUES(); + +SELECT * FROM t2 ORDER BY id; +DROP TABLE t2; + +--echo # End of 10.5 tests + --echo # --echo # MDEV-27006 Assertion `!lock_trx_has_sys_table_locks(trx)' --echo # failed in dberr_t row_discard_tablespace_for_mysql diff --git a/mysql-test/suite/innodb/t/import_hidden_fts.test b/mysql-test/suite/innodb/t/import_hidden_fts.test new file mode 100644 index 00000000000..4129e258fe1 --- /dev/null +++ b/mysql-test/suite/innodb/t/import_hidden_fts.test @@ -0,0 +1,46 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc +# Table with virtual, fulltext, instant add, instant drop column +# and purgeable rows +call mtr.add_suppression("InnoDB: Added system generated FTS_DOC_ID and FTS_DOC_ID_INDEX while importing the tablespace"); +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, + f2 CHAR(2) not null, fulltext f_idx(f2), + f3 INT as (f1) VIRTUAL, INDEX(f3), + f4 INT as (f1) STORED, INDEX(f4), + f5 INT as (f1) VIRTUAL)ENGINE=InnoDB; +INSERT INTO t1(f1, f2) VALUES(1, "on"); +INSERT INTO t1(f1, f2) SELECT seq, "si" FROM seq_2_to_256; +ALTER TABLE t1 ADD COLUMN f6 INT NOT NULL; +ALTER TABLE t1 DROP COLUMN f6; +ALTER TABLE t1 DROP INDEX f_idx; +connect(con1,localhost,root,,); +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +connection default; +DELETE FROM t1 WHERE f1 > 1; +FLUSH TABLE t1 FOR EXPORT; +let MYSQLD_DATADIR =`SELECT @@datadir`; +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespaces("test", "t1"); +EOF +UNLOCK TABLES; +DROP TABLE t1; + +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, + f2 CHAR(2) not null, + f3 INT as (f1) VIRTUAL, INDEX(f3), + f4 INT as (f1) STORED, INDEX(f4), + f5 INT as (f1) VIRTUAL)ENGINE=InnoDB; +ALTER TABLE t1 DISCARD TABLESPACE; +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--disable_warnings +ALTER TABLE t1 IMPORT TABLESPACE; +--enable_warnings +SHOW CREATE TABLE t1; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/import_hidden_fts_debug.test b/mysql-test/suite/innodb/t/import_hidden_fts_debug.test new file mode 100644 index 00000000000..e3d8680d4b7 --- /dev/null +++ b/mysql-test/suite/innodb/t/import_hidden_fts_debug.test @@ -0,0 +1,101 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, + f2 CHAR(2) NOT NULL, FULLTEXT f_idx(f2), + f3 INT as (f1) VIRTUAL, INDEX(f3))ENGINE=InnoDB; +INSERT INTO t1(f1, f2) VALUES(1, "on"); +ALTER TABLE t1 DROP INDEX f_idx; +FLUSH TABLE t1 FOR EXPORT; +let MYSQLD_DATADIR =`SELECT @@datadir`; +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespaces("test", "t1"); +EOF +UNLOCK TABLES; +DROP TABLE t1; + +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, + f2 CHAR(2) NOT NULL, + f3 CHAR(2) NOT NULL, + f4 INT AS (f1) VIRTUAL, INDEX(f4))ENGINE=InnoDB; +ALTER TABLE t1 DISCARD TABLESPACE; +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; +DROP TABLE t1; + +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, + f2 CHAR(2) NOT NULL, + f3 INT as (f1) VIRTUAL, INDEX(f3))ENGINE=InnoDB; +ALTER TABLE t1 DISCARD TABLESPACE; +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--disable_warnings +SET DEBUG_DBUG="+d,ib_import_set_index_root_failure"; +--error ER_TOO_MANY_CONCURRENT_TRXS +ALTER TABLE t1 IMPORT TABLESPACE; +SET DEBUG_DBUG="-d,ib_import_set_index_root_failure"; + +SET DEBUG_DBUG="+d,ib_import_vcol_update_fail"; +--error ER_DUP_KEY +ALTER TABLE t1 IMPORT TABLESPACE; +SET DEBUG_DBUG="-d,ib_import_vcol_update_fail"; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +SET DEBUG_DBUG="+d,ib_import_fts_error"; +--error ER_DUP_KEY +ALTER TABLE t1 IMPORT TABLESPACE; +SET DEBUG_DBUG="-d,ib_import_fts_error"; +--enable_warnings + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_unlink_tablespace("test", "t1"); +EOF + +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS +WHERE table_id IN (SELECT table_id FROM information_schema.innodb_sys_tables where name="test/t1"); + +SHOW CREATE TABLE t1; +DROP TABLE t1; + +# Manually add the FTS_DOC_ID Column with mismatched data type +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, + FTS_DOC_ID BIGINT SIGNED NOT NULL, + f2 CHAR(2) NOT NULL, + FULLTEXT f_idx(f2))ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, 1, "on"); +ALTER TABLE t1 DROP INDEX f_idx; +FLUSH TABLE t1 FOR EXPORT; +let MYSQLD_DATADIR =`SELECT @@datadir`; +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespaces("test", "t1"); +EOF +UNLOCK TABLES; +DROP TABLE t1; + +CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY, + f2 CHAR(2) NOT NULL)ENGINE=InnoDB; +ALTER TABLE t1 DISCARD TABLESPACE; +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF +--error ER_TABLE_SCHEMA_MISMATCH +ALTER TABLE t1 IMPORT TABLESPACE; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/index_length.test b/mysql-test/suite/innodb/t/index_length.test index bf4940d4b39..03e61a5a8f9 100644 --- a/mysql-test/suite/innodb/t/index_length.test +++ b/mysql-test/suite/innodb/t/index_length.test @@ -20,4 +20,12 @@ WHERE table_schema = 'test' AND table_name = 't1'; disconnect stop_purge; DROP TABLE t1; +--echo # +--echo # MDEV-22855 Assertion (!field->prefix_len || +--echo # field->fixed_len == field->prefix_len) +--echo # failed in btr_node_ptr_max_size +--echo # +CREATE TABLE t1(c CHAR(194) CHARACTER SET UTF32, KEY k1(c(193)))ENGINE=InnoDB; +INSERT INTO t1 SET c=''; +DROP TABLE t1; --echo # End of 10.4 tests diff --git a/mysql-test/suite/innodb/t/index_merge_threshold.test b/mysql-test/suite/innodb/t/index_merge_threshold.test index cb8e117d453..acadf4f06a3 100644 --- a/mysql-test/suite/innodb/t/index_merge_threshold.test +++ b/mysql-test/suite/innodb/t/index_merge_threshold.test @@ -10,6 +10,7 @@ # # Check actual behavior for table, partitioned table and temporary table # ############################################################# +--source include/have_innodb.inc --source include/have_innodb_16k.inc --source include/have_partition.inc diff --git a/mysql-test/suite/innodb/t/innodb-alter-debug.test b/mysql-test/suite/innodb/t/innodb-alter-debug.test index c4a68ac71b7..6b94bfd214f 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-debug.test +++ b/mysql-test/suite/innodb/t/innodb-alter-debug.test @@ -144,15 +144,14 @@ DROP TABLE t; --echo # create table t1(f1 int not null primary key, - - f2 int not null, index idx(f2))engine=innodb; + f2 int not null, index idx(f2), index i(f2,f1))engine=innodb; insert into t1 values(1, 1); connect(con1,localhost,root,,,); SET DEBUG_SYNC='before_delete_table_stats SIGNAL blocked WAIT_FOR go'; -SET innodb_lock_wait_timeout=0; -send ALTER TABLE t1 FORCE, ALGORITHM=COPY; +send SET STATEMENT innodb_lock_wait_timeout=0 FOR +ALTER TABLE t1 FORCE, ALGORITHM=COPY; connection default; SET DEBUG_SYNC='now WAIT_FOR blocked'; @@ -167,6 +166,21 @@ connection default; COMMIT; SET DEBUG_SYNC=RESET; +RENAME TABLE mysql.innodb_table_stats TO mysql.innodb_table_stats_hidden; +connection con1; +SET DEBUG_SYNC='innodb_commit_inplace_before_lock SIGNAL blocked WAIT_FOR go'; +send ALTER TABLE t1 DROP INDEX i; + +connection default; +SET DEBUG_SYNC='now WAIT_FOR blocked'; +RENAME TABLE mysql.innodb_table_stats_hidden TO mysql.innodb_table_stats; +SET DEBUG_SYNC='now SIGNAL go'; + +connection con1; +reap; +connection default; +SET DEBUG_SYNC=RESET; + connection con1; ALTER TABLE t1 RENAME KEY idx TO idx1, ALGORITHM=COPY; disconnect con1; diff --git a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test index 2534f03dbec..0b6cbabb802 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test +++ b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test @@ -35,7 +35,7 @@ let datadir= `select @@datadir`; CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=innodb; SET debug_dbug='+d,innodb_alter_commit_crash_before_commit'; ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --error 2013 ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); diff --git a/mysql-test/suite/innodb/t/innodb-corrupted-table.test b/mysql-test/suite/innodb/t/innodb-corrupted-table.test index a064f08d677..dcdaa61859f 100644 --- a/mysql-test/suite/innodb/t/innodb-corrupted-table.test +++ b/mysql-test/suite/innodb/t/innodb-corrupted-table.test @@ -23,14 +23,14 @@ alter table t1 add primary key (pk); --echo # Stop the server, replace the frm with the old one and restart the server ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc --remove_file $datadir/test/t1.frm --copy_file $MYSQLTEST_VARDIR/tmp/t1.frm $datadir/test/t1.frm ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc diff --git a/mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test b/mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test deleted file mode 100644 index d4f08b5afe6..00000000000 --- a/mysql-test/suite/innodb/t/innodb-lru-force-no-free-page.test +++ /dev/null @@ -1,24 +0,0 @@ ---source include/have_innodb.inc ---source include/have_debug.inc ---source include/not_embedded.inc - -call mtr.add_suppression("InnoDB: Difficult to find free blocks in the buffer pool"); - -SET @saved_debug = @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,ib_lru_force_no_free_page"; - -CREATE TABLE t1 (j LONGBLOB) ENGINE = InnoDB; -BEGIN; -INSERT INTO t1 VALUES (repeat('abcdefghijklmnopqrstuvwxyz',200)); -COMMIT; - -SET debug_dbug = @saved_debug; - -DROP TABLE t1; - -# -# There should be only one message -# -let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; ---let SEARCH_PATTERN=InnoDB: Difficult to find free blocks ---source include/search_pattern_in_file.inc diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test index 2c3c95487f0..f83866b0f4c 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test @@ -42,7 +42,7 @@ INSERT INTO t1 VALUES(1),(2),(3); --let $_expect_file_name= `select regexp_replace(@@tmpdir, '^.*/','')` --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/$_expect_file_name.expect ---exec echo wait > $_expect_file_name +--write_line wait $_expect_file_name SET SESSION debug_dbug="+d,ib_discard_before_commit_crash"; --error 2013 ALTER TABLE t1 DISCARD TABLESPACE; @@ -54,7 +54,7 @@ DROP TABLE t1; CREATE TABLE t1 (c1 INT) ENGINE = InnoDB; INSERT INTO t1 VALUES(1),(2),(3); ---exec echo wait > $_expect_file_name +--write_line wait $_expect_file_name SET SESSION debug_dbug="+d,ib_discard_after_commit_crash"; --error 2013 ALTER TABLE t1 DISCARD TABLESPACE; @@ -96,7 +96,7 @@ EOF --error ER_TABLESPACE_DISCARDED SELECT * FROM t1; ---exec echo wait > $_expect_file_name +--write_line wait $_expect_file_name SET SESSION debug_dbug="+d,ib_import_before_commit_crash"; --error 2013 ALTER TABLE t1 IMPORT TABLESPACE; diff --git a/mysql-test/suite/innodb/t/innodb_bug60196.test b/mysql-test/suite/innodb/t/innodb_bug60196.test index 7f1f5c40585..41b9a4d8476 100644 --- a/mysql-test/suite/innodb/t/innodb_bug60196.test +++ b/mysql-test/suite/innodb/t/innodb_bug60196.test @@ -58,7 +58,7 @@ SELECT * FROM bug_60196; --echo # Restart server. # Write file to make mysql-test-run.pl start up the server again ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Turn on reconnect --enable_reconnect @@ -132,7 +132,7 @@ SELECT * FROM Bug_60309; --echo # Restart server. # Write file to make mysql-test-run.pl start up the server again ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Turn on reconnect --enable_reconnect diff --git a/mysql-test/suite/innodb/t/innodb_stats_fetch.test b/mysql-test/suite/innodb/t/innodb_stats_fetch.test index 99fc115af1d..11b8926a50b 100644 --- a/mysql-test/suite/innodb/t/innodb_stats_fetch.test +++ b/mysql-test/suite/innodb/t/innodb_stats_fetch.test @@ -96,3 +96,11 @@ SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_VIRTUAL LIMIT ROWS EXAMINED 5; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN LIMIT ROWS EXAMINED 5; SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS LIMIT ROWS EXAMINED 5; DROP TABLE t1; + +--echo # +--echo # MDEV-33462 Disallow LOCK=NONE operation on statistics table +--echo # +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE mysql.innodb_table_stats FORCE, LOCK=NONE, ALGORITHM=INPLACE; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE mysql.innodb_index_stats FORCE, LOCK=NONE, ALGORITHM=INPLACE; diff --git a/mysql-test/suite/innodb/t/innodb_timeout_rollback.test b/mysql-test/suite/innodb/t/innodb_timeout_rollback.test index 44e8acdde13..aa282352356 100644 --- a/mysql-test/suite/innodb/t/innodb_timeout_rollback.test +++ b/mysql-test/suite/innodb/t/innodb_timeout_rollback.test @@ -1,4 +1,5 @@ +--source include/have_innodb.inc --source include/innodb_rollback_on_timeout.inc ---echo End of 5.0 tests +--echo # End of 5.0 tests diff --git a/mysql-test/suite/innodb/t/innodb_ut_format_name.test b/mysql-test/suite/innodb/t/innodb_ut_format_name.test deleted file mode 100644 index 6e4023c7088..00000000000 --- a/mysql-test/suite/innodb/t/innodb_ut_format_name.test +++ /dev/null @@ -1,17 +0,0 @@ -# -# Test ut_format_name() -# - --- source include/have_debug.inc --- source include/have_innodb.inc - -CREATE TABLE t (c INT) ENGINE=INNODB; - -# This will invoke test_ut_format_name() in debug builds - -SET @save_dbug = @@debug_dbug; -SET debug_dbug = '+d,test_ut_format_name'; - -DROP TABLE t; - -SET debug_dbug = @save_dbug; diff --git a/mysql-test/suite/innodb/t/insert_into_empty.test b/mysql-test/suite/innodb/t/insert_into_empty.test index af7a0b3aec4..e22ed11d723 100644 --- a/mysql-test/suite/innodb/t/insert_into_empty.test +++ b/mysql-test/suite/innodb/t/insert_into_empty.test @@ -271,6 +271,16 @@ connection default; disconnect con1; SELECT * FROM t1; DROP TABLE t1; + +--echo # +--echo # MDEV-33979 Disallow bulk insert operation during +--echo # partition update statement +--echo # +CREATE TABLE t1(a INT KEY)ENGINE=InnoDB + PARTITION BY KEY(a) PARTITIONS 16; +INSERT INTO t1 VALUES(1); +UPDATE t1 SET a = 2 WHERE a = 1; +DROP TABLE t1; --echo # End of 10.6 tests --echo # @@ -495,3 +505,54 @@ DROP TABLE t1; CREATE TABLE t (a CHAR CHARACTER SET utf8) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; INSERT t SELECT left(seq,1) FROM seq_1_to_43691; DROP TABLE t; + +--echo # +--echo # MDEV-32453 Bulk insert fails to apply when trigger +--echo # does insert operation +--echo # +CREATE TABLE t(c INT)ENGINE=InnoDB; +CREATE TRIGGER t2_ai AFTER INSERT ON t FOR EACH ROW SET @a:=(SELECT * FROM t); +BEGIN; +--error ER_SUBQUERY_NO_1_ROW +INSERT INTO t VALUES (1),(1); +COMMIT; +DROP TABLE t; + +--echo # +--echo # MDEV-33868 Assertion `trx->bulk_insert' failed in +--echo # innodb_prepare_commit_versioned +--echo # +CREATE TABLE t (id INT) ENGINE=InnoDB; +--replace_result $MYSQLTEST_VARDIR VARDIR +--disable_ps2_protocol +eval select 1 into outfile "$MYSQLTEST_VARDIR/tmp/t.outfile"; +--enable_ps2_protocol +BEGIN; +--replace_result $MYSQLTEST_VARDIR VARDIR +eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t.outfile' INTO TABLE t; +COMMIT; +DROP TABLE t; +--remove_file $MYSQLTEST_VARDIR/tmp/t.outfile + +--echo # +--echo # MDEV-33934 Assertion `!check_foreigns' failed in +--echo # trx_t::bulk_insert_apply_for_table(dict_table_t*) +--echo # +CREATE TABLE t1(f1 INT,f2 INT,KEY(f1))engine=innodb; +BEGIN; +INSERT INTO t1 VALUES(); +SET STATEMENT FOREIGN_KEY_CHECKS=1 FOR SELECT * FROM t1; +COMMIT; +DROP TABLE t1; + +--echo # +--echo # MDEV-33970 Assertion `!m.first->second.is_bulk_insert()' +--echo # failed in trx_undo_report_row_operation() +--echo # +CREATE TABLE t1(c1 INT,c2 CHAR) ENGINE=INNODB PARTITION BY KEY(c1) PARTITIONS 2; +begin; +INSERT INTO t1 VALUES(2,0); +DELETE FROM t1; +commit; +DROP TABLE t1; +--echo # End of 10.11 tests diff --git a/mysql-test/suite/innodb/t/instant_alter_crash.test b/mysql-test/suite/innodb/t/instant_alter_crash.test index f51f61e3c04..76b85b771f7 100644 --- a/mysql-test/suite/innodb/t/instant_alter_crash.test +++ b/mysql-test/suite/innodb/t/instant_alter_crash.test @@ -230,29 +230,3 @@ CHECK TABLE t2; DROP TABLE t1,t2; --list_files $MYSQLD_DATADIR/test - ---echo # ---echo # MDEV-26198 Assertion `0' failed in row_log_table_apply_op during ---echo # ADD PRIMARY KEY or OPTIMIZE TABLE ---echo # -CREATE TABLE t1(f1 year default null, f2 year default null, - f3 text, f4 year default null, f5 year default null, - f6 year default null, f7 year default null, - f8 year default null)ENGINE=InnoDB ROW_FORMAT=REDUNDANT; -INSERT INTO t1 VALUES(1, 1, 1, 1, 1, 1, 1, 1); -ALTER TABLE t1 ADD COLUMN f9 year default null, ALGORITHM=INPLACE; -set DEBUG_SYNC="row_log_table_apply1_before SIGNAL con1_insert WAIT_FOR con1_finish"; -send ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ADD COLUMN f10 YEAR DEFAULT NULL, ALGORITHM=INPLACE; - -connect(con1,localhost,root,,,); -SET DEBUG_SYNC="now WAIT_FOR con1_insert"; -INSERT IGNORE INTO t1 (f3) VALUES ( 'b' ); -INSERT IGNORE INTO t1 (f3) VALUES ( 'l' ); -SET DEBUG_SYNC="now SIGNAL con1_finish"; - -connection default; -reap; -disconnect con1; -SET DEBUG_SYNC=RESET; -CHECK TABLE t1; -DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/instant_alter_debug.test b/mysql-test/suite/innodb/t/instant_alter_debug.test index b4d6b279ad5..a20f21020cc 100644 --- a/mysql-test/suite/innodb/t/instant_alter_debug.test +++ b/mysql-test/suite/innodb/t/instant_alter_debug.test @@ -546,11 +546,62 @@ SET DEBUG_SYNC="now WAIT_FOR try_insert"; --error ER_LOCK_WAIT_TIMEOUT INSERT INTO t1 VALUES(1, 2); SET DEBUG_SYNC="now SIGNAL alter_progress"; -disconnect con1; connection default; reap; DROP TABLE t1; + +--echo # +--echo # MDEV-26198 Assertion `0' failed in row_log_table_apply_op during +--echo # ADD PRIMARY KEY or OPTIMIZE TABLE +--echo # +CREATE TABLE t1(f1 year default null, f2 year default null, + f3 text, f4 year default null, f5 year default null, + f6 year default null, f7 year default null, + f8 year default null)ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, 1, 1, 1, 1, 1, 1, 1); +ALTER TABLE t1 ADD COLUMN f9 year default null, ALGORITHM=INPLACE; +set DEBUG_SYNC="row_log_table_apply1_before SIGNAL con1_insert WAIT_FOR con1_finish"; +send ALTER TABLE t1 ADD COLUMN f10 YEAR DEFAULT NULL, FORCE, ALGORITHM=INPLACE; + +connection con1; +SET DEBUG_SYNC="now WAIT_FOR con1_insert"; +INSERT IGNORE INTO t1 (f3) VALUES ( 'b' ); +INSERT IGNORE INTO t1 (f3) VALUES ( 'l' ); +SET DEBUG_SYNC="now SIGNAL con1_finish"; + +connection default; +reap; +CHECK TABLE t1; +DROP TABLE t1; + +--echo # +--echo # MDEV-19044 Alter table corrupts while applying the +--echo # modification log +--echo # +CREATE TABLE t1 ( + f1 INT, + f2 INT, + f3 char(19) CHARACTER SET utf8mb3, + f4 VARCHAR(500), + f5 TEXT)ENGINE=InnoDB; +INSERT INTO t1 VALUES(3, 1, REPEAT('a', 2), REPEAT("b", 20),'a'); +ALTER TABLE t1 ADD COLUMN f6 INT NOT NULL, ALGORITHM=INSTANT; +INSERT INTO t1 VALUES(1, 2, REPEAT('InnoDB', 2), + REPEAT("MariaDB", 20), REPEAT('a', 8000), 12); +INSERT INTO t1 VALUES(1, 2, REPEAT('MYSQL', 2), + REPEAT("MariaDB", 20), REPEAT('a', 8000), 12); +SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL con1_begin WAIT_FOR con1_update'; +send ALTER TABLE t1 MODIFY COLUMN f2 INT NOT NULL, FORCE, ALGORITHM=INPLACE; +connection con1; +SET DEBUG_SYNC='now WAIT_FOR con1_begin'; +UPDATE t1 SET f2=204 order by f1 limit 2; +SET DEBUG_SYNC='now SIGNAL con1_update'; +connection default; +reap; +disconnect con1; SET DEBUG_SYNC=reset; +CHECK TABLE t1; +DROP TABLE t1; --echo # End of 10.4 tests diff --git a/mysql-test/suite/innodb/t/instant_alter_extend.test b/mysql-test/suite/innodb/t/instant_alter_extend.test index 7258ba6d238..636527e598c 100644 --- a/mysql-test/suite/innodb/t/instant_alter_extend.test +++ b/mysql-test/suite/innodb/t/instant_alter_extend.test @@ -256,3 +256,16 @@ select * from t1; check table t1; drop database best; + +--echo # +--echo # MDEV-33214 Table is getting rebuild with +--echo # ALTER TABLE ADD COLUMN +--echo # +use test; +CREATE TABLE t1(f1 INT, f2 VARCHAR(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; +INSERT INTO t1 VALUES(1,'abc'),(2,'def'); +ALTER TABLE t1 ADD (f3 VARCHAR(5000), f4 VARCHAR(20)), ALGORITHM=instant; +ALTER TABLE t1 ADD f5 TEXT, ALGORITHM=INSTANT; +DROP TABLE t1; + +--echo # End of 10.4 tests diff --git a/mysql-test/suite/innodb/t/instant_alter_import.test b/mysql-test/suite/innodb/t/instant_alter_import.test index 3a811def170..fa35c582633 100644 --- a/mysql-test/suite/innodb/t/instant_alter_import.test +++ b/mysql-test/suite/innodb/t/instant_alter_import.test @@ -83,6 +83,7 @@ flush tables t2 for export; unlock tables; alter table t1 import tablespace; +--source include/restart_mysqld.inc select * from t1; --remove_file $MYSQLD_DATADIR/test/t1.ibd diff --git a/mysql-test/suite/innodb/t/lock_insert_into_empty.test b/mysql-test/suite/innodb/t/lock_insert_into_empty.test index 91d2bcdd3ba..42409e8cf35 100644 --- a/mysql-test/suite/innodb/t/lock_insert_into_empty.test +++ b/mysql-test/suite/innodb/t/lock_insert_into_empty.test @@ -51,6 +51,7 @@ CREATE TABLE t1 (k INT PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t1 SET k=1; START TRANSACTION; INSERT INTO t1 SET k=2; +SELECT count(*) > 0 FROM mysql.innodb_index_stats lock in share mode; --connect (con1,localhost,root,,test) SET innodb_lock_wait_timeout=0; @@ -59,5 +60,6 @@ CREATE TABLE t2 (pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB AS SELECT k FROM t1; --disconnect con1 --connection default - +SET innodb_lock_wait_timeout=default; DROP TABLE t1; +DROP TABLE IF EXISTS t2; diff --git a/mysql-test/suite/innodb/t/lock_isolation.test b/mysql-test/suite/innodb/t/lock_isolation.test new file mode 100644 index 00000000000..5c60f6e707c --- /dev/null +++ b/mysql-test/suite/innodb/t/lock_isolation.test @@ -0,0 +1,149 @@ +--source include/have_innodb.inc + +--echo # +--echo # MDEV-26642 Weird SELECT view when a record is +--echo # modified to the same value by two transactions +--echo # MDEV-32898 Phantom rows caused by updates of PRIMARY KEY +--echo # + +CREATE TABLE t(a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t VALUES (1,1),(2,2); +BEGIN; SELECT * FROM t LOCK IN SHARE MODE; +--connect con_weird,localhost,root +BEGIN; +SELECT * FROM t; +--connect consistent,localhost,root +SET innodb_snapshot_isolation=ON; +BEGIN; +SELECT * FROM t; +--connection default +UPDATE t SET a=3 WHERE b=2; +COMMIT; +--connection consistent +--error ER_CHECKREAD +UPDATE t SET b=3; +SELECT * FROM t; +COMMIT; +--connection con_weird +UPDATE t SET b=3; +SELECT * FROM t; +COMMIT; +--connection default +SELECT * FROM t; +DROP TABLE t; + +--echo # +--echo # MDEV-26643 Inconsistent behaviors of UPDATE under +--echo # READ UNCOMMITTED and READ COMMITTED isolation level +--echo # + +CREATE TABLE t(a INT, b INT) ENGINE=InnoDB; +INSERT INTO t VALUES(NULL, 1), (2, 2); +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +BEGIN; UPDATE t SET a = 10; + +--connection consistent +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +--send UPDATE t SET b = 20 WHERE a + +--connection default +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'Updating' + and info = 'UPDATE t SET b = 20 WHERE a'; +--source include/wait_condition.inc + +COMMIT; + +--connection consistent +--reap +SELECT * FROM t; + +--connection default +TRUNCATE TABLE t; +INSERT INTO t VALUES(NULL, 1), (2, 2); +BEGIN; UPDATE t SET a = 10; + +--connection consistent +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +--send UPDATE t SET b = 20 WHERE a + +--connection default +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where info = 'UPDATE t SET b = 20 WHERE a'; +--source include/wait_condition.inc + +COMMIT; + +--connection consistent +--reap +SELECT * FROM t; + +--connection default +TRUNCATE TABLE t; +INSERT INTO t VALUES(NULL, 1), (2, 2); +BEGIN; UPDATE t SET a = 10; + +--connection con_weird +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +send UPDATE t SET b = 20 WHERE a; + +--connection default +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'Updating' + and info = 'UPDATE t SET b = 20 WHERE a'; +--source include/wait_condition.inc + +SELECT * FROM t; +COMMIT; + +--connection con_weird +--reap +COMMIT; + +--connection default +SELECT * FROM t; +DROP TABLE t; + +--echo # +--echo # MDEV-33802 Weird read view after ROLLBACK of other transactions +--echo # + +CREATE TABLE t(a INT PRIMARY KEY, b INT UNIQUE) ENGINE=InnoDB; +INSERT INTO t SET a=1; + +BEGIN; INSERT INTO t SET a=2; + +--connection consistent +START TRANSACTION WITH CONSISTENT SNAPSHOT; +--disable_ps2_protocol +--error ER_CHECKREAD +SELECT * FROM t FORCE INDEX (b) FOR UPDATE; +--enable_ps2_protocol + +--connection con_weird +START TRANSACTION WITH CONSISTENT SNAPSHOT; +send +SELECT * FROM t FORCE INDEX (b) FOR UPDATE; + +--connection default +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'Sending data' + and info LIKE 'SELECT * FROM t %'; +--source include/wait_condition.inc +ROLLBACK; + +--connection con_weird +--reap +SELECT * FROM t FORCE INDEX (b) FOR UPDATE; +--disconnect con_weird + +--connection consistent +SELECT * FROM t FORCE INDEX (b) FOR UPDATE; +--disconnect consistent + +--connection default +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/log_file_name.test b/mysql-test/suite/innodb/t/log_file_name.test index 9707a1535af..33b1e37e2ce 100644 --- a/mysql-test/suite/innodb/t/log_file_name.test +++ b/mysql-test/suite/innodb/t/log_file_name.test @@ -204,7 +204,7 @@ print FILE "\0" x 16384; close(FILE); EOF ---exec echo "" > $MYSQLD_DATADIR/test/u2.ibd +--write_line "" $MYSQLD_DATADIR/test/u2.ibd --copy_file $MYSQLD_DATADIR/test/u6.ibd $MYSQLD_DATADIR/test/u4.ibd diff --git a/mysql-test/suite/innodb/t/log_upgrade_101_flags.test b/mysql-test/suite/innodb/t/log_upgrade_101_flags.test new file mode 100644 index 00000000000..7b54e3ae9aa --- /dev/null +++ b/mysql-test/suite/innodb/t/log_upgrade_101_flags.test @@ -0,0 +1,107 @@ +--source include/have_innodb.inc +--source include/big_test.inc +--source include/not_embedded.inc +call mtr.add_suppression("InnoDB: The change buffer is corrupted"); +call mtr.add_suppression("InnoDB: Tablespace size stored in header is 768 pages, but the sum of data file sizes is 384 pages"); +call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS of file"); +--source include/shutdown_mysqld.inc +let bugdir= $MYSQLTEST_VARDIR/tmp/log_upgrade; +--mkdir $bugdir +--let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $dirs= --innodb-data-home-dir=$bugdir --innodb-log-group-home-dir=$bugdir --innodb-undo-directory=$bugdir + +# Test case similar to log_upgrade.test +perl; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl"; +my $polynomial = 0x82f63b78; # CRC-32C + +die unless open OUT, ">", "$ENV{bugdir}/ibdata1"; +binmode OUT; + +my $head = pack("Nx[18]", 0); +# Add FSP_SPACE_FLAGS as 49152 (10.1.0...10.1.20), page_size = 32k +my $body = pack("x[8]Nx[4]Nx[2]Nx[32696]", 768, 49152, 97937874); +my $ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial); +print OUT pack("N",$ck).$head.pack("x[12]").$body.pack("Nx[4]",$ck); + +# Dummy change buffer header page (page 3). +die unless seek(OUT, 3 * 32768, 0); +## FIL_PAGE_OFFSET, FIL_PAGE_PREV, FIL_PAGE_NEXT, FIL_PAGE_TYPE +my $head = pack("NNNx[8]n", 3, 0xffffffff, 0xffffffff, 6); +my $body = pack("x[62]nnx[32656]", 2, 50); +my $ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial); +print OUT pack("N",$ck).$head.pack("x[12]").$body.pack("Nx[4]",$ck); + +# Dummy change buffer root page (page 4). +## FIL_PAGE_OFFSET, FIL_PAGE_PREV, FIL_PAGE_NEXT +my $head = pack("NNNx[10]", 4, 0xffffffff, 0xffffffff); +my $body = chr(0) x 32722; +my $ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial); +print OUT pack("N",$ck).$head.pack("x[12]").$body.pack("Nx[4]",$ck); + + +# Dictionary header page (page 7). +die unless seek(OUT, 7 * 32768, 0); +$head = pack("Nx[18]", 7); +$body = pack("x[32]Nx[8]Nx[32674]", 8, 9); +$ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial); +print OUT pack("N",$ck).$head.pack("x[12]").$body.pack("Nx[4]",$ck); + +# Empty SYS_TABLES page (page 8). +$head = pack("NNNx[8]n", 8, ~0, ~0, 17855); +$body = pack("nnx[31]Cx[20]", 2, 124, 1); +$body .= pack("nxnn", 0x801, 3, 116) . "infimum"; +$body .= pack("xnxnxx", 0x901, 0x803) . "supremum"; +$body .= pack("x[32632]nn", 116, 101); +$ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial); +print OUT pack("N",$ck).$head.pack("x[12]").$body.pack("Nx[4]",$ck); + +# Empty SYS_INDEXES page (page 9). +$head = pack("NNNx[8]n", 9, ~0, ~0, 17855); +$body = pack("nnx[31]Cx[20]", 2, 124, 3); +$body .= pack("nxnn", 0x801, 3, 116) . "infimum"; +$body .= pack("xnxnxx", 0x901, 0x803) . "supremum"; +$body .= pack("x[32632]nn", 116, 101); +$ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial); +print OUT pack("N",$ck).$head.pack("x[12]").$body.pack("Nx[4]",$ck); + +die unless seek(OUT, 768 * 16384 - 1, 0); +print OUT chr(0); +close OUT or die; + +die unless open OUT, ">", "$ENV{bugdir}/ib_logfile0"; +binmode OUT; +$_= pack("Nx[5]nx[5]", 1, 0x1286) . "BogoDB 4.3.2.1" . chr(0) x 478; +print OUT $_, pack("N", mycrc32($_, 0, $polynomial)); +# checkpoint page 1 and all-zero checkpoint 2 +$_= pack("x[13]nCNNx[484]", 0x1286, 12, 2, 0x80c); +print OUT $_, pack("N", mycrc32($_, 0, $polynomial)); +die unless seek(OUT, 0x1FFFFFFFF, 0); +print OUT chr(0); +close OUT or die; +die unless open OUT, ">", "$ENV{bugdir}/ib_logfile1"; +binmode OUT; +die unless seek(OUT, 0x800, 0); # the first 2048 bytes are unused! +$_= pack("Nnnx[500]", 0x80000944, 12, 12); +print OUT $_, pack("N", mycrc32($_, 0, $polynomial)); +die unless seek(OUT, 0x1FFFFFFFF, 0); +print OUT chr(0); +close OUT or die; +EOF + +--let $restart_parameters= $dirs --innodb-force-recovery=5 --innodb-log-file-size=4m --innodb_page_size=32k --innodb_buffer_pool_size=10M +--source include/start_mysqld.inc +SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +--source include/shutdown_mysqld.inc +--let SEARCH_PATTERN= InnoDB: Upgrading redo log: +--source include/search_pattern_in_file.inc +--let $restart_parameters= $dirs + +--remove_files_wildcard $bugdir +--rmdir $bugdir +--let $restart_parameters= +--source include/start_mysqld.inc + +--echo # End of 10.5 tests diff --git a/mysql-test/suite/innodb/t/monitor.test b/mysql-test/suite/innodb/t/monitor.test index 63c339e9489..11da213b6e4 100644 --- a/mysql-test/suite/innodb/t/monitor.test +++ b/mysql-test/suite/innodb/t/monitor.test @@ -5,11 +5,11 @@ # sys_vars.innodb_monitor_enable_basic --source include/have_innodb.inc -# Test turn on/off the monitor counter with "all" option -# By default, they will be off. select name, if(enabled,'enabled','disabled') status from information_schema.innodb_metrics; +create temporary table orig_innodb_metrics as select name, enabled from information_schema.innodb_metrics; + set global innodb_monitor_disable = All; select name from information_schema.innodb_metrics where enabled; @@ -315,18 +315,22 @@ CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0; let $innodb_monitor_enable = `SELECT @@innodb_monitor_enable`; -SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT /*1*/ NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; SET GLOBAL innodb_monitor_enable='module_buffer_page'; INSERT INTO t1 VALUES (1), (2), (3), (4); FLUSH TABLES t1 FOR EXPORT; UNLOCK TABLES; -SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME + +let $wait_condition= select count > 0 from information_schema.innodb_metrics where name like 'buffer_page_written_index_leaf'; +source include/wait_condition.inc; + +SELECT /*2*/ NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; SET GLOBAL innodb_monitor_disable='module_buffer_page'; SET GLOBAL innodb_monitor_reset_all='module_buffer_page'; -SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT /*3*/ NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; SET GLOBAL innodb_monitor_enable='%'; @@ -334,18 +338,22 @@ SET GLOBAL innodb_monitor_enable='%'; SET GLOBAL innodb_monitor_reset_all= '%', innodb_compression_algorithm= foo; INSERT INTO t1 VALUES (5), (6), (7), (8); FLUSH TABLES t1 FOR EXPORT; UNLOCK TABLES; -SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME + +let $wait_condition= select count > 0 from information_schema.innodb_metrics where name like 'buffer_page_written_index_leaf'; +source include/wait_condition.inc; + +SELECT /*4*/ NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; SET GLOBAL innodb_monitor_disable='%'; SET GLOBAL innodb_monitor_reset_all='%'; -SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT /*5*/ NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; SET GLOBAL innodb_monitor_enable='ALL'; INSERT INTO t1 VALUES (9), (10), (11), (12); FLUSH TABLES t1 FOR EXPORT; UNLOCK TABLES; -SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME +SELECT /*6*/ NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'buffer_page_written_index_leaf'; DROP TABLE t1; @@ -462,8 +470,36 @@ DROP TABLE fl2; DROP TABLE fl1; DROP TABLE fl0; ---disable_warnings -SET GLOBAL innodb_monitor_enable=default; -SET GLOBAL innodb_monitor_disable=default; -SET GLOBAL innodb_monitor_reset_all=default; ---enable_warnings +set global innodb_monitor_disable = 'adaptive\\_hash\\_p%'; +set global innodb_monitor_disable = 'adaptive\\_hash\\_r%'; +set global innodb_monitor_disable = 'buffer\\_LRU\\_batch\\_n%'; +set global innodb_monitor_disable = 'buffer\\_LRU\\_batch\\_s%'; +set global innodb_monitor_disable = 'buffer\\_LRU\\_g%'; +set global innodb_monitor_disable = 'buffer\\_LRU\\_s%'; +set global innodb_monitor_disable = 'buffer\\_LRU\\_u%'; +set global innodb_monitor_disable = 'buffer\\_f%'; +set global innodb_monitor_disable = 'buffer\\_page\\_%'; +set global innodb_monitor_disable = 'c%'; +set global innodb_monitor_disable = 'ddl%'; +set global innodb_monitor_disable = 'icp%'; +set global innodb_monitor_disable = 'index\\_p%'; +set global innodb_monitor_disable = 'innodb\\_di%'; +set global innodb_monitor_disable = 'innodb\\_l%'; +set global innodb_monitor_disable = 'innodb\\_m%'; +set global innodb_monitor_disable = 'lock\\_re%'; +set global innodb_monitor_disable = 'lock\\_ta%'; +set global innodb_monitor_disable = 'log%'; +set global innodb_monitor_disable = 'm%'; +set global innodb_monitor_disable = 'p%'; +set global innodb_monitor_disable = 't%'; +set global innodb_monitor_enable = 'log\\_w%'; +set global innodb_monitor_enable = 'trx_rseg_history_len'; +set global innodb_monitor_enable = 'trx_undo_slots_cached'; + +set global innodb_monitor_enable=default; +set global innodb_monitor_disable=default; +set global innodb_monitor_reset_all=default; + +select name, orig.enabled, new.enabled from + orig_innodb_metrics orig join information_schema.innodb_metrics new using(name) + where orig.enabled != new.enabled; diff --git a/mysql-test/suite/innodb/t/purge_secondary.test b/mysql-test/suite/innodb/t/purge_secondary.test index 8a38a418877..ec02c726891 100644 --- a/mysql-test/suite/innodb/t/purge_secondary.test +++ b/mysql-test/suite/innodb/t/purge_secondary.test @@ -4,10 +4,6 @@ SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent; SET GLOBAL innodb_stats_persistent = 0; ---disable_query_log -call mtr.add_suppression("InnoDB: Difficult to find free blocks in the buffer pool"); ---enable_query_log - CREATE TABLE t1 ( a SERIAL, b CHAR(255) NOT NULL DEFAULT '', c BOOLEAN DEFAULT false, l LINESTRING NOT NULL DEFAULT ST_linefromtext('linestring(448 -689, diff --git a/mysql-test/suite/innodb/t/rename_table.test b/mysql-test/suite/innodb/t/rename_table.test index 654f8809b22..a61813429b3 100644 --- a/mysql-test/suite/innodb/t/rename_table.test +++ b/mysql-test/suite/innodb/t/rename_table.test @@ -32,17 +32,22 @@ DROP DATABASE abc_def; DROP DATABASE abc_def2; -call mtr.add_suppression("InnoDB: (Operating system error|Error number \\d+ means|Cannot rename file)"); +call mtr.add_suppression("InnoDB: Cannot rename '.*t1.ibd' to '.*non_existing_db.*' because the target schema directory doesn't exist"); CREATE TABLE t1 (a INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES(100); --replace_result "\\" "/" --error ER_ERROR_ON_RENAME RENAME TABLE t1 TO non_existing_db.t1; ---let SEARCH_PATTERN= \[ERROR\] InnoDB: Cannot rename file '.*t1\.ibd' to '.*non_existing_db +--let SEARCH_PATTERN= \[ERROR\] InnoDB: Cannot rename '.*t1\.ibd' to '.*non_existing_db let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; --source include/search_pattern_in_file.inc +SET GLOBAL innodb_fast_shutdown=2; +--source include/restart_mysqld.inc + +SELECT * FROM t1; # Cleanup DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/row_size_error_log_warnings_3.test b/mysql-test/suite/innodb/t/row_size_error_log_warnings_3.test index 24029a48aa4..47fedc52725 100644 --- a/mysql-test/suite/innodb/t/row_size_error_log_warnings_3.test +++ b/mysql-test/suite/innodb/t/row_size_error_log_warnings_3.test @@ -85,3 +85,19 @@ CREATE TABLE t1(f1 char(200), f2 char(200), f3 char(200), f29(10), f30(10), f31(10), f32(10), f33(10))) ENGINE=InnoDB; + +--echo # +--echo # MDEV-31161 Assertion failures upon adding a too long key +--echo # to table with COMPRESSED row format +--echo # +--let $page_size= `SELECT @@GLOBAL.innodb_page_size` +CREATE TABLE t1(pk INT PRIMARY KEY, f1 INT, f2 TEXT)ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +INSERT INTO t1 (pk) VALUES (1); +let $error_code = 0; +if ($page_size == 4096) { +let $error_code = ER_TOO_BIG_ROWSIZE; +} + +--error $error_code +ALTER TABLE t1 ADD KEY (f1), ADD KEY (f2(1000)); +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/sys_truncate_debug.test b/mysql-test/suite/innodb/t/sys_truncate_debug.test index 312a827effa..b3363f105e3 100644 --- a/mysql-test/suite/innodb/t/sys_truncate_debug.test +++ b/mysql-test/suite/innodb/t/sys_truncate_debug.test @@ -24,7 +24,7 @@ DROP TABLE t1; SELECT NAME, FILE_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 0; # Ran out of buffer pool -let $restart_parameters=--debug_dbug="+d,shrink_buffer_pool_full"; +let $restart_parameters=--debug_dbug=+d,shrink_buffer_pool_full; --source include/restart_mysqld.inc --let SEARCH_PATTERN= \[Warning\] InnoDB: Cannot shrink the system tablespace @@ -36,7 +36,7 @@ WHERE engine = 'innodb' AND support IN ('YES', 'DEFAULT', 'ENABLED'); # Ran out of mtr log size -let $restart_parameters=--debug_dbug="+d,mtr_log_max_size"; +let $restart_parameters=--debug_dbug=+d,mtr_log_max_size; --source include/restart_mysqld.inc --let SEARCH_PATTERN= \[ERROR\] InnoDB: Cannot shrink the system tablespace @@ -48,7 +48,7 @@ WHERE engine = 'innodb' AND support IN ('YES', 'DEFAULT', 'ENABLED'); # Crash after shrinking the system tablespace -let $restart_parameters=--debug_dbug="+d,crash_after_sys_truncate"; +let $restart_parameters=--debug_dbug=+d,crash_after_sys_truncate; --source include/restart_mysqld.inc SELECT * FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'innodb' diff --git a/mysql-test/suite/innodb/t/temporary_table.test b/mysql-test/suite/innodb/t/temporary_table.test index a374f9e1bba..9c742ce75c6 100644 --- a/mysql-test/suite/innodb/t/temporary_table.test +++ b/mysql-test/suite/innodb/t/temporary_table.test @@ -135,7 +135,7 @@ AND support IN ('YES', 'DEFAULT', 'ENABLED'); # We cannot use include/restart_mysqld.inc in this particular test, # because SHOW STATUS would fail due to unwritable (nonexistent) tmpdir. --source include/shutdown_mysqld.inc ---exec echo "restart: --tmpdir=/dev/null/$MYSQL_TMP_DIR --skip-innodb-fast-shutdown" > $_expect_file_name +--write_line "restart: --tmpdir=/dev/null/$MYSQL_TMP_DIR --skip-innodb-fast-shutdown" $_expect_file_name --enable_reconnect --disable_result_log --disable_query_log diff --git a/mysql-test/suite/innodb/t/undo_space_dblwr.test b/mysql-test/suite/innodb/t/undo_space_dblwr.test index b6fd6738a1c..52b19a4b7fb 100644 --- a/mysql-test/suite/innodb/t/undo_space_dblwr.test +++ b/mysql-test/suite/innodb/t/undo_space_dblwr.test @@ -9,19 +9,19 @@ show variables like 'innodb_doublewrite'; create table t1(f1 int not null, f2 int not null)engine=innodb; insert into t1 values (1, 1); ---source include/wait_all_purged.inc +# Slow shutdown and restart to make sure ibuf merge is finished +SET GLOBAL innodb_fast_shutdown = 0; +let $shutdown_timeout=; +let $restart_parameters=--debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0; +--source include/restart_mysqld.inc -set GLOBAL innodb_log_checkpoint_now=1; --source ../include/no_checkpoint_start.inc - --echo # Make the first page dirty for undo tablespace set global innodb_saved_page_number_debug = 0; set global innodb_fil_make_page_dirty_debug = 1; -SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0; -SET GLOBAL innodb_max_dirty_pages_pct=0.0; +SET GLOBAL innodb_buf_flush_list_now = 1; -sleep 1; --let CLEANUP_IF_CHECKPOINT=drop table t1; --source ../include/no_checkpoint_end.inc diff --git a/mysql-test/suite/innodb/t/undo_truncate.test b/mysql-test/suite/innodb/t/undo_truncate.test index 18cc4f36896..9abf08ff436 100644 --- a/mysql-test/suite/innodb/t/undo_truncate.test +++ b/mysql-test/suite/innodb/t/undo_truncate.test @@ -13,7 +13,7 @@ call mtr.add_suppression("InnoDB: Trying to delete tablespace.*pending operation # Re-create the undo log tablespaces after slow shutdown SET GLOBAL innodb_fast_shutdown=0; -let $restart_parameters="--innodb_undo_tablespaces=2"; +let $restart_parameters=--innodb_undo_tablespaces=2; --source include/restart_mysqld.inc SET GLOBAL innodb_undo_log_truncate = 0; @@ -46,6 +46,7 @@ connection con1; reap; send delete from t1; connection con2; reap; delete from t2; connection con1; reap; +SET GLOBAL innodb_max_undo_log_size = @@GLOBAL.innodb_page_size * 4294967296; SET GLOBAL innodb_undo_log_truncate = 1; commit; disconnect con1; connection con2; commit; disconnect con2; @@ -56,6 +57,8 @@ connection default; let $trx_before= `SHOW ENGINE INNODB STATUS`; let $trx_before= `select substr('$trx_before',9)+2`; +SET GLOBAL innodb_max_purge_lag_wait=0; +SET GLOBAL innodb_max_undo_log_size=DEFAULT; SET GLOBAL innodb_max_purge_lag_wait=0; set global innodb_fast_shutdown=0; let $restart_parameters=; diff --git a/mysql-test/suite/innodb/t/undo_truncate_recover.test b/mysql-test/suite/innodb/t/undo_truncate_recover.test index 148c3f939d0..988b28f75b4 100644 --- a/mysql-test/suite/innodb/t/undo_truncate_recover.test +++ b/mysql-test/suite/innodb/t/undo_truncate_recover.test @@ -13,7 +13,7 @@ # Re-create the undo log tablespaces after slow shutdown SET GLOBAL innodb_fast_shutdown=0; -let $restart_parameters="--innodb_undo_tablespaces=2"; +let $restart_parameters=--innodb_undo_tablespaces=2; --source include/restart_mysqld.inc SET GLOBAL innodb_undo_log_truncate = 1; diff --git a/mysql-test/suite/innodb_fts/r/create,orig.rdiff b/mysql-test/suite/innodb_fts/r/create,orig.rdiff new file mode 100644 index 00000000000..e7191646735 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/create,orig.rdiff @@ -0,0 +1,11 @@ +--- create.result ++++ create.reject +@@ -207,7 +207,7 @@ + UNIQUE KEY `FTS_DOC_ID_INDEX` (`FTS_DOC_ID` DESC) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=INPLACE; +-ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for system-versioned operations. Try ALGORITHM=COPY ++ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT index + ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=COPY; + ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT index + DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/create.result b/mysql-test/suite/innodb_fts/r/create.result index 4334344a981..04fc20195b6 100644 --- a/mysql-test/suite/innodb_fts/r/create.result +++ b/mysql-test/suite/innodb_fts/r/create.result @@ -207,7 +207,7 @@ t1 CREATE TABLE `t1` ( UNIQUE KEY `FTS_DOC_ID_INDEX` (`FTS_DOC_ID` DESC) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=INPLACE; -ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT index +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for system-versioned operations. Try ALGORITHM=COPY ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=COPY; ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT index DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/foreign_key_update.result b/mysql-test/suite/innodb_fts/r/foreign_key_update.result index f2d47da78c5..87c21c0bfc5 100644 --- a/mysql-test/suite/innodb_fts/r/foreign_key_update.result +++ b/mysql-test/suite/innodb_fts/r/foreign_key_update.result @@ -32,3 +32,15 @@ database database DROP TABLE t1_fk; DROP TABLE t1; +# +# MDEV-32346 Assertion failure sym_node->table != NULL +# in pars_retrieve_table_def on UPDATE +# +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a INT, b TEXT, FOREIGN KEY(a) REFERENCES t1(a), +FULLTEXT (b))ENGINE=InnoDB; +INSERT INTO t1 SET a=1; +ALTER TABLE t2 DISCARD TABLESPACE; +UPDATE t1 SET a=2; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)) +DROP TABLE t2,t1; diff --git a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl,vers.rdiff b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl,vers.rdiff new file mode 100644 index 00000000000..d0967243056 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl,vers.rdiff @@ -0,0 +1,57 @@ +--- innodb-fts-ddl.result 2023-11-23 13:40:18.932463721 +0100 ++++ innodb-fts-ddl,vers.result 2024-04-09 11:34:42.968505497 +0200 +@@ -11,8 +11,10 @@ + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY; +-ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=INPLACE; ++ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Not implemented for system-versioned operations. Try ALGORITHM=COPY ++ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body); ++affected rows: 6 ++info: Records: 6 Duplicates: 0 Warnings: 0 + SELECT * FROM fts_test WHERE MATCH (title, body) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + id title body +@@ -26,7 +28,9 @@ + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); +-ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY; ++ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body); ++affected rows: 12 ++info: Records: 12 Duplicates: 0 Warnings: 0 + SELECT * FROM fts_test WHERE MATCH (title, body) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + id title body +@@ -76,8 +80,10 @@ + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY, LOCK=NONE; +-ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED +-ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY; ++ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Not implemented for system-versioned operations. Try ALGORITHM=COPY ++ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body); ++affected rows: 6 ++info: Records: 6 Duplicates: 0 Warnings: 0 + ALTER TABLE fts_test ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE; + ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED + ALTER TABLE fts_test ROW_FORMAT=REDUNDANT; +@@ -162,7 +168,7 @@ + (20, 'MySQL Security','When configured properly, MySQL ...'); + ALTER TABLE articles ADD FULLTEXT INDEX idx (title), + ADD FULLTEXT INDEX idx3 (title), ALGORITHM=INPLACE; +-ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try ALGORITHM=COPY ++ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for system-versioned operations. Try ALGORITHM=COPY + ALTER TABLE articles ADD FULLTEXT INDEX idx (title), + ADD FULLTEXT INDEX idx3 (title); + affected rows: 6 +@@ -274,7 +280,7 @@ + call mtr.add_suppression("InnoDB: Failed to create"); + CREATE TABLE t1(a TEXT, FTS_DOC_ID BIGINT UNSIGNED NOT NULL UNIQUE) ENGINE=InnoDB; + ALTER TABLE t1 ADD FULLTEXT(a), ALGORITHM=INPLACE; +-ERROR HY000: Got error 11 "Resource temporarily unavailable" from storage engine InnoDB ++ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for system-versioned operations. Try ALGORITHM=COPY + DROP TABLE t1; + CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB; + ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b); diff --git a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl,vers_trx.rdiff b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl,vers_trx.rdiff new file mode 100644 index 00000000000..515c1c22485 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl,vers_trx.rdiff @@ -0,0 +1,57 @@ +--- innodb-fts-ddl.result 2023-11-23 13:40:18.932463721 +0100 ++++ innodb-fts-ddl,vers_trx.result 2024-04-09 11:45:57.097484346 +0200 +@@ -11,8 +11,10 @@ + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY; +-ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE +-ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=INPLACE; ++ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Not implemented for system-versioned operations. Try ALGORITHM=COPY ++ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body); ++affected rows: 6 ++info: Records: 6 Duplicates: 0 Warnings: 0 + SELECT * FROM fts_test WHERE MATCH (title, body) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + id title body +@@ -26,7 +28,9 @@ + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); +-ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY; ++ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body); ++affected rows: 12 ++info: Records: 12 Duplicates: 0 Warnings: 0 + SELECT * FROM fts_test WHERE MATCH (title, body) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + id title body +@@ -76,8 +80,10 @@ + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY, LOCK=NONE; +-ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED +-ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY; ++ERROR 0A000: ALGORITHM=NOCOPY is not supported. Reason: Not implemented for system-versioned operations. Try ALGORITHM=COPY ++ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body); ++affected rows: 6 ++info: Records: 6 Duplicates: 0 Warnings: 0 + ALTER TABLE fts_test ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE; + ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED + ALTER TABLE fts_test ROW_FORMAT=REDUNDANT; +@@ -162,7 +168,7 @@ + (20, 'MySQL Security','When configured properly, MySQL ...'); + ALTER TABLE articles ADD FULLTEXT INDEX idx (title), + ADD FULLTEXT INDEX idx3 (title), ALGORITHM=INPLACE; +-ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try ALGORITHM=COPY ++ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for system-versioned operations. Try ALGORITHM=COPY + ALTER TABLE articles ADD FULLTEXT INDEX idx (title), + ADD FULLTEXT INDEX idx3 (title); + affected rows: 6 +@@ -274,7 +280,7 @@ + call mtr.add_suppression("InnoDB: Failed to create"); + CREATE TABLE t1(a TEXT, FTS_DOC_ID BIGINT UNSIGNED NOT NULL UNIQUE) ENGINE=InnoDB; + ALTER TABLE t1 ADD FULLTEXT(a), ALGORITHM=INPLACE; +-ERROR HY000: Got error 11 "Resource temporarily unavailable" from storage engine InnoDB ++ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for system-versioned operations. Try ALGORITHM=COPY + DROP TABLE t1; + CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB; + ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b); diff --git a/mysql-test/suite/innodb_fts/r/innodb-fts-fic,vers.rdiff b/mysql-test/suite/innodb_fts/r/innodb-fts-fic,vers.rdiff new file mode 100644 index 00000000000..f9ba217769f --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/innodb-fts-fic,vers.rdiff @@ -0,0 +1,10 @@ +--- innodb-fts-fic.result ++++ innodb-fts-fic.reject +@@ -172,7 +172,6 @@ + (1, 'MySQL Tutorial','DBMS stands for DataBase ...'), + (2, 'How To Use MySQL Well','After you went through a ...'); + CREATE FULLTEXT INDEX idx ON wp(title, text); +-ERROR HY000: Column 'FTS_DOC_ID' is of wrong type for an InnoDB FULLTEXT index + DROP TABLE wp; + CREATE TABLE wp( + FTS_DOC_ID bigint unsigned PRIMARY KEY, diff --git a/mysql-test/suite/innodb_fts/r/innodb-fts-fic,vers_trx.rdiff b/mysql-test/suite/innodb_fts/r/innodb-fts-fic,vers_trx.rdiff new file mode 100644 index 00000000000..f9ba217769f --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/innodb-fts-fic,vers_trx.rdiff @@ -0,0 +1,10 @@ +--- innodb-fts-fic.result ++++ innodb-fts-fic.reject +@@ -172,7 +172,6 @@ + (1, 'MySQL Tutorial','DBMS stands for DataBase ...'), + (2, 'How To Use MySQL Well','After you went through a ...'); + CREATE FULLTEXT INDEX idx ON wp(title, text); +-ERROR HY000: Column 'FTS_DOC_ID' is of wrong type for an InnoDB FULLTEXT index + DROP TABLE wp; + CREATE TABLE wp( + FTS_DOC_ID bigint unsigned PRIMARY KEY, diff --git a/mysql-test/suite/innodb_fts/r/misc_debug,vers.rdiff b/mysql-test/suite/innodb_fts/r/misc_debug,vers.rdiff new file mode 100644 index 00000000000..69294a5a84c --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/misc_debug,vers.rdiff @@ -0,0 +1,66 @@ +--- misc_debug.result ++++ misc_debug.reject +@@ -7,14 +7,14 @@ + SET @saved_debug_dbug = @@SESSION.debug_dbug; + SET SESSION debug_dbug="+d,ib_dict_create_index_tree_fail"; + CREATE FULLTEXT INDEX idx ON articles(body); +-ERROR HY000: Out of memory. ++ERROR HY000: Can't create table `test`.`articles` (errno: 128 "Out of memory in engine") + SET SESSION debug_dbug=@saved_debug_dbug; + ALTER TABLE articles STATS_PERSISTENT=DEFAULT; + DROP TABLE articles; + CREATE TABLE t (a INT, b TEXT) engine=innodb; + SET debug_dbug='+d,alter_table_rollback_new_index'; +-ALTER TABLE t ADD FULLTEXT INDEX (b(64)); +-ERROR HY000: Unknown error ++ALTER TABLE t ADD FULLTEXT INDEX (b(64)), ALGORITHM=INPLACE; ++ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for system-versioned operations. Try ALGORITHM=COPY + SET SESSION debug_dbug=@saved_debug_dbug; + DROP TABLE t; + CREATE TABLE t1 (pk INT, a VARCHAR(8), PRIMARY KEY(pk), +@@ -28,32 +28,6 @@ + DROP TABLE t2, t1; + SET SESSION debug_dbug=@saved_debug_dbug; + # +-# MDEV-25200 Index count mismatch due to aborted FULLTEXT INDEX +-# +-CREATE TABLE t1(a INT, b TEXT, c TEXT, FULLTEXT INDEX(b)) ENGINE=InnoDB; +-INSERT INTO t1 VALUES(1, "test", "test_1"); +-connect con1,localhost,root,,test; +-SET DEBUG_DBUG="+d,innodb_OOM_inplace_alter"; +-SET DEBUG_SYNC='innodb_commit_inplace_alter_table_enter SIGNAL s2 WAIT_FOR g2'; +-ALTER TABLE t1 ADD FULLTEXT(c); +-connection default; +-SET DEBUG_SYNC='now WAIT_FOR s2'; +-START TRANSACTION; +-SELECT * FROM t1; +-a b c +-1 test test_1 +-SET DEBUG_SYNC='now SIGNAL g2'; +-connection con1; +-ERROR HY000: Out of memory. +-disconnect con1; +-connection default; +-SET DEBUG_SYNC=RESET; +-ALTER TABLE t1 ADD bl INT AS (LENGTH(b)) VIRTUAL; +-CHECK TABLE t1; +-Table Op Msg_type Msg_text +-test.t1 check status OK +-DROP TABLE t1; +-# + # MDEV-25663 Double free of transaction during TRUNCATE + # + call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)"); +@@ -65,12 +39,3 @@ + SET debug_dbug=@saved_debug_dbug; + DROP TABLE t1; + # End of 10.3 tests +-CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(100))ENGINE=InnoDB; +-SET DEBUG_DBUG="+d,stats_lock_fail"; +-ALTER TABLE t1 ADD FULLTEXT(f2); +-ERROR HY000: Lock wait timeout exceeded; try restarting transaction +-SET debug_dbug=@saved_debug_dbug; +-ALTER TABLE t1 DISCARD TABLESPACE; +-ALTER TABLE t1 ADD FULLTEXT(f2); +-ERROR HY000: Tablespace has been discarded for table `t1` +-DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/misc_debug,vers_trx.rdiff b/mysql-test/suite/innodb_fts/r/misc_debug,vers_trx.rdiff new file mode 100644 index 00000000000..69294a5a84c --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/misc_debug,vers_trx.rdiff @@ -0,0 +1,66 @@ +--- misc_debug.result ++++ misc_debug.reject +@@ -7,14 +7,14 @@ + SET @saved_debug_dbug = @@SESSION.debug_dbug; + SET SESSION debug_dbug="+d,ib_dict_create_index_tree_fail"; + CREATE FULLTEXT INDEX idx ON articles(body); +-ERROR HY000: Out of memory. ++ERROR HY000: Can't create table `test`.`articles` (errno: 128 "Out of memory in engine") + SET SESSION debug_dbug=@saved_debug_dbug; + ALTER TABLE articles STATS_PERSISTENT=DEFAULT; + DROP TABLE articles; + CREATE TABLE t (a INT, b TEXT) engine=innodb; + SET debug_dbug='+d,alter_table_rollback_new_index'; +-ALTER TABLE t ADD FULLTEXT INDEX (b(64)); +-ERROR HY000: Unknown error ++ALTER TABLE t ADD FULLTEXT INDEX (b(64)), ALGORITHM=INPLACE; ++ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Not implemented for system-versioned operations. Try ALGORITHM=COPY + SET SESSION debug_dbug=@saved_debug_dbug; + DROP TABLE t; + CREATE TABLE t1 (pk INT, a VARCHAR(8), PRIMARY KEY(pk), +@@ -28,32 +28,6 @@ + DROP TABLE t2, t1; + SET SESSION debug_dbug=@saved_debug_dbug; + # +-# MDEV-25200 Index count mismatch due to aborted FULLTEXT INDEX +-# +-CREATE TABLE t1(a INT, b TEXT, c TEXT, FULLTEXT INDEX(b)) ENGINE=InnoDB; +-INSERT INTO t1 VALUES(1, "test", "test_1"); +-connect con1,localhost,root,,test; +-SET DEBUG_DBUG="+d,innodb_OOM_inplace_alter"; +-SET DEBUG_SYNC='innodb_commit_inplace_alter_table_enter SIGNAL s2 WAIT_FOR g2'; +-ALTER TABLE t1 ADD FULLTEXT(c); +-connection default; +-SET DEBUG_SYNC='now WAIT_FOR s2'; +-START TRANSACTION; +-SELECT * FROM t1; +-a b c +-1 test test_1 +-SET DEBUG_SYNC='now SIGNAL g2'; +-connection con1; +-ERROR HY000: Out of memory. +-disconnect con1; +-connection default; +-SET DEBUG_SYNC=RESET; +-ALTER TABLE t1 ADD bl INT AS (LENGTH(b)) VIRTUAL; +-CHECK TABLE t1; +-Table Op Msg_type Msg_text +-test.t1 check status OK +-DROP TABLE t1; +-# + # MDEV-25663 Double free of transaction during TRUNCATE + # + call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)"); +@@ -65,12 +39,3 @@ + SET debug_dbug=@saved_debug_dbug; + DROP TABLE t1; + # End of 10.3 tests +-CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(100))ENGINE=InnoDB; +-SET DEBUG_DBUG="+d,stats_lock_fail"; +-ALTER TABLE t1 ADD FULLTEXT(f2); +-ERROR HY000: Lock wait timeout exceeded; try restarting transaction +-SET debug_dbug=@saved_debug_dbug; +-ALTER TABLE t1 DISCARD TABLESPACE; +-ALTER TABLE t1 ADD FULLTEXT(f2); +-ERROR HY000: Tablespace has been discarded for table `t1` +-DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/sync_ddl,vers.rdiff b/mysql-test/suite/innodb_fts/r/sync_ddl,vers.rdiff new file mode 100644 index 00000000000..7834e04c9f3 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/sync_ddl,vers.rdiff @@ -0,0 +1,12 @@ +--- sync_ddl.result ++++ sync_ddl.reject +@@ -100,7 +100,7 @@ + ADD COLUMN id2 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + DROP INDEX idx1, + ADD FULLTEXT INDEX idx2(value); +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 0 ++affected rows: 2 ++info: Records: 2 Duplicates: 0 Warnings: 0 + DROP TABLE t1; + SET GLOBAL debug_dbug = @save_debug; diff --git a/mysql-test/suite/innodb_fts/r/sync_ddl,vers_trx.rdiff b/mysql-test/suite/innodb_fts/r/sync_ddl,vers_trx.rdiff new file mode 100644 index 00000000000..7834e04c9f3 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/sync_ddl,vers_trx.rdiff @@ -0,0 +1,12 @@ +--- sync_ddl.result ++++ sync_ddl.reject +@@ -100,7 +100,7 @@ + ADD COLUMN id2 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + DROP INDEX idx1, + ADD FULLTEXT INDEX idx2(value); +-affected rows: 0 +-info: Records: 0 Duplicates: 0 Warnings: 0 ++affected rows: 2 ++info: Records: 2 Duplicates: 0 Warnings: 0 + DROP TABLE t1; + SET GLOBAL debug_dbug = @save_debug; diff --git a/mysql-test/suite/innodb_fts/r/sync_ddl.result b/mysql-test/suite/innodb_fts/r/sync_ddl.result index 441954dc77b..5ebe1575d91 100644 --- a/mysql-test/suite/innodb_fts/r/sync_ddl.result +++ b/mysql-test/suite/innodb_fts/r/sync_ddl.result @@ -99,7 +99,8 @@ ALTER TABLE t1 DROP COLUMN id1, ADD COLUMN id2 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, DROP INDEX idx1, -ADD FULLTEXT INDEX idx2(value), -ALGORITHM=INPLACE; +ADD FULLTEXT INDEX idx2(value); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 DROP TABLE t1; SET GLOBAL debug_dbug = @save_debug; diff --git a/mysql-test/suite/innodb_fts/t/create.test b/mysql-test/suite/innodb_fts/t/create.test index e6a7e993f84..9d88c1eddd4 100644 --- a/mysql-test/suite/innodb_fts/t/create.test +++ b/mysql-test/suite/innodb_fts/t/create.test @@ -131,8 +131,14 @@ ENGINE=InnoDB; CREATE TABLE t1(a INT PRIMARY KEY, b TEXT, FTS_DOC_ID BIGINT UNSIGNED NOT NULL, UNIQUE KEY FTS_DOC_ID_INDEX(FTS_DOC_ID DESC)) ENGINE=InnoDB; SHOW CREATE TABLE t1; +if ($MTR_COMBINATION_ORIG) { --error ER_INNODB_FT_WRONG_DOCID_INDEX ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=INPLACE; +} +if (!$MTR_COMBINATION_ORIG) { +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=INPLACE; +} --error ER_INNODB_FT_WRONG_DOCID_INDEX ALTER TABLE t1 ADD FULLTEXT INDEX(b), ALGORITHM=COPY; DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/foreign_key_update.test b/mysql-test/suite/innodb_fts/t/foreign_key_update.test index 1f74e640088..8a64ac33d69 100644 --- a/mysql-test/suite/innodb_fts/t/foreign_key_update.test +++ b/mysql-test/suite/innodb_fts/t/foreign_key_update.test @@ -32,3 +32,16 @@ SELECT * FROM t1_fk WHERE MATCH(a) AGAINST('database'); DROP TABLE t1_fk; DROP TABLE t1; + +--echo # +--echo # MDEV-32346 Assertion failure sym_node->table != NULL +--echo # in pars_retrieve_table_def on UPDATE +--echo # +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a INT, b TEXT, FOREIGN KEY(a) REFERENCES t1(a), + FULLTEXT (b))ENGINE=InnoDB; +INSERT INTO t1 SET a=1; +ALTER TABLE t2 DISCARD TABLESPACE; +--error ER_ROW_IS_REFERENCED_2 +UPDATE t1 SET a=2; +DROP TABLE t2,t1; diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test index bc0880c35c2..17f319c96dd 100644 --- a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test +++ b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test @@ -20,11 +20,20 @@ INSERT INTO fts_test (title,body) VALUES ('MySQL Security','When configured properly, MySQL ...'); # Table does rebuild when fts index builds for the first time +# Create the FTS index + +if ($MTR_COMBINATION_ORIG) { --error ER_ALTER_OPERATION_NOT_SUPPORTED ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY; - -# Create the FTS index ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=INPLACE; +} +if (!$MTR_COMBINATION_ORIG) { +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY; +--enable_info +ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body); +--disable_info +} # Select word "tutorial" in the table SELECT * FROM fts_test WHERE MATCH (title, body) @@ -43,7 +52,14 @@ INSERT INTO fts_test (title,body) VALUES ('MySQL Security','When configured properly, MySQL ...'); # FTS_DOC_ID hidden column and FTS_DOC_ID index exist +if ($MTR_COMBINATION_ORIG) { ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY; +} +if (!$MTR_COMBINATION_ORIG) { +--enable_info +ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body); +--disable_info +} # Select word "tutorial" in the table SELECT * FROM fts_test WHERE MATCH (title, body) @@ -112,7 +128,14 @@ INSERT INTO fts_test (title,body) VALUES # column already exists. This has not been implemented yet. --error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY, LOCK=NONE; +if ($MTR_COMBINATION_ORIG) { ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body), ALGORITHM=NOCOPY; +} +if (!$MTR_COMBINATION_ORIG) { +--enable_info +ALTER TABLE fts_test ADD FULLTEXT `idx` (title, body); +--disable_info +} --error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON ALTER TABLE fts_test ROW_FORMAT=REDUNDANT, ALGORITHM=INPLACE, LOCK=NONE; @@ -349,8 +372,14 @@ let $fts_aux_file= `select concat('FTS_',right(concat(repeat('0',16), lower(hex( write_file $MYSQLD_DATADIR/test/$fts_aux_file; EOF --replace_regex /".*" from/"Resource temporarily unavailable" from/ +if ($MTR_COMBINATION_ORIG) { --error ER_GET_ERRNO ALTER TABLE t1 ADD FULLTEXT(a), ALGORITHM=INPLACE; +} +if (!$MTR_COMBINATION_ORIG) { +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 ADD FULLTEXT(a), ALGORITHM=INPLACE; +} DROP TABLE t1; remove_file $MYSQLD_DATADIR/test/$fts_aux_file; diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-fic.test b/mysql-test/suite/innodb_fts/t/innodb-fts-fic.test index 2d94c21398c..05855106226 100644 --- a/mysql-test/suite/innodb_fts/t/innodb-fts-fic.test +++ b/mysql-test/suite/innodb_fts/t/innodb-fts-fic.test @@ -211,8 +211,13 @@ INSERT INTO wp (FTS_DOC_ID, title, text) VALUES (1, 'MySQL Tutorial','DBMS stands for DataBase ...'), (2, 'How To Use MySQL Well','After you went through a ...'); +if ($MTR_COMBINATION_ORIG) { --error ER_INNODB_FT_WRONG_DOCID_COLUMN CREATE FULLTEXT INDEX idx ON wp(title, text); +} +if (!$MTR_COMBINATION_ORIG) { +CREATE FULLTEXT INDEX idx ON wp(title, text); +} DROP TABLE wp; CREATE TABLE wp( diff --git a/mysql-test/suite/innodb_fts/t/misc_debug.test b/mysql-test/suite/innodb_fts/t/misc_debug.test index 08581768eec..8e4ec5d9baf 100644 --- a/mysql-test/suite/innodb_fts/t/misc_debug.test +++ b/mysql-test/suite/innodb_fts/t/misc_debug.test @@ -23,8 +23,14 @@ CREATE TABLE articles ( # The newly create dict_index_t should be removed from fts cache SET @saved_debug_dbug = @@SESSION.debug_dbug; SET SESSION debug_dbug="+d,ib_dict_create_index_tree_fail"; +if ($MTR_COMBINATION_ORIG) { --error ER_OUT_OF_RESOURCES CREATE FULLTEXT INDEX idx ON articles(body); +} +if (!$MTR_COMBINATION_ORIG) { +--error ER_CANT_CREATE_TABLE +CREATE FULLTEXT INDEX idx ON articles(body); +} SET SESSION debug_dbug=@saved_debug_dbug; # This simply go through ha_innobase::commit_inplace_alter_table @@ -37,8 +43,14 @@ DROP TABLE articles; CREATE TABLE t (a INT, b TEXT) engine=innodb; SET debug_dbug='+d,alter_table_rollback_new_index'; +if ($MTR_COMBINATION_ORIG) { -- error ER_UNKNOWN_ERROR ALTER TABLE t ADD FULLTEXT INDEX (b(64)); +} +if (!$MTR_COMBINATION_ORIG) { +-- error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t ADD FULLTEXT INDEX (b(64)), ALGORITHM=INPLACE; +} SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t; @@ -57,6 +69,7 @@ ALTER TABLE t1 FORCE; DROP TABLE t2, t1; SET SESSION debug_dbug=@saved_debug_dbug; +if ($MTR_COMBINATION_ORIG) { --echo # --echo # MDEV-25200 Index count mismatch due to aborted FULLTEXT INDEX --echo # @@ -82,6 +95,7 @@ ALTER TABLE t1 ADD bl INT AS (LENGTH(b)) VIRTUAL; CHECK TABLE t1; DROP TABLE t1; --source include/wait_until_count_sessions.inc +} --echo # --echo # MDEV-25663 Double free of transaction during TRUNCATE @@ -104,6 +118,7 @@ SET debug_dbug=@saved_debug_dbug; DROP TABLE t1; --echo # End of 10.3 tests +if ($MTR_COMBINATION_ORIG) { # Fulltext fails in commit phase CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(100))ENGINE=InnoDB; @@ -115,3 +130,4 @@ ALTER TABLE t1 DISCARD TABLESPACE; --error ER_TABLESPACE_DISCARDED ALTER TABLE t1 ADD FULLTEXT(f2); DROP TABLE t1; +} diff --git a/mysql-test/suite/innodb_fts/t/sync.test b/mysql-test/suite/innodb_fts/t/sync.test index 168309a5c92..56b9052a47a 100644 --- a/mysql-test/suite/innodb_fts/t/sync.test +++ b/mysql-test/suite/innodb_fts/t/sync.test @@ -115,7 +115,7 @@ CREATE TABLE t1 ( INSERT INTO t1(title) VALUES('database'); ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect SET debug_dbug = '+d,fts_instrument_sync_debug,fts_write_node_crash'; diff --git a/mysql-test/suite/innodb_fts/t/sync_ddl.test b/mysql-test/suite/innodb_fts/t/sync_ddl.test index 6a16ececa60..9a0451e9d38 100644 --- a/mysql-test/suite/innodb_fts/t/sync_ddl.test +++ b/mysql-test/suite/innodb_fts/t/sync_ddl.test @@ -182,12 +182,13 @@ INSERT INTO t1 (value) VALUES ('collation of latin1_bin to make it case sensitive') ; +--enable_info ALTER TABLE t1 DROP COLUMN id1, ADD COLUMN id2 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, DROP INDEX idx1, - ADD FULLTEXT INDEX idx2(value), - ALGORITHM=INPLACE; + ADD FULLTEXT INDEX idx2(value); +--disable_info DROP TABLE t1; diff --git a/mysql-test/suite/innodb_gis/t/rollback.test b/mysql-test/suite/innodb_gis/t/rollback.test index ec6da015c16..8483b3569d8 100644 --- a/mysql-test/suite/innodb_gis/t/rollback.test +++ b/mysql-test/suite/innodb_gis/t/rollback.test @@ -463,7 +463,7 @@ rollback; # Test partial update rollback after recovered. # Crash the server in partial update. ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect set session debug_dbug="+d,row_mysql_crash_if_error"; --error 2013 update t1 set a=point(5,5), b=point(5,5), c=5 where i < 3; diff --git a/mysql-test/suite/innodb_zip/t/innochecksum_2.test b/mysql-test/suite/innodb_zip/t/innochecksum_2.test index 1743bd4a1eb..f6b0e5de252 100644 --- a/mysql-test/suite/innodb_zip/t/innochecksum_2.test +++ b/mysql-test/suite/innodb_zip/t/innochecksum_2.test @@ -9,11 +9,6 @@ --source include/not_embedded.inc -- source include/big_test.inc ---disable_query_log -# This warning occurs due to small buffer pool size(i.e. 8MB). It doesn't occur -# with --mysqld=--innodb_buffer_pool_size=10MB -call mtr.add_suppression("\\[Warning\\] InnoDB: Difficult to find free blocks in the buffer pool.*"); ---enable_query_log let MYSQLD_BASEDIR= `SELECT @@basedir`; let MYSQLD_DATADIR= `SELECT @@datadir`; let SEARCH_FILE= $MYSQLTEST_VARDIR/log/my_restart.err; diff --git a/mysql-test/suite/innodb_zip/t/restart.test b/mysql-test/suite/innodb_zip/t/restart.test index 644496d70d6..18c90eff393 100644 --- a/mysql-test/suite/innodb_zip/t/restart.test +++ b/mysql-test/suite/innodb_zip/t/restart.test @@ -404,13 +404,13 @@ SHOW CREATE TABLE t77_restart; --echo # Moving tablespace 't4_restart' from MYSQL_DATA_DIR to MYSQL_TMP_DIR/new_dir --copy_file $MYSQL_DATA_DIR/test/t4_restart.ibd $MYSQL_TMP_DIR/new_dir/test/t4_restart.ibd --remove_file $MYSQL_DATA_DIR/test/t4_restart.ibd ---exec echo $MYSQL_TMP_DIR/new_dir/test/t4_restart.ibd > $MYSQL_DATA_DIR/test/t4_restart.isl +--write_line $MYSQL_TMP_DIR/new_dir/test/t4_restart.ibd $MYSQL_DATA_DIR/test/t4_restart.isl --echo # Moving tablespace 't55_restart' from MYSQL_TMP_DIR/alt_dir to MYSQL_TMP_DIR/new_dir --copy_file $MYSQL_TMP_DIR/alt_dir/test/t55_restart.ibd $MYSQL_TMP_DIR/new_dir/test/t55_restart.ibd --remove_file $MYSQL_TMP_DIR/alt_dir/test/t55_restart.ibd --remove_file $MYSQL_DATA_DIR/test/t55_restart.isl ---exec echo $MYSQL_TMP_DIR/new_dir/test/t55_restart.ibd > $MYSQL_DATA_DIR/test/t55_restart.isl +--write_line $MYSQL_TMP_DIR/new_dir/test/t55_restart.ibd $MYSQL_DATA_DIR/test/t55_restart.isl --echo # Moving tablespace 't66_restart' from MYSQL_TMP_DIR/alt_dir to MYSQL_TMP_DIR/new_dir --copy_file $MYSQL_TMP_DIR/alt_dir/test/t66_restart#P#p0.ibd $MYSQL_TMP_DIR/new_dir/test/t66_restart#P#p0.ibd @@ -422,9 +422,9 @@ SHOW CREATE TABLE t77_restart; --remove_file $MYSQL_DATA_DIR/test/t66_restart#P#p0.isl --remove_file $MYSQL_DATA_DIR/test/t66_restart#P#p1.isl --remove_file $MYSQL_DATA_DIR/test/t66_restart#P#p2.isl ---exec echo $MYSQL_TMP_DIR/new_dir/test/t66_restart#P#p0.ibd > $MYSQL_DATA_DIR/test/t66_restart#P#p0.isl ---exec echo $MYSQL_TMP_DIR/new_dir/test/t66_restart#P#p1.ibd > $MYSQL_DATA_DIR/test/t66_restart#P#p1.isl ---exec echo $MYSQL_TMP_DIR/new_dir/test/t66_restart#P#p2.ibd > $MYSQL_DATA_DIR/test/t66_restart#P#p2.isl +--write_line $MYSQL_TMP_DIR/new_dir/test/t66_restart#P#p0.ibd $MYSQL_DATA_DIR/test/t66_restart#P#p0.isl +--write_line $MYSQL_TMP_DIR/new_dir/test/t66_restart#P#p1.ibd $MYSQL_DATA_DIR/test/t66_restart#P#p1.isl +--write_line $MYSQL_TMP_DIR/new_dir/test/t66_restart#P#p2.ibd $MYSQL_DATA_DIR/test/t66_restart#P#p2.isl --echo # Moving tablespace 't77_restart' from MYSQL_TMP_DIR/alt_dir to MYSQL_TMP_DIR/new_dir --copy_file $MYSQL_TMP_DIR/alt_dir/test/t77_restart#P#p0#SP#s0.ibd $MYSQL_TMP_DIR/new_dir/test/t77_restart#P#p0#SP#s0.ibd @@ -439,10 +439,10 @@ SHOW CREATE TABLE t77_restart; --remove_file $MYSQL_DATA_DIR/test/t77_restart#P#p0#SP#s1.isl --remove_file $MYSQL_DATA_DIR/test/t77_restart#P#p1#SP#s2.isl --remove_file $MYSQL_DATA_DIR/test/t77_restart#P#p1#SP#s3.isl ---exec echo $MYSQL_TMP_DIR/new_dir/test/t77_restart#P#p0#SP#s0.ibd > $MYSQL_DATA_DIR/test/t77_restart#P#p0#SP#s0.isl ---exec echo $MYSQL_TMP_DIR/new_dir/test/t77_restart#P#p0#SP#s1.ibd > $MYSQL_DATA_DIR/test/t77_restart#P#p0#SP#s1.isl ---exec echo $MYSQL_TMP_DIR/new_dir/test/t77_restart#P#p1#SP#s2.ibd > $MYSQL_DATA_DIR/test/t77_restart#P#p1#SP#s2.isl ---exec echo $MYSQL_TMP_DIR/new_dir/test/t77_restart#P#p1#SP#s3.ibd > $MYSQL_DATA_DIR/test/t77_restart#P#p1#SP#s3.isl +--write_line $MYSQL_TMP_DIR/new_dir/test/t77_restart#P#p0#SP#s0.ibd $MYSQL_DATA_DIR/test/t77_restart#P#p0#SP#s0.isl +--write_line $MYSQL_TMP_DIR/new_dir/test/t77_restart#P#p0#SP#s1.ibd $MYSQL_DATA_DIR/test/t77_restart#P#p0#SP#s1.isl +--write_line $MYSQL_TMP_DIR/new_dir/test/t77_restart#P#p1#SP#s2.ibd $MYSQL_DATA_DIR/test/t77_restart#P#p1#SP#s2.isl +--write_line $MYSQL_TMP_DIR/new_dir/test/t77_restart#P#p1#SP#s3.ibd $MYSQL_DATA_DIR/test/t77_restart#P#p1#SP#s3.isl --echo ---- MYSQL_DATA_DIR/test --list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test diff --git a/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test b/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test index b5bc2a94f01..97a1909a875 100644 --- a/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test +++ b/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test @@ -75,7 +75,7 @@ SET SESSION debug_dbug="+d,ib_import_before_commit_crash"; SELECT * FROM t1; # Write file to make mysql-test-run.pl start up the server again ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Execute the statement that causes the crash --error 2013 @@ -96,7 +96,7 @@ SET SESSION debug_dbug="+d,ib_import_before_checkpoint_crash"; SELECT COUNT(*) FROM t1; # Don't start up the server right away. ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Execute the statement that causes the crash --error 2013 @@ -113,7 +113,7 @@ EOF --echo # Restart and reconnect to the server --enable_reconnect ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --source include/wait_until_connected_again.inc --disable_reconnect diff --git a/mysql-test/suite/json/r/json_no_table.result b/mysql-test/suite/json/r/json_no_table.result index 375b29d51de..df8ce6f6c5e 100644 --- a/mysql-test/suite/json/r/json_no_table.result +++ b/mysql-test/suite/json/r/json_no_table.result @@ -1002,19 +1002,27 @@ DOUBLE error ER_INVALID_JSON_TEXT_IN_PARAM select json_type(CAST(CAST('2015-01-15' AS DATE) as CHAR CHARACTER SET 'utf8')); json_type(CAST(CAST('2015-01-15' AS DATE) as CHAR CHARACTER SET 'utf8')) -INTEGER +NULL +Warnings: +Warning 4038 Syntax error in JSON text in argument 1 to function 'json_type' at position 5 # ---------------------------------------------------------------------- # Test of json_compact(literal) # ---------------------------------------------------------------------- select json_type(json_compact(cast('2014-11-25 18:00' as datetime))); json_type(json_compact(cast('2014-11-25 18:00' as datetime))) -INTEGER +NULL +Warnings: +Warning 4038 Syntax error in JSON text in argument 1 to function 'json_type' at position 5 select json_type(json_compact(cast('2014-11-25' as date))); json_type(json_compact(cast('2014-11-25' as date))) -INTEGER +NULL +Warnings: +Warning 4038 Syntax error in JSON text in argument 1 to function 'json_type' at position 5 select json_type(json_compact(cast('18:00:59' as time))); json_type(json_compact(cast('18:00:59' as time))) -INTEGER +NULL +Warnings: +Warning 4038 Syntax error in JSON text in argument 1 to function 'json_type' at position 3 select json_type(json_compact(127)); json_type(json_compact(127)) INTEGER @@ -1064,7 +1072,9 @@ json_type(json_compact(3.14E30)) DOUBLE select json_type(json_compact(cast('10101abcde' as binary))); json_type(json_compact(cast('10101abcde' as binary))) -INTEGER +NULL +Warnings: +Warning 4038 Syntax error in JSON text in argument 1 to function 'json_type' at position 6 select json_type(json_compact(ST_GeomFromText('POINT(1 1)'))); json_type(json_compact(ST_GeomFromText('POINT(1 1)'))) NULL diff --git a/mysql-test/suite/json/r/type_json.result b/mysql-test/suite/json/r/type_json.result index 333e933eda9..44e14978934 100644 --- a/mysql-test/suite/json/r/type_json.result +++ b/mysql-test/suite/json/r/type_json.result @@ -2880,5 +2880,13 @@ DROP PROCEDURE p1; DROP PROCEDURE p2; DROP TABLE t1, t1c, t2; # +# MDEV-30646 View created via JSON_ARRAYAGG returns incorrect json object +# +CREATE VIEW v1 AS SELECT JSON_OBJECT('plugin','unix_socket') as v1_json; +SELECT JSON_ARRAYAGG(v1_json) FROM v1; +JSON_ARRAYAGG(v1_json) +[{"plugin": "unix_socket"}] +DROP VIEW v1; +# # End of 10.5 tests # diff --git a/mysql-test/suite/json/t/type_json.test b/mysql-test/suite/json/t/type_json.test index f84bef780c3..03236070c8e 100644 --- a/mysql-test/suite/json/t/type_json.test +++ b/mysql-test/suite/json/t/type_json.test @@ -138,6 +138,15 @@ DROP PROCEDURE p2; DROP TABLE t1, t1c, t2; +--echo # +--echo # MDEV-30646 View created via JSON_ARRAYAGG returns incorrect json object +--echo # + +CREATE VIEW v1 AS SELECT JSON_OBJECT('plugin','unix_socket') as v1_json; +SELECT JSON_ARRAYAGG(v1_json) FROM v1; +DROP VIEW v1; + + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/suite/large_tests/r/maria_recover_encrypted.result b/mysql-test/suite/large_tests/r/maria_recover_encrypted.result index a7293d45db6..fb7f1ef1c2f 100644 --- a/mysql-test/suite/large_tests/r/maria_recover_encrypted.result +++ b/mysql-test/suite/large_tests/r/maria_recover_encrypted.result @@ -36,7 +36,7 @@ CALL proc_insert_many(); UNLOCK TABLES; SET debug_dbug="d,crash_shutdown"; shutdown; -ERROR HY000: Lost connection to MySQL server during query +ERROR HY000: Lost connection to server during query SELECT * FROM t1 ORDER BY 1 DESC LIMIT 10; field1 field2 field3 1069999 2069999 3069999 diff --git a/mysql-test/suite/large_tests/t/maria_recover_encrypted.test b/mysql-test/suite/large_tests/t/maria_recover_encrypted.test index 4c590e5e1f9..1064c2c0884 100644 --- a/mysql-test/suite/large_tests/t/maria_recover_encrypted.test +++ b/mysql-test/suite/large_tests/t/maria_recover_encrypted.test @@ -3,6 +3,8 @@ --source include/have_maria.inc --source include/default_charset.inc +--source include/not_embedded.inc +--source include/have_debug.inc # Cleanup --disable_warnings @@ -13,7 +15,7 @@ DROP PROCEDURE IF EXISTS proc_insert_many; # -------- # Configure encryption ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc @@ -21,7 +23,7 @@ DROP PROCEDURE IF EXISTS proc_insert_many; 1;76025E3ADC78D74819927DB02AAA4C35 EOF ---exec echo "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/key.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/key.txt" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc @@ -73,7 +75,7 @@ CALL proc_insert_many(); UNLOCK TABLES; # Crash and restart the server while it's still flushing index ---exec echo "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/key.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/key.txt" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect SET debug_dbug="d,crash_shutdown"; --error 2013 shutdown; diff --git a/mysql-test/suite/maria/alter.result b/mysql-test/suite/maria/alter.result index cc035426745..17164343163 100644 --- a/mysql-test/suite/maria/alter.result +++ b/mysql-test/suite/maria/alter.result @@ -193,3 +193,29 @@ ALTER TABLE t1 DISABLE KEYS; INSERT INTO t1 VALUES (1, 'Nine chars or more'); ALTER TABLE t1 ENABLE KEYS; DROP TABLE t1; +# +# MDEV-25923 Memory not freed or Assertion `old_flags == ((my_flags & +# 0x10000U) ? 1 : 0)' failed in my_realloc upon ALTER on Aria table +# with GIS column +# +CREATE TABLE t1 (pk INT PRIMARY KEY, a POINT DEFAULT ST_GEOMFROMTEXT('Point(1 1)')) ENGINE=Aria; +INSERT INTO t1 (pk) SELECT seq FROM seq_1_to_100; +SET @old_threads= @@SESSION.aria_repair_threads; +SET SESSION aria_repair_threads= 2; +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +DROP TABLE t1; +# +# MDEV-33562: Assertion `(old_flags & 1) == ((my_flags & 0x10000U) ? +# 1 : 0)' failed in my_realloc from sort_get_next_record on INSERT +# +SET @old_mode= @@SESSION.sql_mode; +SET sql_mode=''; +CREATE TEMPORARY TABLE t (b TEXT, INDEX s(b(300))) ROW_FORMAT=DYNAMIC ENGINE=Aria; +INSERT INTO t VALUES (REPEAT ('a',10000000)); +Warnings: +Warning 1265 Data truncated for column 'b' at row 1 +CREATE TABLE ti LIKE t; +INSERT INTO ti SELECT * FROM t; +DROP TABLE t, ti; +SET SESSION aria_repair_threads= @old_threads; +SET SESSION sql_mode= @old_mode; diff --git a/mysql-test/suite/maria/alter.test b/mysql-test/suite/maria/alter.test index 525cd80f3d9..a68b5f2e0d7 100644 --- a/mysql-test/suite/maria/alter.test +++ b/mysql-test/suite/maria/alter.test @@ -203,3 +203,31 @@ ALTER TABLE t1 DISABLE KEYS; INSERT INTO t1 VALUES (1, 'Nine chars or more'); ALTER TABLE t1 ENABLE KEYS; DROP TABLE t1; + +--echo # +--echo # MDEV-25923 Memory not freed or Assertion `old_flags == ((my_flags & +--echo # 0x10000U) ? 1 : 0)' failed in my_realloc upon ALTER on Aria table +--echo # with GIS column +--echo # + +CREATE TABLE t1 (pk INT PRIMARY KEY, a POINT DEFAULT ST_GEOMFROMTEXT('Point(1 1)')) ENGINE=Aria; +INSERT INTO t1 (pk) SELECT seq FROM seq_1_to_100; +SET @old_threads= @@SESSION.aria_repair_threads; +SET SESSION aria_repair_threads= 2; +ALTER TABLE t1 ROW_FORMAT=DYNAMIC; +DROP TABLE t1; + +--echo # +--echo # MDEV-33562: Assertion `(old_flags & 1) == ((my_flags & 0x10000U) ? +--echo # 1 : 0)' failed in my_realloc from sort_get_next_record on INSERT +--echo # + +SET @old_mode= @@SESSION.sql_mode; +SET sql_mode=''; +CREATE TEMPORARY TABLE t (b TEXT, INDEX s(b(300))) ROW_FORMAT=DYNAMIC ENGINE=Aria; +INSERT INTO t VALUES (REPEAT ('a',10000000)); +CREATE TABLE ti LIKE t; +INSERT INTO ti SELECT * FROM t; +DROP TABLE t, ti; +SET SESSION aria_repair_threads= @old_threads; +SET SESSION sql_mode= @old_mode; diff --git a/mysql-test/suite/maria/bulk_insert_crash.test b/mysql-test/suite/maria/bulk_insert_crash.test index d9167c3f0d7..04f3a148ad4 100644 --- a/mysql-test/suite/maria/bulk_insert_crash.test +++ b/mysql-test/suite/maria/bulk_insert_crash.test @@ -12,7 +12,7 @@ # # Write file to make mysql-test-run.pl expect crash and restart ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect create table t1 (a int primary key, b int, c int, unique key(b), key(c)) engine=aria transactional=1; insert into t1 values (1000,1000,1000); diff --git a/mysql-test/suite/maria/encrypt-no-key.test b/mysql-test/suite/maria/encrypt-no-key.test index 457441226cc..e1d674097bf 100644 --- a/mysql-test/suite/maria/encrypt-no-key.test +++ b/mysql-test/suite/maria/encrypt-no-key.test @@ -29,10 +29,10 @@ CREATE TABLE t1 (a INT KEY,b INT,KEY(b)) ENGINE=Aria; --echo # Restart with encryption enabled ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc ---exec echo "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc @@ -43,10 +43,10 @@ LOAD INDEX INTO CACHE t1; # Restart without encryption. Above table should be unreadable ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc ---exec echo "restart:--aria-encrypt-tables=0" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart:--aria-encrypt-tables=0" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc diff --git a/mysql-test/suite/maria/encrypt-wrong-key.test b/mysql-test/suite/maria/encrypt-wrong-key.test index ac060c4e9dd..274a165ca4d 100644 --- a/mysql-test/suite/maria/encrypt-wrong-key.test +++ b/mysql-test/suite/maria/encrypt-wrong-key.test @@ -9,7 +9,7 @@ call mtr.add_suppression("System key id 1 is missing"); call mtr.add_suppression("Unknown key id 1"); call mtr.add_suppression("Initialization of encryption failed.*"); ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc @@ -17,14 +17,14 @@ call mtr.add_suppression("Initialization of encryption failed.*"); 1;770A8A65DA156D24EE2A093277530142 EOF ---exec echo "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc CREATE TABLE t1 (i INT, KEY(i)) ENGINE=Aria; INSERT INTO t1 VALUES (1); ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc @@ -32,7 +32,7 @@ INSERT INTO t1 VALUES (1); 2;770A8A65DA156D24EE2A093277530143 EOF ---exec echo "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys2.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys2.txt" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc @@ -43,11 +43,11 @@ repair table t1; --error HA_ERR_NO_ENCRYPTION INSERT INTO t1 VALUES (2); ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server --source include/wait_until_disconnected.inc ---exec echo "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc diff --git a/mysql-test/suite/maria/ps_maria.result b/mysql-test/suite/maria/ps_maria.result index 5c128a32dd1..3f806c43dbd 100644 --- a/mysql-test/suite/maria/ps_maria.result +++ b/mysql-test/suite/maria/ps_maria.result @@ -1798,7 +1798,7 @@ t5 CREATE TABLE `t5` ( `param09` longtext DEFAULT NULL, `const10` bigint(17) DEFAULT NULL, `param10` bigint(20) DEFAULT NULL, - `const11` int(4) DEFAULT NULL, + `const11` int(5) DEFAULT NULL, `param11` bigint(20) DEFAULT NULL, `const12` binary(0) DEFAULT NULL, `param12` bigint(20) DEFAULT NULL, @@ -1828,7 +1828,7 @@ def test t5 t5 const09 const09 12 19 19 Y 128 0 63 def test t5 t5 param09 param09 252 4294967295 19 Y 16 0 8 def test t5 t5 const10 const10 8 17 9 Y 32768 0 63 def test t5 t5 param10 param10 8 20 9 Y 32768 0 63 -def test t5 t5 const11 const11 3 4 4 Y 32768 0 63 +def test t5 t5 const11 const11 3 5 4 Y 32768 0 63 def test t5 t5 param11 param11 8 20 4 Y 32768 0 63 def test t5 t5 const12 const12 254 0 0 Y 128 0 63 def test t5 t5 param12 param12 8 20 0 Y 32768 0 63 diff --git a/mysql-test/suite/maria/repair.result b/mysql-test/suite/maria/repair.result index 458b5503602..7905cb02f28 100644 --- a/mysql-test/suite/maria/repair.result +++ b/mysql-test/suite/maria/repair.result @@ -62,3 +62,26 @@ SET SESSION aria_sort_buffer_size=default; # # End of 10.3 tests # +# +# MDEV-34055 Assertion `readbytes != (size_t)-1 || +# (*__errno_location ()) != 9' failure or corruption errors upon +# REPAIR on Aria tables +# +CREATE OR REPLACE TABLE t1 (a INT, b INT, UNIQUE(b), UNIQUE(a)) ENGINE=Aria; +INSERT INTO t1 VALUES (1,2); +REPAIR TABLE t1 EXTENDED QUICK USE_FRM; +Table Op Msg_type Msg_text +test.t1 repair warning Number of rows changed from 0 to 1 +test.t1 repair status OK +CREATE TABLE t2 (c INT) ENGINE=Aria; +SELECT * FROM t2; +c +REPLACE INTO t1 VALUES (1,3); +REPAIR TABLE t2, t1 QUICK; +Table Op Msg_type Msg_text +test.t2 repair status OK +test.t1 repair status OK +DROP TABLE t1, t2; +# +# End of 10.5 tests +# diff --git a/mysql-test/suite/maria/repair.test b/mysql-test/suite/maria/repair.test index 688ac076e1d..08234a5a546 100644 --- a/mysql-test/suite/maria/repair.test +++ b/mysql-test/suite/maria/repair.test @@ -74,3 +74,22 @@ SET SESSION aria_sort_buffer_size=default; --echo # --echo # End of 10.3 tests --echo # + +--echo # +--echo # MDEV-34055 Assertion `readbytes != (size_t)-1 || +--echo # (*__errno_location ()) != 9' failure or corruption errors upon +--echo # REPAIR on Aria tables +--echo # + +CREATE OR REPLACE TABLE t1 (a INT, b INT, UNIQUE(b), UNIQUE(a)) ENGINE=Aria; +INSERT INTO t1 VALUES (1,2); +REPAIR TABLE t1 EXTENDED QUICK USE_FRM; +CREATE TABLE t2 (c INT) ENGINE=Aria; +SELECT * FROM t2; +REPLACE INTO t1 VALUES (1,3); +REPAIR TABLE t2, t1 QUICK; +DROP TABLE t1, t2; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/suite/mariabackup/absolute_ibdata_paths.test b/mysql-test/suite/mariabackup/absolute_ibdata_paths.test index fa304f0bc55..f4d0e2a5bd5 100644 --- a/mysql-test/suite/mariabackup/absolute_ibdata_paths.test +++ b/mysql-test/suite/mariabackup/absolute_ibdata_paths.test @@ -30,7 +30,7 @@ let $_innodb_data_file_path=`select @@innodb_data_file_path`; let $_innodb_data_home_dir=`select @@innodb_data_home_dir`; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; --enable_result_log exec $XTRABACKUP --prepare --target-dir=$targetdir; diff --git a/mysql-test/suite/mariabackup/alter_copy_race.result b/mysql-test/suite/mariabackup/alter_copy_race.result index 82202249f81..ae58ac28881 100644 --- a/mysql-test/suite/mariabackup/alter_copy_race.result +++ b/mysql-test/suite/mariabackup/alter_copy_race.result @@ -4,7 +4,7 @@ INSERT into t1 values(1); connect con2, localhost, root,,; connection con2; set lock_wait_timeout=1; -SET debug_sync='copy_data_between_tables_before_reset_backup_lock SIGNAL go WAIT_FOR after_backup_stage_block_commit'; +SET debug_sync='copy_data_between_tables_before_reset_backup_lock SIGNAL go WAIT_FOR after_backup_stage_block_ddl'; SET debug_sync='alter_table_after_temp_table_drop SIGNAL temp_table_dropped'; SET debug_sync='now WAIT_FOR after_backup_stage_start';ALTER TABLE test.t1 FORCE, algorithm=COPY;| connection default; diff --git a/mysql-test/suite/mariabackup/alter_copy_race.test b/mysql-test/suite/mariabackup/alter_copy_race.test index 553643bf667..cfabd76c513 100644 --- a/mysql-test/suite/mariabackup/alter_copy_race.test +++ b/mysql-test/suite/mariabackup/alter_copy_race.test @@ -18,7 +18,7 @@ INSERT into t1 values(1); connect con2, localhost, root,,; connection con2; set lock_wait_timeout=1; -SET debug_sync='copy_data_between_tables_before_reset_backup_lock SIGNAL go WAIT_FOR after_backup_stage_block_commit'; +SET debug_sync='copy_data_between_tables_before_reset_backup_lock SIGNAL go WAIT_FOR after_backup_stage_block_ddl'; SET debug_sync='alter_table_after_temp_table_drop SIGNAL temp_table_dropped'; DELIMITER |; send SET debug_sync='now WAIT_FOR after_backup_stage_start';ALTER TABLE test.t1 FORCE, algorithm=COPY;| @@ -27,7 +27,7 @@ connection default; # setup mariabackup events let after_backup_stage_start=SET debug_sync='now SIGNAL after_backup_stage_start WAIT_FOR go'; -let after_backup_stage_block_commit=SET debug_sync='now SIGNAL after_backup_stage_block_commit'; +let after_backup_stage_block_ddl=SET debug_sync='now SIGNAL after_backup_stage_block_ddl'; let backup_fix_ddl=SET debug_sync='now WAIT_FOR temp_table_dropped'; --disable_result_log exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events; diff --git a/mysql-test/suite/mariabackup/apply-log-only-incr.test b/mysql-test/suite/mariabackup/apply-log-only-incr.test index 01b74af2211..1da2be090d6 100644 --- a/mysql-test/suite/mariabackup/apply-log-only-incr.test +++ b/mysql-test/suite/mariabackup/apply-log-only-incr.test @@ -19,7 +19,7 @@ dec $n; } --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$basedir; --enable_result_log let $n=100; while ($n) { @@ -36,7 +36,7 @@ disconnect flush_log; connection default; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --ftwrl-wait-timeout=5 --ftwrl-wait-threshold=300 --ftwrl-wait-query-type=all --target-dir=$incremental_dir --incremental-basedir=$basedir ; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --ftwrl-wait-timeout=5 --ftwrl-wait-threshold=300 --ftwrl-wait-query-type=all --target-dir=$incremental_dir --incremental-basedir=$basedir ; exec $XTRABACKUP --prepare --verbose --target-dir=$basedir ; --enable_result_log diff --git a/mysql-test/suite/mariabackup/apply-log-only.test b/mysql-test/suite/mariabackup/apply-log-only.test index 7ffed0719f0..dbae77b7c9a 100644 --- a/mysql-test/suite/mariabackup/apply-log-only.test +++ b/mysql-test/suite/mariabackup/apply-log-only.test @@ -8,7 +8,7 @@ start transaction; INSERT INTO t VALUES(1); --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$basedir; --enable_result_log exec $XTRABACKUP --prepare --target-dir=$basedir ; diff --git a/mysql-test/suite/mariabackup/aria_backup.opt b/mysql-test/suite/mariabackup/aria_backup.opt new file mode 100644 index 00000000000..3565e3f1023 --- /dev/null +++ b/mysql-test/suite/mariabackup/aria_backup.opt @@ -0,0 +1 @@ +--loose-partition --loose-aria-log-file-size=8388608 diff --git a/mysql-test/suite/mariabackup/aria_backup.result b/mysql-test/suite/mariabackup/aria_backup.result new file mode 100644 index 00000000000..e8c73f0ab1e --- /dev/null +++ b/mysql-test/suite/mariabackup/aria_backup.result @@ -0,0 +1,780 @@ +### +# Test for backup to stream +##### +### +# Test for mix of online/offline backup tables +##### +CREATE TABLE t_default(i INT PRIMARY KEY) +ENGINE ARIA; +INSERT INTO t_default VALUES (1); +CREATE TABLE t_tr_p_ch(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_tr_p_ch VALUES (1); +CREATE TABLE t_tr_p_nch(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=0; +INSERT INTO t_tr_p_nch VALUES (1); +CREATE TABLE t_p_ch(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=0 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_p_ch VALUES (1); +CREATE TABLE t_p_nch(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=0 ROW_FORMAT=PAGE PAGE_CHECKSUM=0; +INSERT INTO t_p_nch VALUES (1); +CREATE TABLE t_fixed(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=0 ROW_FORMAT=FIXED PAGE_CHECKSUM=1; +INSERT INTO t_fixed VALUES (1); +CREATE TABLE t_dyn(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=0 ROW_FORMAT=DYNAMIC PAGE_CHECKSUM=1; +INSERT INTO t_dyn VALUES (1); +# Test for partitioned table +CREATE TABLE t_part_online(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL = 1 PAGE_CHECKSUM = 1 +PARTITION BY RANGE( i ) ( +PARTITION p0 VALUES LESS THAN (10), +PARTITION p1 VALUES LESS THAN (20), +PARTITION p2 VALUES LESS THAN (30) +); +INSERT INTO t_part_online VALUES(5); +INSERT INTO t_part_online VALUES(15); +INSERT INTO t_part_online VALUES(25); +SELECT * FROM t_part_online; +i +5 +15 +25 +CREATE TABLE t_part_offline(i INT) +ENGINE ARIA TRANSACTIONAL = 0 PAGE_CHECKSUM = 0 +PARTITION BY RANGE( i ) ( +PARTITION p0 VALUES LESS THAN (10), +PARTITION p1 VALUES LESS THAN (20), +PARTITION p2 VALUES LESS THAN (30) +); +INSERT INTO t_part_offline VALUES(5); +INSERT INTO t_part_offline VALUES(15); +INSERT INTO t_part_offline VALUES(25); +# Test for filename to tablename mapping +CREATE TABLE `t 1 t-1`(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO `t 1 t-1` VALUES (1); +CREATE TABLE `t-part online`(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL = 1 PAGE_CHECKSUM = 1 +PARTITION BY RANGE( i ) ( +PARTITION p0 VALUES LESS THAN (10), +PARTITION p1 VALUES LESS THAN (20), +PARTITION p2 VALUES LESS THAN (30) +); +INSERT INTO `t-part online` VALUES(5); +INSERT INTO `t-part online` VALUES(15); +INSERT INTO `t-part online` VALUES(25); +### +# Test for redo log files backup; +##### +CREATE TABLE t_logs_1(i INT) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +CREATE TABLE t_logs_2 LIKE t_logs_1; +CREATE TABLE t_bulk_ins LIKE t_logs_1; +INSERT INTO t_logs_1 VALUES +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9); +# Generate several log files +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +### +# Test for DML during backup for online backup +##### +CREATE TABLE t_dml_ins(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_dml_ins VALUES(1); +CREATE TABLE t_dml_upd(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_dml_upd VALUES(1); +CREATE TABLE t_dml_del(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_dml_del VALUES(1); +### +# Test for DDL during backup for online backup +##### +CREATE DATABASE test_for_db_drop; +CREATE TABLE test_for_db_drop.t(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_db_create(i INT PRIMARY KEY) ENGINE ARIA; +SHOW DATABASES; +Database +information_schema +mtr +mysql +performance_schema +sys +test +test_for_db_drop +CREATE TABLE t_alter(i INT PRIMARY KEY) ENGINE ARIA; +INSERT INTO t_alter VALUES (1); +CREATE TABLE t_trunc(i INT PRIMARY KEY) ENGINE ARIA; +INSERT INTO t_trunc VALUES (1); +CREATE TABLE t_ch_i (i int(10), index(i) ) ENGINE=Aria; +INSERT INTO t_ch_i VALUES(1); +CREATE TABLE t_change_engine(i INT PRIMARY KEY) ENGINE InnoDB; +INSERT INTO t_change_engine VALUES (1); +CREATE TABLE t_rename(i INT PRIMARY KEY) ENGINE ARIA; +CREATE DATABASE test_for_rename; +CREATE TABLE t_rename_2(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_rename_3(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_rename_4(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_delete(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_delete_2(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_rename_alter(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_rename_create(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_part_create(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_part_add_part(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_part_change_eng(i INT PRIMARY KEY) ENGINE ARIA PARTITION BY HASH(i) PARTITIONS 2; +CREATE TABLE t_part_change_eng_2(i INT PRIMARY KEY) ENGINE InnoDB PARTITION BY HASH(i) PARTITIONS 2; +CREATE TABLE t_part_change_eng_3(i INT PRIMARY KEY) ENGINE Aria; +CREATE TABLE t_part_alter(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +CREATE TABLE t_part_alter_2(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 3; +CREATE TABLE t_part_drop(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +CREATE TABLE t_part_rename(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +CREATE TABLE t_part_rename_3(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +CREATE TABLE t_part_rm_part(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +SET SESSION debug_dbug="+d,maria_flush_whole_log"; +SET GLOBAL aria_checkpoint_interval=10000; +### Backup to stream +# xtrabackup prepare +# shutdown server +# remove datadir +# xtrabackup move back +# restart +### Result for DDL test +SHOW CREATE TABLE t_alter; +Table Create Table +t_alter CREATE TABLE `t_alter` ( + `i` int(11) NOT NULL, + `c` int(11) DEFAULT NULL, + PRIMARY KEY (`i`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +SELECT * FROM t_alter; +i c +1 NULL +SHOW CREATE TABLE t_change_engine; +Table Create Table +t_change_engine CREATE TABLE `t_change_engine` ( + `i` int(11) NOT NULL, + PRIMARY KEY (`i`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +SELECT * FROM t_change_engine; +i +1 +SELECT * FROM t_trunc; +i +1 +SELECT * FROM t_ch_i; +i +1 +SELECT * FROM t_rename_new; +i +SELECT * FROM test_for_rename.t_rename_new_2; +i +SELECT * FROM t_rename_new_new_3; +i +SELECT * FROM t_rename_new_4; +i +SELECT * FROM t_delete; +ERROR 42S02: Table 'test.t_delete' doesn't exist +SHOW CREATE TABLE t_delete_2; +Table Create Table +t_delete_2 CREATE TABLE `t_delete_2` ( + `i` int(11) NOT NULL, + PRIMARY KEY (`i`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +SELECT * FROM t_rename_alter_2; +i c +SELECT * FROM t_rename_create; +d +SELECT * FROM t_rename_create_new; +i +SHOW CREATE TABLE t_part_create_2; +Table Create Table +t_part_create_2 CREATE TABLE `t_part_create_2` ( + `i` int(11) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY HASH (`i`) +PARTITIONS 2 +SELECT * FROM t_part_create_2; +i +SHOW CREATE TABLE t_part_add_part; +Table Create Table +t_part_add_part CREATE TABLE `t_part_add_part` ( + `i` int(11) NOT NULL, + PRIMARY KEY (`i`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 + PARTITION BY HASH (`i`) +PARTITIONS 2 +SELECT * FROM t_part_add_part; +i +SHOW CREATE TABLE t_part_change_eng; +Table Create Table +t_part_change_eng CREATE TABLE `t_part_change_eng` ( + `i` int(11) NOT NULL, + PRIMARY KEY (`i`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY HASH (`i`) +PARTITIONS 2 +SELECT * FROM t_part_change_eng; +i +SHOW CREATE TABLE t_part_change_eng_2; +Table Create Table +t_part_change_eng_2 CREATE TABLE `t_part_change_eng_2` ( + `i` int(11) NOT NULL, + PRIMARY KEY (`i`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY HASH (`i`) +PARTITIONS 2 +SELECT * FROM t_part_change_eng_2; +i +SELECT * FROM t_part_alter; +i c +SHOW CREATE TABLE t_part_alter_2; +Table Create Table +t_part_alter_2 CREATE TABLE `t_part_alter_2` ( + `i` int(11) NOT NULL, + PRIMARY KEY (`i`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY HASH (`i`) +PARTITIONS 2 +SELECT * FROM t_part_alter_2; +i +SELECT * FROM t_part_drop; +ERROR 42S02: Table 'test.t_part_drop' doesn't exist +SELECT * FROM t_part_rename; +ERROR 42S02: Table 'test.t_part_rename' doesn't exist +SELECT * FROM t_part_rename_2; +i +SELECT * FROM t_part_rename_3; +ERROR 42S02: Table 'test.t_part_rename_3' doesn't exist +SELECT * FROM test_for_rename.t_part_rename_4; +i +SHOW CREATE TABLE t_part_rm_part; +Table Create Table +t_part_rm_part CREATE TABLE `t_part_rm_part` ( + `i` int(11) NOT NULL, + `c` int(11) DEFAULT NULL, + PRIMARY KEY (`i`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +SELECT * FROM t_part_rm_part; +i c +SHOW DATABASES; +Database +information_schema +mtr +mysql +performance_schema +sys +test +test_for_db_create +test_for_rename +### Clean up for DDL test +DROP DATABASE test_for_db_create; +DROP TABLE t_db_create; +DROP TABLE t_change_engine; +DROP TABLE t_alter; +DROP TABLE t_trunc; +DROP TABLE t_ch_i; +DROP TABLE t_rename_new; +DROP TABLE t_rename_new_new_3; +DROP TABLE t_rename_new_4; +DROP TABLE t_delete_2; +DROP TABLE t_rename_alter_2; +DROP TABLE t_rename_create; +DROP TABLE t_rename_create_new; +DROP TABLE t_part_create; +DROP TABLE t_part_create_2; +DROP TABLE t_part_add_part; +DROP TABLE t_part_change_eng; +DROP TABLE t_part_change_eng_2; +DROP TABLE t_part_change_eng_3; +DROP TABLE t_part_alter; +DROP TABLE t_part_alter_2; +DROP TABLE t_part_rename_2; +DROP TABLE t_part_rm_part; +DROP DATABASE test_for_rename; +### Result for DML test +SELECT * FROM t_dml_ins; +i +1 +2 +SELECT * FROM t_dml_upd; +i +2 +SELECT * FROM t_dml_del; +i +### Clean up for DML test +DROP TABLE t_dml_ins; +DROP TABLE t_dml_upd; +DROP TABLE t_dml_del; +### Result for redo log files backup +# ok +# ok +# ok +### Cleanup for redo log files backup +DROP TABLE t_logs_1; +DROP TABLE t_logs_2; +DROP TABLE t_bulk_ins; +### Result for online/offline tables test +SELECT * FROM t_default; +i +1 +SELECT * FROM t_tr_p_ch; +i +1 +SELECT * FROM t_tr_p_nch; +i +1 +SELECT * FROM t_p_ch; +i +1 +SELECT * FROM t_p_nch; +i +1 +SELECT * FROM t_fixed; +i +1 +SELECT * FROM t_dyn; +i +1 +SELECT * FROM t_part_online; +i +5 +15 +25 +SELECT * FROM t_part_offline; +i +5 +15 +25 +SELECT * FROM `t 1 t-1`; +i +1 +SELECT * FROM `t-part online`; +i +5 +15 +25 +### Cleanup for online/offline tables test +DROP TABLE t_default; +DROP TABLE t_tr_p_ch; +DROP TABLE t_tr_p_nch; +DROP TABLE t_p_ch; +DROP TABLE t_p_nch; +DROP TABLE t_fixed; +DROP TABLE t_dyn; +DROP TABLE t_part_online; +DROP TABLE t_part_offline; +DROP TABLE `t 1 t-1`; +DROP TABLE `t-part online`; +### +# Test for backup to directory +##### +### +# Test for mix of online/offline backup tables +##### +CREATE TABLE t_default(i INT PRIMARY KEY) +ENGINE ARIA; +INSERT INTO t_default VALUES (1); +CREATE TABLE t_tr_p_ch(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_tr_p_ch VALUES (1); +CREATE TABLE t_tr_p_nch(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=0; +INSERT INTO t_tr_p_nch VALUES (1); +CREATE TABLE t_p_ch(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=0 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_p_ch VALUES (1); +CREATE TABLE t_p_nch(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=0 ROW_FORMAT=PAGE PAGE_CHECKSUM=0; +INSERT INTO t_p_nch VALUES (1); +CREATE TABLE t_fixed(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=0 ROW_FORMAT=FIXED PAGE_CHECKSUM=1; +INSERT INTO t_fixed VALUES (1); +CREATE TABLE t_dyn(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=0 ROW_FORMAT=DYNAMIC PAGE_CHECKSUM=1; +INSERT INTO t_dyn VALUES (1); +# Test for partitioned table +CREATE TABLE t_part_online(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL = 1 PAGE_CHECKSUM = 1 +PARTITION BY RANGE( i ) ( +PARTITION p0 VALUES LESS THAN (10), +PARTITION p1 VALUES LESS THAN (20), +PARTITION p2 VALUES LESS THAN (30) +); +INSERT INTO t_part_online VALUES(5); +INSERT INTO t_part_online VALUES(15); +INSERT INTO t_part_online VALUES(25); +SELECT * FROM t_part_online; +i +5 +15 +25 +CREATE TABLE t_part_offline(i INT) +ENGINE ARIA TRANSACTIONAL = 0 PAGE_CHECKSUM = 0 +PARTITION BY RANGE( i ) ( +PARTITION p0 VALUES LESS THAN (10), +PARTITION p1 VALUES LESS THAN (20), +PARTITION p2 VALUES LESS THAN (30) +); +INSERT INTO t_part_offline VALUES(5); +INSERT INTO t_part_offline VALUES(15); +INSERT INTO t_part_offline VALUES(25); +# Test for filename to tablename mapping +CREATE TABLE `t 1 t-1`(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO `t 1 t-1` VALUES (1); +CREATE TABLE `t-part online`(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL = 1 PAGE_CHECKSUM = 1 +PARTITION BY RANGE( i ) ( +PARTITION p0 VALUES LESS THAN (10), +PARTITION p1 VALUES LESS THAN (20), +PARTITION p2 VALUES LESS THAN (30) +); +INSERT INTO `t-part online` VALUES(5); +INSERT INTO `t-part online` VALUES(15); +INSERT INTO `t-part online` VALUES(25); +### +# Test for redo log files backup; +##### +CREATE TABLE t_logs_1(i INT) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +CREATE TABLE t_logs_2 LIKE t_logs_1; +CREATE TABLE t_bulk_ins LIKE t_logs_1; +INSERT INTO t_logs_1 VALUES +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9); +# Generate several log files +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +### +# Test for DML during backup for online backup +##### +CREATE TABLE t_dml_ins(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_dml_ins VALUES(1); +CREATE TABLE t_dml_upd(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_dml_upd VALUES(1); +CREATE TABLE t_dml_del(i INT PRIMARY KEY) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_dml_del VALUES(1); +### +# Test for DDL during backup for online backup +##### +CREATE DATABASE test_for_db_drop; +CREATE TABLE test_for_db_drop.t(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_db_create(i INT PRIMARY KEY) ENGINE ARIA; +SHOW DATABASES; +Database +information_schema +mtr +mysql +performance_schema +sys +test +test_for_db_drop +CREATE TABLE t_alter(i INT PRIMARY KEY) ENGINE ARIA; +INSERT INTO t_alter VALUES (1); +CREATE TABLE t_trunc(i INT PRIMARY KEY) ENGINE ARIA; +INSERT INTO t_trunc VALUES (1); +CREATE TABLE t_ch_i (i int(10), index(i) ) ENGINE=Aria; +INSERT INTO t_ch_i VALUES(1); +CREATE TABLE t_change_engine(i INT PRIMARY KEY) ENGINE InnoDB; +INSERT INTO t_change_engine VALUES (1); +CREATE TABLE t_rename(i INT PRIMARY KEY) ENGINE ARIA; +CREATE DATABASE test_for_rename; +CREATE TABLE t_rename_2(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_rename_3(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_rename_4(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_delete(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_delete_2(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_rename_alter(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_rename_create(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_part_create(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_part_add_part(i INT PRIMARY KEY) ENGINE ARIA; +CREATE TABLE t_part_change_eng(i INT PRIMARY KEY) ENGINE ARIA PARTITION BY HASH(i) PARTITIONS 2; +CREATE TABLE t_part_change_eng_2(i INT PRIMARY KEY) ENGINE InnoDB PARTITION BY HASH(i) PARTITIONS 2; +CREATE TABLE t_part_change_eng_3(i INT PRIMARY KEY) ENGINE Aria; +CREATE TABLE t_part_alter(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +CREATE TABLE t_part_alter_2(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 3; +CREATE TABLE t_part_drop(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +CREATE TABLE t_part_rename(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +CREATE TABLE t_part_rename_3(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +CREATE TABLE t_part_rm_part(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +SET SESSION debug_dbug="+d,maria_flush_whole_log"; +SET GLOBAL aria_checkpoint_interval=10000; +### Backup to dir +# xtrabackup prepare +# shutdown server +# remove datadir +# xtrabackup move back +# restart +### Result for DDL test +SHOW CREATE TABLE t_alter; +Table Create Table +t_alter CREATE TABLE `t_alter` ( + `i` int(11) NOT NULL, + `c` int(11) DEFAULT NULL, + PRIMARY KEY (`i`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +SELECT * FROM t_alter; +i c +1 NULL +SHOW CREATE TABLE t_change_engine; +Table Create Table +t_change_engine CREATE TABLE `t_change_engine` ( + `i` int(11) NOT NULL, + PRIMARY KEY (`i`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +SELECT * FROM t_change_engine; +i +1 +SELECT * FROM t_trunc; +i +1 +SELECT * FROM t_ch_i; +i +1 +SELECT * FROM t_rename_new; +i +SELECT * FROM test_for_rename.t_rename_new_2; +i +SELECT * FROM t_rename_new_new_3; +i +SELECT * FROM t_rename_new_4; +i +SELECT * FROM t_delete; +ERROR 42S02: Table 'test.t_delete' doesn't exist +SHOW CREATE TABLE t_delete_2; +Table Create Table +t_delete_2 CREATE TABLE `t_delete_2` ( + `i` int(11) NOT NULL, + PRIMARY KEY (`i`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +SELECT * FROM t_rename_alter_2; +i c +SELECT * FROM t_rename_create; +d +SELECT * FROM t_rename_create_new; +i +SHOW CREATE TABLE t_part_create_2; +Table Create Table +t_part_create_2 CREATE TABLE `t_part_create_2` ( + `i` int(11) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY HASH (`i`) +PARTITIONS 2 +SELECT * FROM t_part_create_2; +i +SHOW CREATE TABLE t_part_add_part; +Table Create Table +t_part_add_part CREATE TABLE `t_part_add_part` ( + `i` int(11) NOT NULL, + PRIMARY KEY (`i`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 + PARTITION BY HASH (`i`) +PARTITIONS 2 +SELECT * FROM t_part_add_part; +i +SHOW CREATE TABLE t_part_change_eng; +Table Create Table +t_part_change_eng CREATE TABLE `t_part_change_eng` ( + `i` int(11) NOT NULL, + PRIMARY KEY (`i`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY HASH (`i`) +PARTITIONS 2 +SELECT * FROM t_part_change_eng; +i +SHOW CREATE TABLE t_part_change_eng_2; +Table Create Table +t_part_change_eng_2 CREATE TABLE `t_part_change_eng_2` ( + `i` int(11) NOT NULL, + PRIMARY KEY (`i`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY HASH (`i`) +PARTITIONS 2 +SELECT * FROM t_part_change_eng_2; +i +SELECT * FROM t_part_alter; +i c +SHOW CREATE TABLE t_part_alter_2; +Table Create Table +t_part_alter_2 CREATE TABLE `t_part_alter_2` ( + `i` int(11) NOT NULL, + PRIMARY KEY (`i`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY HASH (`i`) +PARTITIONS 2 +SELECT * FROM t_part_alter_2; +i +SELECT * FROM t_part_drop; +ERROR 42S02: Table 'test.t_part_drop' doesn't exist +SELECT * FROM t_part_rename; +ERROR 42S02: Table 'test.t_part_rename' doesn't exist +SELECT * FROM t_part_rename_2; +i +SELECT * FROM t_part_rename_3; +ERROR 42S02: Table 'test.t_part_rename_3' doesn't exist +SELECT * FROM test_for_rename.t_part_rename_4; +i +SHOW CREATE TABLE t_part_rm_part; +Table Create Table +t_part_rm_part CREATE TABLE `t_part_rm_part` ( + `i` int(11) NOT NULL, + `c` int(11) DEFAULT NULL, + PRIMARY KEY (`i`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +SELECT * FROM t_part_rm_part; +i c +SHOW DATABASES; +Database +information_schema +mtr +mysql +performance_schema +sys +test +test_for_db_create +test_for_rename +### Clean up for DDL test +DROP DATABASE test_for_db_create; +DROP TABLE t_db_create; +DROP TABLE t_change_engine; +DROP TABLE t_alter; +DROP TABLE t_trunc; +DROP TABLE t_ch_i; +DROP TABLE t_rename_new; +DROP TABLE t_rename_new_new_3; +DROP TABLE t_rename_new_4; +DROP TABLE t_delete_2; +DROP TABLE t_rename_alter_2; +DROP TABLE t_rename_create; +DROP TABLE t_rename_create_new; +DROP TABLE t_part_create; +DROP TABLE t_part_create_2; +DROP TABLE t_part_add_part; +DROP TABLE t_part_change_eng; +DROP TABLE t_part_change_eng_2; +DROP TABLE t_part_change_eng_3; +DROP TABLE t_part_alter; +DROP TABLE t_part_alter_2; +DROP TABLE t_part_rename_2; +DROP TABLE t_part_rm_part; +DROP DATABASE test_for_rename; +### Result for DML test +SELECT * FROM t_dml_ins; +i +1 +2 +SELECT * FROM t_dml_upd; +i +2 +SELECT * FROM t_dml_del; +i +### Clean up for DML test +DROP TABLE t_dml_ins; +DROP TABLE t_dml_upd; +DROP TABLE t_dml_del; +### Result for redo log files backup +# ok +# ok +# ok +### Cleanup for redo log files backup +DROP TABLE t_logs_1; +DROP TABLE t_logs_2; +DROP TABLE t_bulk_ins; +### Result for online/offline tables test +SELECT * FROM t_default; +i +1 +SELECT * FROM t_tr_p_ch; +i +1 +SELECT * FROM t_tr_p_nch; +i +1 +SELECT * FROM t_p_ch; +i +1 +SELECT * FROM t_p_nch; +i +1 +SELECT * FROM t_fixed; +i +1 +SELECT * FROM t_dyn; +i +1 +SELECT * FROM t_part_online; +i +5 +15 +25 +SELECT * FROM t_part_offline; +i +5 +15 +25 +SELECT * FROM `t 1 t-1`; +i +1 +SELECT * FROM `t-part online`; +i +5 +15 +25 +### Cleanup for online/offline tables test +DROP TABLE t_default; +DROP TABLE t_tr_p_ch; +DROP TABLE t_tr_p_nch; +DROP TABLE t_p_ch; +DROP TABLE t_p_nch; +DROP TABLE t_fixed; +DROP TABLE t_dyn; +DROP TABLE t_part_online; +DROP TABLE t_part_offline; +DROP TABLE `t 1 t-1`; +DROP TABLE `t-part online`; diff --git a/mysql-test/suite/mariabackup/aria_backup.test b/mysql-test/suite/mariabackup/aria_backup.test new file mode 100644 index 00000000000..b844518bdf1 --- /dev/null +++ b/mysql-test/suite/mariabackup/aria_backup.test @@ -0,0 +1,425 @@ +--source include/have_aria.inc +--source include/have_partition.inc +--source include/have_debug.inc +--source include/big_test.inc +# This test timeouts with msan +--source include/not_msan.inc + +--let $targetdir=$MYSQLTEST_VARDIR/tmp/backup +--let $backup_stream=2 +--let $backup_dir=1 +--let $backup_variant=$backup_stream + +while ($backup_variant) { +if ($backup_variant == $backup_stream) { +--echo ### +--echo # Test for backup to stream +--echo ##### +} +if ($backup_variant == $backup_dir) { +--echo ### +--echo # Test for backup to directory +--echo ##### +} + +--echo ### +--echo # Test for mix of online/offline backup tables +--echo ##### + +CREATE TABLE t_default(i INT PRIMARY KEY) + ENGINE ARIA; +INSERT INTO t_default VALUES (1); + +CREATE TABLE t_tr_p_ch(i INT PRIMARY KEY) + ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_tr_p_ch VALUES (1); + +CREATE TABLE t_tr_p_nch(i INT PRIMARY KEY) + ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=0; +INSERT INTO t_tr_p_nch VALUES (1); + +CREATE TABLE t_p_ch(i INT PRIMARY KEY) + ENGINE ARIA TRANSACTIONAL=0 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_p_ch VALUES (1); + +CREATE TABLE t_p_nch(i INT PRIMARY KEY) + ENGINE ARIA TRANSACTIONAL=0 ROW_FORMAT=PAGE PAGE_CHECKSUM=0; +INSERT INTO t_p_nch VALUES (1); + +CREATE TABLE t_fixed(i INT PRIMARY KEY) + ENGINE ARIA TRANSACTIONAL=0 ROW_FORMAT=FIXED PAGE_CHECKSUM=1; +INSERT INTO t_fixed VALUES (1); + +CREATE TABLE t_dyn(i INT PRIMARY KEY) + ENGINE ARIA TRANSACTIONAL=0 ROW_FORMAT=DYNAMIC PAGE_CHECKSUM=1; +INSERT INTO t_dyn VALUES (1); + +--echo # Test for partitioned table +CREATE TABLE t_part_online(i INT PRIMARY KEY) + ENGINE ARIA TRANSACTIONAL = 1 PAGE_CHECKSUM = 1 + PARTITION BY RANGE( i ) ( + PARTITION p0 VALUES LESS THAN (10), + PARTITION p1 VALUES LESS THAN (20), + PARTITION p2 VALUES LESS THAN (30) + ); + +INSERT INTO t_part_online VALUES(5); +INSERT INTO t_part_online VALUES(15); +INSERT INTO t_part_online VALUES(25); +SELECT * FROM t_part_online; + +CREATE TABLE t_part_offline(i INT) + ENGINE ARIA TRANSACTIONAL = 0 PAGE_CHECKSUM = 0 + PARTITION BY RANGE( i ) ( + PARTITION p0 VALUES LESS THAN (10), + PARTITION p1 VALUES LESS THAN (20), + PARTITION p2 VALUES LESS THAN (30) + ); + +INSERT INTO t_part_offline VALUES(5); +INSERT INTO t_part_offline VALUES(15); +INSERT INTO t_part_offline VALUES(25); + +--echo # Test for filename to tablename mapping +CREATE TABLE `t 1 t-1`(i INT PRIMARY KEY) + ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO `t 1 t-1` VALUES (1); + +CREATE TABLE `t-part online`(i INT PRIMARY KEY) + ENGINE ARIA TRANSACTIONAL = 1 PAGE_CHECKSUM = 1 + PARTITION BY RANGE( i ) ( + PARTITION p0 VALUES LESS THAN (10), + PARTITION p1 VALUES LESS THAN (20), + PARTITION p2 VALUES LESS THAN (30) + ); + +INSERT INTO `t-part online` VALUES(5); +INSERT INTO `t-part online` VALUES(15); +INSERT INTO `t-part online` VALUES(25); + + +--echo ### +--echo # Test for redo log files backup; +--echo ##### +CREATE TABLE t_logs_1(i INT) + ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +CREATE TABLE t_logs_2 LIKE t_logs_1; +CREATE TABLE t_bulk_ins LIKE t_logs_1; +INSERT INTO t_logs_1 VALUES + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9); +--echo # Generate several log files +--let $i = 0 +while ($i < 14) { +INSERT INTO t_logs_1 SELECT * FROM t_logs_1; +--inc $i +} + +--echo ### +--echo # Test for DML during backup for online backup +--echo ##### +CREATE TABLE t_dml_ins(i INT PRIMARY KEY) + ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_dml_ins VALUES(1); +--let after_aria_table_copy_test_t_dml_ins=INSERT INTO test.t_dml_ins VALUES(2) +CREATE TABLE t_dml_upd(i INT PRIMARY KEY) + ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_dml_upd VALUES(1); +--let after_aria_table_copy_test_t_dml_upd=UPDATE test.t_dml_upd SET i = 2 +CREATE TABLE t_dml_del(i INT PRIMARY KEY) + ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +INSERT INTO t_dml_del VALUES(1); +--let after_aria_table_copy_test_t_dml_del=DELETE FROM test.t_dml_del + +--echo ### +--echo # Test for DDL during backup for online backup +--echo ##### +CREATE DATABASE test_for_db_drop; +CREATE TABLE test_for_db_drop.t(i INT PRIMARY KEY) ENGINE ARIA; +--let after_aria_table_copy_test_for_db_drop_t=DROP DATABASE test_for_db_drop +CREATE TABLE t_db_create(i INT PRIMARY KEY) ENGINE ARIA; +--let after_aria_table_copy_test_t_db_create=CREATE DATABASE test_for_db_create +--sorted_result +SHOW DATABASES; + +CREATE TABLE t_alter(i INT PRIMARY KEY) ENGINE ARIA; +INSERT INTO t_alter VALUES (1); +--let after_aria_table_copy_test_t_alter=ALTER TABLE test.t_alter ADD COLUMN c INT + +CREATE TABLE t_trunc(i INT PRIMARY KEY) ENGINE ARIA; +INSERT INTO t_trunc VALUES (1); +--let after_aria_table_copy_test_t_trunc=TRUNCATE TABLE test.t_trunc + +CREATE TABLE t_ch_i (i int(10), index(i) ) ENGINE=Aria; +INSERT INTO t_ch_i VALUES(1); +--let after_aria_table_copy_test_t_ch_i=ALTER TABLE test.t_ch_i DISABLE KEYS + +CREATE TABLE t_change_engine(i INT PRIMARY KEY) ENGINE InnoDB; +INSERT INTO t_change_engine VALUES (1); +--let after_aria_background=begin not atomic ALTER TABLE test.t_change_engine ENGINE = ARIA; INSERT INTO test.t_logs_1 SELECT * FROM test.t_logs_1; INSERT INTO test.t_bulk_ins SELECT * FROM test.t_logs_1; INSERT INTO test.t_logs_2 SET i = 1; end + +CREATE TABLE t_rename(i INT PRIMARY KEY) ENGINE ARIA; +--let after_aria_table_copy_test_t_rename=RENAME TABLE test.t_rename TO test.t_rename_new +CREATE DATABASE test_for_rename; +CREATE TABLE t_rename_2(i INT PRIMARY KEY) ENGINE ARIA; +--let after_aria_table_copy_test_t_rename_2=RENAME TABLE test.t_rename_2 TO test_for_rename.t_rename_new_2 + +CREATE TABLE t_rename_3(i INT PRIMARY KEY) ENGINE ARIA; +--let after_aria_table_copy_test_t_rename_3=begin not atomic RENAME TABLE test.t_rename_3 TO test.t_rename_new_3; RENAME TABLE test.t_rename_new_3 TO test.t_rename_new_new_3; end + +CREATE TABLE t_rename_4(i INT PRIMARY KEY) ENGINE ARIA; +--let after_aria_table_copy_test_t_rename_4=begin not atomic RENAME TABLE test.t_rename_4 TO test.t_rename_new_4; RENAME TABLE test.t_rename_new_4 TO test.t_rename_new_new_4; RENAME TABLE test.t_rename_new_new_4 TO test.t_rename_new_4; end + +CREATE TABLE t_delete(i INT PRIMARY KEY) ENGINE ARIA; +--let after_aria_table_copy_test_t_delete=DROP TABLE test.t_delete + +CREATE TABLE t_delete_2(i INT PRIMARY KEY) ENGINE ARIA; +--let after_aria_table_copy_test_t_delete_2=ALTER TABLE test.t_delete_2 ENGINE=Innodb + +CREATE TABLE t_rename_alter(i INT PRIMARY KEY) ENGINE ARIA; +--let after_aria_table_copy_test_t_rename_alter=begin not atomic RENAME TABLE test.t_rename_alter TO test.t_rename_alter_2; ALTER TABLE test.t_rename_alter_2 ADD COLUMN c INT; end + +CREATE TABLE t_rename_create(i INT PRIMARY KEY) ENGINE ARIA; +--let after_aria_table_copy_test_t_rename_create=begin not atomic RENAME TABLE test.t_rename_create TO test.t_rename_create_new; CREATE TABLE test.t_rename_create(d INT PRIMARY KEY) ENGINE ARIA; end + +CREATE TABLE t_part_create(i INT PRIMARY KEY) ENGINE ARIA; +--let after_aria_table_copy_test_t_part_create=create table test.t_part_create_2 (i int) engine=Aria PARTITION BY HASH(i) PARTITIONS 2 + +CREATE TABLE t_part_add_part(i INT PRIMARY KEY) ENGINE ARIA; +--let after_aria_table_copy_test_t_part_add_part=alter table test.t_part_add_part PARTITION BY HASH(i) PARTITIONS 2 + +CREATE TABLE t_part_change_eng(i INT PRIMARY KEY) ENGINE ARIA PARTITION BY HASH(i) PARTITIONS 2; +--let after_aria_table_copy_test_t_part_change_eng=alter table test.t_part_change_eng ENGINE=InnoDB + +CREATE TABLE t_part_change_eng_2(i INT PRIMARY KEY) ENGINE InnoDB PARTITION BY HASH(i) PARTITIONS 2; +CREATE TABLE t_part_change_eng_3(i INT PRIMARY KEY) ENGINE Aria; +--let after_aria_table_copy_test_t_part_change_eng_3=alter table test.t_part_change_eng_2 ENGINE=Aria + +CREATE TABLE t_part_alter(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +--let after_aria_table_copy_test_t_part_alter=alter table test.t_part_alter ADD COLUMN c INT + +CREATE TABLE t_part_alter_2(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 3; +--let after_aria_table_copy_test_t_part_alter_2=alter table test.t_part_alter_2 COALESCE PARTITION 1 + +CREATE TABLE t_part_drop(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +--let after_aria_table_copy_test_t_part_drop=DROP table test.t_part_drop + +CREATE TABLE t_part_rename(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +--let after_aria_table_copy_test_t_part_rename=RENAME TABLE test.t_part_rename TO test.t_part_rename_2 + +CREATE TABLE t_part_rename_3(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +--let after_aria_table_copy_test_t_part_rename_3=RENAME TABLE test.t_part_rename_3 TO test_for_rename.t_part_rename_4 + +CREATE TABLE t_part_rm_part(i INT PRIMARY KEY) ENGINE Aria PARTITION BY HASH(i) PARTITIONS 2; +--let after_aria_table_copy_test_t_part_rm_part=begin not atomic ALTER TABLE test.t_part_rm_part REMOVE PARTITIONING; ALTER TABLE test.t_part_rm_part ADD COLUMN c INT; end + +SET SESSION debug_dbug="+d,maria_flush_whole_log"; +SET GLOBAL aria_checkpoint_interval=10000; + +--mkdir $targetdir + +if ($backup_variant == $backup_stream) { +--echo ### Backup to stream +--let $streamfile=$MYSQLTEST_VARDIR/tmp/backup.xb +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --dbug=+d,mariabackup_events --stream=xbstream > $streamfile 2>$targetdir/backup_stream.log; +--disable_result_log +exec $XBSTREAM -x -C $targetdir < $streamfile; +--enable_result_log +} + +if ($backup_variant == $backup_dir) { +--echo ### Backup to dir +--disable_result_log +--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --dbug=+d,mariabackup_events +--enable_result_log +} + +--let $t_logs_1_records_count_before_backup=`SELECT COUNT(*) FROM t_logs_1` +--let $t_logs_2_records_count_before_backup=`SELECT COUNT(*) FROM t_logs_2` +--let $t_bulk_ins_records_count_before_backup=`SELECT COUNT(*) FROM t_bulk_ins` + +--echo # xtrabackup prepare +--disable_result_log +--exec $XTRABACKUP --prepare --target-dir=$targetdir +--source include/restart_and_restore.inc +--enable_result_log + +--echo ### Result for DDL test +SHOW CREATE TABLE t_alter; +SELECT * FROM t_alter; +SHOW CREATE TABLE t_change_engine; +SELECT * FROM t_change_engine; +SELECT * FROM t_trunc; +SELECT * FROM t_ch_i; +SELECT * FROM t_rename_new; +SELECT * FROM test_for_rename.t_rename_new_2; +SELECT * FROM t_rename_new_new_3; +SELECT * FROM t_rename_new_4; +--error ER_NO_SUCH_TABLE +SELECT * FROM t_delete; +SHOW CREATE TABLE t_delete_2; +SELECT * FROM t_rename_alter_2; +SELECT * FROM t_rename_create; +SELECT * FROM t_rename_create_new; +SHOW CREATE TABLE t_part_create_2; +SELECT * FROM t_part_create_2; +SHOW CREATE TABLE t_part_add_part; +SELECT * FROM t_part_add_part; +SHOW CREATE TABLE t_part_change_eng; +SELECT * FROM t_part_change_eng; +SHOW CREATE TABLE t_part_change_eng_2; +SELECT * FROM t_part_change_eng_2; +SELECT * FROM t_part_alter; +SHOW CREATE TABLE t_part_alter_2; +SELECT * FROM t_part_alter_2; +--error ER_NO_SUCH_TABLE +SELECT * FROM t_part_drop; +--error ER_NO_SUCH_TABLE +SELECT * FROM t_part_rename; +SELECT * FROM t_part_rename_2; +--error ER_NO_SUCH_TABLE +SELECT * FROM t_part_rename_3; +SELECT * FROM test_for_rename.t_part_rename_4; +SHOW CREATE TABLE t_part_rm_part; +SELECT * FROM t_part_rm_part; +--sorted_result +SHOW DATABASES; + +--echo ### Clean up for DDL test +DROP DATABASE test_for_db_create; +DROP TABLE t_db_create; +DROP TABLE t_change_engine; +DROP TABLE t_alter; +DROP TABLE t_trunc; +DROP TABLE t_ch_i; +DROP TABLE t_rename_new; +DROP TABLE t_rename_new_new_3; +DROP TABLE t_rename_new_4; +DROP TABLE t_delete_2; +DROP TABLE t_rename_alter_2; +DROP TABLE t_rename_create; +DROP TABLE t_rename_create_new; +DROP TABLE t_part_create; +DROP TABLE t_part_create_2; +DROP TABLE t_part_add_part; +DROP TABLE t_part_change_eng; +DROP TABLE t_part_change_eng_2; +DROP TABLE t_part_change_eng_3; +DROP TABLE t_part_alter; +DROP TABLE t_part_alter_2; +DROP TABLE t_part_rename_2; +DROP TABLE t_part_rm_part; +DROP DATABASE test_for_rename; +--let after_aria_table_copy_test_for_db_drop_t= +--let after_aria_table_copy_test_t_db_create= +--let after_aria_table_copy_test_t_alter= +--let after_aria_background= +--let after_aria_table_copy_test_t_trunc= +--let after_aria_table_copy_test_t_ch_i= +--let after_aria_table_copy_test_t_rename= +--let after_aria_table_copy_test_t_rename_2= +--let after_aria_table_copy_test_t_rename_3= +--let after_aria_table_copy_test_t_rename_4= +--let after_aria_table_copy_test_t_delete= +--let after_aria_table_copy_test_t_delete_2= +--let after_aria_table_copy_test_t_rename_alter= +--let after_aria_table_copy_test_t_rename_create= +--let after_aria_table_copy_test_t_part_create= +--let after_aria_table_copy_test_t_part_add_part= +--let after_aria_table_copy_test_t_part_change_eng= +--let after_aria_table_copy_test_t_part_change_eng_3= +--let after_aria_table_copy_test_t_part_alter= +--let after_aria_table_copy_test_t_part_alter_2= +--let after_aria_table_copy_test_t_part_drop= +--let after_aria_table_copy_test_t_part_rename= +--let after_aria_table_copy_test_t_part_rename_3= +--let after_aria_table_copy_test_t_part_rm_part= + +--echo ### Result for DML test +SELECT * FROM t_dml_ins; +SELECT * FROM t_dml_upd; +SELECT * FROM t_dml_del; + +--echo ### Clean up for DML test +DROP TABLE t_dml_ins; +DROP TABLE t_dml_upd; +DROP TABLE t_dml_del; +--let after_aria_table_copy_test_t_dml_ins= +--let after_aria_table_copy_test_t_dml_upd= +--let after_aria_table_copy_test_t_dml_del= + +--echo ### Result for redo log files backup +--let $t_logs_1_records_count_after_backup=`SELECT COUNT(*) FROM t_logs_1` +--let $t_logs_2_records_count_after_backup=`SELECT COUNT(*) FROM t_logs_2` +--let $t_bulk_ins_records_count_after_backup=`SELECT COUNT(*) FROM t_bulk_ins` +if ($t_logs_1_records_count_after_backup == $t_logs_1_records_count_before_backup) { +--echo # ok +} +if ($t_logs_1_records_count_after_backup != $t_logs_1_records_count_before_backup) { +--echo # failed +} +if ($t_logs_2_records_count_after_backup == $t_logs_2_records_count_before_backup) { +--echo # ok +} +if ($t_logs_2_records_count_after_backup != $t_logs_2_records_count_before_backup) { +--echo # failed +} +if ($t_bulk_ins_records_count_after_backup == $t_bulk_ins_records_count_before_backup) { +--echo # ok +} +if ($t_bulk_ins_records_count_after_backup != $t_bulk_ins_records_count_before_backup) { +--echo # failed +} + +--echo ### Cleanup for redo log files backup +DROP TABLE t_logs_1; +DROP TABLE t_logs_2; +DROP TABLE t_bulk_ins; +--let $t_logs_1_records_count_before_backup= +--let $t_logs_1_records_count_after_backup= +--let $t_logs_2_records_count_before_backup= +--let $t_logs_2_records_count_after_backup= +--let $t_bulk_ins_records_count_before_backup= +--let $t_bulk_ins_records_count_after_backup= + +--echo ### Result for online/offline tables test +SELECT * FROM t_default; +SELECT * FROM t_tr_p_ch; +SELECT * FROM t_tr_p_nch; +SELECT * FROM t_p_ch; +SELECT * FROM t_p_nch; +SELECT * FROM t_fixed; +SELECT * FROM t_dyn; +SELECT * FROM t_part_online; +SELECT * FROM t_part_offline; +SELECT * FROM `t 1 t-1`; +SELECT * FROM `t-part online`; + +--echo ### Cleanup for online/offline tables test +DROP TABLE t_default; +DROP TABLE t_tr_p_ch; +DROP TABLE t_tr_p_nch; +DROP TABLE t_p_ch; +DROP TABLE t_p_nch; +DROP TABLE t_fixed; +DROP TABLE t_dyn; +DROP TABLE t_part_online; +DROP TABLE t_part_offline; +DROP TABLE `t 1 t-1`; +DROP TABLE `t-part online`; + +if ($backup_variant == $backup_stream) { +--remove_file $streamfile +} +--rmdir $targetdir +--dec $backup_variant +} + diff --git a/mysql-test/suite/mariabackup/aria_log.opt b/mysql-test/suite/mariabackup/aria_log.opt new file mode 100644 index 00000000000..f226499f5dd --- /dev/null +++ b/mysql-test/suite/mariabackup/aria_log.opt @@ -0,0 +1 @@ +--loose-aria-log-file-size=8388608 diff --git a/mysql-test/suite/mariabackup/aria_log_dir_path.result b/mysql-test/suite/mariabackup/aria_log_dir_path.result index 1a877321bbe..ead4b836682 100644 --- a/mysql-test/suite/mariabackup/aria_log_dir_path.result +++ b/mysql-test/suite/mariabackup/aria_log_dir_path.result @@ -35,7 +35,6 @@ DROP TABLE t1; SET @@global.aria_checkpoint_interval=DEFAULT /*Force checkpoint*/; SHOW ENGINE aria logs; Type Name Status -Aria aria_log.00000001 free Aria aria_log.00000002 in use # Restarting mariadbd with default parameters # restart diff --git a/mysql-test/suite/mariabackup/aria_log_dir_path.test b/mysql-test/suite/mariabackup/aria_log_dir_path.test index 0178cd4eae5..40bc39446bf 100644 --- a/mysql-test/suite/mariabackup/aria_log_dir_path.test +++ b/mysql-test/suite/mariabackup/aria_log_dir_path.test @@ -48,7 +48,6 @@ SET @@global.aria_checkpoint_interval=DEFAULT /*Force checkpoint*/; --replace_regex /Size +[0-9]+ ; .+aria_log/aria_log/ SHOW ENGINE aria logs; - --echo # mariadb-backup --backup --disable_result_log --mkdir $targetdir @@ -61,7 +60,6 @@ SHOW ENGINE aria logs; --exec $XTRABACKUP --prepare --target-dir=$targetdir --enable_result_log - --echo # shutdown server --disable_result_log --source include/shutdown_mysqld.inc @@ -70,12 +68,14 @@ SHOW ENGINE aria logs; --echo # remove aria-log-dir-path --rmdir $ARIA_LOGDIR_FS + --echo # mariadb-backup --copy-back --let $mariadb_backup_parameters=--defaults-file=$MYSQLTEST_VARDIR/my.cnf --copy-back --datadir=$datadir --target-dir=$targetdir --parallel=2 --throttle=1 --aria-log-dir-path=$ARIA_LOGDIR_MARIADB --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --exec echo "# with parameters: $mariadb_backup_parameters" --exec $XTRABACKUP $mariadb_backup_parameters + --echo # starting server --let $restart_parameters=$server_parameters --source include/start_mysqld.inc @@ -91,7 +91,7 @@ DROP TABLE t1; --echo # Testing aria log files after --copy-back SET @@global.aria_checkpoint_interval=DEFAULT /*Force checkpoint*/; --file_exists $ARIA_LOGDIR_FS/aria_log_control ---file_exists $ARIA_LOGDIR_FS/aria_log.00000001 +#--file_exists $ARIA_LOGDIR_FS/aria_log.00000001 --file_exists $ARIA_LOGDIR_FS/aria_log.00000002 --error 1 --file_exists $ARIA_LOGDIR_FS/aria_log.00000003 diff --git a/mysql-test/suite/mariabackup/aria_log_dir_path_rel.result b/mysql-test/suite/mariabackup/aria_log_dir_path_rel.result index 7fef26096e0..736bc5564e8 100644 --- a/mysql-test/suite/mariabackup/aria_log_dir_path_rel.result +++ b/mysql-test/suite/mariabackup/aria_log_dir_path_rel.result @@ -35,7 +35,6 @@ DROP TABLE t1; SET @@global.aria_checkpoint_interval=DEFAULT /*Force checkpoint*/; SHOW ENGINE aria logs; Type Name Status -Aria aria_log.00000001 free Aria aria_log.00000002 in use # Restarting mariadbd with default parameters # restart diff --git a/mysql-test/suite/mariabackup/aria_log_rotate_during_backup.opt b/mysql-test/suite/mariabackup/aria_log_rotate_during_backup.opt new file mode 100644 index 00000000000..7c3ebe422c3 --- /dev/null +++ b/mysql-test/suite/mariabackup/aria_log_rotate_during_backup.opt @@ -0,0 +1,2 @@ +--loose-aria-log-file-size=8388608 +--loose-restart-for-aria_log_rotate_during_backup="This is needed to recreate datadir, to have Aria start logs from aria_log.00000001" diff --git a/mysql-test/suite/mariabackup/aria_log_rotate_during_backup.result b/mysql-test/suite/mariabackup/aria_log_rotate_during_backup.result new file mode 100644 index 00000000000..0691bce8554 --- /dev/null +++ b/mysql-test/suite/mariabackup/aria_log_rotate_during_backup.result @@ -0,0 +1,58 @@ +SHOW VARIABLES LIKE 'aria_log_file_size'; +Variable_name Value +aria_log_file_size 8388608 +CREATE PROCEDURE display_aria_log_control(ctrl BLOB) +BEGIN +SELECT HEX(REVERSE(SUBSTRING(ctrl, 42, 4))) AS last_logno; +END; +$$ +CREATE PROCEDURE populate_t1() +BEGIN +FOR id IN 0..9 DO +INSERT INTO test.t1 (id, txt) VALUES (id, REPEAT(id,1024*1024)); +END FOR; +END; +$$ +CREATE TABLE test.t1(id INT, txt LONGTEXT) ENGINE=Aria; +# MYSQLD_DATADIR/aria_log_control before --backup +CALL display_aria_log_control(@aria_log_control); +last_logno +00000001 +# Running --backup +# MYSQLD_DATADIR/aria_log_control after --backup +CALL display_aria_log_control(@aria_log_control); +last_logno +00000002 +# targetdir/aria_log_control after --backup +CALL display_aria_log_control(@aria_log_control); +last_logno +00000001 +# Running --prepare +# targetdir/aria_log_control after --prepare +CALL display_aria_log_control(@aria_log_control); +last_logno +00000002 +# shutdown server +# remove datadir +# xtrabackup move back +# restart +# MYSQLD_DATADIR/aria_log_control after --copy-back +CALL display_aria_log_control(@aria_log_control); +last_logno +00000002 +# Checking that after --restore all t1 data is there +SELECT id, LENGTH(txt) FROM t1 ORDER BY id; +id LENGTH(txt) +0 1048576 +1 1048576 +2 1048576 +3 1048576 +4 1048576 +5 1048576 +6 1048576 +7 1048576 +8 1048576 +9 1048576 +DROP TABLE t1; +DROP PROCEDURE populate_t1; +DROP PROCEDURE display_aria_log_control; diff --git a/mysql-test/suite/mariabackup/aria_log_rotate_during_backup.test b/mysql-test/suite/mariabackup/aria_log_rotate_during_backup.test new file mode 100644 index 00000000000..172ade338d5 --- /dev/null +++ b/mysql-test/suite/mariabackup/aria_log_rotate_during_backup.test @@ -0,0 +1,82 @@ +--source include/have_debug.inc +--source include/have_aria.inc + +SHOW VARIABLES LIKE 'aria_log_file_size'; + +--let $MYSQLD_DATADIR= `select @@datadir` +--let $targetdir=$MYSQLTEST_VARDIR/tmp/backup +mkdir $targetdir; + + +DELIMITER $$; +CREATE PROCEDURE display_aria_log_control(ctrl BLOB) +BEGIN + SELECT HEX(REVERSE(SUBSTRING(ctrl, 42, 4))) AS last_logno; +END; +$$ +DELIMITER ;$$ + +DELIMITER $$; +CREATE PROCEDURE populate_t1() +BEGIN + FOR id IN 0..9 DO + INSERT INTO test.t1 (id, txt) VALUES (id, REPEAT(id,1024*1024)); + END FOR; +END; +$$ +DELIMITER ;$$ + + +CREATE TABLE test.t1(id INT, txt LONGTEXT) ENGINE=Aria; + +--echo # MYSQLD_DATADIR/aria_log_control before --backup +--let ARIA_DATADIR=$MYSQLD_DATADIR +--source include/aria_log_control_load.inc +CALL display_aria_log_control(@aria_log_control); + + +--echo # Running --backup +--let after_scanning_log_files=CALL test.populate_t1 +--disable_result_log +--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --dbug=+d,mariabackup_events 2>&1 +--let after_scanning_log_files= +--enable_result_log + +--echo # MYSQLD_DATADIR/aria_log_control after --backup +--let ARIA_DATADIR=$MYSQLD_DATADIR +--source include/aria_log_control_load.inc +CALL display_aria_log_control(@aria_log_control); + +--echo # targetdir/aria_log_control after --backup +--let ARIA_DATADIR=$targetdir +--source include/aria_log_control_load.inc +CALL display_aria_log_control(@aria_log_control); + + +--echo # Running --prepare +--disable_result_log +--exec $XTRABACKUP --prepare --target-dir=$targetdir +--enable_result_log + +--echo # targetdir/aria_log_control after --prepare +--let ARIA_DATADIR=$targetdir +--source include/aria_log_control_load.inc +CALL display_aria_log_control(@aria_log_control); + + +--disable_result_log +--source include/restart_and_restore.inc +--enable_result_log + +--echo # MYSQLD_DATADIR/aria_log_control after --copy-back +--let ARIA_DATADIR=$MYSQLD_DATADIR +--source include/aria_log_control_load.inc +CALL display_aria_log_control(@aria_log_control); + +--echo # Checking that after --restore all t1 data is there +SELECT id, LENGTH(txt) FROM t1 ORDER BY id; +DROP TABLE t1; +rmdir $targetdir; + +DROP PROCEDURE populate_t1; +DROP PROCEDURE display_aria_log_control; diff --git a/mysql-test/suite/mariabackup/auth_plugin_win.test b/mysql-test/suite/mariabackup/auth_plugin_win.test index 70ae74b7028..7c0ba047014 100644 --- a/mysql-test/suite/mariabackup/auth_plugin_win.test +++ b/mysql-test/suite/mariabackup/auth_plugin_win.test @@ -22,7 +22,7 @@ eval GRANT ALL PRIVILEGES ON *.* to '$USERNAME'; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf -u $USERNAME --backup --protocol=pipe --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf -u $USERNAME --backup --parallel=10 --protocol=pipe --target-dir=$targetdir; --enable_result_log --replace_result $USERNAME USERNAME eval DROP USER '$USERNAME'; diff --git a/mysql-test/suite/mariabackup/backup_grants.result b/mysql-test/suite/mariabackup/backup_grants.result index 6bd6c9f42cd..3407d288264 100644 --- a/mysql-test/suite/mariabackup/backup_grants.result +++ b/mysql-test/suite/mariabackup/backup_grants.result @@ -1,4 +1,4 @@ -CREATE user backup@localhost; +CREATE user backup@localhost IDENTIFIED BY 'xyz'; FOUND 1 /missing required privilege RELOAD/ in backup.log FOUND 1 /missing required privilege PROCESS/ in backup.log FOUND 1 /GRANT USAGE ON/ in backup.log @@ -6,8 +6,6 @@ GRANT RELOAD, PROCESS on *.* to backup@localhost; FOUND 1 /missing required privilege REPLICA MONITOR/ in backup.log GRANT REPLICA MONITOR ON *.* TO backup@localhost; REVOKE REPLICA MONITOR ON *.* FROM backup@localhost; -FOUND 1 /missing required privilege CONNECTION ADMIN/ in backup.log -GRANT CONNECTION ADMIN ON *.* TO backup@localhost; FOUND 1 /missing required privilege REPLICATION SLAVE ADMIN/ in backup.log FOUND 1 /missing required privilege REPLICA MONITOR/ in backup.log GRANT REPLICATION SLAVE ADMIN ON *.* TO backup@localhost; diff --git a/mysql-test/suite/mariabackup/backup_grants.test b/mysql-test/suite/mariabackup/backup_grants.test index 18db3489a94..a90b4678d44 100644 --- a/mysql-test/suite/mariabackup/backup_grants.test +++ b/mysql-test/suite/mariabackup/backup_grants.test @@ -1,16 +1,16 @@ let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; -CREATE user backup@localhost; +CREATE user backup@localhost IDENTIFIED BY 'xyz'; # backup possible for unprivileges user, with --no-lock --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --no-lock --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 -ubackup -pxyz --no-lock --target-dir=$targetdir; --enable_result_log rmdir $targetdir; # backup fails without --no-lock, because of FTWRL --disable_result_log error 1; -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 -ubackup -pxyz --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; --enable_result_log let SEARCH_FILE=$MYSQLTEST_VARDIR/tmp/backup.log; @@ -23,7 +23,7 @@ let SEARCH_FILE=$MYSQLTEST_VARDIR/tmp/backup.log; # backup succeeds with RELOAD privilege GRANT RELOAD, PROCESS on *.* to backup@localhost; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --user=backup --password=xyz --target-dir=$targetdir; --enable_result_log rmdir $targetdir; @@ -31,7 +31,7 @@ rmdir $targetdir; # --slave-info and galera info require REPLICA MONITOR --disable_result_log error 1; -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --slave-info --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --user=backup --password=xyz --slave-info --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; --enable_result_log rmdir $targetdir; @@ -40,33 +40,15 @@ rmdir $targetdir; GRANT REPLICA MONITOR ON *.* TO backup@localhost; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --slave-info --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --user backup --password xyz --slave-info --target-dir=$targetdir; --enable_result_log rmdir $targetdir; REVOKE REPLICA MONITOR ON *.* FROM backup@localhost; -# TODO need a query that would delay a BACKUP STAGE START/ BACKUP STAGE BLOCK_COMMIT longer than the kill-long-queries-timeout -#--send SELECT SLEEP(9) kill_me - -# kill-long-query-type=(not empty) requires CONNECTION ADMIN ---disable_result_log ---exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --kill-long-query-type=ALL --kill-long-queries-timeout=4 --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; ---enable_result_log -rmdir $targetdir; - ---let SEARCH_PATTERN= missing required privilege CONNECTION ADMIN ---source include/search_pattern_in_file.inc - -GRANT CONNECTION ADMIN ON *.* TO backup@localhost; ---disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --kill-long-query-type=all --kill-long-queries-timeout=1 --target-dir=$targetdir; ---enable_result_log -rmdir $targetdir; - # --safe-slave-backup requires REPLICATION SLAVE ADMIN, and REPLICA MONITOR --disable_result_log error 1; -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --safe-slave-backup --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --user backup --password xyz --safe-slave-backup --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log; --enable_result_log rmdir $targetdir; @@ -78,7 +60,7 @@ rmdir $targetdir; GRANT REPLICATION SLAVE ADMIN ON *.* TO backup@localhost; GRANT REPLICA MONITOR ON *.* TO backup@localhost; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --safe-slave-backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup -pxyz --safe-slave-backup --target-dir=$targetdir; --enable_result_log rmdir $targetdir; diff --git a/mysql-test/suite/mariabackup/backup_ssl.test b/mysql-test/suite/mariabackup/backup_ssl.test index 39d12229bd3..c38efc885c6 100644 --- a/mysql-test/suite/mariabackup/backup_ssl.test +++ b/mysql-test/suite/mariabackup/backup_ssl.test @@ -3,7 +3,7 @@ FLUSH PRIVILEGES; echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --user=backup_user --password=x --ssl --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --user=backup_user --password=x --ssl --backup --parallel=10 --target-dir=$targetdir; --enable_result_log echo # xtrabackup prepare; diff --git a/mysql-test/suite/mariabackup/binlog.test b/mysql-test/suite/mariabackup/binlog.test index 9d62e5f8d6b..d02d135ebbd 100644 --- a/mysql-test/suite/mariabackup/binlog.test +++ b/mysql-test/suite/mariabackup/binlog.test @@ -9,7 +9,7 @@ INSERT INTO t VALUES(1); SHOW VARIABLES like 'log_bin'; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$basedir; --enable_result_log exec $XTRABACKUP --prepare --binlog-info=1 --target-dir=$basedir ; diff --git a/mysql-test/suite/mariabackup/compress_qpress.test b/mysql-test/suite/mariabackup/compress_qpress.test index c7762f8e55e..263fc55eb67 100644 --- a/mysql-test/suite/mariabackup/compress_qpress.test +++ b/mysql-test/suite/mariabackup/compress_qpress.test @@ -4,7 +4,7 @@ echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --compress --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --compress --target-dir=$targetdir; --enable_result_log INSERT INTO t VALUES(2); diff --git a/mysql-test/suite/mariabackup/create_during_backup.test b/mysql-test/suite/mariabackup/create_during_backup.test index 985a5a3e53a..16d47a648f8 100644 --- a/mysql-test/suite/mariabackup/create_during_backup.test +++ b/mysql-test/suite/mariabackup/create_during_backup.test @@ -7,7 +7,7 @@ mkdir $targetdir; echo # xtrabackup backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --dbug=+d,mariabackup_events; --enable_result_log --let after_load_tables= diff --git a/mysql-test/suite/mariabackup/create_with_data_directory_during_backup.test b/mysql-test/suite/mariabackup/create_with_data_directory_during_backup.test index f01028b6494..aa7d6de2739 100644 --- a/mysql-test/suite/mariabackup/create_with_data_directory_during_backup.test +++ b/mysql-test/suite/mariabackup/create_with_data_directory_during_backup.test @@ -8,7 +8,7 @@ mkdir $table_data_dir; echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --dbug=+d,mariabackup_events; --enable_result_log --source include/shutdown_mysqld.inc echo # xtrabackup prepare; diff --git a/mysql-test/suite/mariabackup/data_directory.test b/mysql-test/suite/mariabackup/data_directory.test index ffb3ab3073c..96d76ba0253 100644 --- a/mysql-test/suite/mariabackup/data_directory.test +++ b/mysql-test/suite/mariabackup/data_directory.test @@ -7,7 +7,7 @@ INSERT INTO t VALUES(1); echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; --enable_result_log --source include/shutdown_mysqld.inc echo # xtrabackup prepare; @@ -21,6 +21,7 @@ rmdir $table_data_dir; SELECT * FROM t; DROP TABLE t; rmdir $targetdir; +rmdir $table_data_dir; --echo # --echo # MDEV-18200 MariaBackup full backup failed with InnoDB: Failing assertion: success @@ -32,8 +33,8 @@ chmod 0000 $DATADIR/ibdata1; exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; --enable_result_log chmod 0755 $DATADIR/ibdata1; -rmdir $table_data_dir; rmdir $targetdir; + --echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/suite/mariabackup/ddl_for_common_engine.result b/mysql-test/suite/mariabackup/ddl_for_common_engine.result new file mode 100644 index 00000000000..27a2f288107 --- /dev/null +++ b/mysql-test/suite/mariabackup/ddl_for_common_engine.result @@ -0,0 +1,67 @@ +CREATE TABLE t1 (a INT NOT NULL) ENGINE=CSV; +CREATE TABLE t2 (a INT NOT NULL) ENGINE=CSV; +CREATE TABLE t3 (a INT NOT NULL) ENGINE=CSV; +### Backup to dir +# xtrabackup prepare +# shutdown server +# remove datadir +# xtrabackup move back +# restart +SELECT * FROM t4; +a +SELECT * FROM t2; +ERROR 42S02: Table 'test.t2' doesn't exist +SELECT * FROM t3; +ERROR 42S02: Table 'test.t3' doesn't exist +SELECT * FROM t5; +a +SELECT * FROM t1; +a +DROP TABLE t4, t5, t1; +CREATE TABLE t1_m1 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t1_m2 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t1 (a INT NOT NULL) ENGINE=MERGE UNION=(t1_m1, t1_m2) INSERT_METHOD=LAST; +CREATE TABLE t2_m1 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t2_m2 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t2 (a INT NOT NULL) ENGINE=MERGE UNION=(t2_m1, t2_m2) INSERT_METHOD=LAST; +CREATE TABLE t3_m1 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t3_m2 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t3 (a INT NOT NULL) ENGINE=MERGE UNION=(t3_m1, t3_m2) INSERT_METHOD=LAST; +### Backup to dir +# xtrabackup prepare +# shutdown server +# remove datadir +# xtrabackup move back +# restart +SELECT * FROM t4; +a +SELECT * FROM t2; +ERROR 42S02: Table 'test.t2' doesn't exist +SELECT * FROM t3; +ERROR 42S02: Table 'test.t3' doesn't exist +SELECT * FROM t5; +a +SELECT * FROM t1; +a +DROP TABLE t4, t5, t1; +DROP TABLE t1_m1, t1_m2, t2_m1, t2_m2, t3_m1, t3_m2; +CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t2 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t3 (a INT NOT NULL) ENGINE=MyISAM; +### Backup to dir +# xtrabackup prepare +# shutdown server +# remove datadir +# xtrabackup move back +# restart +SELECT * FROM t4; +a +SELECT * FROM t2; +ERROR 42S02: Table 'test.t2' doesn't exist +SELECT * FROM t3; +ERROR 42S02: Table 'test.t3' doesn't exist +SELECT * FROM t5; +a +SELECT * FROM t1; +a +DROP TABLE t4, t5, t1; diff --git a/mysql-test/suite/mariabackup/ddl_for_common_engine.test b/mysql-test/suite/mariabackup/ddl_for_common_engine.test new file mode 100644 index 00000000000..045c2320edb --- /dev/null +++ b/mysql-test/suite/mariabackup/ddl_for_common_engine.test @@ -0,0 +1,79 @@ +# This test is just to ensure the DDL processing works for common engines like +# MyISAM, ARCHIVE, CSV etc. The more complex test for different cases is +# implemented in aria_backup.test. +--source include/have_archive.inc +--source include/have_csv.inc +--source include/have_debug.inc + +--let $targetdir=$MYSQLTEST_VARDIR/tmp/backup + +--let $e_myisam = 1 +--let $e_merge = 2 +--let $e_csv = 3 +--let $e_archive = 4 +# 'rename' is not logged in $e_archive, return when fix +--let $e_var = $e_csv + +while ($e_var) { +if ($e_var == $e_csv) { +--let $engine = CSV +} +if ($e_var == $e_archive) { +--let $engine = ARCHIVE +} +if ($e_var == $e_merge) { +--let $engine = MERGE +} +if ($e_var == $e_myisam) { +--let $engine = MyISAM +} + +if ($e_var == $e_merge) { +CREATE TABLE t1_m1 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t1_m2 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t1 (a INT NOT NULL) ENGINE=MERGE UNION=(t1_m1, t1_m2) INSERT_METHOD=LAST; +CREATE TABLE t2_m1 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t2_m2 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t2 (a INT NOT NULL) ENGINE=MERGE UNION=(t2_m1, t2_m2) INSERT_METHOD=LAST; +CREATE TABLE t3_m1 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t3_m2 (a INT NOT NULL) ENGINE=MyISAM; +CREATE TABLE t3 (a INT NOT NULL) ENGINE=MERGE UNION=(t3_m1, t3_m2) INSERT_METHOD=LAST; +} +if ($e_var != $e_merge) { +eval CREATE TABLE t1 (a INT NOT NULL) ENGINE=$engine; +eval CREATE TABLE t2 (a INT NOT NULL) ENGINE=$engine; +eval CREATE TABLE t3 (a INT NOT NULL) ENGINE=$engine; +} + +--let after_ce_table_copy_test_t1=begin not atomic CREATE TABLE test.t4 LIKE test.t1; DROP TABLE test.t2; RENAME TABLE test.t3 TO test.t5; end + +--mkdir $targetdir +--echo ### Backup to dir +--disable_result_log +--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --dbug=+d,mariabackup_events +--enable_result_log + +--echo # xtrabackup prepare +--disable_result_log +--exec $XTRABACKUP --prepare --target-dir=$targetdir +--source include/restart_and_restore.inc +--enable_result_log +--rmdir $targetdir + +SELECT * FROM t4; +--error ER_NO_SUCH_TABLE +SELECT * FROM t2; +--error ER_NO_SUCH_TABLE +SELECT * FROM t3; +SELECT * FROM t5; +SELECT * FROM t1; + +DROP TABLE t4, t5, t1; + +if ($e_var == $e_merge) { +DROP TABLE t1_m1, t1_m2, t2_m1, t2_m2, t3_m1, t3_m2; +} +--let after_ce_table_copy_test_t1= +--dec $e_var +} + diff --git a/mysql-test/suite/mariabackup/disabled.def b/mysql-test/suite/mariabackup/disabled.def index d272540cec8..f8a341814da 100644 --- a/mysql-test/suite/mariabackup/disabled.def +++ b/mysql-test/suite/mariabackup/disabled.def @@ -1 +1,3 @@ log_page_corruption : MDEV-26210 +mariabackup.xb_compressed_encrypted : MDEV-26154 (error 194 "Tablespace is missing for a table") +innodb_ddl_on_intermediate_table : MENT-1213 diff --git a/mysql-test/suite/mariabackup/encrypted_export.opt b/mysql-test/suite/mariabackup/encrypted_export.opt new file mode 100644 index 00000000000..227c2e03f2f --- /dev/null +++ b/mysql-test/suite/mariabackup/encrypted_export.opt @@ -0,0 +1,6 @@ +--innodb_encrypt_tables=1 +--plugin-load-add=$FILE_KEY_MANAGEMENT_SO +--loose-file-key-management +--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/filekeys-data.key +--loose-file-key-management-filename=$MTR_SUITE_DIR/filekeys-data.enc +--loose-file-key-management-encryption-algorithm=aes_cbc diff --git a/mysql-test/suite/mariabackup/encrypted_export.result b/mysql-test/suite/mariabackup/encrypted_export.result new file mode 100644 index 00000000000..b2add8e6136 --- /dev/null +++ b/mysql-test/suite/mariabackup/encrypted_export.result @@ -0,0 +1,14 @@ +CREATE TABLE t1(c VARCHAR(128)) ENGINE INNODB; +insert into t1 values(repeat('a',100)); +select @@innodb_encrypt_tables; +@@innodb_encrypt_tables +ON +# xtrabackup backup +# xtrabackup prepare export +# restart +ALTER TABLE t1 DISCARD TABLESPACE; +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; diff --git a/mysql-test/suite/mariabackup/encrypted_export.test b/mysql-test/suite/mariabackup/encrypted_export.test new file mode 100644 index 00000000000..d1802118a09 --- /dev/null +++ b/mysql-test/suite/mariabackup/encrypted_export.test @@ -0,0 +1,29 @@ +--source include/have_file_key_management.inc +--source include/have_innodb.inc + +CREATE TABLE t1(c VARCHAR(128)) ENGINE INNODB; +insert into t1 values(repeat('a',100)); + +select @@innodb_encrypt_tables; +echo # xtrabackup backup; +let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; + +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; +--enable_result_log +--source include/shutdown_mysqld.inc + +echo # xtrabackup prepare export; +--disable_result_log +exec $XTRABACKUP --prepare --export --target-dir=$targetdir; +--enable_result_log + +--source include/start_mysqld.inc +let MYSQLD_DATADIR=`select @@datadir`; +ALTER TABLE t1 DISCARD TABLESPACE; +copy_file $targetdir/test/t1.ibd $MYSQLD_DATADIR/test/t1.ibd; +copy_file $targetdir/test/t1.cfg $MYSQLD_DATADIR/test/t1.cfg; +ALTER TABLE t1 IMPORT TABLESPACE; +CHECK TABLE t1; +DROP TABLE t1; +rmdir $targetdir; diff --git a/mysql-test/suite/mariabackup/encrypted_page_compressed.test b/mysql-test/suite/mariabackup/encrypted_page_compressed.test index 54fffb7d08f..245fcc31c0d 100644 --- a/mysql-test/suite/mariabackup/encrypted_page_compressed.test +++ b/mysql-test/suite/mariabackup/encrypted_page_compressed.test @@ -37,7 +37,7 @@ echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; let $backuplog=$MYSQLTEST_VARDIR/tmp/backup.log; --error 1 -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --core-file > $backuplog; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --core-file > $backuplog; --enable_result_log --let SEARCH_PATTERN=Database page corruption detected.* diff --git a/mysql-test/suite/mariabackup/encrypted_page_corruption.test b/mysql-test/suite/mariabackup/encrypted_page_corruption.test index 1beb020b463..9ba958c68a0 100644 --- a/mysql-test/suite/mariabackup/encrypted_page_corruption.test +++ b/mysql-test/suite/mariabackup/encrypted_page_corruption.test @@ -65,7 +65,7 @@ if (`select @@innodb_checksum_algorithm LIKE '%full_crc32'`) } --disable_result_log --error $expect_error -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --extended-validation --target-dir=$targetdir --core-file > $backuplog; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --extended-validation --target-dir=$targetdir --core-file > $backuplog; --enable_result_log @@ -77,7 +77,7 @@ rmdir $targetdir; # Due to very constructed nature of the "corruption" (faking checksums), the "corruption" won't be found without --extended-validation --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; --enable_result_log drop table t1; diff --git a/mysql-test/suite/mariabackup/extra_lsndir.test b/mysql-test/suite/mariabackup/extra_lsndir.test index 092ee34c6cc..f880edbef9e 100644 --- a/mysql-test/suite/mariabackup/extra_lsndir.test +++ b/mysql-test/suite/mariabackup/extra_lsndir.test @@ -2,7 +2,7 @@ let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; let $extra_lsndir=$MYSQLTEST_VARDIR/tmp/extra_lsndir; mkdir $extra_lsndir; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --extra-lsndir=$extra_lsndir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --extra-lsndir=$extra_lsndir; --enable_result_log list_files $extra_lsndir; rmdir $extra_lsndir; diff --git a/mysql-test/suite/mariabackup/full_backup.test b/mysql-test/suite/mariabackup/full_backup.test index c6a21112b60..385f3b8785d 100644 --- a/mysql-test/suite/mariabackup/full_backup.test +++ b/mysql-test/suite/mariabackup/full_backup.test @@ -7,7 +7,7 @@ let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --let $backup_log=$MYSQLTEST_VARDIR/tmp/backup.log --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir > $backup_log 2>&1; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --parallel=10 > $backup_log 2>&1; --enable_result_log # The following warning must not appear after MDEV-27343 fix diff --git a/mysql-test/suite/mariabackup/huge_lsn.test b/mysql-test/suite/mariabackup/huge_lsn.test index 8850e9d8954..0da67744457 100644 --- a/mysql-test/suite/mariabackup/huge_lsn.test +++ b/mysql-test/suite/mariabackup/huge_lsn.test @@ -79,7 +79,7 @@ INSERT INTO t VALUES(1); echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; --enable_result_log SET GLOBAL innodb_flush_log_at_trx_commit=1; INSERT INTO t VALUES(2); diff --git a/mysql-test/suite/mariabackup/incremental_encrypted.test b/mysql-test/suite/mariabackup/incremental_encrypted.test index d5570f20006..d4619e1f454 100644 --- a/mysql-test/suite/mariabackup/incremental_encrypted.test +++ b/mysql-test/suite/mariabackup/incremental_encrypted.test @@ -7,6 +7,12 @@ if (!$EXAMPLE_KEY_MANAGEMENT_SO) } call mtr.add_suppression("InnoDB: New log files created"); +if (`select @@innodb_page_size=65536`) +{ + # this needs too much memory for 32bit + source include/have_64bit.inc; +} + let $basedir=$MYSQLTEST_VARDIR/tmp/backup; let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1; @@ -18,7 +24,7 @@ INSERT INTO t VALUES(1); echo # Create full backup , modify table, then create incremental/differential backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$basedir; --enable_result_log SET GLOBAL innodb_flush_log_at_trx_commit = 1; @@ -26,7 +32,7 @@ INSERT INTO t VALUES(2); SELECT * FROM t; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$incremental_dir --incremental-basedir=$basedir; echo # Prepare full backup, apply incremental one; exec $XTRABACKUP --prepare --target-dir=$basedir; exec $XTRABACKUP --prepare --target-dir=$basedir --incremental-dir=$incremental_dir; diff --git a/mysql-test/suite/mariabackup/innodb_ddl_on_intermediate_table.result b/mysql-test/suite/mariabackup/innodb_ddl_on_intermediate_table.result new file mode 100644 index 00000000000..46fdfe77145 --- /dev/null +++ b/mysql-test/suite/mariabackup/innodb_ddl_on_intermediate_table.result @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS t1 ( col1 INT, col_text TEXT ) ENGINE = InnoDB; +ALTER TABLE t1 ADD FULLTEXT KEY `ftidx1` ( col_text ); +# xtrabackup backup +SET debug_sync='RESET'; +DROP TABLE t1; diff --git a/mysql-test/suite/mariabackup/innodb_ddl_on_intermediate_table.test b/mysql-test/suite/mariabackup/innodb_ddl_on_intermediate_table.test new file mode 100644 index 00000000000..d4c4d70d1a5 --- /dev/null +++ b/mysql-test/suite/mariabackup/innodb_ddl_on_intermediate_table.test @@ -0,0 +1,18 @@ +--source include/have_debug.inc +--source include/have_innodb.inc +--source include/have_debug_sync.inc + +--let $targetdir=$MYSQLTEST_VARDIR/tmp/backup +--mkdir $targetdir + +CREATE TABLE IF NOT EXISTS t1 ( col1 INT, col_text TEXT ) ENGINE = InnoDB; +ALTER TABLE t1 ADD FULLTEXT KEY `ftidx1` ( col_text ); + +echo # xtrabackup backup; +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --dbug=+d,mariabackup_events,emulate_ddl_on_intermediate_table; +--enable_result_log + +SET debug_sync='RESET'; +rmdir $targetdir; +DROP TABLE t1; diff --git a/mysql-test/suite/mariabackup/lock_ddl_per_table.test b/mysql-test/suite/mariabackup/lock_ddl_per_table.test index 18c207718b5..98e7c5eaf6f 100644 --- a/mysql-test/suite/mariabackup/lock_ddl_per_table.test +++ b/mysql-test/suite/mariabackup/lock_ddl_per_table.test @@ -16,7 +16,7 @@ CREATE TABLE `bobby``tables` (id INT, name VARCHAR(50), purchased DATE) ENGINE I set global innodb_log_checkpoint_now = 1; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --lock-ddl-per-table=1 --dbug=+d,check_mdl_lock_works; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --lock-ddl-per-table=1 --dbug=+d,check_mdl_lock_works; --enable_result_log DROP TABLE t; DROP TABLE `bobby``tables`; diff --git a/mysql-test/suite/mariabackup/log_checksum_mismatch.test b/mysql-test/suite/mariabackup/log_checksum_mismatch.test index c8baf66e917..6cf4b3547e5 100644 --- a/mysql-test/suite/mariabackup/log_checksum_mismatch.test +++ b/mysql-test/suite/mariabackup/log_checksum_mismatch.test @@ -7,7 +7,7 @@ let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; let $backuplog=$MYSQLTEST_VARDIR/tmp/backup.log; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,log_intermittent_checksum_mismatch --core-file > $backuplog; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --dbug=+d,log_intermittent_checksum_mismatch --core-file > $backuplog; --enable_result_log --let SEARCH_RANGE = 10000000 diff --git a/mysql-test/suite/mariabackup/log_file_unexpected_large_number_in_name.result b/mysql-test/suite/mariabackup/log_file_unexpected_large_number_in_name.result new file mode 100644 index 00000000000..51b4dfc5536 --- /dev/null +++ b/mysql-test/suite/mariabackup/log_file_unexpected_large_number_in_name.result @@ -0,0 +1,20 @@ +# +# Start of 10.5 tests +# +# +# MENT-1587 mariabackup failing due to aria log file copy +# +CREATE TABLE t1(i INT PRIMARY KEY) ENGINE=ARIA; +INSERT INTO t1 VALUES (10); +# Prepare full backup +# shutdown server +# remove datadir +# xtrabackup move back +# restart +SELECT * FROM t1; +i +10 +DROP TABLE t1; +# +# End of 10.5 tests +# diff --git a/mysql-test/suite/mariabackup/log_file_unexpected_large_number_in_name.test b/mysql-test/suite/mariabackup/log_file_unexpected_large_number_in_name.test new file mode 100644 index 00000000000..7fef9d61549 --- /dev/null +++ b/mysql-test/suite/mariabackup/log_file_unexpected_large_number_in_name.test @@ -0,0 +1,47 @@ +--let $MYSQLD_DATADIR=`select @@datadir` + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MENT-1587 mariabackup failing due to aria log file copy +--echo # + + +--let $basedir=$MYSQLTEST_VARDIR/tmp/backup +--let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1 + +CREATE TABLE t1(i INT PRIMARY KEY) ENGINE=ARIA; +INSERT INTO t1 VALUES (10); + +# +# Add a log file with a number outside of last_log_number +# specified in aria_log_control. +# The actual file number written in the header is 4. +# Let's rename it to 100 for test purposes. +# Hopefully 100 should be enough. +# +--copy_file suite/mariabackup/std_data/ment1587_aria_log.00000004 $MYSQLD_DATADIR/aria_log.00000100 + +--disable_result_log +--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir +--enable_result_log + +--disable_result_log +--echo # Prepare full backup +--exec $XTRABACKUP --prepare --target-dir=$basedir +--enable_result_log + +--let $targetdir=$basedir +--source include/restart_and_restore.inc +--enable_result_log +--rmdir $basedir + +SELECT * FROM t1; +DROP TABLE t1; + + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/suite/mariabackup/log_tables.result b/mysql-test/suite/mariabackup/log_tables.result new file mode 100644 index 00000000000..840efc718e9 --- /dev/null +++ b/mysql-test/suite/mariabackup/log_tables.result @@ -0,0 +1,24 @@ +CREATE TABLE t(i INT) +ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; +SET GLOBAL general_log = 1; +SET GLOBAL log_output = 'TABLE'; +INSERT INTO t VALUES (1); +SELECT * FROM mysql.general_log +WHERE argument LIKE "INSERT INTO %" AND +(command_type = "Query" OR command_type = "Execute") ; +event_time user_host thread_id server_id command_type argument +TIMESTAMP USER_HOST THREAD_ID 1 Query INSERT INTO t VALUES (1) +# Insert new row into general_log table after it has been copied on BLOCK_DDL. +# Backup to dir. +# Xtrabackup prepare. +# shutdown server +# remove datadir +# xtrabackup move back +# restart +SELECT * FROM mysql.general_log +WHERE argument LIKE "INSERT INTO %" AND +(command_type = "Query" OR command_type = "Execute") ; +event_time user_host thread_id server_id command_type argument +TIMESTAMP USER_HOST THREAD_ID 1 Query INSERT INTO t VALUES (1) +TIMESTAMP USER_HOST THREAD_ID 1 Query INSERT INTO test.t VALUES (2) +DROP TABLE t; diff --git a/mysql-test/suite/mariabackup/log_tables.test b/mysql-test/suite/mariabackup/log_tables.test new file mode 100644 index 00000000000..fe540a1ca91 --- /dev/null +++ b/mysql-test/suite/mariabackup/log_tables.test @@ -0,0 +1,49 @@ +# Test for copying log tables tail +--source include/have_aria.inc +--source include/have_debug.inc + +--let $targetdir=$MYSQLTEST_VARDIR/tmp/backup + +CREATE TABLE t(i INT) + ENGINE ARIA TRANSACTIONAL=1 ROW_FORMAT=PAGE PAGE_CHECKSUM=1; + +--let $general_log_old = `SELECT @@global.general_log` +--let $log_output_old = `SELECT @@global.log_output` + +SET GLOBAL general_log = 1; +SET GLOBAL log_output = 'TABLE'; + +INSERT INTO t VALUES (1); + +--replace_column 1 TIMESTAMP 2 USER_HOST 3 THREAD_ID 5 Query +--sorted_result +SELECT * FROM mysql.general_log + WHERE argument LIKE "INSERT INTO %" AND + (command_type = "Query" OR command_type = "Execute") ; + +--echo # Insert new row into general_log table after it has been copied on BLOCK_DDL. +--let after_stage_block_ddl=INSERT INTO test.t VALUES (2) + +--echo # Backup to dir. +--disable_result_log +--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --dbug=+d,mariabackup_events +--enable_result_log + +--echo # Xtrabackup prepare. +--disable_result_log +--exec $XTRABACKUP --prepare --target-dir=$targetdir +--source include/restart_and_restore.inc +--enable_result_log + +--replace_column 1 TIMESTAMP 2 USER_HOST 3 THREAD_ID 5 Query +--sorted_result +SELECT * FROM mysql.general_log + WHERE argument LIKE "INSERT INTO %" AND + (command_type = "Query" OR command_type = "Execute") ; + +--rmdir $targetdir +DROP TABLE t; +--disable_query_log +--eval SET GLOBAL general_log = $general_log_old +--eval SET GLOBAL log_output = $log_output_old +--enable_query_log diff --git a/mysql-test/suite/mariabackup/mdev-14447.test b/mysql-test/suite/mariabackup/mdev-14447.test index 79a0d075897..74ae1378ac6 100644 --- a/mysql-test/suite/mariabackup/mdev-14447.test +++ b/mysql-test/suite/mariabackup/mdev-14447.test @@ -11,7 +11,7 @@ CREATE TABLE t(a varchar(40) PRIMARY KEY, b varchar(40), c varchar(40), d varcha echo # Create full backup , modify table, then create incremental/differential backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$basedir; --enable_result_log SET debug_dbug='+d,skip_page_checksum',foreign_key_checks=0,unique_checks=0; diff --git a/mysql-test/suite/mariabackup/missing_ibd.test b/mysql-test/suite/mariabackup/missing_ibd.test index f406a555b4a..76d5a4ff281 100644 --- a/mysql-test/suite/mariabackup/missing_ibd.test +++ b/mysql-test/suite/mariabackup/missing_ibd.test @@ -24,7 +24,7 @@ call mtr.add_suppression('InnoDB: Ignoring tablespace for test/t1 because it cou echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; --enable_result_log rmdir $targetdir; diff --git a/mysql-test/suite/mariabackup/nolock_ddl_during_backup_end.test b/mysql-test/suite/mariabackup/nolock_ddl_during_backup_end.test index f6bc51bd9a6..c75c063ab2a 100644 --- a/mysql-test/suite/mariabackup/nolock_ddl_during_backup_end.test +++ b/mysql-test/suite/mariabackup/nolock_ddl_during_backup_end.test @@ -9,6 +9,6 @@ CREATE TABLE t1(i int) ENGINE=INNODB; echo # xtrabackup backup; --disable_result_log error 1; -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --no-lock --dbug=+d,mariabackup_events; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --no-lock --dbug=+d,mariabackup_events; --enable_result_log rmdir $targetdir; diff --git a/mysql-test/suite/mariabackup/partial.result b/mysql-test/suite/mariabackup/partial.result index 981bef4e40c..9ff3a20c01f 100644 --- a/mysql-test/suite/mariabackup/partial.result +++ b/mysql-test/suite/mariabackup/partial.result @@ -14,6 +14,14 @@ ALTER TABLE t1 IMPORT TABLESPACE; SELECT * FROM t1; i 1 +# MDEV-33023 Crash in mariadb-backup --prepare --export after --prepare +t1.cfg +t21.cfg +ALTER TABLE t1 DISCARD TABLESPACE; +ALTER TABLE t1 IMPORT TABLESPACE; +SELECT * FROM t1; +i +1 DROP TABLE t1; DROP TABLE t2; DROP TABLE t21; diff --git a/mysql-test/suite/mariabackup/partial.test b/mysql-test/suite/mariabackup/partial.test index d0d07daf2ea..af6da274102 100644 --- a/mysql-test/suite/mariabackup/partial.test +++ b/mysql-test/suite/mariabackup/partial.test @@ -14,7 +14,7 @@ echo # xtrabackup backup; let targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables=test.*1" --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 "--tables=test.*1" --target-dir=$targetdir; --enable_result_log list_files $targetdir/test *.ibd; list_files $targetdir/test *.new; @@ -55,6 +55,25 @@ copy_file $targetdir/test/t1.cfg $MYSQLD_DATADIR/test/t1.cfg; ALTER TABLE t1 IMPORT TABLESPACE; SELECT * FROM t1; + +--echo # MDEV-33023 Crash in mariadb-backup --prepare --export after --prepare +--disable_result_log +exec $XTRABACKUP --defaults-file=$server_cnf --defaults-group-suffix=.1 --prepare --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$server_cnf --defaults-group-suffix=.1 --prepare --export --target-dir=$targetdir; +--enable_result_log + +list_files $targetdir/test *.cfg; +# There must not be binary logs created on --prepare step +list_files $targetdir/ mysqld-bin.*; + +let $MYSQLD_DATADIR= `select @@datadir`; +ALTER TABLE t1 DISCARD TABLESPACE; +copy_file $targetdir/test/t1.ibd $MYSQLD_DATADIR/test/t1.ibd; +copy_file $targetdir/test/t1.cfg $MYSQLD_DATADIR/test/t1.cfg; +ALTER TABLE t1 IMPORT TABLESPACE; + +SELECT * FROM t1; + DROP TABLE t1; DROP TABLE t2; DROP TABLE t21; diff --git a/mysql-test/suite/mariabackup/partial_exclude.test b/mysql-test/suite/mariabackup/partial_exclude.test index 6a1ae13b512..973e7a4f328 100644 --- a/mysql-test/suite/mariabackup/partial_exclude.test +++ b/mysql-test/suite/mariabackup/partial_exclude.test @@ -28,7 +28,7 @@ echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables-exclude=test.*2" "--databases-exclude=db2" --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 "--tables-exclude=test.*2" "--databases-exclude=db2" --target-dir=$targetdir; --enable_result_log COMMIT; diff --git a/mysql-test/suite/mariabackup/partition_datadir.test b/mysql-test/suite/mariabackup/partition_datadir.test index 36520d331bf..078055a5a1a 100644 --- a/mysql-test/suite/mariabackup/partition_datadir.test +++ b/mysql-test/suite/mariabackup/partition_datadir.test @@ -14,7 +14,7 @@ PARTITION BY RANGE (i) PARTITION p3 VALUES LESS THAN (400) DATA DIRECTORY = '$MYSQLTEST_VARDIR/partitdata', PARTITION p4 VALUES LESS THAN MAXVALUE); INSERT INTO t VALUES (1), (101), (201), (301), (401); -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; exec $XTRABACKUP --prepare --target-dir=$targetdir; DROP TABLE t; rmdir $MYSQLTEST_VARDIR/partitdata; diff --git a/mysql-test/suite/mariabackup/partition_partial.test b/mysql-test/suite/mariabackup/partition_partial.test index 7ccc42c036c..30e31a9d43e 100644 --- a/mysql-test/suite/mariabackup/partition_partial.test +++ b/mysql-test/suite/mariabackup/partition_partial.test @@ -16,7 +16,7 @@ echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables=test.t1" --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 "--tables=test.t1" --target-dir=$targetdir; --enable_result_log INSERT INTO t1 VALUES (1), (101), (201), (301); diff --git a/mysql-test/suite/mariabackup/rename_during_backup.result b/mysql-test/suite/mariabackup/rename_during_backup.result index e071b6b2e21..ba509efe0cb 100644 --- a/mysql-test/suite/mariabackup/rename_during_backup.result +++ b/mysql-test/suite/mariabackup/rename_during_backup.result @@ -61,3 +61,15 @@ SELECT * from t6; i 5 DROP TABLE t6; +# +# MDEV-33011 mariabackup --backup: FATAL ERROR: ... Can't open datafile cool_down/t3 +# +# Simulate zero initialized page to defer tablespace load after rename log is found +SET @save_dbug = @@SESSION.debug_dbug; +SET DEBUG_DBUG="+d,checkpoint_after_file_create"; +CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB; +INSERT INTO t1 VALUES(1); +# RENAME that fails after redo log entry is written and flushed +RENAME TABLE t1 TO non_existing_db.t1; +ERROR HY000: Error on rename of './test/t1' to './non_existing_db/t1' (errno: 168 "Unknown (generic) error from engine") +DROP TABLE t1; diff --git a/mysql-test/suite/mariabackup/rename_during_backup.test b/mysql-test/suite/mariabackup/rename_during_backup.test index d8e40b28941..44036691b6d 100644 --- a/mysql-test/suite/mariabackup/rename_during_backup.test +++ b/mysql-test/suite/mariabackup/rename_during_backup.test @@ -92,4 +92,31 @@ SELECT * from t6; DROP TABLE t6; rmdir $targetdir; +--echo # +--echo # MDEV-33011 mariabackup --backup: FATAL ERROR: ... Can't open datafile cool_down/t3 +--echo # +--disable_query_log +call mtr.add_suppression("InnoDB: Cannot rename '.*t1.ibd' to '.*non_existing_db.*' because the target schema directory doesn't exist"); +--enable_query_log + +mkdir $targetdir; + +--echo # Simulate zero initialized page to defer tablespace load after rename log is found +SET @save_dbug = @@SESSION.debug_dbug; +SET DEBUG_DBUG="+d,checkpoint_after_file_create"; +CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB; +INSERT INTO t1 VALUES(1); + +--echo # RENAME that fails after redo log entry is written and flushed +--replace_result "\\" "/" +--error ER_ERROR_ON_RENAME +RENAME TABLE t1 TO non_existing_db.t1; + +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --prepare --target-dir=$targetdir; +--enable_result_log + +DROP TABLE t1; +rmdir $targetdir; diff --git a/mysql-test/suite/mariabackup/rename_during_mdl_lock.test b/mysql-test/suite/mariabackup/rename_during_mdl_lock.test index 212b7aabd69..b14b04a5e26 100644 --- a/mysql-test/suite/mariabackup/rename_during_mdl_lock.test +++ b/mysql-test/suite/mariabackup/rename_during_mdl_lock.test @@ -3,7 +3,7 @@ let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; mkdir $targetdir; CREATE TABLE t1(i int) ENGINE INNODB; set global innodb_log_checkpoint_now = 1; -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --lock-ddl-per-table --dbug=+d,rename_during_mdl_lock_table; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --lock-ddl-per-table --dbug=+d,rename_during_mdl_lock_table; echo # xtrabackup prepare; --disable_result_log diff --git a/mysql-test/suite/mariabackup/rpl_clone_slave.result b/mysql-test/suite/mariabackup/rpl_clone_slave.result new file mode 100644 index 00000000000..fc6390eb897 --- /dev/null +++ b/mysql-test/suite/mariabackup/rpl_clone_slave.result @@ -0,0 +1,202 @@ +include/master-slave.inc +[connection master] +# +# MDEV-33342 Add a replication MTR test cloning the slave with mariadb-backup +# +connection slave; +stop slave; +change master to master_use_gtid=no; +start slave; +connection master; +connection slave; +############################################################## +### Initial block with some transactions +### Slave: Make sure replication is not using GTID +connection slave; +# Using_Gtid=No +### Master: Create and populate t1 +connection master; +CREATE TABLE t1(a TEXT) ENGINE=InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#00:stmt#00 - slave run#0, before backup'); +INSERT INTO t1 VALUES ('tr#00:stmt#01 - slave run#0, before backup'); +INSERT INTO t1 VALUES ('tr#00:stmt#02 - slave run#0, before backup'); +COMMIT; +connection slave; +############################################################## +### Run the last transaction before mariadb-backup --backup +### Remember SHOW MASTER STATUS and @@gtid_binlog_pos +### before and after the transaction. +### Master: Rember MASTER STATUS and @@gtid_binlog_pos before tr#01 +connection master; +### Slave: Remember MASTER STATUS and @@gtid_binlog_pos before tr#01 +connection slave; +### Master: Run the actual last transaction before the backup +connection master; +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#01:stmt#00 - slave run#0, before backup'); +INSERT INTO t1 VALUES ('tr#01:stmt#01 - slave run#0, before backup'); +INSERT INTO t1 VALUES ('tr#01:stmt#02 - slave run#0, before backup'); +COMMIT; +connection slave; +### Master: Remember MASTER STATUS and @@gtid_binlog_pos after tr#01 +connection master; +### Slave: Remember MASTER STATUS and @@gtid_binlog_pos after tr#01 +connection slave; +############################################################## +### Running `mariadb-backup --backup,--prepare` and checking +### that mariadb_backup_slave_info and mariadb_backup_binlog_info are OK +### Slave: Create a backup +### Slave: Prepare the backup +### Slave: xtrabackup files: +############################ mariadb_backup_slave_info +CHANGE MASTER TO MASTER_LOG_FILE='master_after_tr01_show_master_status_file', MASTER_LOG_POS=master_after_tr01_show_master_status_position; +############################ mariadb_backup_binlog_info +slave_after_tr01_show_master_status_file slave_after_tr01_show_master_status_position slave_after_tr01_gtid_binlog_pos +############################ +############################################################## +### Run more transactions after the backup: +### - while the slave is still running, then +### - while the slave is shut down +### Master: Run another transaction while the slave is still running +connection master; +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup'); +INSERT INTO t1 VALUES ('tr#02:stmt#01 - slave run#0, after backup'); +INSERT INTO t1 VALUES ('tr#02:stmt@02 - slave run#0, after backup'); +COMMIT; +connection slave; +### Master: Remember MASTER STATUS and @@gtid_binlog_pos after tr#02 +connection master; +### Slave: Remember MASTER STATUS and @@gtid_binlog_pos after tr#02 +connection slave; +### Master: Checking SHOW BINLOG EVENTS +connection master; +SHOW BINLOG EVENTS IN 'master_after_tr01_show_master_status_file' FROM master_after_tr01_show_master_status_position LIMIT 0,1; +Log_name master_after_tr01_show_master_status_file +Pos master_after_tr01_show_master_status_position +Event_type Gtid +Server_id # +End_log_pos # +Info BEGIN GTID master_after_tr02_gtid_binlog_pos +SHOW BINLOG EVENTS IN 'master_after_tr01_show_master_status_file' FROM master_after_tr01_show_master_status_position LIMIT 1,1; +Log_name master_after_tr01_show_master_status_file +Pos # +Event_type Query_or_Annotate_rows +Server_id # +End_log_pos # +Info INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup') +### Slave: Checking SHOW BINLOG EVENTS +connection slave; +SHOW BINLOG EVENTS IN 'slave_after_tr01_show_master_status_file' FROM slave_after_tr01_show_master_status_position LIMIT 0,1; +Log_name slave_after_tr01_show_master_status_file +Pos # +Event_type Gtid +Server_id 1 +End_log_pos # +Info BEGIN GTID slave_after_tr02_gtid_binlog_pos +SHOW BINLOG EVENTS IN 'slave_after_tr01_show_master_status_file' FROM slave_after_tr01_show_master_status_position LIMIT 1,1; +Log_name slave_after_tr01_show_master_status_file +Pos # +Event_type Query_or_Annotate_rows +Server_id # +End_log_pos # +Info INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup') +### Slave: Stop replication +connection slave; +STOP SLAVE; +include/wait_for_slave_to_stop.inc +RESET SLAVE; +Warnings: +Note 4190 RESET SLAVE is implicitly changing the value of 'Using_Gtid' from 'No' to 'Slave_Pos' +### Slave: Shutdown the server +include/rpl_stop_server.inc [server_number=2] +### Master: Run a transaction while the slave is shut down +connection master; +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#03:stmt#00 - after slave run#0, slave is shut down, after backup'); +INSERT INTO t1 VALUES ('tr#03:stmt#01 - after slave run#0, slave is shut down, after backup'); +INSERT INTO t1 VALUES ('tr#03:stmt#02 - after slave run#0, slave is shut down, after backup'); +COMMIT; +############################################################## +### Emulate starting a new virgin slave +### Slave: Remove the data directory +### Slave: Copy back the backup +### Slave: Restart the server +include/rpl_start_server.inc [server_number=2] +### Slave: Display the restored data before START SLAVE +connection slave; +SELECT * FROM t1 ORDER BY a; +a +tr#00:stmt#00 - slave run#0, before backup +tr#00:stmt#01 - slave run#0, before backup +tr#00:stmt#02 - slave run#0, before backup +tr#01:stmt#00 - slave run#0, before backup +tr#01:stmt#01 - slave run#0, before backup +tr#01:stmt#02 - slave run#0, before backup +### Slave: Execute the CHANGE MASTER statement to set up the host and port +CHANGE MASTER '' TO MASTER_USER='root', MASTER_HOST='127.0.0.1', MASTER_PORT=###, MASTER_CONNECT_RETRY=1, MASTER_SSL_VERIFY_SERVER_CERT=0; +### Slave: Execute the CHANGE MASTER statement from mariadb_backup_slave_info +CHANGE MASTER TO MASTER_LOG_FILE='master_after_tr01_show_master_status_file', MASTER_LOG_POS=master_after_tr01_show_master_status_position; +Warnings: +Note 4190 CHANGE MASTER TO is implicitly changing the value of 'Using_Gtid' from 'Slave_Pos' to 'No' +### Slave: Execute START SLAVE +include/start_slave.inc +### Master: Wait for the slave to apply all master events +connection master; +connection slave; +### Slave: Make sure replication is not using GTID after the slave restart +connection slave; +# Using_Gtid=No +### Slave: Display the restored data after START SLAVE +connection slave; +SELECT * FROM t1 ORDER BY a; +a +tr#00:stmt#00 - slave run#0, before backup +tr#00:stmt#01 - slave run#0, before backup +tr#00:stmt#02 - slave run#0, before backup +tr#01:stmt#00 - slave run#0, before backup +tr#01:stmt#01 - slave run#0, before backup +tr#01:stmt#02 - slave run#0, before backup +tr#02:stmt#00 - slave run#0, after backup +tr#02:stmt#01 - slave run#0, after backup +tr#02:stmt@02 - slave run#0, after backup +tr#03:stmt#00 - after slave run#0, slave is shut down, after backup +tr#03:stmt#01 - after slave run#0, slave is shut down, after backup +tr#03:stmt#02 - after slave run#0, slave is shut down, after backup +############################################################## +### Continue master transactions, check the new slave replicates well. +### Master: Run a transaction after restarting replication +connection master; +START TRANSACTION; +INSERT INTO t1 VALUES ('tr#04:stmt#00 - slave run#1'); +INSERT INTO t1 VALUES ('tr#04:stmt#01 - slave run#1'); +INSERT INTO t1 VALUES ('tr#04:stmt#02 - slave run#1'); +COMMIT; +connection slave; +### Slave: Display the restored data + new transactions +connection slave; +SELECT * FROM t1 ORDER BY a; +a +tr#00:stmt#00 - slave run#0, before backup +tr#00:stmt#01 - slave run#0, before backup +tr#00:stmt#02 - slave run#0, before backup +tr#01:stmt#00 - slave run#0, before backup +tr#01:stmt#01 - slave run#0, before backup +tr#01:stmt#02 - slave run#0, before backup +tr#02:stmt#00 - slave run#0, after backup +tr#02:stmt#01 - slave run#0, after backup +tr#02:stmt@02 - slave run#0, after backup +tr#03:stmt#00 - after slave run#0, slave is shut down, after backup +tr#03:stmt#01 - after slave run#0, slave is shut down, after backup +tr#03:stmt#02 - after slave run#0, slave is shut down, after backup +tr#04:stmt#00 - slave run#1 +tr#04:stmt#01 - slave run#1 +tr#04:stmt#02 - slave run#1 +############################################################## +### Cleanup +### Removing the backup directory +connection master; +DROP TABLE t1; +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/mariabackup/rpl_clone_slave.test b/mysql-test/suite/mariabackup/rpl_clone_slave.test new file mode 100644 index 00000000000..7d93f72327f --- /dev/null +++ b/mysql-test/suite/mariabackup/rpl_clone_slave.test @@ -0,0 +1,17 @@ +# +# Cloning a slave using mariadb-backup +# +--source include/have_innodb.inc +--source include/master-slave.inc + +--echo # +--echo # MDEV-33342 Add a replication MTR test cloning the slave with mariadb-backup +--echo # + +connection slave; +stop slave; +change master to master_use_gtid=no; +start slave; + +--let cnf=mariadb_to_mariadb +--source include/rpl_clone_slave_using_mariadb-backup.inc diff --git a/mysql-test/suite/mariabackup/small_ibd.test b/mysql-test/suite/mariabackup/small_ibd.test index e8175fce7c9..bb476b8771e 100644 --- a/mysql-test/suite/mariabackup/small_ibd.test +++ b/mysql-test/suite/mariabackup/small_ibd.test @@ -13,7 +13,7 @@ echo #backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; --enable_result_log remove_file $_datadir/test/small.ibd; rmdir $targetdir; diff --git a/mysql-test/suite/mariabackup/std_data/ment1587_aria_log.00000004 b/mysql-test/suite/mariabackup/std_data/ment1587_aria_log.00000004 new file mode 100644 index 00000000000..e69de29bb2d diff --git a/mysql-test/suite/mariabackup/suite.opt b/mysql-test/suite/mariabackup/suite.opt index 1df4643562e..e6b20c328b2 100644 --- a/mysql-test/suite/mariabackup/suite.opt +++ b/mysql-test/suite/mariabackup/suite.opt @@ -1 +1 @@ ---innodb --loose-changed_page_bitmaps --innodb-sys-tables --innodb-flush-log-at-trx-commit=2 --sequence +--innodb --innodb-sys-tables --innodb-flush-log-at-trx-commit=2 --sequence diff --git a/mysql-test/suite/mariabackup/system_versioning.test b/mysql-test/suite/mariabackup/system_versioning.test index 1ced00b4588..04a5f72ac2c 100644 --- a/mysql-test/suite/mariabackup/system_versioning.test +++ b/mysql-test/suite/mariabackup/system_versioning.test @@ -5,7 +5,7 @@ update t set a=2; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; --enable_result_log insert into t values (3); @@ -32,7 +32,7 @@ insert into t values (1); update t set a=2; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; --enable_result_log insert into t values (3); diff --git a/mysql-test/suite/mariabackup/truncate_during_backup.test b/mysql-test/suite/mariabackup/truncate_during_backup.test index 46ee244dfb0..8928fc4eb07 100644 --- a/mysql-test/suite/mariabackup/truncate_during_backup.test +++ b/mysql-test/suite/mariabackup/truncate_during_backup.test @@ -7,7 +7,7 @@ CREATE TABLE t1 ENGINE=InnoDB SELECT 1; --let after_load_tablespaces=TRUNCATE test.t1 --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --dbug=+d,mariabackup_events; --enable_result_log --let after_load_tablespaces= diff --git a/mysql-test/suite/mariabackup/undo_space_id.result b/mysql-test/suite/mariabackup/undo_space_id.result index b03b9705569..fd720d123c1 100644 --- a/mysql-test/suite/mariabackup/undo_space_id.result +++ b/mysql-test/suite/mariabackup/undo_space_id.result @@ -11,3 +11,10 @@ undo002 undo001 undo002 DROP TABLE t1; +# +# MDEV-33980 mariadb-backup --backup is missing +# retry logic for undo tablespaces +# +# xtrabackup backup +# Display undo log files from target directory +FOUND 5 /Retrying to read undo tablespace*/ in backup.log diff --git a/mysql-test/suite/mariabackup/undo_space_id.test b/mysql-test/suite/mariabackup/undo_space_id.test index 2c56492fd8e..32782354537 100644 --- a/mysql-test/suite/mariabackup/undo_space_id.test +++ b/mysql-test/suite/mariabackup/undo_space_id.test @@ -11,7 +11,7 @@ INSERT INTO t1 VALUES(1); --echo # xtrabackup backup --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$basedir; --enable_result_log --echo # Display undo log files from target directory list_files $basedir undo*; @@ -23,3 +23,22 @@ list_files $basedir undo*; DROP TABLE t1; rmdir $basedir; + +--echo # +--echo # MDEV-33980 mariadb-backup --backup is missing +--echo # retry logic for undo tablespaces +--echo # +let $backuplog= $MYSQLTEST_VARDIR/tmp/backup.log; +--echo # xtrabackup backup +--disable_result_log +--error 1 +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir --dbug=+d,undo_space_read_fail > $backuplog; +--enable_result_log +--echo # Display undo log files from target directory +list_files $basedir undo*; + +--let SEARCH_PATTERN=Retrying to read undo tablespace* +--let SEARCH_FILE=$backuplog +--source include/search_pattern_in_file.inc +rmdir $basedir; +remove_file $backuplog; diff --git a/mysql-test/suite/mariabackup/unencrypted_page_compressed.test b/mysql-test/suite/mariabackup/unencrypted_page_compressed.test index 700c4dd2034..31e8323b8b6 100644 --- a/mysql-test/suite/mariabackup/unencrypted_page_compressed.test +++ b/mysql-test/suite/mariabackup/unencrypted_page_compressed.test @@ -38,7 +38,7 @@ echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; let $backuplog=$MYSQLTEST_VARDIR/tmp/backup.log; --error 1 -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --core-file > $backuplog; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --core-file > $backuplog; --enable_result_log --let SEARCH_PATTERN=Database page corruption detected.* diff --git a/mysql-test/suite/mariabackup/unsupported_redo.test b/mysql-test/suite/mariabackup/unsupported_redo.test index 97e1cad222d..38cceb2f687 100644 --- a/mysql-test/suite/mariabackup/unsupported_redo.test +++ b/mysql-test/suite/mariabackup/unsupported_redo.test @@ -15,7 +15,7 @@ ALTER TABLE t1 FORCE, ALGORITHM=INPLACE; echo # No longer fails during full backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$basedir; --enable_result_log DROP TABLE t1; @@ -29,13 +29,13 @@ INSERT INTO t1(a) select 1 union select 2 union select 3; --echo # Create full backup , modify table, then fails during creation of --echo # incremental/differential backup --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$basedir; --enable_result_log ALTER TABLE t1 FORCE, ALGORITHM=INPLACE; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$incremental_dir --incremental-basedir=$basedir; --enable_result_log DROP TABLE t1; @@ -58,7 +58,7 @@ ALTER TABLE t21 FORCE, ALGORITHM=INPLACE; --echo # unsupported redo log for the table t21. --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables-exclude=test.t21" --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 "--tables-exclude=test.t21" --target-dir=$targetdir; --enable_result_log --list_files $targetdir/test *.ibd --list_files $targetdir/test *.new diff --git a/mysql-test/suite/mariabackup/xb_aws_key_management.test b/mysql-test/suite/mariabackup/xb_aws_key_management.test index c8a12f6ed08..a2e407d3b22 100644 --- a/mysql-test/suite/mariabackup/xb_aws_key_management.test +++ b/mysql-test/suite/mariabackup/xb_aws_key_management.test @@ -10,7 +10,7 @@ INSERT INTO t VALUES('foobar1'); echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; exec $XTRABACKUP --prepare --target-dir=$targetdir; -- source include/restart_and_restore.inc --enable_result_log diff --git a/mysql-test/suite/mariabackup/xb_file_key_management.test b/mysql-test/suite/mariabackup/xb_file_key_management.test index 4d27b2dfa95..eca69c976ff 100644 --- a/mysql-test/suite/mariabackup/xb_file_key_management.test +++ b/mysql-test/suite/mariabackup/xb_file_key_management.test @@ -8,7 +8,7 @@ DELETE FROM t LIMIT 1; echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; --enable_result_log --let SEARCH_RANGE = 10000000 diff --git a/mysql-test/suite/mariabackup/xb_history.test b/mysql-test/suite/mariabackup/xb_history.test index f9374a1aaab..e05b7721dc9 100644 --- a/mysql-test/suite/mariabackup/xb_history.test +++ b/mysql-test/suite/mariabackup/xb_history.test @@ -6,7 +6,7 @@ DROP TABLE IF EXISTS mysql.mariadb_backup_history; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --history=foo --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --history=foo --backup --parallel=10 --target-dir=$targetdir; --enable_result_log rmdir $targetdir; diff --git a/mysql-test/suite/mariabackup/xb_page_compress.test b/mysql-test/suite/mariabackup/xb_page_compress.test index 7e806e6de22..e2819e264c1 100644 --- a/mysql-test/suite/mariabackup/xb_page_compress.test +++ b/mysql-test/suite/mariabackup/xb_page_compress.test @@ -27,7 +27,7 @@ echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables=test.*1" --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 "--tables=test.*1" --target-dir=$targetdir; echo # xtrabackup prepare; exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group-suffix=.1 --prepare --export --target-dir=$targetdir; --enable_result_log diff --git a/mysql-test/suite/mariabackup/xb_partition.test b/mysql-test/suite/mariabackup/xb_partition.test index 1c8eeaa19e6..13ce8fa2b39 100644 --- a/mysql-test/suite/mariabackup/xb_partition.test +++ b/mysql-test/suite/mariabackup/xb_partition.test @@ -39,7 +39,7 @@ INSERT INTO isam_p VALUES (1), (101), (201), (301); let $targetdir=$MYSQLTEST_VARDIR/tmp; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir/full; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir/full; --enable_result_log DROP TABLE t1; diff --git a/mysql-test/suite/mariabackup/xb_rocksdb.test b/mysql-test/suite/mariabackup/xb_rocksdb.test index e41f3b2bf7e..6c23fe3d1ea 100644 --- a/mysql-test/suite/mariabackup/xb_rocksdb.test +++ b/mysql-test/suite/mariabackup/xb_rocksdb.test @@ -8,9 +8,9 @@ echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; let $stream=$MYSQLTEST_VARDIR/tmp/backup.xb; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir $backup_extra_param; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir $backup_extra_param; --enable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --stream=xbstream > $stream 2>$MYSQLTEST_VARDIR/tmp/backup_stream.log; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --stream=xbstream > $stream 2>$MYSQLTEST_VARDIR/tmp/backup_stream.log; INSERT INTO t VALUES(2); diff --git a/mysql-test/suite/mariabackup/xb_rocksdb_datadir.test b/mysql-test/suite/mariabackup/xb_rocksdb_datadir.test index c2e90d9075b..2a0b2a4666e 100644 --- a/mysql-test/suite/mariabackup/xb_rocksdb_datadir.test +++ b/mysql-test/suite/mariabackup/xb_rocksdb_datadir.test @@ -9,7 +9,7 @@ INSERT INTO t VALUES(1); echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir; --enable_result_log INSERT INTO t VALUES(2); diff --git a/mysql-test/suite/mariabackup/xbstream.test b/mysql-test/suite/mariabackup/xbstream.test index 212ac598064..8429a3b587d 100644 --- a/mysql-test/suite/mariabackup/xbstream.test +++ b/mysql-test/suite/mariabackup/xbstream.test @@ -8,7 +8,7 @@ mkdir $targetdir; let $streamfile=$MYSQLTEST_VARDIR/tmp/backup.xb; echo # xtrabackup backup to stream; -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --databases-exclude=foobar --stream=xbstream > $streamfile 2>$targetdir/backup_stream.log; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --databases-exclude=foobar --stream=xbstream > $streamfile 2>$targetdir/backup_stream.log; echo # xbstream extract; --disable_result_log exec $XBSTREAM -x -C $targetdir < $streamfile; diff --git a/mysql-test/suite/multi_source/gtid_ignore_duplicates.result b/mysql-test/suite/multi_source/gtid_ignore_duplicates.result index d23e7597543..b5ef07bec1c 100644 --- a/mysql-test/suite/multi_source/gtid_ignore_duplicates.result +++ b/mysql-test/suite/multi_source/gtid_ignore_duplicates.result @@ -174,6 +174,105 @@ a 10 11 12 +*** MDEV-33475: --gtid-ignore-duplicate can double-apply event in case of parallel replication retry +connection server_2; +STOP SLAVE "c2b"; +SET default_master_connection = "c2b"; +include/wait_for_slave_to_stop.inc +STOP SLAVE "a2b"; +SET default_master_connection = "a2b"; +include/wait_for_slave_to_stop.inc +connection server_1; +CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +BEGIN; +INSERT INTO t2 VALUES (0, 0); +INSERT INTO t2 VALUES (1, 0); +INSERT INTO t2 VALUES (2, 0); +INSERT INTO t2 VALUES (3, 0); +INSERT INTO t2 VALUES (4, 0); +INSERT INTO t2 VALUES (5, 0); +INSERT INTO t2 VALUES (6, 0); +INSERT INTO t2 VALUES (7, 0); +INSERT INTO t2 VALUES (8, 0); +INSERT INTO t2 VALUES (9, 0); +COMMIT; +BEGIN; +INSERT INTO t2 VALUES (0+10, 100); +UPDATE t2 SET b=0 WHERE a<10; +INSERT INTO t2 VALUES (0+20, 200); +COMMIT; +BEGIN; +INSERT INTO t2 VALUES (1+10, 100); +UPDATE t2 SET b=1 WHERE a<10; +INSERT INTO t2 VALUES (1+20, 200); +COMMIT; +BEGIN; +INSERT INTO t2 VALUES (2+10, 100); +UPDATE t2 SET b=2 WHERE a<10; +INSERT INTO t2 VALUES (2+20, 200); +COMMIT; +BEGIN; +INSERT INTO t2 VALUES (3+10, 100); +UPDATE t2 SET b=3 WHERE a<10; +INSERT INTO t2 VALUES (3+20, 200); +COMMIT; +BEGIN; +INSERT INTO t2 VALUES (4+10, 100); +UPDATE t2 SET b=4 WHERE a<10; +INSERT INTO t2 VALUES (4+20, 200); +COMMIT; +BEGIN; +INSERT INTO t2 VALUES (5+10, 100); +UPDATE t2 SET b=5 WHERE a<10; +INSERT INTO t2 VALUES (5+20, 200); +COMMIT; +BEGIN; +INSERT INTO t2 VALUES (6+10, 100); +UPDATE t2 SET b=6 WHERE a<10; +INSERT INTO t2 VALUES (6+20, 200); +COMMIT; +BEGIN; +INSERT INTO t2 VALUES (7+10, 100); +UPDATE t2 SET b=7 WHERE a<10; +INSERT INTO t2 VALUES (7+20, 200); +COMMIT; +BEGIN; +INSERT INTO t2 VALUES (8+10, 100); +UPDATE t2 SET b=8 WHERE a<10; +INSERT INTO t2 VALUES (8+20, 200); +COMMIT; +BEGIN; +INSERT INTO t2 VALUES (9+10, 100); +UPDATE t2 SET b=9 WHERE a<10; +INSERT INTO t2 VALUES (9+20, 200); +COMMIT; +SELECT COUNT(*), SUM(a), SUM(b) FROM t2; +COUNT(*) SUM(a) SUM(b) +30 435 3090 +include/save_master_gtid.inc +connection server_2; +SET @old_mode= @@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode=aggressive; +SET default_master_connection = "a2b"; +START SLAVE; +include/wait_for_slave_to_start.inc +SET default_master_connection = "c2b"; +START SLAVE; +include/wait_for_slave_to_start.inc +include/sync_with_master_gtid.inc +SELECT COUNT(*), SUM(a), SUM(b) FROM t2; +COUNT(*) SUM(a) SUM(b) +30 435 3090 +connection server_3; +include/sync_with_master_gtid.inc +SELECT COUNT(*), SUM(a), SUM(b) FROM t2; +COUNT(*) SUM(a) SUM(b) +30 435 3090 +connection server_4; +include/sync_with_master_gtid.inc +SELECT COUNT(*), SUM(a), SUM(b) FROM t2; +COUNT(*) SUM(a) SUM(b) +30 435 3090 *** Test also with not using parallel replication. connection server_1; SET default_master_connection = "b2a"; @@ -474,6 +573,7 @@ Warnings: Note 1938 SLAVE 'a2b' stopped Note 1938 SLAVE 'c2b' stopped SET GLOBAL slave_parallel_threads= @old_parallel; +SET GLOBAL slave_parallel_mode= @old_mode; SET GLOBAL gtid_ignore_duplicates= @old_ignore_duplicates; connection server_3; SET GLOBAL gtid_domain_id=0; @@ -491,22 +591,22 @@ Note 1938 SLAVE 'a2d' stopped SET GLOBAL slave_parallel_threads= @old_parallel; SET GLOBAL gtid_ignore_duplicates= @old_ignore_duplicates; connection server_1; -DROP TABLE t1; +DROP TABLE t1, t2; ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; include/reset_master_slave.inc disconnect server_1; connection server_2; -DROP TABLE t1; +DROP TABLE t1, t2; ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; include/reset_master_slave.inc disconnect server_2; connection server_3; -DROP TABLE t1; +DROP TABLE t1, t2; ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; include/reset_master_slave.inc disconnect server_3; connection server_4; -DROP TABLE t1; +DROP TABLE t1, t2; ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; include/reset_master_slave.inc disconnect server_4; diff --git a/mysql-test/suite/multi_source/gtid_ignore_duplicates.test b/mysql-test/suite/multi_source/gtid_ignore_duplicates.test index 2e5bd6da482..75c56877404 100644 --- a/mysql-test/suite/multi_source/gtid_ignore_duplicates.test +++ b/mysql-test/suite/multi_source/gtid_ignore_duplicates.test @@ -173,6 +173,65 @@ SET default_master_connection = "a2b"; SELECT * FROM t1 WHERE a >= 10 ORDER BY a; +--echo *** MDEV-33475: --gtid-ignore-duplicate can double-apply event in case of parallel replication retry + +# Create a bunch of transactions that will cause conflicts and retries. +# The bug was that the retry code was not handling the --gtid-ignore-duplicates +# option, so events could be doubly-applied. + +--connection server_2 +STOP SLAVE "c2b"; +SET default_master_connection = "c2b"; +--source include/wait_for_slave_to_stop.inc +STOP SLAVE "a2b"; +SET default_master_connection = "a2b"; +--source include/wait_for_slave_to_stop.inc + +--connection server_1 +CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +BEGIN; +--let $i= 0 +while ($i < 10) { + eval INSERT INTO t2 VALUES ($i, 0); + inc $i; +} +COMMIT; + +--let $i= 0 +while ($i < 10) { + BEGIN; + eval INSERT INTO t2 VALUES ($i+10, 100); + eval UPDATE t2 SET b=$i WHERE a<10; + eval INSERT INTO t2 VALUES ($i+20, 200); + COMMIT; + inc $i; +} + +SELECT COUNT(*), SUM(a), SUM(b) FROM t2; +--source include/save_master_gtid.inc + +--connection server_2 +SET @old_mode= @@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode=aggressive; +SET default_master_connection = "a2b"; +START SLAVE; +--source include/wait_for_slave_to_start.inc +SET default_master_connection = "c2b"; +START SLAVE; +--source include/wait_for_slave_to_start.inc + +--source include/sync_with_master_gtid.inc +SELECT COUNT(*), SUM(a), SUM(b) FROM t2; + +--connection server_3 +--source include/sync_with_master_gtid.inc +SELECT COUNT(*), SUM(a), SUM(b) FROM t2; + +--connection server_4 +--source include/sync_with_master_gtid.inc +SELECT COUNT(*), SUM(a), SUM(b) FROM t2; + + --echo *** Test also with not using parallel replication. --connection server_1 @@ -414,6 +473,7 @@ SET GLOBAL gtid_domain_id=0; --sorted_result STOP ALL SLAVES; SET GLOBAL slave_parallel_threads= @old_parallel; +SET GLOBAL slave_parallel_mode= @old_mode; SET GLOBAL gtid_ignore_duplicates= @old_ignore_duplicates; --connection server_3 @@ -431,25 +491,25 @@ SET GLOBAL slave_parallel_threads= @old_parallel; SET GLOBAL gtid_ignore_duplicates= @old_ignore_duplicates; --connection server_1 -DROP TABLE t1; +DROP TABLE t1, t2; ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; --source include/reset_master_slave.inc --disconnect server_1 --connection server_2 -DROP TABLE t1; +DROP TABLE t1, t2; ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; --source include/reset_master_slave.inc --disconnect server_2 --connection server_3 -DROP TABLE t1; +DROP TABLE t1, t2; ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; --source include/reset_master_slave.inc --disconnect server_3 --connection server_4 -DROP TABLE t1; +DROP TABLE t1, t2; ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; --source include/reset_master_slave.inc --disconnect server_4 diff --git a/mysql-test/suite/multi_source/info_logs.result b/mysql-test/suite/multi_source/info_logs.result index dd06fd0aeb9..36065116784 100644 --- a/mysql-test/suite/multi_source/info_logs.result +++ b/mysql-test/suite/multi_source/info_logs.result @@ -94,17 +94,17 @@ MASTER 2.2 # EOF # show all slaves status; -Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos - Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 relay.000002 master-bin.000001 Yes Yes 0 0 None 0 Yes 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 7 0 60.000 -MASTER 2.2 Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 relay-master@00202@002e2.000002 master-bin.000001 Yes Yes 0 0 None 0 Yes 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 7 0 60.000 +Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos + Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 relay.000002 master-bin.000001 Yes Yes 0 0 None 0 Yes 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 7 0 60.000 +MASTER 2.2 Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 relay-master@00202@002e2.000002 master-bin.000001 Yes Yes 0 0 None 0 Yes 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 7 0 60.000 include/wait_for_slave_to_start.inc set default_master_connection = 'MASTER 2.2'; include/wait_for_slave_to_start.inc set default_master_connection = ''; show all slaves status; -Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos - Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 relay.000004 master-bin.000001 Yes Yes 0 0 None 0 Yes 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 6 0 60.000 -MASTER 2.2 Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 relay-master@00202@002e2.000004 master-bin.000001 Yes Yes 0 0 None 0 Yes 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 6 0 60.000 +Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos + Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 relay.000004 master-bin.000001 Yes Yes 0 0 None 0 Yes 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 6 0 60.000 +MASTER 2.2 Slave has read all relay log; waiting for more updates Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 relay-master@00202@002e2.000004 master-bin.000001 Yes Yes 0 0 None 0 Yes 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for more updates 0 0 0 0 1073741824 6 0 60.000 # # List of files matching '*info*' pattern # after slave server restart diff --git a/mysql-test/suite/multi_source/multi_source_slave_alias_replica.result b/mysql-test/suite/multi_source/multi_source_slave_alias_replica.result index f81bc73ec80..4c721a17428 100644 --- a/mysql-test/suite/multi_source/multi_source_slave_alias_replica.result +++ b/mysql-test/suite/multi_source/multi_source_slave_alias_replica.result @@ -34,7 +34,6 @@ Relay_Log_Pos Relay_Master_Log_File master-bin.000001 Slave_IO_Running Yes Slave_SQL_Running Yes -Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table @@ -76,6 +75,7 @@ Slave_SQL_Running_State Slave has read all relay log; waiting for more updates Slave_DDL_Groups 0 Slave_Non_Transactional_Groups 0 Slave_Transactional_Groups 0 +Replicate_Rewrite_DB Retried_transactions 0 Max_relay_log_size 1073741824 Executed_log_entries 7 @@ -96,7 +96,6 @@ Relay_Log_Pos Relay_Master_Log_File master-bin.000001 Slave_IO_Running Yes Slave_SQL_Running Yes -Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table @@ -138,6 +137,7 @@ Slave_SQL_Running_State Slave has read all relay log; waiting for more updates Slave_DDL_Groups 0 Slave_Non_Transactional_Groups 0 Slave_Transactional_Groups 0 +Replicate_Rewrite_DB Retried_transactions 0 Max_relay_log_size 1073741824 Executed_log_entries 7 diff --git a/mysql-test/suite/multi_source/reset_slave.result b/mysql-test/suite/multi_source/reset_slave.result index 387efc2369b..c859c5d7eb3 100644 --- a/mysql-test/suite/multi_source/reset_slave.result +++ b/mysql-test/suite/multi_source/reset_slave.result @@ -13,15 +13,15 @@ insert into t1 values (1),(2); connection slave; stop slave 'master1'; show slave 'master1' status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups - 127.0.0.1 root MYPORT_1 60 master-bin.000001 mysqld-relay-bin-master1.000002 master-bin.000001 No No 0 0 None 0 Yes NULL No 0 0 1 Slave_Pos 0-1-3 optimistic 0 NULL 2 1 0 +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB + 127.0.0.1 root MYPORT_1 60 master-bin.000001 mysqld-relay-bin-master1.000002 master-bin.000001 No No 0 0 None 0 Yes NULL No 0 0 1 Slave_Pos 0-1-3 optimistic 0 NULL 2 1 0 mysqld-relay-bin-master1.000001 mysqld-relay-bin-master1.000002 mysqld-relay-bin-master1.index reset slave 'master1'; show slave 'master1' status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups - 127.0.0.1 root MYPORT_1 60 4 No No 0 0 0 None 0 Yes NULL No 0 0 1 Slave_Pos optimistic 0 NULL 2 1 0 +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB + 127.0.0.1 root MYPORT_1 60 4 No No 0 0 0 None 0 Yes NULL No 0 0 1 Slave_Pos optimistic 0 NULL 2 1 0 reset slave 'master1' all; show slave 'master1' status; ERROR HY000: There is no master connection 'master1' diff --git a/mysql-test/suite/multi_source/simple.result b/mysql-test/suite/multi_source/simple.result index 4e70e7c9548..f9f43d44ca7 100644 --- a/mysql-test/suite/multi_source/simple.result +++ b/mysql-test/suite/multi_source/simple.result @@ -32,7 +32,6 @@ Relay_Log_Pos Relay_Master_Log_File master-bin.000001 Slave_IO_Running Yes Slave_SQL_Running Yes -Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table @@ -74,6 +73,7 @@ Slave_SQL_Running_State Slave has read all relay log; waiting for more updates Slave_DDL_Groups 0 Slave_Non_Transactional_Groups 0 Slave_Transactional_Groups 0 +Replicate_Rewrite_DB Retried_transactions 0 Max_relay_log_size 1073741824 Executed_log_entries 7 @@ -94,7 +94,6 @@ Relay_Log_Pos Relay_Master_Log_File master-bin.000001 Slave_IO_Running Yes Slave_SQL_Running Yes -Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table @@ -136,6 +135,7 @@ Slave_SQL_Running_State Slave has read all relay log; waiting for more updates Slave_DDL_Groups 0 Slave_Non_Transactional_Groups 0 Slave_Transactional_Groups 0 +Replicate_Rewrite_DB Retried_transactions 0 Max_relay_log_size 1073741824 Executed_log_entries 7 @@ -221,7 +221,6 @@ Relay_Log_Pos Relay_Master_Log_File master-bin.000001 Slave_IO_Running No Slave_SQL_Running No -Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table @@ -263,6 +262,7 @@ Slave_SQL_Running_State Slave_DDL_Groups 0 Slave_Non_Transactional_Groups 0 Slave_Transactional_Groups 0 +Replicate_Rewrite_DB reset slave 'slave1'; show all slaves status; Connection_name slave1 @@ -279,7 +279,6 @@ Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running No Slave_SQL_Running No -Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table @@ -321,6 +320,7 @@ Slave_SQL_Running_State Slave_DDL_Groups 0 Slave_Non_Transactional_Groups 0 Slave_Transactional_Groups 0 +Replicate_Rewrite_DB Retried_transactions 0 Max_relay_log_size 1073741824 Executed_log_entries 7 @@ -341,7 +341,6 @@ Relay_Log_Pos Relay_Master_Log_File master-bin.000001 Slave_IO_Running Yes Slave_SQL_Running Yes -Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table @@ -383,6 +382,7 @@ Slave_SQL_Running_State Slave has read all relay log; waiting for more updates Slave_DDL_Groups 0 Slave_Non_Transactional_Groups 0 Slave_Transactional_Groups 0 +Replicate_Rewrite_DB Retried_transactions 0 Max_relay_log_size 1073741824 Executed_log_entries 7 @@ -405,7 +405,6 @@ Relay_Log_Pos Relay_Master_Log_File master-bin.000001 Slave_IO_Running Yes Slave_SQL_Running Yes -Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table @@ -447,6 +446,7 @@ Slave_SQL_Running_State Slave has read all relay log; waiting for more updates Slave_DDL_Groups 0 Slave_Non_Transactional_Groups 0 Slave_Transactional_Groups 0 +Replicate_Rewrite_DB Retried_transactions 0 Max_relay_log_size 1073741824 Executed_log_entries 7 @@ -471,7 +471,6 @@ Relay_Log_Pos Relay_Master_Log_File master-bin.000001 Slave_IO_Running No Slave_SQL_Running No -Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table @@ -513,6 +512,7 @@ Slave_SQL_Running_State Slave_DDL_Groups 0 Slave_Non_Transactional_Groups 0 Slave_Transactional_Groups 0 +Replicate_Rewrite_DB Retried_transactions 0 Max_relay_log_size 1073741824 Executed_log_entries 7 diff --git a/mysql-test/suite/multi_source/syntax.result b/mysql-test/suite/multi_source/syntax.result index 3c7c91c35c8..6b214fe3644 100644 --- a/mysql-test/suite/multi_source/syntax.result +++ b/mysql-test/suite/multi_source/syntax.result @@ -1,11 +1,11 @@ include/master-slave.inc [connection master] show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB show slave '' status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB show all slaves status; -Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Rewrite_DB Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos +Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Replicate_Rewrite_DB Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos # # Check error handling # diff --git a/mysql-test/suite/parts/inc/partition_crash.inc b/mysql-test/suite/parts/inc/partition_crash.inc index c657ba880c9..bd00f6ca0d5 100644 --- a/mysql-test/suite/parts/inc/partition_crash.inc +++ b/mysql-test/suite/parts/inc/partition_crash.inc @@ -11,7 +11,7 @@ SHOW CREATE TABLE t1; --sorted_result SELECT * FROM t1; ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --disable_reconnect # CR_SERVER_LOST --error 2013 @@ -22,7 +22,7 @@ SELECT * FROM t1; --replace_regex /sql-exchange.*\./sql-exchange./ /sql-shadow-[0-9a-f]*-/sql-shadow-/ --cat_file $DATADIR.files.txt --remove_file $DATADIR.files.txt ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc --echo # State after crash recovery diff --git a/mysql-test/suite/parts/r/alter_table.result b/mysql-test/suite/parts/r/alter_table.result index feb43dc7554..0a78be2b215 100644 --- a/mysql-test/suite/parts/r/alter_table.result +++ b/mysql-test/suite/parts/r/alter_table.result @@ -1,3 +1,6 @@ +# +# MDEV-22649 SIGSEGV in ha_partition::create_partitioning_metadata on ALTER +# set @save_alter_algorithm= @@session.alter_algorithm; SET SESSION alter_algorithm=4; CREATE TABLE t1(a INT) engine=myisam PARTITION BY RANGE(a) SUBPARTITION BY KEY(a) (PARTITION p0 VALUES LESS THAN (10) (SUBPARTITION s0,SUBPARTITION s1), PARTITION p1 VALUES LESS THAN (20) (SUBPARTITION s2,SUBPARTITION s3)); @@ -18,9 +21,16 @@ ALTER TABLE t1 ADD COLUMN c INT; ERROR 0A000: ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=COPY DROP table if exists t1; set @@session.alter_algorithm= @save_alter_algorithm; +# +# MDEV-22804 SIGSEGV in ha_partition::create_partitioning_metadata | +# ERROR 1507 (HY000): Error in list of partitions to DROP +# CREATE TABLE t1 (a INT) PARTITION BY RANGE(a) SUBPARTITION BY HASH(a) (PARTITION p VALUES LESS THAN (5) (SUBPARTITION sp, SUBPARTITION sp1), PARTITION p1 VALUES LESS THAN MAXVALUE (SUBPARTITION sp2, SUBPARTITION sp3)); ALTER TABLE t1 DROP PARTITION p; DROP TABLE if exists t1; +# +# MDEV-23357 Server crashes in Sql_cmd_alter_table_exchange_partition::exchange_partition +# CREATE TABLE t1 (i INT); CREATE VIEW v1 as SELECT * FROM t1; CREATE TABLE t2 (i INT); @@ -28,6 +38,7 @@ ALTER TABLE v1 EXCHANGE PARTITION p2 WITH TABLE t2 ; ERROR 42000: Can't open table DROP VIEW v1; DROP TABLE t1, t2; +# End of 10.5 tests # # MDEV-22165 CONVERT PARTITION: move in partition from existing table # @@ -358,6 +369,7 @@ disconnect con1; connection default; drop user u@localhost; drop database db; +# End of 10.11 tests # # MDEV-22164 without validation for exchange partition/convert in # diff --git a/mysql-test/suite/parts/r/mdev_21007.result b/mysql-test/suite/parts/r/mdev_21007.result new file mode 100644 index 00000000000..fb2417ac3ae --- /dev/null +++ b/mysql-test/suite/parts/r/mdev_21007.result @@ -0,0 +1,5 @@ +CREATE TABLE t1 (a INT) PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (1), PARTITION p1 VALUES LESS THAN (MAXVALUE)); +INSERT INTO t1 VALUES (1),(2); +ALTER TABLE t1 MODIFY a INT AUTO_INCREMENT PRIMARY KEY; +UPDATE t1 PARTITION (p1) SET a=9 ORDER BY a LIMIT 1; +DROP TABLE t1; diff --git a/mysql-test/suite/parts/r/partition_alter4_innodb.result b/mysql-test/suite/parts/r/partition_alter4_innodb.result index aab121f2b23..d4efb87a59c 100644 --- a/mysql-test/suite/parts/r/partition_alter4_innodb.result +++ b/mysql-test/suite/parts/r/partition_alter4_innodb.result @@ -60,7 +60,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -521,7 +520,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -993,7 +991,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -1466,7 +1463,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -1933,7 +1929,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -2406,7 +2401,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -2884,7 +2878,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -3360,7 +3353,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -3826,7 +3818,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -4287,7 +4278,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -4759,7 +4749,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -5232,7 +5221,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -5699,7 +5687,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -6172,7 +6159,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -6650,7 +6636,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -7126,7 +7111,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -15108,7 +15092,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -15569,7 +15552,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -16041,7 +16023,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -16514,7 +16495,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -16981,7 +16961,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -17454,7 +17433,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -17932,7 +17910,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -18408,7 +18385,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template diff --git a/mysql-test/suite/parts/r/partition_alter4_myisam.result b/mysql-test/suite/parts/r/partition_alter4_myisam.result index c863d479fbb..3c06585e93a 100644 --- a/mysql-test/suite/parts/r/partition_alter4_myisam.result +++ b/mysql-test/suite/parts/r/partition_alter4_myisam.result @@ -60,7 +60,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -530,7 +529,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -1017,7 +1015,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -1511,7 +1508,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -1995,7 +1991,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -2489,7 +2484,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -2988,7 +2982,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -3485,7 +3478,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -3974,7 +3966,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -4444,7 +4435,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -4931,7 +4921,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -5425,7 +5414,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -5909,7 +5897,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -6403,7 +6390,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -6902,7 +6888,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -7399,7 +7384,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -15700,7 +15684,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -16170,7 +16153,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -16657,7 +16639,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -17151,7 +17132,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -17635,7 +17615,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -18129,7 +18108,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -18628,7 +18606,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -19125,7 +19102,6 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template diff --git a/mysql-test/suite/parts/r/partition_alter_myisam.result b/mysql-test/suite/parts/r/partition_alter_myisam.result index ec6cbe92b0a..c76c6aba921 100644 --- a/mysql-test/suite/parts/r/partition_alter_myisam.result +++ b/mysql-test/suite/parts/r/partition_alter_myisam.result @@ -88,3 +88,25 @@ insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1; alter online table t1 delay_key_write=0; alter online table t1 delay_key_write=1; drop table t1; +# +# MDEV-25102 UNIQUE USING HASH error after ALTER ... DISABLE KEYS +# +create table t1 (i1 int primary key, i2 int, d1 date, key(i2)) +partition by hash(i1) partitions 3; +insert into t1 values(0, 1, '2010-10-10'); +select index_name, comment from information_schema.statistics where table_schema='test' and table_name='t1'; +index_name comment +PRIMARY +i2 +alter table t1 disable keys; +select index_name, comment from information_schema.statistics where table_schema='test' and table_name='t1'; +index_name comment +PRIMARY +i2 disabled +alter table t1 add partition (partition p4); +select index_name, comment from information_schema.statistics where table_schema='test' and table_name='t1'; +index_name comment +PRIMARY +i2 disabled +drop table t1; +# End of 10.11 tests diff --git a/mysql-test/suite/parts/r/partition_mgm_lc0_innodb.result b/mysql-test/suite/parts/r/partition_mgm_lc0_innodb.result index 88784224723..28dcddd9aef 100644 --- a/mysql-test/suite/parts/r/partition_mgm_lc0_innodb.result +++ b/mysql-test/suite/parts/r/partition_mgm_lc0_innodb.result @@ -1020,7 +1020,6 @@ a b 2001 Second in MAX ALTER TABLE t1 ANALYZE PARTITION MAX; Table Op Msg_type Msg_text -MySQL_Test_DB.t1 analyze status Engine-independent statistics collected MySQL_Test_DB.t1 analyze status OK # Truncate without FLUSH ALTER TABLE t1 TRUNCATE PARTITION MAX; diff --git a/mysql-test/suite/parts/r/partition_mgm_lc0_memory.result b/mysql-test/suite/parts/r/partition_mgm_lc0_memory.result index 92457a21043..204ef94da6e 100644 --- a/mysql-test/suite/parts/r/partition_mgm_lc0_memory.result +++ b/mysql-test/suite/parts/r/partition_mgm_lc0_memory.result @@ -1020,7 +1020,6 @@ a b 2001 Second in MAX ALTER TABLE t1 ANALYZE PARTITION MAX; Table Op Msg_type Msg_text -MySQL_Test_DB.t1 analyze status Engine-independent statistics collected MySQL_Test_DB.t1 analyze note The storage engine for the table doesn't support analyze # Truncate without FLUSH ALTER TABLE t1 TRUNCATE PARTITION MAX; diff --git a/mysql-test/suite/parts/r/partition_mgm_lc0_myisam.result b/mysql-test/suite/parts/r/partition_mgm_lc0_myisam.result index fea80a3feb3..10f8fbe11a4 100644 --- a/mysql-test/suite/parts/r/partition_mgm_lc0_myisam.result +++ b/mysql-test/suite/parts/r/partition_mgm_lc0_myisam.result @@ -1020,7 +1020,6 @@ a b 2001 Second in MAX ALTER TABLE t1 ANALYZE PARTITION MAX; Table Op Msg_type Msg_text -MySQL_Test_DB.t1 analyze status Engine-independent statistics collected MySQL_Test_DB.t1 analyze status OK # Truncate without FLUSH ALTER TABLE t1 TRUNCATE PARTITION MAX; diff --git a/mysql-test/suite/parts/r/partition_mgm_lc1_innodb.result b/mysql-test/suite/parts/r/partition_mgm_lc1_innodb.result index 418650eb438..d9b677acf5a 100644 --- a/mysql-test/suite/parts/r/partition_mgm_lc1_innodb.result +++ b/mysql-test/suite/parts/r/partition_mgm_lc1_innodb.result @@ -987,7 +987,6 @@ a b 2001 Second in MAX ALTER TABLE t1 ANALYZE PARTITION MAX; Table Op Msg_type Msg_text -mysql_test_db.t1 analyze status Engine-independent statistics collected mysql_test_db.t1 analyze status OK # Truncate without FLUSH ALTER TABLE t1 TRUNCATE PARTITION MAX; diff --git a/mysql-test/suite/parts/r/partition_mgm_lc1_memory.result b/mysql-test/suite/parts/r/partition_mgm_lc1_memory.result index 96e72cbfb41..601f6cb7812 100644 --- a/mysql-test/suite/parts/r/partition_mgm_lc1_memory.result +++ b/mysql-test/suite/parts/r/partition_mgm_lc1_memory.result @@ -987,7 +987,6 @@ a b 2001 Second in MAX ALTER TABLE t1 ANALYZE PARTITION MAX; Table Op Msg_type Msg_text -mysql_test_db.t1 analyze status Engine-independent statistics collected mysql_test_db.t1 analyze note The storage engine for the table doesn't support analyze # Truncate without FLUSH ALTER TABLE t1 TRUNCATE PARTITION MAX; diff --git a/mysql-test/suite/parts/r/partition_mgm_lc1_myisam.result b/mysql-test/suite/parts/r/partition_mgm_lc1_myisam.result index 0ab07cdc993..936f972ddb8 100644 --- a/mysql-test/suite/parts/r/partition_mgm_lc1_myisam.result +++ b/mysql-test/suite/parts/r/partition_mgm_lc1_myisam.result @@ -987,7 +987,6 @@ a b 2001 Second in MAX ALTER TABLE t1 ANALYZE PARTITION MAX; Table Op Msg_type Msg_text -mysql_test_db.t1 analyze status Engine-independent statistics collected mysql_test_db.t1 analyze status OK # Truncate without FLUSH ALTER TABLE t1 TRUNCATE PARTITION MAX; diff --git a/mysql-test/suite/parts/r/partition_recover_myisam.result b/mysql-test/suite/parts/r/partition_recover_myisam.result index 1eddf51b087..129e84e5db4 100644 --- a/mysql-test/suite/parts/r/partition_recover_myisam.result +++ b/mysql-test/suite/parts/r/partition_recover_myisam.result @@ -1,3 +1,6 @@ +call mtr.add_suppression("..test.t1_will_crash"); +call mtr.add_suppression("Got an error from unknown thread"); +call mtr.add_suppression("Table 't1_will_crash' is marked as crashed and should be repaired"); CREATE TABLE t1_will_crash (a INT, KEY (a)) ENGINE=MyISAM; INSERT INTO t1_will_crash VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11); FLUSH TABLES; diff --git a/mysql-test/suite/parts/t/alter_table.test b/mysql-test/suite/parts/t/alter_table.test index b52e33ac79d..f1da7cc3284 100644 --- a/mysql-test/suite/parts/t/alter_table.test +++ b/mysql-test/suite/parts/t/alter_table.test @@ -1,12 +1,18 @@ # Permissions don't work with embedded --source include/not_embedded.inc + +# +# General bugs with ALTER TABLE and partitions that doesn't have to be run +# on all engines +# + --source include/have_partition.inc --source include/lcase_names.inc --source suite/parts/inc/engines.inc -# -# MDEV-22649 SIGSEGV in ha_partition::create_partitioning_metadata on ALTER -# +--echo # +--echo # MDEV-22649 SIGSEGV in ha_partition::create_partitioning_metadata on ALTER +--echo # set @save_alter_algorithm= @@session.alter_algorithm; SET SESSION alter_algorithm=4; @@ -18,18 +24,18 @@ DROP table if exists t1; set @@session.alter_algorithm= @save_alter_algorithm; -# -# MDEV-22804 SIGSEGV in ha_partition::create_partitioning_metadata | -# ERROR 1507 (HY000): Error in list of partitions to DROP -# +--echo # +--echo # MDEV-22804 SIGSEGV in ha_partition::create_partitioning_metadata | +--echo # ERROR 1507 (HY000): Error in list of partitions to DROP +--echo # CREATE TABLE t1 (a INT) PARTITION BY RANGE(a) SUBPARTITION BY HASH(a) (PARTITION p VALUES LESS THAN (5) (SUBPARTITION sp, SUBPARTITION sp1), PARTITION p1 VALUES LESS THAN MAXVALUE (SUBPARTITION sp2, SUBPARTITION sp3)); ALTER TABLE t1 DROP PARTITION p; DROP TABLE if exists t1; -# -# MDEV-23357 Server crashes in Sql_cmd_alter_table_exchange_partition::exchange_partition -# +--echo # +--echo # MDEV-23357 Server crashes in Sql_cmd_alter_table_exchange_partition::exchange_partition +--echo # CREATE TABLE t1 (i INT); CREATE VIEW v1 as SELECT * FROM t1; CREATE TABLE t2 (i INT); @@ -38,6 +44,8 @@ ALTER TABLE v1 EXCHANGE PARTITION p2 WITH TABLE t2 ; DROP VIEW v1; DROP TABLE t1, t2; +--echo # End of 10.5 tests + --echo # --echo # MDEV-22165 CONVERT PARTITION: move in partition from existing table --echo # @@ -320,6 +328,8 @@ alter table t1 convert table tp to partition p2 values less than (1000); drop user u@localhost; drop database db; +--echo # End of 10.11 tests + --echo # --echo # MDEV-22164 without validation for exchange partition/convert in --echo # diff --git a/mysql-test/suite/parts/t/mdev_21007.test b/mysql-test/suite/parts/t/mdev_21007.test new file mode 100644 index 00000000000..ec6fbe4d108 --- /dev/null +++ b/mysql-test/suite/parts/t/mdev_21007.test @@ -0,0 +1,9 @@ +--source include/have_partition.inc + +CREATE TABLE t1 (a INT) PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (1), PARTITION p1 VALUES LESS THAN (MAXVALUE)); +INSERT INTO t1 VALUES (1),(2); +ALTER TABLE t1 MODIFY a INT AUTO_INCREMENT PRIMARY KEY; +UPDATE t1 PARTITION (p1) SET a=9 ORDER BY a LIMIT 1; + +# Cleanup +DROP TABLE t1; diff --git a/mysql-test/suite/parts/t/partition_alter_myisam.test b/mysql-test/suite/parts/t/partition_alter_myisam.test index d3abb8842e1..794c07797f9 100644 --- a/mysql-test/suite/parts/t/partition_alter_myisam.test +++ b/mysql-test/suite/parts/t/partition_alter_myisam.test @@ -22,3 +22,18 @@ insert into t1 select rand()*1000, rand()*1000, repeat('b', 100) from t1; alter online table t1 delay_key_write=0; alter online table t1 delay_key_write=1; drop table t1; + +--echo # +--echo # MDEV-25102 UNIQUE USING HASH error after ALTER ... DISABLE KEYS +--echo # +create table t1 (i1 int primary key, i2 int, d1 date, key(i2)) +partition by hash(i1) partitions 3; +insert into t1 values(0, 1, '2010-10-10'); +select index_name, comment from information_schema.statistics where table_schema='test' and table_name='t1'; +alter table t1 disable keys; +select index_name, comment from information_schema.statistics where table_schema='test' and table_name='t1'; +alter table t1 add partition (partition p4); +select index_name, comment from information_schema.statistics where table_schema='test' and table_name='t1'; +drop table t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/suite/parts/t/partition_recover_myisam-master.opt b/mysql-test/suite/parts/t/partition_recover_myisam-master.opt deleted file mode 100644 index ddbd7a0a8c5..00000000000 --- a/mysql-test/suite/parts/t/partition_recover_myisam-master.opt +++ /dev/null @@ -1 +0,0 @@ ---myisam-recover-options diff --git a/mysql-test/suite/parts/t/partition_recover_myisam.opt b/mysql-test/suite/parts/t/partition_recover_myisam.opt new file mode 100644 index 00000000000..ca3d0cddc18 --- /dev/null +++ b/mysql-test/suite/parts/t/partition_recover_myisam.opt @@ -0,0 +1 @@ +--safe-mode diff --git a/mysql-test/suite/parts/t/partition_recover_myisam.test b/mysql-test/suite/parts/t/partition_recover_myisam.test index 91a14a51b3c..3106407bea9 100644 --- a/mysql-test/suite/parts/t/partition_recover_myisam.test +++ b/mysql-test/suite/parts/t/partition_recover_myisam.test @@ -1,18 +1,10 @@ # test the auto-recover (--myisam-recover) of partitioned myisam tables ---disable_query_log call mtr.add_suppression("..test.t1_will_crash"); call mtr.add_suppression("Got an error from unknown thread"); call mtr.add_suppression("Table 't1_will_crash' is marked as crashed and should be repaired"); ---enable_query_log --source include/have_partition.inc ---disable_warnings ---disable_query_log -drop table if exists t1_will_crash; ---enable_query_log ---enable_warnings - CREATE TABLE t1_will_crash (a INT, KEY (a)) ENGINE=MyISAM; INSERT INTO t1_will_crash VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11); diff --git a/mysql-test/suite/perfschema/include/memory_aggregate_load.inc b/mysql-test/suite/perfschema/include/memory_aggregate_load.inc index 7a54d25216e..c6e58d094d6 100644 --- a/mysql-test/suite/perfschema/include/memory_aggregate_load.inc +++ b/mysql-test/suite/perfschema/include/memory_aggregate_load.inc @@ -274,7 +274,6 @@ execute dump_users; execute dump_hosts; --disconnect con1 ---disconnect con5 --connection default @@ -283,6 +282,8 @@ let $wait_condition= select count(*) = 0 from performance_schema.threads where `TYPE`='FOREGROUND' and PROCESSLIST_USER= 'user1'; --source include/wait_condition.inc + +--disconnect con5 let $wait_condition= select count(*) = 1 from performance_schema.threads where `TYPE`='FOREGROUND' and PROCESSLIST_USER= 'user4'; diff --git a/mysql-test/suite/perfschema/include/program_execution.inc b/mysql-test/suite/perfschema/include/program_execution.inc index 8c0bc691898..f774a4d7b50 100644 --- a/mysql-test/suite/perfschema/include/program_execution.inc +++ b/mysql-test/suite/perfschema/include/program_execution.inc @@ -32,7 +32,7 @@ SET GLOBAL event_scheduler=ON; CREATE TABLE table_t(a INT); DELIMITER |; -CREATE EVENT e1 ON SCHEDULE EVERY 2 SECOND DO +CREATE EVENT e1 ON SCHEDULE EVERY 2 SECOND ON COMPLETION NOT PRESERVE DO BEGIN INSERT INTO table_t VALUES(1); END| diff --git a/mysql-test/suite/perfschema/include/stage_setup.inc b/mysql-test/suite/perfschema/include/stage_setup.inc index 683c4561c15..ba97d9094a9 100644 --- a/mysql-test/suite/perfschema/include/stage_setup.inc +++ b/mysql-test/suite/perfschema/include/stage_setup.inc @@ -121,12 +121,23 @@ begin where thread_id = my_thread_id and nesting_event_id = my_statement_id order by event_id asc; - # Ignore query cache as it may not be enabled - select username, event_name, nesting_event_type - from performance_schema.events_stages_history - where thread_id = my_thread_id - and nesting_event_id = my_statement_id and - event_name not like "%query cache%" + # 1. Ignore query cache as it may not be enabled + # 2. MDL wait consists of short 1 second waits (this is not configurable) + # repeated until lock_wait_timeout is reached. The stage is changed + # to Waiting and back every second. To have predictable result here + # the query filters all sequences of X, "Waiting for MDL", X, + # leaving just X. + with h as ( + select event_id, username, event_name, nesting_event_type, + lag(event_name) over (order by event_id) = lead(event_name) over (order by event_id) + and event_name = "stage/sql/Waiting for stored function metadata lock" as v1, + lag(event_name, 2) over (order by event_id) = event_name + and lag(event_name, 1) over (order by event_id) = "stage/sql/Waiting for stored function metadata lock" as v2 + from performance_schema.events_stages_history + where thread_id = my_thread_id + and nesting_event_id = my_statement_id and + event_name not like "%query cache%" + ) select username, event_name, nesting_event_type from h where v1 is not true and v2 is not true order by event_id asc; end; else diff --git a/mysql-test/suite/perfschema/r/alter_table_progress.result b/mysql-test/suite/perfschema/r/alter_table_progress.result index d97377d3721..85262bf3264 100644 --- a/mysql-test/suite/perfschema/r/alter_table_progress.result +++ b/mysql-test/suite/perfschema/r/alter_table_progress.result @@ -82,9 +82,8 @@ stage/sql/After apply log event NULL NULL stage/sql/Rename result table NULL NULL stage/sql/End of update loop NULL NULL stage/sql/Query end NULL NULL -stage/sql/Commit NULL NULL stage/sql/closing tables NULL NULL -stage/sql/Commit implicit NULL NULL +stage/sql/Query end NULL NULL stage/sql/Starting cleanup NULL NULL stage/sql/Freeing items NULL NULL stage/sql/Reset for next command NULL NULL diff --git a/mysql-test/suite/perfschema/r/event_aggregate.result b/mysql-test/suite/perfschema/r/event_aggregate.result index 795232a9bcc..02d2c134c9a 100644 --- a/mysql-test/suite/perfschema/r/event_aggregate.result +++ b/mysql-test/suite/perfschema/r/event_aggregate.result @@ -251,35 +251,35 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 4 localhost stage/sql/closing tables 12 localhost stage/sql/init 3 localhost stage/sql/Opening tables 8 -localhost stage/sql/starting 6 +localhost stage/sql/starting 7 execute dump_stages_global; event_name count_star stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -383,7 +383,7 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 0 user2 localhost stage/sql/closing tables 0 user2 localhost stage/sql/init 0 @@ -395,7 +395,7 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 0 user2 stage/sql/closing tables 0 user2 stage/sql/init 0 @@ -407,21 +407,21 @@ localhost stage/sql/checking permissions 4 localhost stage/sql/closing tables 12 localhost stage/sql/init 3 localhost stage/sql/Opening tables 8 -localhost stage/sql/starting 6 +localhost stage/sql/starting 7 execute dump_stages_global; event_name count_star stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -551,45 +551,45 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 8 localhost stage/sql/closing tables 23 localhost stage/sql/init 6 localhost stage/sql/Opening tables 15 -localhost stage/sql/starting 12 +localhost stage/sql/starting 14 execute dump_stages_global; event_name count_star stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -712,12 +712,12 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 0 user3 localhost stage/sql/closing tables 0 user3 localhost stage/sql/init 0 @@ -729,12 +729,12 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 0 user3 stage/sql/closing tables 0 user3 stage/sql/init 0 @@ -746,21 +746,21 @@ localhost stage/sql/checking permissions 8 localhost stage/sql/closing tables 23 localhost stage/sql/init 6 localhost stage/sql/Opening tables 15 -localhost stage/sql/starting 12 +localhost stage/sql/starting 14 execute dump_stages_global; event_name count_star stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -909,55 +909,55 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 12 localhost stage/sql/closing tables 34 localhost stage/sql/init 9 localhost stage/sql/Opening tables 22 -localhost stage/sql/starting 18 +localhost stage/sql/starting 21 execute dump_stages_global; event_name count_star stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1099,17 +1099,17 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 0 user4 localhost stage/sql/closing tables 0 user4 localhost stage/sql/init 0 @@ -1121,17 +1121,17 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 0 user4 stage/sql/closing tables 0 user4 stage/sql/init 0 @@ -1143,21 +1143,21 @@ localhost stage/sql/checking permissions 12 localhost stage/sql/closing tables 34 localhost stage/sql/init 9 localhost stage/sql/Opening tables 22 -localhost stage/sql/starting 18 +localhost stage/sql/starting 21 execute dump_stages_global; event_name count_star stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1325,65 +1325,65 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 24 +localhost stage/sql/starting 28 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1538,65 +1538,65 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 25 +localhost stage/sql/starting 29 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1751,65 +1751,65 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 26 +localhost stage/sql/starting 30 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1963,65 +1963,65 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 27 +localhost stage/sql/starting 31 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2174,65 +2174,65 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2386,65 +2386,65 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2597,65 +2597,65 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2808,65 +2808,65 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3019,65 +3019,65 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3230,65 +3230,65 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3441,65 +3441,65 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3674,43 +3674,43 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3907,21 +3907,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4125,14 +4125,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4343,7 +4343,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4554,7 +4554,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4765,7 +4765,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4976,7 +4976,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -5187,7 +5187,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -5398,7 +5398,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -5609,7 +5609,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -5820,7 +5820,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -6031,7 +6031,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -6242,7 +6242,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -6453,7 +6453,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -6636,7 +6636,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -6763,7 +6763,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -6862,7 +6862,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; diff --git a/mysql-test/suite/perfschema/r/event_aggregate_no_a.result b/mysql-test/suite/perfschema/r/event_aggregate_no_a.result index 076a5c9945e..f53a54ecae4 100644 --- a/mysql-test/suite/perfschema/r/event_aggregate_no_a.result +++ b/mysql-test/suite/perfschema/r/event_aggregate_no_a.result @@ -235,28 +235,28 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 4 localhost stage/sql/closing tables 12 localhost stage/sql/init 3 localhost stage/sql/Opening tables 8 -localhost stage/sql/starting 6 +localhost stage/sql/starting 7 execute dump_stages_global; event_name count_star stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -350,7 +350,7 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 0 user2 stage/sql/closing tables 0 user2 stage/sql/init 0 @@ -362,21 +362,21 @@ localhost stage/sql/checking permissions 4 localhost stage/sql/closing tables 12 localhost stage/sql/init 3 localhost stage/sql/Opening tables 8 -localhost stage/sql/starting 6 +localhost stage/sql/starting 7 execute dump_stages_global; event_name count_star stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -489,33 +489,33 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 8 localhost stage/sql/closing tables 23 localhost stage/sql/init 6 localhost stage/sql/Opening tables 15 -localhost stage/sql/starting 12 +localhost stage/sql/starting 14 execute dump_stages_global; event_name count_star stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -619,12 +619,12 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 0 user3 stage/sql/closing tables 0 user3 stage/sql/init 0 @@ -636,21 +636,21 @@ localhost stage/sql/checking permissions 8 localhost stage/sql/closing tables 23 localhost stage/sql/init 6 localhost stage/sql/Opening tables 15 -localhost stage/sql/starting 12 +localhost stage/sql/starting 14 execute dump_stages_global; event_name count_star stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -773,38 +773,38 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 12 localhost stage/sql/closing tables 34 localhost stage/sql/init 9 localhost stage/sql/Opening tables 22 -localhost stage/sql/starting 18 +localhost stage/sql/starting 21 execute dump_stages_global; event_name count_star stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -918,17 +918,17 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 0 user4 stage/sql/closing tables 0 user4 stage/sql/init 0 @@ -940,21 +940,21 @@ localhost stage/sql/checking permissions 12 localhost stage/sql/closing tables 34 localhost stage/sql/init 9 localhost stage/sql/Opening tables 22 -localhost stage/sql/starting 18 +localhost stage/sql/starting 21 execute dump_stages_global; event_name count_star stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1087,43 +1087,43 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 24 +localhost stage/sql/starting 28 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1243,43 +1243,43 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 25 +localhost stage/sql/starting 29 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1399,43 +1399,43 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 26 +localhost stage/sql/starting 30 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1554,43 +1554,43 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 27 +localhost stage/sql/starting 31 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1708,43 +1708,43 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1863,43 +1863,43 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2017,43 +2017,43 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2171,43 +2171,43 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2325,43 +2325,43 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2479,43 +2479,43 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2633,43 +2633,43 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2787,43 +2787,43 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2963,21 +2963,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3124,14 +3124,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3285,7 +3285,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3439,7 +3439,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3593,7 +3593,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3747,7 +3747,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3901,7 +3901,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4055,7 +4055,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4209,7 +4209,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4363,7 +4363,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4517,7 +4517,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4671,7 +4671,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4825,7 +4825,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4979,7 +4979,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -5105,7 +5105,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -5203,7 +5203,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; diff --git a/mysql-test/suite/perfschema/r/event_aggregate_no_a_no_h.result b/mysql-test/suite/perfschema/r/event_aggregate_no_a_no_h.result index 4d590f15b68..a4510e11694 100644 --- a/mysql-test/suite/perfschema/r/event_aggregate_no_a_no_h.result +++ b/mysql-test/suite/perfschema/r/event_aggregate_no_a_no_h.result @@ -205,7 +205,7 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -214,14 +214,14 @@ stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -306,7 +306,7 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 0 user2 stage/sql/closing tables 0 user2 stage/sql/init 0 @@ -320,14 +320,14 @@ stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -431,12 +431,12 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -445,14 +445,14 @@ stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -547,12 +547,12 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 0 user3 stage/sql/closing tables 0 user3 stage/sql/init 0 @@ -566,14 +566,14 @@ stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -687,17 +687,17 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -706,14 +706,14 @@ stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -818,17 +818,17 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 0 user4 stage/sql/closing tables 0 user4 stage/sql/init 0 @@ -842,14 +842,14 @@ stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -973,22 +973,22 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -997,14 +997,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1115,22 +1115,22 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -1139,14 +1139,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1257,22 +1257,22 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -1281,14 +1281,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1398,22 +1398,22 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -1422,14 +1422,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1538,22 +1538,22 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -1562,14 +1562,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1679,22 +1679,22 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -1703,14 +1703,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1819,22 +1819,22 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -1843,14 +1843,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1959,22 +1959,22 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -1983,14 +1983,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2099,22 +2099,22 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -2123,14 +2123,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2239,22 +2239,22 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -2263,14 +2263,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2379,22 +2379,22 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -2403,14 +2403,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2519,22 +2519,22 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -2543,14 +2543,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2683,14 +2683,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2823,14 +2823,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2970,7 +2970,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3110,7 +3110,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3250,7 +3250,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3390,7 +3390,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3530,7 +3530,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3670,7 +3670,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3810,7 +3810,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3950,7 +3950,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4090,7 +4090,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4230,7 +4230,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4370,7 +4370,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4510,7 +4510,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4622,7 +4622,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4706,7 +4706,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; diff --git a/mysql-test/suite/perfschema/r/event_aggregate_no_a_no_u.result b/mysql-test/suite/perfschema/r/event_aggregate_no_a_no_u.result index c420f3a7d10..0623f5b9459 100644 --- a/mysql-test/suite/perfschema/r/event_aggregate_no_a_no_u.result +++ b/mysql-test/suite/perfschema/r/event_aggregate_no_a_no_u.result @@ -219,21 +219,21 @@ localhost stage/sql/checking permissions 4 localhost stage/sql/closing tables 12 localhost stage/sql/init 3 localhost stage/sql/Opening tables 8 -localhost stage/sql/starting 6 +localhost stage/sql/starting 7 execute dump_stages_global; event_name count_star stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -317,21 +317,21 @@ localhost stage/sql/checking permissions 4 localhost stage/sql/closing tables 12 localhost stage/sql/init 3 localhost stage/sql/Opening tables 8 -localhost stage/sql/starting 6 +localhost stage/sql/starting 7 execute dump_stages_global; event_name count_star stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -427,21 +427,21 @@ localhost stage/sql/checking permissions 8 localhost stage/sql/closing tables 23 localhost stage/sql/init 6 localhost stage/sql/Opening tables 15 -localhost stage/sql/starting 12 +localhost stage/sql/starting 14 execute dump_stages_global; event_name count_star stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -526,21 +526,21 @@ localhost stage/sql/checking permissions 8 localhost stage/sql/closing tables 23 localhost stage/sql/init 6 localhost stage/sql/Opening tables 15 -localhost stage/sql/starting 12 +localhost stage/sql/starting 14 execute dump_stages_global; event_name count_star stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -637,21 +637,21 @@ localhost stage/sql/checking permissions 12 localhost stage/sql/closing tables 34 localhost stage/sql/init 9 localhost stage/sql/Opening tables 22 -localhost stage/sql/starting 18 +localhost stage/sql/starting 21 execute dump_stages_global; event_name count_star stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -737,21 +737,21 @@ localhost stage/sql/checking permissions 12 localhost stage/sql/closing tables 34 localhost stage/sql/init 9 localhost stage/sql/Opening tables 22 -localhost stage/sql/starting 18 +localhost stage/sql/starting 21 execute dump_stages_global; event_name count_star stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -849,21 +849,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 24 +localhost stage/sql/starting 28 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -948,21 +948,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 25 +localhost stage/sql/starting 29 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1047,21 +1047,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 26 +localhost stage/sql/starting 30 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1145,21 +1145,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 27 +localhost stage/sql/starting 31 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1242,21 +1242,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1340,21 +1340,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1437,21 +1437,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1534,21 +1534,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1631,21 +1631,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1728,21 +1728,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1825,21 +1825,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1922,21 +1922,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2019,21 +2019,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2123,14 +2123,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2227,7 +2227,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2324,7 +2324,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2421,7 +2421,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2518,7 +2518,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2615,7 +2615,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2712,7 +2712,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2809,7 +2809,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2906,7 +2906,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3003,7 +3003,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3100,7 +3100,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3197,7 +3197,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3294,7 +3294,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3391,7 +3391,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -3488,7 +3488,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; diff --git a/mysql-test/suite/perfschema/r/event_aggregate_no_a_no_u_no_h.result b/mysql-test/suite/perfschema/r/event_aggregate_no_a_no_u_no_h.result index f3708c72c1d..d4161510a57 100644 --- a/mysql-test/suite/perfschema/r/event_aggregate_no_a_no_u_no_h.result +++ b/mysql-test/suite/perfschema/r/event_aggregate_no_a_no_u_no_h.result @@ -191,14 +191,14 @@ stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -275,14 +275,14 @@ stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -371,14 +371,14 @@ stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -456,14 +456,14 @@ stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -553,14 +553,14 @@ stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -639,14 +639,14 @@ stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -737,14 +737,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -822,14 +822,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -907,14 +907,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -991,14 +991,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1074,14 +1074,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1158,14 +1158,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1241,14 +1241,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1324,14 +1324,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1407,14 +1407,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1490,14 +1490,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1573,14 +1573,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1656,14 +1656,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1739,14 +1739,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1822,14 +1822,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1912,7 +1912,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -1995,7 +1995,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2078,7 +2078,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2161,7 +2161,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2244,7 +2244,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2327,7 +2327,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2410,7 +2410,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2493,7 +2493,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2576,7 +2576,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2659,7 +2659,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2742,7 +2742,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2825,7 +2825,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2908,7 +2908,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -2991,7 +2991,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; diff --git a/mysql-test/suite/perfschema/r/event_aggregate_no_h.result b/mysql-test/suite/perfschema/r/event_aggregate_no_h.result index 8ea30a0f8c1..edd335e4f11 100644 --- a/mysql-test/suite/perfschema/r/event_aggregate_no_h.result +++ b/mysql-test/suite/perfschema/r/event_aggregate_no_h.result @@ -221,14 +221,14 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -237,14 +237,14 @@ stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -339,7 +339,7 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 0 user2 localhost stage/sql/closing tables 0 user2 localhost stage/sql/init 0 @@ -351,7 +351,7 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 0 user2 stage/sql/closing tables 0 user2 stage/sql/init 0 @@ -365,14 +365,14 @@ stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -493,24 +493,24 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -519,14 +519,14 @@ stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -640,12 +640,12 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 0 user3 localhost stage/sql/closing tables 0 user3 localhost stage/sql/init 0 @@ -657,12 +657,12 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 0 user3 stage/sql/closing tables 0 user3 stage/sql/init 0 @@ -676,14 +676,14 @@ stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -823,34 +823,34 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -859,14 +859,14 @@ stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -999,17 +999,17 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 0 user4 localhost stage/sql/closing tables 0 user4 localhost stage/sql/init 0 @@ -1021,17 +1021,17 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 0 user4 stage/sql/closing tables 0 user4 stage/sql/init 0 @@ -1045,14 +1045,14 @@ stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1211,44 +1211,44 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 6 +user1 stage/sql/starting 7 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -1257,14 +1257,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1410,44 +1410,44 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 6 +user2 stage/sql/starting 7 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -1456,14 +1456,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1609,44 +1609,44 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 6 +user3 stage/sql/starting 7 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -1655,14 +1655,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1807,44 +1807,44 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 6 +user4 stage/sql/starting 7 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -1853,14 +1853,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2004,44 +2004,44 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -2050,14 +2050,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2202,44 +2202,44 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -2248,14 +2248,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2399,44 +2399,44 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -2445,14 +2445,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2596,44 +2596,44 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -2642,14 +2642,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2793,44 +2793,44 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -2839,14 +2839,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2990,44 +2990,44 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -3036,14 +3036,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3187,44 +3187,44 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -3233,14 +3233,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3406,22 +3406,22 @@ user1 stage/sql/checking permissions 4 user1 stage/sql/closing tables 12 user1 stage/sql/init 3 user1 stage/sql/Opening tables 8 -user1 stage/sql/starting 7 +user1 stage/sql/starting 8 user2 stage/sql/checking permissions 4 user2 stage/sql/closing tables 11 user2 stage/sql/init 3 user2 stage/sql/Opening tables 7 -user2 stage/sql/starting 7 +user2 stage/sql/starting 8 user3 stage/sql/checking permissions 4 user3 stage/sql/closing tables 11 user3 stage/sql/init 3 user3 stage/sql/Opening tables 7 -user3 stage/sql/starting 7 +user3 stage/sql/starting 8 user4 stage/sql/checking permissions 4 user4 stage/sql/closing tables 11 user4 stage/sql/init 3 user4 stage/sql/Opening tables 7 -user4 stage/sql/starting 7 +user4 stage/sql/starting 8 execute dump_stages_host; host event_name count_star execute dump_stages_global; @@ -3430,14 +3430,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3627,14 +3627,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3824,14 +3824,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4028,7 +4028,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4225,7 +4225,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4422,7 +4422,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4619,7 +4619,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4816,7 +4816,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -5013,7 +5013,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -5210,7 +5210,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -5407,7 +5407,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -5604,7 +5604,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -5801,7 +5801,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -5998,7 +5998,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -6167,7 +6167,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -6280,7 +6280,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -6365,7 +6365,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; diff --git a/mysql-test/suite/perfschema/r/event_aggregate_no_u.result b/mysql-test/suite/perfschema/r/event_aggregate_no_u.result index 0b41bb81cb3..69bf76ea22f 100644 --- a/mysql-test/suite/perfschema/r/event_aggregate_no_u.result +++ b/mysql-test/suite/perfschema/r/event_aggregate_no_u.result @@ -233,7 +233,7 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -242,21 +242,21 @@ localhost stage/sql/checking permissions 4 localhost stage/sql/closing tables 12 localhost stage/sql/init 3 localhost stage/sql/Opening tables 8 -localhost stage/sql/starting 6 +localhost stage/sql/starting 7 execute dump_stages_global; event_name count_star stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -348,7 +348,7 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 0 user2 localhost stage/sql/closing tables 0 user2 localhost stage/sql/init 0 @@ -362,21 +362,21 @@ localhost stage/sql/checking permissions 4 localhost stage/sql/closing tables 12 localhost stage/sql/init 3 localhost stage/sql/Opening tables 8 -localhost stage/sql/starting 6 +localhost stage/sql/starting 7 execute dump_stages_global; event_name count_star stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -487,12 +487,12 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -501,21 +501,21 @@ localhost stage/sql/checking permissions 8 localhost stage/sql/closing tables 23 localhost stage/sql/init 6 localhost stage/sql/Opening tables 15 -localhost stage/sql/starting 12 +localhost stage/sql/starting 14 execute dump_stages_global; event_name count_star stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -617,12 +617,12 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 0 user3 localhost stage/sql/closing tables 0 user3 localhost stage/sql/init 0 @@ -636,21 +636,21 @@ localhost stage/sql/checking permissions 8 localhost stage/sql/closing tables 23 localhost stage/sql/init 6 localhost stage/sql/Opening tables 15 -localhost stage/sql/starting 12 +localhost stage/sql/starting 14 execute dump_stages_global; event_name count_star stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -771,17 +771,17 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -790,21 +790,21 @@ localhost stage/sql/checking permissions 12 localhost stage/sql/closing tables 34 localhost stage/sql/init 9 localhost stage/sql/Opening tables 22 -localhost stage/sql/starting 18 +localhost stage/sql/starting 21 execute dump_stages_global; event_name count_star stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -916,17 +916,17 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 0 user4 localhost stage/sql/closing tables 0 user4 localhost stage/sql/init 0 @@ -940,21 +940,21 @@ localhost stage/sql/checking permissions 12 localhost stage/sql/closing tables 34 localhost stage/sql/init 9 localhost stage/sql/Opening tables 22 -localhost stage/sql/starting 18 +localhost stage/sql/starting 21 execute dump_stages_global; event_name count_star stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1085,22 +1085,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -1109,21 +1109,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 24 +localhost stage/sql/starting 28 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1241,22 +1241,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -1265,21 +1265,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 25 +localhost stage/sql/starting 29 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1397,22 +1397,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -1421,21 +1421,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 26 +localhost stage/sql/starting 30 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1552,22 +1552,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -1576,21 +1576,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 27 +localhost stage/sql/starting 31 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1706,22 +1706,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -1730,21 +1730,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1861,22 +1861,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -1885,21 +1885,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2015,22 +2015,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -2039,21 +2039,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2169,22 +2169,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -2193,21 +2193,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2323,22 +2323,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -2347,21 +2347,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2477,22 +2477,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -2501,21 +2501,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2631,22 +2631,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -2655,21 +2655,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2809,21 +2809,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2963,21 +2963,21 @@ localhost stage/sql/checking permissions 16 localhost stage/sql/closing tables 45 localhost stage/sql/init 12 localhost stage/sql/Opening tables 29 -localhost stage/sql/starting 28 +localhost stage/sql/starting 32 execute dump_stages_global; event_name count_star stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3124,14 +3124,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3285,7 +3285,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3439,7 +3439,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3593,7 +3593,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3747,7 +3747,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3901,7 +3901,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4055,7 +4055,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4209,7 +4209,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4363,7 +4363,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4517,7 +4517,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4671,7 +4671,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4825,7 +4825,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4951,7 +4951,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -5049,7 +5049,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -5147,7 +5147,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; diff --git a/mysql-test/suite/perfschema/r/event_aggregate_no_u_no_h.result b/mysql-test/suite/perfschema/r/event_aggregate_no_u_no_h.result index 19e7c6ef9a3..bd3a44bdcd1 100644 --- a/mysql-test/suite/perfschema/r/event_aggregate_no_u_no_h.result +++ b/mysql-test/suite/perfschema/r/event_aggregate_no_u_no_h.result @@ -203,7 +203,7 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -214,14 +214,14 @@ stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -304,7 +304,7 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 0 user2 localhost stage/sql/closing tables 0 user2 localhost stage/sql/init 0 @@ -320,14 +320,14 @@ stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 4 stage/sql/closing tables 12 stage/sql/init 3 stage/sql/Opening tables 8 -stage/sql/starting 6 +stage/sql/starting 7 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -429,12 +429,12 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -445,14 +445,14 @@ stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -545,12 +545,12 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 0 user3 localhost stage/sql/closing tables 0 user3 localhost stage/sql/init 0 @@ -566,14 +566,14 @@ stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 8 stage/sql/closing tables 23 stage/sql/init 6 stage/sql/Opening tables 15 -stage/sql/starting 12 +stage/sql/starting 14 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -685,17 +685,17 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -706,14 +706,14 @@ stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -816,17 +816,17 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 0 user4 localhost stage/sql/closing tables 0 user4 localhost stage/sql/init 0 @@ -842,14 +842,14 @@ stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 12 stage/sql/closing tables 34 stage/sql/init 9 stage/sql/Opening tables 22 -stage/sql/starting 18 +stage/sql/starting 21 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -971,22 +971,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 6 +user1 localhost stage/sql/starting 7 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -997,14 +997,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 24 +stage/sql/starting 28 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1113,22 +1113,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 6 +user2 localhost stage/sql/starting 7 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -1139,14 +1139,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 25 +stage/sql/starting 29 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1255,22 +1255,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 6 +user3 localhost stage/sql/starting 7 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -1281,14 +1281,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 26 +stage/sql/starting 30 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1396,22 +1396,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 6 +user4 localhost stage/sql/starting 7 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -1422,14 +1422,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 27 +stage/sql/starting 31 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1536,22 +1536,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -1562,14 +1562,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1677,22 +1677,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -1703,14 +1703,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1817,22 +1817,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -1843,14 +1843,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -1957,22 +1957,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -1983,14 +1983,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2097,22 +2097,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -2123,14 +2123,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2237,22 +2237,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -2263,14 +2263,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2377,22 +2377,22 @@ user1 localhost stage/sql/checking permissions 4 user1 localhost stage/sql/closing tables 12 user1 localhost stage/sql/init 3 user1 localhost stage/sql/Opening tables 8 -user1 localhost stage/sql/starting 7 +user1 localhost stage/sql/starting 8 user2 localhost stage/sql/checking permissions 4 user2 localhost stage/sql/closing tables 11 user2 localhost stage/sql/init 3 user2 localhost stage/sql/Opening tables 7 -user2 localhost stage/sql/starting 7 +user2 localhost stage/sql/starting 8 user3 localhost stage/sql/checking permissions 4 user3 localhost stage/sql/closing tables 11 user3 localhost stage/sql/init 3 user3 localhost stage/sql/Opening tables 7 -user3 localhost stage/sql/starting 7 +user3 localhost stage/sql/starting 8 user4 localhost stage/sql/checking permissions 4 user4 localhost stage/sql/closing tables 11 user4 localhost stage/sql/init 3 user4 localhost stage/sql/Opening tables 7 -user4 localhost stage/sql/starting 7 +user4 localhost stage/sql/starting 8 execute dump_stages_user; user event_name count_star execute dump_stages_host; @@ -2403,14 +2403,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2543,14 +2543,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2683,14 +2683,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2823,14 +2823,14 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_stages_history; event_name count(event_name) stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -2970,7 +2970,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3110,7 +3110,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3250,7 +3250,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3390,7 +3390,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3530,7 +3530,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3670,7 +3670,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3810,7 +3810,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -3950,7 +3950,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4090,7 +4090,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4230,7 +4230,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4370,7 +4370,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star user1 localhost statement/com/Error 0 @@ -4482,7 +4482,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4566,7 +4566,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; @@ -4650,7 +4650,7 @@ stage/sql/checking permissions 16 stage/sql/closing tables 45 stage/sql/init 12 stage/sql/Opening tables 29 -stage/sql/starting 28 +stage/sql/starting 32 execute dump_statements_account; user host event_name count_star execute dump_statements_user; diff --git a/mysql-test/suite/perfschema/r/max_program_zero.result b/mysql-test/suite/perfschema/r/max_program_zero.result index a825e864a60..543cc6d336f 100644 --- a/mysql-test/suite/perfschema/r/max_program_zero.result +++ b/mysql-test/suite/perfschema/r/max_program_zero.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/memory_aggregate.result b/mysql-test/suite/perfschema/r/memory_aggregate.result index 69eb033e74b..1d963dd8caa 100644 --- a/mysql-test/suite/perfschema/r/memory_aggregate.result +++ b/mysql-test/suite/perfschema/r/memory_aggregate.result @@ -2507,8 +2507,8 @@ execute dump_hosts; HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS localhost 6 6 disconnect con1; -disconnect con5; connection default; +disconnect con5; "================== con1/con5 disconnected ==================" "================== Step 10 ==================" call dump_thread(); diff --git a/mysql-test/suite/perfschema/r/memory_aggregate_32bit.result b/mysql-test/suite/perfschema/r/memory_aggregate_32bit.result index 2b8ee675650..387af11f91a 100644 --- a/mysql-test/suite/perfschema/r/memory_aggregate_32bit.result +++ b/mysql-test/suite/perfschema/r/memory_aggregate_32bit.result @@ -2507,8 +2507,8 @@ execute dump_hosts; HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS localhost 6 6 disconnect con1; -disconnect con5; connection default; +disconnect con5; "================== con1/con5 disconnected ==================" "================== Step 10 ==================" call dump_thread(); diff --git a/mysql-test/suite/perfschema/r/memory_aggregate_no_a.result b/mysql-test/suite/perfschema/r/memory_aggregate_no_a.result index b5c8e1cd3c7..abac503b965 100644 --- a/mysql-test/suite/perfschema/r/memory_aggregate_no_a.result +++ b/mysql-test/suite/perfschema/r/memory_aggregate_no_a.result @@ -1903,8 +1903,8 @@ execute dump_hosts; HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS localhost 6 6 disconnect con1; -disconnect con5; connection default; +disconnect con5; "================== con1/con5 disconnected ==================" "================== Step 10 ==================" call dump_thread(); diff --git a/mysql-test/suite/perfschema/r/memory_aggregate_no_a_no_h.result b/mysql-test/suite/perfschema/r/memory_aggregate_no_a_no_h.result index cc0e0c03dcf..f63e6f1d002 100644 --- a/mysql-test/suite/perfschema/r/memory_aggregate_no_a_no_h.result +++ b/mysql-test/suite/perfschema/r/memory_aggregate_no_a_no_h.result @@ -1653,8 +1653,8 @@ user4 2 2 execute dump_hosts; HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS disconnect con1; -disconnect con5; connection default; +disconnect con5; "================== con1/con5 disconnected ==================" "================== Step 10 ==================" call dump_thread(); diff --git a/mysql-test/suite/perfschema/r/memory_aggregate_no_a_no_u.result b/mysql-test/suite/perfschema/r/memory_aggregate_no_a_no_u.result index 8b24b5b565b..32785952fe7 100644 --- a/mysql-test/suite/perfschema/r/memory_aggregate_no_a_no_u.result +++ b/mysql-test/suite/perfschema/r/memory_aggregate_no_a_no_u.result @@ -1343,8 +1343,8 @@ execute dump_hosts; HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS localhost 6 6 disconnect con1; -disconnect con5; connection default; +disconnect con5; "================== con1/con5 disconnected ==================" "================== Step 10 ==================" call dump_thread(); diff --git a/mysql-test/suite/perfschema/r/memory_aggregate_no_a_no_u_no_h.result b/mysql-test/suite/perfschema/r/memory_aggregate_no_a_no_u_no_h.result index 45cbaf88372..e68f0e1baf6 100644 --- a/mysql-test/suite/perfschema/r/memory_aggregate_no_a_no_u_no_h.result +++ b/mysql-test/suite/perfschema/r/memory_aggregate_no_a_no_u_no_h.result @@ -1093,8 +1093,8 @@ USER CURRENT_CONNECTIONS TOTAL_CONNECTIONS execute dump_hosts; HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS disconnect con1; -disconnect con5; connection default; +disconnect con5; "================== con1/con5 disconnected ==================" "================== Step 10 ==================" call dump_thread(); diff --git a/mysql-test/suite/perfschema/r/memory_aggregate_no_h.result b/mysql-test/suite/perfschema/r/memory_aggregate_no_h.result index 35d528bf63c..e3b7cd0f998 100644 --- a/mysql-test/suite/perfschema/r/memory_aggregate_no_h.result +++ b/mysql-test/suite/perfschema/r/memory_aggregate_no_h.result @@ -2257,8 +2257,8 @@ user4 2 2 execute dump_hosts; HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS disconnect con1; -disconnect con5; connection default; +disconnect con5; "================== con1/con5 disconnected ==================" "================== Step 10 ==================" call dump_thread(); diff --git a/mysql-test/suite/perfschema/r/memory_aggregate_no_u.result b/mysql-test/suite/perfschema/r/memory_aggregate_no_u.result index 1f800ce4ba6..fd9f2c69a42 100644 --- a/mysql-test/suite/perfschema/r/memory_aggregate_no_u.result +++ b/mysql-test/suite/perfschema/r/memory_aggregate_no_u.result @@ -1947,8 +1947,8 @@ execute dump_hosts; HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS localhost 6 6 disconnect con1; -disconnect con5; connection default; +disconnect con5; "================== con1/con5 disconnected ==================" "================== Step 10 ==================" call dump_thread(); diff --git a/mysql-test/suite/perfschema/r/memory_aggregate_no_u_no_h.result b/mysql-test/suite/perfschema/r/memory_aggregate_no_u_no_h.result index b1ac5f24ec9..fdbd2d75d56 100644 --- a/mysql-test/suite/perfschema/r/memory_aggregate_no_u_no_h.result +++ b/mysql-test/suite/perfschema/r/memory_aggregate_no_u_no_h.result @@ -1697,8 +1697,8 @@ USER CURRENT_CONNECTIONS TOTAL_CONNECTIONS execute dump_hosts; HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS disconnect con1; -disconnect con5; connection default; +disconnect con5; "================== con1/con5 disconnected ==================" "================== Step 10 ==================" call dump_thread(); diff --git a/mysql-test/suite/perfschema/r/misc.result b/mysql-test/suite/perfschema/r/misc.result index 2258cbceea4..6bc0fa32314 100644 --- a/mysql-test/suite/perfschema/r/misc.result +++ b/mysql-test/suite/perfschema/r/misc.result @@ -94,7 +94,7 @@ test t_60905 NULL 5 5 0 1 DROP TABLE t_60905; show global variables like "performance_schema_max_thread_instances"; Variable_name Value -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 explain select * from performance_schema.threads; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE threads ALL NULL NULL NULL NULL 256 diff --git a/mysql-test/suite/perfschema/r/nesting.result b/mysql-test/suite/perfschema/r/nesting.result index 9e18e5ac272..f17a6462432 100644 --- a/mysql-test/suite/perfschema/r/nesting.result +++ b/mysql-test/suite/perfschema/r/nesting.result @@ -127,10 +127,10 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re 10 10 stage/sql/Optimizing (stage) STATEMENT 0 11 11 stage/sql/Executing (stage) STATEMENT 0 12 12 stage/sql/End of update loop (stage) STATEMENT 0 -13 13 stage/sql/Query end (stage) STATEMENT 0 -14 15 stage/sql/Commit (stage) STATEMENT 0 -15 15 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 14 -16 16 stage/sql/closing tables (stage) STATEMENT 0 +13 14 stage/sql/Query end (stage) STATEMENT 0 +14 14 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 13 +15 15 stage/sql/closing tables (stage) STATEMENT 0 +16 16 stage/sql/Query end (stage) STATEMENT 0 17 17 stage/sql/Starting cleanup (stage) STATEMENT 0 18 18 stage/sql/Freeing items (stage) STATEMENT 0 19 19 wait/io/socket/sql/client_connection send STATEMENT 0 @@ -151,10 +151,10 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re 34 34 stage/sql/Optimizing (stage) STATEMENT 24 35 35 stage/sql/Executing (stage) STATEMENT 24 36 36 stage/sql/End of update loop (stage) STATEMENT 24 -37 37 stage/sql/Query end (stage) STATEMENT 24 -38 39 stage/sql/Commit (stage) STATEMENT 24 -39 39 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 38 -40 40 stage/sql/closing tables (stage) STATEMENT 24 +37 38 stage/sql/Query end (stage) STATEMENT 24 +38 38 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 37 +39 39 stage/sql/closing tables (stage) STATEMENT 24 +40 40 stage/sql/Query end (stage) STATEMENT 24 41 41 stage/sql/Starting cleanup (stage) STATEMENT 24 42 42 stage/sql/Freeing items (stage) STATEMENT 24 43 43 wait/io/socket/sql/client_connection send STATEMENT 24 @@ -175,10 +175,10 @@ relative_event_id relative_end_event_id event_name comment nesting_event_type re 58 58 stage/sql/Optimizing (stage) STATEMENT 48 59 59 stage/sql/Executing (stage) STATEMENT 48 60 60 stage/sql/End of update loop (stage) STATEMENT 48 -61 61 stage/sql/Query end (stage) STATEMENT 48 -62 63 stage/sql/Commit (stage) STATEMENT 48 -63 63 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 62 -64 64 stage/sql/closing tables (stage) STATEMENT 48 +61 62 stage/sql/Query end (stage) STATEMENT 48 +62 62 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 61 +63 63 stage/sql/closing tables (stage) STATEMENT 48 +64 64 stage/sql/Query end (stage) STATEMENT 48 65 65 stage/sql/Starting cleanup (stage) STATEMENT 48 66 66 stage/sql/Freeing items (stage) STATEMENT 48 67 67 wait/io/socket/sql/client_connection send STATEMENT 48 @@ -202,10 +202,10 @@ select "With a third part to make things complete" as payload NULL NULL 83 83 stage/sql/Optimizing (stage) STATEMENT 72 84 84 stage/sql/Executing (stage) STATEMENT 72 85 85 stage/sql/End of update loop (stage) STATEMENT 72 -86 86 stage/sql/Query end (stage) STATEMENT 72 -87 88 stage/sql/Commit (stage) STATEMENT 72 -88 88 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 87 -89 89 stage/sql/closing tables (stage) STATEMENT 72 +86 87 stage/sql/Query end (stage) STATEMENT 72 +87 87 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 86 +88 88 stage/sql/closing tables (stage) STATEMENT 72 +89 89 stage/sql/Query end (stage) STATEMENT 72 90 90 stage/sql/Starting cleanup (stage) STATEMENT 72 91 92 stage/sql/Freeing items (stage) STATEMENT 72 92 92 wait/io/socket/sql/client_connection send STAGE 91 @@ -221,10 +221,10 @@ select "With a third part to make things complete" as payload NULL NULL 101 101 stage/sql/Optimizing (stage) STATEMENT 93 102 102 stage/sql/Executing (stage) STATEMENT 93 103 103 stage/sql/End of update loop (stage) STATEMENT 93 -104 104 stage/sql/Query end (stage) STATEMENT 93 -105 106 stage/sql/Commit (stage) STATEMENT 93 -106 106 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 105 -107 107 stage/sql/closing tables (stage) STATEMENT 93 +104 105 stage/sql/Query end (stage) STATEMENT 93 +105 105 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 104 +106 106 stage/sql/closing tables (stage) STATEMENT 93 +107 107 stage/sql/Query end (stage) STATEMENT 93 108 108 stage/sql/Starting cleanup (stage) STATEMENT 93 109 110 stage/sql/Freeing items (stage) STATEMENT 93 110 110 wait/io/socket/sql/client_connection send STAGE 109 @@ -238,10 +238,10 @@ select "With a third part to make things complete" as payload NULL NULL 118 118 stage/sql/Optimizing (stage) STATEMENT 111 119 119 stage/sql/Executing (stage) STATEMENT 111 120 120 stage/sql/End of update loop (stage) STATEMENT 111 -121 121 stage/sql/Query end (stage) STATEMENT 111 -122 123 stage/sql/Commit (stage) STATEMENT 111 -123 123 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 122 -124 124 stage/sql/closing tables (stage) STATEMENT 111 +121 122 stage/sql/Query end (stage) STATEMENT 111 +122 122 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 121 +123 123 stage/sql/closing tables (stage) STATEMENT 111 +124 124 stage/sql/Query end (stage) STATEMENT 111 125 125 stage/sql/Starting cleanup (stage) STATEMENT 111 126 126 stage/sql/Freeing items (stage) STATEMENT 111 127 127 wait/io/socket/sql/client_connection send STATEMENT 111 @@ -262,10 +262,10 @@ select "With a third part to make things complete" as payload NULL NULL 142 142 stage/sql/Optimizing (stage) STATEMENT 132 143 143 stage/sql/Executing (stage) STATEMENT 132 144 144 stage/sql/End of update loop (stage) STATEMENT 132 -145 145 stage/sql/Query end (stage) STATEMENT 132 -146 147 stage/sql/Commit (stage) STATEMENT 132 -147 147 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 146 -148 148 stage/sql/closing tables (stage) STATEMENT 132 +145 146 stage/sql/Query end (stage) STATEMENT 132 +146 146 wait/synch/mutex/sql/THD::LOCK_thd_kill lock STAGE 145 +147 147 stage/sql/closing tables (stage) STATEMENT 132 +148 148 stage/sql/Query end (stage) STATEMENT 132 149 149 stage/sql/Starting cleanup (stage) STATEMENT 132 150 150 stage/sql/Freeing items (stage) STATEMENT 132 151 151 wait/io/socket/sql/client_connection send STATEMENT 132 diff --git a/mysql-test/suite/perfschema/r/ortho_iter.result b/mysql-test/suite/perfschema/r/ortho_iter.result index 69e9319cefa..de47b49dbab 100644 --- a/mysql-test/suite/perfschema/r/ortho_iter.result +++ b/mysql-test/suite/perfschema/r/ortho_iter.result @@ -233,7 +233,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -257,7 +257,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/privilege_table_io.result b/mysql-test/suite/perfschema/r/privilege_table_io.result index 8be4b9583ec..9e5e0ad31cc 100644 --- a/mysql-test/suite/perfschema/r/privilege_table_io.result +++ b/mysql-test/suite/perfschema/r/privilege_table_io.result @@ -39,7 +39,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -63,7 +63,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/stage_mdl_global.result b/mysql-test/suite/perfschema/r/stage_mdl_global.result index b9eda506700..48aca9e5529 100644 --- a/mysql-test/suite/perfschema/r/stage_mdl_global.result +++ b/mysql-test/suite/perfschema/r/stage_mdl_global.result @@ -10,10 +10,10 @@ username event_name nesting_event_type username event_name nesting_event_type user1 stage/sql/starting STATEMENT user1 stage/sql/starting STATEMENT +user1 stage/sql/starting STATEMENT user1 stage/sql/Query end STATEMENT -user1 stage/sql/Commit STATEMENT user1 stage/sql/closing tables STATEMENT -user1 stage/sql/Commit implicit STATEMENT +user1 stage/sql/Query end STATEMENT user1 stage/sql/Starting cleanup STATEMENT user1 stage/sql/Freeing items STATEMENT user1 stage/sql/Reset for next command STATEMENT diff --git a/mysql-test/suite/perfschema/r/stage_mdl_table.result b/mysql-test/suite/perfschema/r/stage_mdl_table.result index 5ba0ba04fca..b9b2dc1257d 100644 --- a/mysql-test/suite/perfschema/r/stage_mdl_table.result +++ b/mysql-test/suite/perfschema/r/stage_mdl_table.result @@ -19,10 +19,10 @@ username event_name nesting_event_type user1 stage/sql/Sending data STATEMENT user1 stage/sql/End of update loop STATEMENT user1 stage/sql/Query end STATEMENT -user1 stage/sql/Commit STATEMENT user1 stage/sql/closing tables STATEMENT user1 stage/sql/Unlocking tables STATEMENT user1 stage/sql/closing tables STATEMENT +user1 stage/sql/Query end STATEMENT user1 stage/sql/Starting cleanup STATEMENT user1 stage/sql/Freeing items STATEMENT user1 stage/sql/Reset for next command STATEMENT diff --git a/mysql-test/suite/perfschema/r/start_server_disable_idle.result b/mysql-test/suite/perfschema/r/start_server_disable_idle.result index 9235faf735e..8c9650cb6b7 100644 --- a/mysql-test/suite/perfschema/r/start_server_disable_idle.result +++ b/mysql-test/suite/perfschema/r/start_server_disable_idle.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_disable_stages.result b/mysql-test/suite/perfschema/r/start_server_disable_stages.result index 3436faf1df0..0f5a34ba250 100644 --- a/mysql-test/suite/perfschema/r/start_server_disable_stages.result +++ b/mysql-test/suite/perfschema/r/start_server_disable_stages.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_disable_statements.result b/mysql-test/suite/perfschema/r/start_server_disable_statements.result index 24f504e67f0..0ab9f958a6a 100644 --- a/mysql-test/suite/perfschema/r/start_server_disable_statements.result +++ b/mysql-test/suite/perfschema/r/start_server_disable_statements.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_disable_transactions.result b/mysql-test/suite/perfschema/r/start_server_disable_transactions.result index e13ced555d7..dcb0c1c53c8 100644 --- a/mysql-test/suite/perfschema/r/start_server_disable_transactions.result +++ b/mysql-test/suite/perfschema/r/start_server_disable_transactions.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_disable_waits.result b/mysql-test/suite/perfschema/r/start_server_disable_waits.result index 18448f00b01..08155259b73 100644 --- a/mysql-test/suite/perfschema/r/start_server_disable_waits.result +++ b/mysql-test/suite/perfschema/r/start_server_disable_waits.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_innodb.result b/mysql-test/suite/perfschema/r/start_server_innodb.result index 80fd0d387de..64cef77badd 100644 --- a/mysql-test/suite/perfschema/r/start_server_innodb.result +++ b/mysql-test/suite/perfschema/r/start_server_innodb.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_low_index.result b/mysql-test/suite/perfschema/r/start_server_low_index.result index 2a3c6bcff54..da7bf4adec6 100644 --- a/mysql-test/suite/perfschema/r/start_server_low_index.result +++ b/mysql-test/suite/perfschema/r/start_server_low_index.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_low_table_lock.result b/mysql-test/suite/perfschema/r/start_server_low_table_lock.result index c1c59b4da52..820b30de4b5 100644 --- a/mysql-test/suite/perfschema/r/start_server_low_table_lock.result +++ b/mysql-test/suite/perfschema/r/start_server_low_table_lock.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 1 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_account.result b/mysql-test/suite/perfschema/r/start_server_no_account.result index 6ae5b3b58e0..8447a803d2b 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_account.result +++ b/mysql-test/suite/perfschema/r/start_server_no_account.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_cond_class.result b/mysql-test/suite/perfschema/r/start_server_no_cond_class.result index ac0554cc634..2407e5c4c02 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_cond_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_cond_class.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 0 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_cond_inst.result b/mysql-test/suite/perfschema/r/start_server_no_cond_inst.result index 81e6eb25e69..bcca782e45e 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_cond_inst.result +++ b/mysql-test/suite/perfschema/r/start_server_no_cond_inst.result @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_file_class.result b/mysql-test/suite/perfschema/r/start_server_no_file_class.result index 31c1049dfef..fce0eb195dc 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_file_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_file_class.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 0 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_file_inst.result b/mysql-test/suite/perfschema/r/start_server_no_file_inst.result index 384a1f9ca81..5cb5cb24fe3 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_file_inst.result +++ b/mysql-test/suite/perfschema/r/start_server_no_file_inst.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_host.result b/mysql-test/suite/perfschema/r/start_server_no_host.result index b9949956aa4..f246ef96f00 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_host.result +++ b/mysql-test/suite/perfschema/r/start_server_no_host.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 0 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_index.result b/mysql-test/suite/perfschema/r/start_server_no_index.result index 8f0be8241a0..6574a8c60f8 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_index.result +++ b/mysql-test/suite/perfschema/r/start_server_no_index.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_mdl.result b/mysql-test/suite/perfschema/r/start_server_no_mdl.result index f5f7691e1c4..1bfbc0d1b29 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_mdl.result +++ b/mysql-test/suite/perfschema/r/start_server_no_mdl.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_memory_class.result b/mysql-test/suite/perfschema/r/start_server_no_memory_class.result index 1b71c3e4406..01c6ffe25da 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_memory_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_memory_class.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_mutex_class.result b/mysql-test/suite/perfschema/r/start_server_no_mutex_class.result index 5b6545aa9f3..b7f6ff4b6e3 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_mutex_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_mutex_class.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_mutex_inst.result b/mysql-test/suite/perfschema/r/start_server_no_mutex_inst.result index b657f234d18..0ae8874c27f 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_mutex_inst.result +++ b/mysql-test/suite/perfschema/r/start_server_no_mutex_inst.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_prepared_stmts_instances.result b/mysql-test/suite/perfschema/r/start_server_no_prepared_stmts_instances.result index 7f40850f123..8ce0396c6d3 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_prepared_stmts_instances.result +++ b/mysql-test/suite/perfschema/r/start_server_no_prepared_stmts_instances.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_rwlock_class.result b/mysql-test/suite/perfschema/r/start_server_no_rwlock_class.result index 1db87999a14..b07046bd073 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_rwlock_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_rwlock_class.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_rwlock_inst.result b/mysql-test/suite/perfschema/r/start_server_no_rwlock_inst.result index a8e3ef23440..1e4e5110029 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_rwlock_inst.result +++ b/mysql-test/suite/perfschema/r/start_server_no_rwlock_inst.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_setup_actors.result b/mysql-test/suite/perfschema/r/start_server_no_setup_actors.result index bfbdb5bf2cc..bd312802870 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_setup_actors.result +++ b/mysql-test/suite/perfschema/r/start_server_no_setup_actors.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 0 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_setup_objects.result b/mysql-test/suite/perfschema/r/start_server_no_setup_objects.result index 549ee06a4bb..a8b2923ac0d 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_setup_objects.result +++ b/mysql-test/suite/perfschema/r/start_server_no_setup_objects.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 0 diff --git a/mysql-test/suite/perfschema/r/start_server_no_socket_class.result b/mysql-test/suite/perfschema/r/start_server_no_socket_class.result index 2a98e896fbc..f8dc24a868e 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_socket_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_socket_class.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_socket_inst.result b/mysql-test/suite/perfschema/r/start_server_no_socket_inst.result index 8c509c8b412..596e895789c 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_socket_inst.result +++ b/mysql-test/suite/perfschema/r/start_server_no_socket_inst.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_stage_class.result b/mysql-test/suite/perfschema/r/start_server_no_stage_class.result index 72c9cd336fa..ae2b10fc9c0 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_stage_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_stage_class.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_stages_history.result b/mysql-test/suite/perfschema/r/start_server_no_stages_history.result index 1ed72609619..6c303b41691 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_stages_history.result +++ b/mysql-test/suite/perfschema/r/start_server_no_stages_history.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_stages_history_long.result b/mysql-test/suite/perfschema/r/start_server_no_stages_history_long.result index 37a0dc0e15b..b259f9022a4 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_stages_history_long.result +++ b/mysql-test/suite/perfschema/r/start_server_no_stages_history_long.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_statement_class.result b/mysql-test/suite/perfschema/r/start_server_no_statement_class.result index 67275e600ba..ea02b9f7cc6 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_statement_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_statement_class.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_statements_history.result b/mysql-test/suite/perfschema/r/start_server_no_statements_history.result index 9fe2a45d466..23ca665753b 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_statements_history.result +++ b/mysql-test/suite/perfschema/r/start_server_no_statements_history.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_statements_history_long.result b/mysql-test/suite/perfschema/r/start_server_no_statements_history_long.result index 1d780f630d8..c55338fd7ed 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_statements_history_long.result +++ b/mysql-test/suite/perfschema/r/start_server_no_statements_history_long.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_table_hdl.result b/mysql-test/suite/perfschema/r/start_server_no_table_hdl.result index f053f8beb09..53d09af2a23 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_table_hdl.result +++ b/mysql-test/suite/perfschema/r/start_server_no_table_hdl.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 0 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_table_inst.result b/mysql-test/suite/perfschema/r/start_server_no_table_inst.result index 5d08edc2210..234813fb000 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_table_inst.result +++ b/mysql-test/suite/perfschema/r/start_server_no_table_inst.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 0 performance_schema_max_table_lock_stat 0 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_table_lock.result b/mysql-test/suite/perfschema/r/start_server_no_table_lock.result index 50295ea306f..bc87ec4fa24 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_table_lock.result +++ b/mysql-test/suite/perfschema/r/start_server_no_table_lock.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 0 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_thread_class.result b/mysql-test/suite/perfschema/r/start_server_no_thread_class.result index 82b3b3b5f8b..52a5e7468a8 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_thread_class.result +++ b/mysql-test/suite/perfschema/r/start_server_no_thread_class.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 0 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_thread_inst.result b/mysql-test/suite/perfschema/r/start_server_no_thread_inst.result index 67a40ace6c0..7035397580d 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_thread_inst.result +++ b/mysql-test/suite/perfschema/r/start_server_no_thread_inst.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 diff --git a/mysql-test/suite/perfschema/r/start_server_no_transactions_history.result b/mysql-test/suite/perfschema/r/start_server_no_transactions_history.result index d281c4daaea..d295c15b028 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_transactions_history.result +++ b/mysql-test/suite/perfschema/r/start_server_no_transactions_history.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_transactions_history_long.result b/mysql-test/suite/perfschema/r/start_server_no_transactions_history_long.result index 69582327979..90c0ea540ee 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_transactions_history_long.result +++ b/mysql-test/suite/perfschema/r/start_server_no_transactions_history_long.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_user.result b/mysql-test/suite/perfschema/r/start_server_no_user.result index 423616c4aaf..1f2099c767c 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_user.result +++ b/mysql-test/suite/perfschema/r/start_server_no_user.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_waits_history.result b/mysql-test/suite/perfschema/r/start_server_no_waits_history.result index 024f9adc2fa..fc0a265a6da 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_waits_history.result +++ b/mysql-test/suite/perfschema/r/start_server_no_waits_history.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 0 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_no_waits_history_long.result b/mysql-test/suite/perfschema/r/start_server_no_waits_history_long.result index c890c48500d..02d562a73e6 100644 --- a/mysql-test/suite/perfschema/r/start_server_no_waits_history_long.result +++ b/mysql-test/suite/perfschema/r/start_server_no_waits_history_long.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 0 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_off.result b/mysql-test/suite/perfschema/r/start_server_off.result index b62ffb83f75..40740510642 100644 --- a/mysql-test/suite/perfschema/r/start_server_off.result +++ b/mysql-test/suite/perfschema/r/start_server_off.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_on.result b/mysql-test/suite/perfschema/r/start_server_on.result index 80fd0d387de..64cef77badd 100644 --- a/mysql-test/suite/perfschema/r/start_server_on.result +++ b/mysql-test/suite/perfschema/r/start_server_on.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/start_server_variables.result b/mysql-test/suite/perfschema/r/start_server_variables.result index afd79f0a544..e1c7b23affd 100644 --- a/mysql-test/suite/perfschema/r/start_server_variables.result +++ b/mysql-test/suite/perfschema/r/start_server_variables.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 @@ -165,7 +165,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -188,7 +188,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/statement_program_lost_inst.result b/mysql-test/suite/perfschema/r/statement_program_lost_inst.result index 2c9d768f2a4..41ac7419c07 100644 --- a/mysql-test/suite/perfschema/r/statement_program_lost_inst.result +++ b/mysql-test/suite/perfschema/r/statement_program_lost_inst.result @@ -117,7 +117,7 @@ performance_schema_events_waits_history_long_size 10000 performance_schema_events_waits_history_size 10 performance_schema_hosts_size 100 performance_schema_max_cond_classes 90 -performance_schema_max_cond_instances 1000 +performance_schema_max_cond_instances 1500 performance_schema_max_digest_length 1024 performance_schema_max_file_classes 80 performance_schema_max_file_handles 32768 @@ -141,7 +141,7 @@ performance_schema_max_table_handles 1000 performance_schema_max_table_instances 500 performance_schema_max_table_lock_stat 500 performance_schema_max_thread_classes 50 -performance_schema_max_thread_instances 200 +performance_schema_max_thread_instances 400 performance_schema_session_connect_attrs_size 2048 performance_schema_setup_actors_size 100 performance_schema_setup_objects_size 100 diff --git a/mysql-test/suite/perfschema/r/statement_program_nesting_event_check.result b/mysql-test/suite/perfschema/r/statement_program_nesting_event_check.result index 5e376a12a18..1a973c9448b 100644 --- a/mysql-test/suite/perfschema/r/statement_program_nesting_event_check.result +++ b/mysql-test/suite/perfschema/r/statement_program_nesting_event_check.result @@ -145,7 +145,7 @@ Bollywood # Event SET GLOBAL event_scheduler=ON; CREATE TABLE table_t(a INT); -CREATE EVENT e1 ON SCHEDULE EVERY 2 SECOND DO +CREATE EVENT e1 ON SCHEDULE EVERY 2 SECOND ON COMPLETION NOT PRESERVE DO BEGIN INSERT INTO table_t VALUES(1); END| @@ -165,7 +165,7 @@ statement/sql/call_procedure CALL SampleProc1(30,40,50) NULL NULL 0 statement/sql/call_procedure CALL SampleProc2("Jwalamukhi",34) NULL NULL 0 statement/sql/call_procedure CALL SampleProc3() NULL NULL 0 statement/sql/call_procedure CALL SampleProc4() NULL NULL 0 -statement/sql/create_event CREATE EVENT e1 ON SCHEDULE EVERY 2 SECOND DO +statement/sql/create_event CREATE EVENT e1 ON SCHEDULE EVERY 2 SECOND ON COMPLETION NOT PRESERVE DO BEGIN INSERT INTO table_t VALUES(1); END NULL NULL 0 diff --git a/mysql-test/suite/perfschema/r/statement_program_non_nested.result b/mysql-test/suite/perfschema/r/statement_program_non_nested.result index af9807cbc97..1c75dac11ac 100644 --- a/mysql-test/suite/perfschema/r/statement_program_non_nested.result +++ b/mysql-test/suite/perfschema/r/statement_program_non_nested.result @@ -145,7 +145,7 @@ Bollywood # Event SET GLOBAL event_scheduler=ON; CREATE TABLE table_t(a INT); -CREATE EVENT e1 ON SCHEDULE EVERY 2 SECOND DO +CREATE EVENT e1 ON SCHEDULE EVERY 2 SECOND ON COMPLETION NOT PRESERVE DO BEGIN INSERT INTO table_t VALUES(1); END| @@ -182,7 +182,7 @@ statement/sql/call_procedure CALL SampleProc1(30,40,50) stored_programs NULL NUL statement/sql/call_procedure CALL SampleProc2("Jwalamukhi",34) stored_programs NULL NULL NULL NULL 0 statement/sql/call_procedure CALL SampleProc3() stored_programs NULL NULL NULL NULL 0 statement/sql/call_procedure CALL SampleProc4() stored_programs NULL NULL NULL NULL 0 -statement/sql/create_event CREATE EVENT e1 ON SCHEDULE EVERY 2 SECOND DO +statement/sql/create_event CREATE EVENT e1 ON SCHEDULE EVERY 2 SECOND ON COMPLETION NOT PRESERVE DO BEGIN INSERT INTO table_t VALUES(1); END stored_programs NULL NULL NULL NULL 0 @@ -553,7 +553,7 @@ Bollywood # Event SET GLOBAL event_scheduler=ON; CREATE TABLE table_t(a INT); -CREATE EVENT e1 ON SCHEDULE EVERY 2 SECOND DO +CREATE EVENT e1 ON SCHEDULE EVERY 2 SECOND ON COMPLETION NOT PRESERVE DO BEGIN INSERT INTO table_t VALUES(1); END| diff --git a/mysql-test/suite/perfschema/r/threads_history.result b/mysql-test/suite/perfschema/r/threads_history.result index aaf2cd09e31..d72ace62255 100644 --- a/mysql-test/suite/perfschema/r/threads_history.result +++ b/mysql-test/suite/perfschema/r/threads_history.result @@ -24,27 +24,22 @@ events_waits_history_long YES global_instrumentation YES thread_instrumentation YES statements_digest YES -# Switch to (con1, localhost, user1, , ) connect con1, localhost, user1, , ; update performance_schema.threads set INSTRUMENTED='YES', HISTORY='YES' where PROCESSLIST_ID = connection_id(); -# Switch to (con2, localhost, user2, , ) connect con2, localhost, user2, , ; update performance_schema.threads set INSTRUMENTED='YES', HISTORY='NO' where PROCESSLIST_ID = connection_id(); -# Switch to (con3, localhost, user3, , ) connect con3, localhost, user3, , ; update performance_schema.threads set INSTRUMENTED='NO', HISTORY='YES' where PROCESSLIST_ID = connection_id(); -# Switch to (con4, localhost, user4, , ) connect con4, localhost, user4, , ; update performance_schema.threads set INSTRUMENTED='NO', HISTORY='NO' where PROCESSLIST_ID = connection_id(); -# Switch to connection default connection default; truncate table performance_schema.events_transactions_current; truncate table performance_schema.events_transactions_history; @@ -58,7 +53,6 @@ truncate table performance_schema.events_stages_history_long; truncate table performance_schema.events_waits_current; truncate table performance_schema.events_waits_history; truncate table performance_schema.events_waits_history_long; -# Switch to connection con1 connection con1; XA START 'XA_CON1', 'XA_BQUAL', 12; select "Hi from con1"; @@ -67,7 +61,6 @@ Hi from con1 XA END 'XA_CON1', 'XA_BQUAL', 12; XA PREPARE 'XA_CON1', 'XA_BQUAL', 12; XA COMMIT 'XA_CON1', 'XA_BQUAL', 12; -# Switch to connection con2 connection con2; XA START 'XA_CON2', 'XA_BQUAL', 12; select "Hi from con2"; @@ -76,7 +69,6 @@ Hi from con2 XA END 'XA_CON2', 'XA_BQUAL', 12; XA PREPARE 'XA_CON2', 'XA_BQUAL', 12; XA COMMIT 'XA_CON2', 'XA_BQUAL', 12; -# Switch to connection con3 connection con3; XA START 'XA_CON3', 'XA_BQUAL', 12; select "Hi from con3"; @@ -85,7 +77,6 @@ Hi from con3 XA END 'XA_CON3', 'XA_BQUAL', 12; XA PREPARE 'XA_CON3', 'XA_BQUAL', 12; XA COMMIT 'XA_CON3', 'XA_BQUAL', 12; -# Switch to connection con4 connection con4; XA START 'XA_CON4', 'XA_BQUAL', 12; select "Hi from con4"; @@ -95,88 +86,142 @@ XA END 'XA_CON4', 'XA_BQUAL', 12; XA PREPARE 'XA_CON4', 'XA_BQUAL', 12; XA COMMIT 'XA_CON4', 'XA_BQUAL', 12; connection default; -"=========================== Transactions user 1" +########################### Transactions user 1 - 1 +select /*1-1*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current +where THREAD_ID = $con1_thread_id; XID_FORMAT_ID XID_GTRID XID_BQUAL 12 XA_CON1 XA_BQUAL +select /*1-1*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_history +where THREAD_ID = $con1_thread_id; XID_FORMAT_ID XID_GTRID XID_BQUAL 12 XA_CON1 XA_BQUAL +select /*1-1*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_history_long +where THREAD_ID = $con1_thread_id; XID_FORMAT_ID XID_GTRID XID_BQUAL 12 XA_CON1 XA_BQUAL -"=========================== Transactions user 2" +########################### Transactions user 2 - 1 +select /*2-1*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current +where THREAD_ID = $con2_thread_id; XID_FORMAT_ID XID_GTRID XID_BQUAL 12 XA_CON2 XA_BQUAL +select /*2-1*/ count(*) from performance_schema.events_transactions_history +where THREAD_ID = $con2_thread_id; count(*) 0 +select /*2-1*/ count(*) from performance_schema.events_transactions_history_long +where THREAD_ID = $con2_thread_id; count(*) 0 -"=========================== Transactions user 3" +########################### Transactions user 3 - 1 +select /*3-1*/ count(*) from performance_schema.events_transactions_current +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-1*/ count(*) from performance_schema.events_transactions_history +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-1*/ count(*) from performance_schema.events_transactions_history_long +where THREAD_ID = $con3_thread_id; count(*) 0 -"=========================== Transactions user 4" +########################### Transactions user 4 - 1 +select /*4-1*/ count(*) from performance_schema.events_transactions_current +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-1*/ count(*) from performance_schema.events_transactions_history +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-1*/ count(*) from performance_schema.events_transactions_history_long +where THREAD_ID = $con4_thread_id; count(*) 0 -"=========================== Statements user 1" +########################### Statements user 1 - 1 +select /*1-1*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME SQL_TEXT statement/sql/xa_commit XA COMMIT 'XA_CON1', 'XA_BQUAL', 12 +select /*1-1*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_history +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME SQL_TEXT statement/sql/xa_start XA START 'XA_CON1', 'XA_BQUAL', 12 statement/sql/select select "Hi from con1" statement/sql/xa_end XA END 'XA_CON1', 'XA_BQUAL', 12 statement/sql/xa_prepare XA PREPARE 'XA_CON1', 'XA_BQUAL', 12 statement/sql/xa_commit XA COMMIT 'XA_CON1', 'XA_BQUAL', 12 +select /*1-1*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_history_long +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME SQL_TEXT statement/sql/xa_start XA START 'XA_CON1', 'XA_BQUAL', 12 statement/sql/select select "Hi from con1" statement/sql/xa_end XA END 'XA_CON1', 'XA_BQUAL', 12 statement/sql/xa_prepare XA PREPARE 'XA_CON1', 'XA_BQUAL', 12 statement/sql/xa_commit XA COMMIT 'XA_CON1', 'XA_BQUAL', 12 -"=========================== Statements user 2" +########################### Statements user 2 - 1 +select /*2-1*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current +where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME SQL_TEXT statement/sql/xa_commit XA COMMIT 'XA_CON2', 'XA_BQUAL', 12 +select /*2-1*/ count(*) from performance_schema.events_statements_history +where THREAD_ID = $con2_thread_id; count(*) 0 +select /*2-1*/ count(*) from performance_schema.events_statements_history_long +where THREAD_ID = $con2_thread_id; count(*) 0 -"=========================== Statements user 3" +########################### Statements user 3 - 1 +select /*3-1*/ count(*) from performance_schema.events_statements_current +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-1*/ count(*) from performance_schema.events_statements_history +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-1*/ count(*) from performance_schema.events_statements_history_long +where THREAD_ID = $con3_thread_id; count(*) 0 -"=========================== Statements user 4" +########################### Statements user 4 - 1 +select /*4-1*/ count(*) from performance_schema.events_statements_current +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-1*/ count(*) from performance_schema.events_statements_history +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-1*/ count(*) from performance_schema.events_statements_history_long +where THREAD_ID = $con4_thread_id; count(*) 0 -"=========================== Stages user 1" +########################### Stages user 1 - 1 +select /*1-1*/ EVENT_NAME from performance_schema.events_stages_current +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME +select /*1-1*/ EVENT_NAME from performance_schema.events_stages_history +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command stage/sql/starting stage/sql/Query end -stage/sql/Commit stage/sql/closing tables +stage/sql/Query end stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command +select /*1-1*/ EVENT_NAME from performance_schema.events_stages_history_long +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME stage/sql/starting stage/sql/Query end -stage/sql/Commit stage/sql/closing tables +stage/sql/Query end stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command @@ -189,81 +234,122 @@ stage/sql/Optimizing stage/sql/Executing stage/sql/End of update loop stage/sql/Query end -stage/sql/Commit stage/sql/closing tables +stage/sql/Query end stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command stage/sql/starting stage/sql/Query end -stage/sql/Commit stage/sql/closing tables +stage/sql/Query end stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command stage/sql/starting stage/sql/Query end -stage/sql/Commit stage/sql/closing tables +stage/sql/Query end stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command stage/sql/starting stage/sql/Query end -stage/sql/Commit stage/sql/closing tables +stage/sql/Query end stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command -"=========================== Stages user 2" +########################### Stages user 2 - 1 +select /*2-1*/ EVENT_NAME from performance_schema.events_stages_current +where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME +select /*2-1*/ count(*) from performance_schema.events_stages_history +where THREAD_ID = $con2_thread_id; count(*) 0 +select /*2-1*/ count(*) from performance_schema.events_stages_history_long +where THREAD_ID = $con2_thread_id; count(*) 0 -"=========================== Stages user 3" +########################### Stages user 3 - 1 +select /*3-1*/ count(*) from performance_schema.events_stages_current +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-1*/ count(*) from performance_schema.events_stages_history +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-1*/ count(*) from performance_schema.events_stages_history_long +where THREAD_ID = $con3_thread_id; count(*) 0 -"=========================== Stages user 4" +########################### Stages user 4 - 1 +select /*4-1*/ count(*) from performance_schema.events_stages_current +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-1*/ count(*) from performance_schema.events_stages_history +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-1*/ count(*) from performance_schema.events_stages_history_long +where THREAD_ID = $con4_thread_id; count(*) 0 -"=========================== Waits user 1" +########################### Waits user 1 - 1 +select /*1-1*/ EVENT_NAME from performance_schema.events_waits_current +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME idle +select /*1-1*/ (count(*) > 5) as has_waits from performance_schema.events_waits_history +where THREAD_ID = $con1_thread_id; has_waits 1 +select /*1-1*/ (count(*) > 15) as has_waits from performance_schema.events_waits_history_long +where THREAD_ID = $con1_thread_id; has_waits 1 -"=========================== Waits user 2" +########################### Waits user 2 - 1 +select /*2-1*/ EVENT_NAME from performance_schema.events_waits_current +where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME idle +select /*2-1*/ count(*) from performance_schema.events_waits_history +where THREAD_ID = $con2_thread_id; count(*) 0 +select /*2-1*/ count(*) from performance_schema.events_waits_history_long +where THREAD_ID = $con2_thread_id; count(*) 0 -"=========================== Waits user 3" +########################### Waits user 3 - 1 +select /*3-1*/ count(*) from performance_schema.events_waits_current +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-1*/ count(*) from performance_schema.events_waits_history +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-1*/ count(*) from performance_schema.events_waits_history_long +where THREAD_ID = $con3_thread_id; count(*) 0 -"=========================== Waits user 4" +########################### Waits user 4 - 1 +select /*4-1*/ count(*) from performance_schema.events_waits_current +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-1*/ count(*) from performance_schema.events_waits_history +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-1*/ count(*) from performance_schema.events_waits_history_long +where THREAD_ID = $con4_thread_id; count(*) 0 -# Switch to connection default, disable consumers connection default; update performance_schema.setup_consumers set enabled='NO' where name like "%history%"; @@ -296,7 +382,6 @@ truncate table performance_schema.events_stages_history_long; truncate table performance_schema.events_waits_current; truncate table performance_schema.events_waits_history; truncate table performance_schema.events_waits_history_long; -# Switch to connection con1 connection con1; XA START 'XA_CON1', 'XA_BQUAL', 12; select "Hi from con1"; @@ -305,7 +390,6 @@ Hi from con1 XA END 'XA_CON1', 'XA_BQUAL', 12; XA PREPARE 'XA_CON1', 'XA_BQUAL', 12; XA COMMIT 'XA_CON1', 'XA_BQUAL', 12; -# Switch to connection con2 connection con2; XA START 'XA_CON2', 'XA_BQUAL', 12; select "Hi from con2"; @@ -314,7 +398,6 @@ Hi from con2 XA END 'XA_CON2', 'XA_BQUAL', 12; XA PREPARE 'XA_CON2', 'XA_BQUAL', 12; XA COMMIT 'XA_CON2', 'XA_BQUAL', 12; -# Switch to connection con3 connection con3; XA START 'XA_CON3', 'XA_BQUAL', 12; select "Hi from con3"; @@ -323,7 +406,6 @@ Hi from con3 XA END 'XA_CON3', 'XA_BQUAL', 12; XA PREPARE 'XA_CON3', 'XA_BQUAL', 12; XA COMMIT 'XA_CON3', 'XA_BQUAL', 12; -# Switch to connection con4 connection con4; XA START 'XA_CON4', 'XA_BQUAL', 12; select "Hi from con4"; @@ -333,117 +415,212 @@ XA END 'XA_CON4', 'XA_BQUAL', 12; XA PREPARE 'XA_CON4', 'XA_BQUAL', 12; XA COMMIT 'XA_CON4', 'XA_BQUAL', 12; connection default; -"=========================== Transactions user 1" +########################### Transactions user 1 - 2 +select /*1-2*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current +where THREAD_ID = $con1_thread_id; XID_FORMAT_ID XID_GTRID XID_BQUAL 12 XA_CON1 XA_BQUAL +select /*1-2*/ count(*) from performance_schema.events_transactions_history +where THREAD_ID = $con1_thread_id; count(*) 0 +select /*1-2*/ count(*) from performance_schema.events_transactions_history_long +where THREAD_ID = $con1_thread_id; count(*) 0 -"=========================== Transactions user 2" +########################### Transactions user 2 - 2 +select /*2-2*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current +where THREAD_ID = $con2_thread_id; XID_FORMAT_ID XID_GTRID XID_BQUAL 12 XA_CON2 XA_BQUAL +select /*2-2*/ count(*) from performance_schema.events_transactions_history +where THREAD_ID = $con2_thread_id; count(*) 0 +select /*2-2*/ count(*) from performance_schema.events_transactions_history_long +where THREAD_ID = $con2_thread_id; count(*) 0 -"=========================== Transactions user 3" +########################### Transactions user 3 - 2 +select /*3-2*/ count(*) from performance_schema.events_transactions_current +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-2*/ count(*) from performance_schema.events_transactions_history +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-2*/ count(*) from performance_schema.events_transactions_history_long +where THREAD_ID = $con3_thread_id; count(*) 0 -"=========================== Transactions user 4" +########################### Transactions user 4 - 2 +select /*4-2*/ count(*) from performance_schema.events_transactions_current +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-2*/ count(*) from performance_schema.events_transactions_history +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-2*/ count(*) from performance_schema.events_transactions_history_long +where THREAD_ID = $con4_thread_id; count(*) 0 -"=========================== Statements user 1" +########################### Statements user 1 - 2 +select /*1-2*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME SQL_TEXT statement/sql/xa_commit XA COMMIT 'XA_CON1', 'XA_BQUAL', 12 +select /*1-2*/ count(*) from performance_schema.events_statements_history +where THREAD_ID = $con1_thread_id; count(*) 0 +select /*1-2*/ count(*) from performance_schema.events_statements_history_long +where THREAD_ID = $con1_thread_id; count(*) 0 -"=========================== Statements user 2" +########################### Statements user 2 - 2 +select /*2-2*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current +where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME SQL_TEXT statement/sql/xa_commit XA COMMIT 'XA_CON2', 'XA_BQUAL', 12 +select /*2-2*/ count(*) from performance_schema.events_statements_history +where THREAD_ID = $con2_thread_id; count(*) 0 +select /*2-2*/ count(*) from performance_schema.events_statements_history_long +where THREAD_ID = $con2_thread_id; count(*) 0 -"=========================== Statements user 3" +########################### Statements user 3 - 2 +select /*3-2*/ count(*) from performance_schema.events_statements_current +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-2*/ count(*) from performance_schema.events_statements_history +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-2*/ count(*) from performance_schema.events_statements_history_long +where THREAD_ID = $con3_thread_id; count(*) 0 -"=========================== Statements user 4" +########################### Statements user 4 - 2 +select /*4-2*/ count(*) from performance_schema.events_statements_current +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-2*/ count(*) from performance_schema.events_statements_history +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-2*/ count(*) from performance_schema.events_statements_history_long +where THREAD_ID = $con4_thread_id; count(*) 0 -"=========================== Stages user 1" +########################### Stages user 1 - 2 +select /*1-2*/ EVENT_NAME from performance_schema.events_stages_current +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME +select /*1-2*/ count(*) from performance_schema.events_stages_history +where THREAD_ID = $con1_thread_id; count(*) 0 +select /*1-2*/ count(*) from performance_schema.events_stages_history_long +where THREAD_ID = $con1_thread_id; count(*) 0 -"=========================== Stages user 2" +########################### Stages user 2 - 2 +select /*2-2*/ EVENT_NAME from performance_schema.events_stages_current +where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME +select /*2-2*/ count(*) from performance_schema.events_stages_history +where THREAD_ID = $con2_thread_id; count(*) 0 +select /*2-2*/ count(*) from performance_schema.events_stages_history_long +where THREAD_ID = $con2_thread_id; count(*) 0 -"=========================== Stages user 3" +########################### Stages user 3 - 2 +select /*3-2*/ count(*) from performance_schema.events_stages_current +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-2*/ count(*) from performance_schema.events_stages_history +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-2*/ count(*) from performance_schema.events_stages_history_long +where THREAD_ID = $con3_thread_id; count(*) 0 -"=========================== Stages user 4" +########################### Stages user 4 - 2 +select /*4-2*/ count(*) from performance_schema.events_stages_current +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-2*/ count(*) from performance_schema.events_stages_history +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-2*/ count(*) from performance_schema.events_stages_history_long +where THREAD_ID = $con4_thread_id; count(*) 0 -"=========================== Waits user 1" +########################### Waits user 1 - 2 +select /*1-2*/ EVENT_NAME from performance_schema.events_waits_current +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME idle +select /*1-2*/ count(*) as has_waits from performance_schema.events_waits_history +where THREAD_ID = $con1_thread_id; has_waits 0 +select /*1-2*/ count(*) as has_waits from performance_schema.events_waits_history_long +where THREAD_ID = $con1_thread_id; has_waits 0 -"=========================== Waits user 2" +########################### Waits user 2 - 2 +select /*2-2*/ EVENT_NAME from performance_schema.events_waits_current +where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME idle +select /*2-2*/ count(*) from performance_schema.events_waits_history +where THREAD_ID = $con2_thread_id; count(*) 0 +select /*2-2*/ count(*) from performance_schema.events_waits_history_long +where THREAD_ID = $con2_thread_id; count(*) 0 -"=========================== Waits user 3" +########################### Waits user 3 - 2 +select /*3-2*/ count(*) from performance_schema.events_waits_current +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-2*/ count(*) from performance_schema.events_waits_history +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-2*/ count(*) from performance_schema.events_waits_history_long +where THREAD_ID = $con3_thread_id; count(*) 0 -"=========================== Waits user 4" +########################### Waits user 4 - 2 +select /*4-2*/ count(*) from performance_schema.events_waits_current +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-2*/ count(*) from performance_schema.events_waits_history +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-2*/ count(*) from performance_schema.events_waits_history_long +where THREAD_ID = $con4_thread_id; count(*) 0 -# Switch to connection default, enable consumers connection default; update performance_schema.setup_consumers set enabled='YES' where name like "%history%"; @@ -476,7 +653,6 @@ truncate table performance_schema.events_stages_history_long; truncate table performance_schema.events_waits_current; truncate table performance_schema.events_waits_history; truncate table performance_schema.events_waits_history_long; -# Switch to connection con1 connection con1; XA START 'XA_CON1', 'XA_BQUAL', 12; select "Hi from con1"; @@ -485,7 +661,6 @@ Hi from con1 XA END 'XA_CON1', 'XA_BQUAL', 12; XA PREPARE 'XA_CON1', 'XA_BQUAL', 12; XA COMMIT 'XA_CON1', 'XA_BQUAL', 12; -# Switch to connection con2 connection con2; XA START 'XA_CON2', 'XA_BQUAL', 12; select "Hi from con2"; @@ -494,7 +669,6 @@ Hi from con2 XA END 'XA_CON2', 'XA_BQUAL', 12; XA PREPARE 'XA_CON2', 'XA_BQUAL', 12; XA COMMIT 'XA_CON2', 'XA_BQUAL', 12; -# Switch to connection con3 connection con3; XA START 'XA_CON3', 'XA_BQUAL', 12; select "Hi from con3"; @@ -503,7 +677,6 @@ Hi from con3 XA END 'XA_CON3', 'XA_BQUAL', 12; XA PREPARE 'XA_CON3', 'XA_BQUAL', 12; XA COMMIT 'XA_CON3', 'XA_BQUAL', 12; -# Switch to connection con4 connection con4; XA START 'XA_CON4', 'XA_BQUAL', 12; select "Hi from con4"; @@ -513,88 +686,142 @@ XA END 'XA_CON4', 'XA_BQUAL', 12; XA PREPARE 'XA_CON4', 'XA_BQUAL', 12; XA COMMIT 'XA_CON4', 'XA_BQUAL', 12; connection default; -"=========================== Transactions user 1" +########################### Transactions user 1 - 3 +select /*1-3*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current +where THREAD_ID = $con1_thread_id; XID_FORMAT_ID XID_GTRID XID_BQUAL 12 XA_CON1 XA_BQUAL +select /*1-3*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_history +where THREAD_ID = $con1_thread_id; XID_FORMAT_ID XID_GTRID XID_BQUAL 12 XA_CON1 XA_BQUAL +select /*1-3*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_history_long +where THREAD_ID = $con1_thread_id; XID_FORMAT_ID XID_GTRID XID_BQUAL 12 XA_CON1 XA_BQUAL -"=========================== Transactions user 2" +########################### Transactions user 2 - 3 +select /*2-3*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current +where THREAD_ID = $con2_thread_id; XID_FORMAT_ID XID_GTRID XID_BQUAL 12 XA_CON2 XA_BQUAL +select /*2-3*/ count(*) from performance_schema.events_transactions_history +where THREAD_ID = $con2_thread_id; count(*) 0 +select /*2-3*/ count(*) from performance_schema.events_transactions_history_long +where THREAD_ID = $con2_thread_id; count(*) 0 -"=========================== Transactions user 3" +########################### Transactions user 3 - 3 +select /*3-3*/ count(*) from performance_schema.events_transactions_current +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-3*/ count(*) from performance_schema.events_transactions_history +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-3*/ count(*) from performance_schema.events_transactions_history_long +where THREAD_ID = $con3_thread_id; count(*) 0 -"=========================== Transactions user 4" +########################### Transactions user 4 - 3 +select /*4-3*/ count(*) from performance_schema.events_transactions_current +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-3*/ count(*) from performance_schema.events_transactions_history +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-3*/ count(*) from performance_schema.events_transactions_history_long +where THREAD_ID = $con4_thread_id; count(*) 0 -"=========================== Statements user 1" +########################### Statements user 1 - 3 +select /*1-3*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME SQL_TEXT statement/sql/xa_commit XA COMMIT 'XA_CON1', 'XA_BQUAL', 12 +select /*1-3*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_history +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME SQL_TEXT statement/sql/xa_start XA START 'XA_CON1', 'XA_BQUAL', 12 statement/sql/select select "Hi from con1" statement/sql/xa_end XA END 'XA_CON1', 'XA_BQUAL', 12 statement/sql/xa_prepare XA PREPARE 'XA_CON1', 'XA_BQUAL', 12 statement/sql/xa_commit XA COMMIT 'XA_CON1', 'XA_BQUAL', 12 +select /*1-3*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_history_long +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME SQL_TEXT statement/sql/xa_start XA START 'XA_CON1', 'XA_BQUAL', 12 statement/sql/select select "Hi from con1" statement/sql/xa_end XA END 'XA_CON1', 'XA_BQUAL', 12 statement/sql/xa_prepare XA PREPARE 'XA_CON1', 'XA_BQUAL', 12 statement/sql/xa_commit XA COMMIT 'XA_CON1', 'XA_BQUAL', 12 -"=========================== Statements user 2" +########################### Statements user 2 - 3 +select /*2-3*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current +where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME SQL_TEXT statement/sql/xa_commit XA COMMIT 'XA_CON2', 'XA_BQUAL', 12 +select /*2-3*/ count(*) from performance_schema.events_statements_history +where THREAD_ID = $con2_thread_id; count(*) 0 +select /*2-3*/ count(*) from performance_schema.events_statements_history_long +where THREAD_ID = $con2_thread_id; count(*) 0 -"=========================== Statements user 3" +########################### Statements user 3 - 3 +select /*3-3*/ count(*) from performance_schema.events_statements_current +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-3*/ count(*) from performance_schema.events_statements_history +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-3*/ count(*) from performance_schema.events_statements_history_long +where THREAD_ID = $con3_thread_id; count(*) 0 -"=========================== Statements user 4" +########################### Statements user 4 - 3 +select /*4-3*/ count(*) from performance_schema.events_statements_current +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-3*/ count(*) from performance_schema.events_statements_history +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-3*/ count(*) from performance_schema.events_statements_history_long +where THREAD_ID = $con4_thread_id; count(*) 0 -"=========================== Stages user 1" +########################### Stages user 1 - 3 +select /*1-3*/ EVENT_NAME from performance_schema.events_stages_current +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME +select /*1-3*/ EVENT_NAME from performance_schema.events_stages_history +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command stage/sql/starting stage/sql/Query end -stage/sql/Commit stage/sql/closing tables +stage/sql/Query end stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command +select /*1-3*/ EVENT_NAME from performance_schema.events_stages_history_long +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME stage/sql/starting stage/sql/Query end -stage/sql/Commit stage/sql/closing tables +stage/sql/Query end stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command @@ -607,81 +834,122 @@ stage/sql/Optimizing stage/sql/Executing stage/sql/End of update loop stage/sql/Query end -stage/sql/Commit stage/sql/closing tables +stage/sql/Query end stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command stage/sql/starting stage/sql/Query end -stage/sql/Commit stage/sql/closing tables +stage/sql/Query end stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command stage/sql/starting stage/sql/Query end -stage/sql/Commit stage/sql/closing tables +stage/sql/Query end stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command stage/sql/starting stage/sql/Query end -stage/sql/Commit stage/sql/closing tables +stage/sql/Query end stage/sql/Starting cleanup stage/sql/Freeing items stage/sql/Reset for next command -"=========================== Stages user 2" +########################### Stages user 2 - 3 +select /*2-3*/ EVENT_NAME from performance_schema.events_stages_current +where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME +select /*2-3*/ count(*) from performance_schema.events_stages_history +where THREAD_ID = $con2_thread_id; count(*) 0 +select /*2-3*/ count(*) from performance_schema.events_stages_history_long +where THREAD_ID = $con2_thread_id; count(*) 0 -"=========================== Stages user 3" +########################### Stages user 3 - 3 +select /*3-3*/ count(*) from performance_schema.events_stages_current +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-3*/ count(*) from performance_schema.events_stages_history +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-3*/ count(*) from performance_schema.events_stages_history_long +where THREAD_ID = $con3_thread_id; count(*) 0 -"=========================== Stages user 4" +########################### Stages user 4 - 3 +select /*4-3*/ count(*) from performance_schema.events_stages_current +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-3*/ count(*) from performance_schema.events_stages_history +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-3*/ count(*) from performance_schema.events_stages_history_long +where THREAD_ID = $con4_thread_id; count(*) 0 -"=========================== Waits user 1" +########################### Waits user 1 - 3 +select /*1-3*/ EVENT_NAME from performance_schema.events_waits_current +where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME idle +select /*1-3*/ (count(*) > 5) as has_waits from performance_schema.events_waits_history +where THREAD_ID = $con1_thread_id; has_waits 1 +select /*1-3*/ (count(*) > 15) as has_waits from performance_schema.events_waits_history_long +where THREAD_ID = $con1_thread_id; has_waits 1 -"=========================== Waits user 2" +########################### Waits user 2 - 3 +select /*2-3*/ EVENT_NAME from performance_schema.events_waits_current +where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; EVENT_NAME idle +select /*2-3*/ count(*) from performance_schema.events_waits_history +where THREAD_ID = $con2_thread_id; count(*) 0 +select /*2-3*/ count(*) from performance_schema.events_waits_history_long +where THREAD_ID = $con2_thread_id; count(*) 0 -"=========================== Waits user 3" +########################### Waits user 3 - 3 +select /*3-3*/ count(*) from performance_schema.events_waits_current +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-3*/ count(*) from performance_schema.events_waits_history +where THREAD_ID = $con3_thread_id; count(*) 0 +select /*3-3*/ count(*) from performance_schema.events_waits_history_long +where THREAD_ID = $con3_thread_id; count(*) 0 -"=========================== Waits user 4" +########################### Waits user 4 - 3 +select /*4-3*/ count(*) from performance_schema.events_waits_current +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-3*/ count(*) from performance_schema.events_waits_history +where THREAD_ID = $con4_thread_id; count(*) 0 +select /*4-3*/ count(*) from performance_schema.events_waits_history_long +where THREAD_ID = $con4_thread_id; count(*) 0 -# Switch to connection default connection default; revoke all privileges, grant option from user1@localhost; revoke all privileges, grant option from user2@localhost; diff --git a/mysql-test/suite/perfschema/t/bad_option.test b/mysql-test/suite/perfschema/t/bad_option.test index 4feb0468e66..3eee669bdde 100644 --- a/mysql-test/suite/perfschema/t/bad_option.test +++ b/mysql-test/suite/perfschema/t/bad_option.test @@ -14,7 +14,7 @@ let $error_log= $MYSQLTEST_VARDIR/log/my_restart.err; let SEARCH_FILE= $error_log; # Stop the server let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; ---exec echo "wait" > $restart_file +--write_line wait $restart_file --shutdown_server --source include/wait_until_disconnected.inc --error 7 @@ -62,7 +62,7 @@ let SEARCH_PATTERN= Can.t change dir to .*bad_option_h_param; --remove_file $error_log # Write file to make mysql-test-run.pl start up the server again ---exec echo "restart" > $restart_file +--write_line restart $restart_file # Turn on reconnect --enable_reconnect diff --git a/mysql-test/suite/perfschema/t/misc.test b/mysql-test/suite/perfschema/t/misc.test index 79c23c65616..e8b9691fda5 100644 --- a/mysql-test/suite/perfschema/t/misc.test +++ b/mysql-test/suite/perfschema/t/misc.test @@ -175,6 +175,7 @@ DROP TABLE t_60905; # show global variables like "performance_schema_max_thread_instances"; +replace_result 512 256; explain select * from performance_schema.threads; # diff --git a/mysql-test/suite/perfschema/t/processlist_57.test b/mysql-test/suite/perfschema/t/processlist_57.test index 748d8b7402b..fe8898ed049 100644 --- a/mysql-test/suite/perfschema/t/processlist_57.test +++ b/mysql-test/suite/perfschema/t/processlist_57.test @@ -23,7 +23,7 @@ DROP TABLE performance_schema.processlist; SHOW CREATE TABLE performance_schema.processlist; let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; ---exec echo "wait" > $restart_file +--write_line wait $restart_file --echo ## --echo ## Server shutdown --echo ## @@ -93,7 +93,7 @@ SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; --error ER_BAD_FIELD_ERROR SHOW PROCESSLIST; ---exec echo "wait" > $restart_file +--write_line wait $restart_file --echo ## --echo ## Server shutdown --echo ## @@ -166,7 +166,7 @@ SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; # Works and returns no data, innodb table is empty. SHOW PROCESSLIST; ---exec echo "wait" > $restart_file +--write_line wait $restart_file --echo ## --echo ## Server shutdown --echo ## @@ -231,7 +231,7 @@ SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; # Works and returns no data, innodb table is empty. SHOW PROCESSLIST; ---exec echo "wait" > $restart_file +--write_line wait $restart_file --echo ## --echo ## Server shutdown --echo ## @@ -306,7 +306,7 @@ SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; --replace_column 3 [HOST:PORT] 6 [TIME] SHOW PROCESSLIST; ---exec echo "wait" > $restart_file +--write_line wait $restart_file --echo ## --echo ## Server shutdown --echo ## diff --git a/mysql-test/suite/perfschema/t/setup_instruments_defaults.test b/mysql-test/suite/perfschema/t/setup_instruments_defaults.test index ea59cd4f266..bd33c559d9a 100644 --- a/mysql-test/suite/perfschema/t/setup_instruments_defaults.test +++ b/mysql-test/suite/perfschema/t/setup_instruments_defaults.test @@ -69,7 +69,7 @@ SELECT * FROM performance_schema.setup_instruments WHERE name like "%wait/io/table/sql/handler%"; # Write file to make mysql-test-run.pl wait for the server to stop ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Restart the server --echo # @@ -79,7 +79,7 @@ WHERE name like "%wait/io/table/sql/handler%"; --echo # Restart server with wait/io/table/sql/handler disabled ---exec echo "restart:--loose-performance-schema-instrument=%wait/io/table/sql/%=off" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line "restart:--loose-performance-schema-instrument=%wait/io/table/sql/%=off" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Turn on reconnect --echo # Enable reconnect diff --git a/mysql-test/suite/perfschema/t/statement_program_lost_inst.test b/mysql-test/suite/perfschema/t/statement_program_lost_inst.test index 023180b9d2b..0742043bba3 100644 --- a/mysql-test/suite/perfschema/t/statement_program_lost_inst.test +++ b/mysql-test/suite/perfschema/t/statement_program_lost_inst.test @@ -19,10 +19,10 @@ --source include/have_perfschema.inc let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; ---exec echo "wait" > $restart_file +--write_line wait $restart_file --shutdown_server --source include/wait_until_disconnected.inc ---exec echo "restart:--performance_schema_max_program_instances=7 --performance_schema_max_statement_stack=2 --thread_stack=655360">$restart_file +--write_line "restart:--performance_schema_max_program_instances=7 --performance_schema_max_statement_stack=2 --thread_stack=655360" $restart_file --enable_reconnect --source include/wait_until_connected_again.inc diff --git a/mysql-test/suite/perfschema/t/threads_history.test b/mysql-test/suite/perfschema/t/threads_history.test index f42dd6d0ab4..aee983339d2 100644 --- a/mysql-test/suite/perfschema/t/threads_history.test +++ b/mysql-test/suite/perfschema/t/threads_history.test @@ -23,7 +23,6 @@ flush privileges; select * from performance_schema.setup_consumers; ---echo # Switch to (con1, localhost, user1, , ) connect (con1, localhost, user1, , ); update performance_schema.threads @@ -33,7 +32,6 @@ update performance_schema.threads let $con1_thread_id= `select THREAD_ID from performance_schema.threads where PROCESSLIST_ID = connection_id()`; ---echo # Switch to (con2, localhost, user2, , ) connect (con2, localhost, user2, , ); update performance_schema.threads @@ -43,7 +41,6 @@ update performance_schema.threads let $con2_thread_id= `select THREAD_ID from performance_schema.threads where PROCESSLIST_ID = connection_id()`; ---echo # Switch to (con3, localhost, user3, , ) connect (con3, localhost, user3, , ); update performance_schema.threads @@ -53,7 +50,6 @@ update performance_schema.threads let $con3_thread_id= `select THREAD_ID from performance_schema.threads where PROCESSLIST_ID = connection_id()`; ---echo # Switch to (con4, localhost, user4, , ) connect (con4, localhost, user4, , ); update performance_schema.threads @@ -63,7 +59,6 @@ update performance_schema.threads let $con4_thread_id= `select THREAD_ID from performance_schema.threads where PROCESSLIST_ID = connection_id()`; ---echo # Switch to connection default --connection default truncate table performance_schema.events_transactions_current; @@ -79,7 +74,6 @@ truncate table performance_schema.events_waits_current; truncate table performance_schema.events_waits_history; truncate table performance_schema.events_waits_history_long; ---echo # Switch to connection con1 --connection con1 XA START 'XA_CON1', 'XA_BQUAL', 12; @@ -88,7 +82,6 @@ XA END 'XA_CON1', 'XA_BQUAL', 12; XA PREPARE 'XA_CON1', 'XA_BQUAL', 12; XA COMMIT 'XA_CON1', 'XA_BQUAL', 12; ---echo # Switch to connection con2 --connection con2 XA START 'XA_CON2', 'XA_BQUAL', 12; @@ -97,7 +90,6 @@ XA END 'XA_CON2', 'XA_BQUAL', 12; XA PREPARE 'XA_CON2', 'XA_BQUAL', 12; XA COMMIT 'XA_CON2', 'XA_BQUAL', 12; ---echo # Switch to connection con3 --connection con3 XA START 'XA_CON3', 'XA_BQUAL', 12; @@ -106,7 +98,6 @@ XA END 'XA_CON3', 'XA_BQUAL', 12; XA PREPARE 'XA_CON3', 'XA_BQUAL', 12; XA COMMIT 'XA_CON3', 'XA_BQUAL', 12; ---echo # Switch to connection con4 --connection con4 XA START 'XA_CON4', 'XA_BQUAL', 12; @@ -117,165 +108,150 @@ XA COMMIT 'XA_CON4', 'XA_BQUAL', 12; --connection default ---disable_query_log +echo ########################### Transactions user 1 - 1; -echo "=========================== Transactions user 1"; - -eval select XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current +evalp select /*1-1*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current where THREAD_ID = $con1_thread_id; -eval select XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_history +evalp select /*1-1*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_history where THREAD_ID = $con1_thread_id; -eval select XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_history_long +evalp select /*1-1*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_history_long where THREAD_ID = $con1_thread_id; -echo "=========================== Transactions user 2"; +echo ########################### Transactions user 2 - 1; -eval select XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current +evalp select /*2-1*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_transactions_history +evalp select /*2-1*/ count(*) from performance_schema.events_transactions_history where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_transactions_history_long +evalp select /*2-1*/ count(*) from performance_schema.events_transactions_history_long where THREAD_ID = $con2_thread_id; -echo "=========================== Transactions user 3"; +echo ########################### Transactions user 3 - 1; -eval select count(*) from performance_schema.events_transactions_current +evalp select /*3-1*/ count(*) from performance_schema.events_transactions_current where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_transactions_history +evalp select /*3-1*/ count(*) from performance_schema.events_transactions_history where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_transactions_history_long +evalp select /*3-1*/ count(*) from performance_schema.events_transactions_history_long where THREAD_ID = $con3_thread_id; -echo "=========================== Transactions user 4"; +echo ########################### Transactions user 4 - 1; -eval select count(*) from performance_schema.events_transactions_current +evalp select /*4-1*/ count(*) from performance_schema.events_transactions_current where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_transactions_history +evalp select /*4-1*/ count(*) from performance_schema.events_transactions_history where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_transactions_history_long +evalp select /*4-1*/ count(*) from performance_schema.events_transactions_history_long where THREAD_ID = $con4_thread_id; -echo "=========================== Statements user 1"; +echo ########################### Statements user 1 - 1; -eval select EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; -eval select EVENT_NAME, SQL_TEXT from performance_schema.events_statements_history - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; -eval select EVENT_NAME, SQL_TEXT from performance_schema.events_statements_history_long - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; +evalp select /*1-1*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*1-1*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_history + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*1-1*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_history_long + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; -echo "=========================== Statements user 2"; +echo ########################### Statements user 2 - 1; -eval select EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current - where THREAD_ID = $con2_thread_id - order by THREAD_ID, EVENT_ID; -eval select count(*) from performance_schema.events_statements_history +evalp select /*2-1*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current + where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*2-1*/ count(*) from performance_schema.events_statements_history where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_statements_history_long +evalp select /*2-1*/ count(*) from performance_schema.events_statements_history_long where THREAD_ID = $con2_thread_id; -echo "=========================== Statements user 3"; +echo ########################### Statements user 3 - 1; -eval select count(*) from performance_schema.events_statements_current +evalp select /*3-1*/ count(*) from performance_schema.events_statements_current where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_statements_history +evalp select /*3-1*/ count(*) from performance_schema.events_statements_history where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_statements_history_long +evalp select /*3-1*/ count(*) from performance_schema.events_statements_history_long where THREAD_ID = $con3_thread_id; -echo "=========================== Statements user 4"; +echo ########################### Statements user 4 - 1; -eval select count(*) from performance_schema.events_statements_current +evalp select /*4-1*/ count(*) from performance_schema.events_statements_current where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_statements_history +evalp select /*4-1*/ count(*) from performance_schema.events_statements_history where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_statements_history_long +evalp select /*4-1*/ count(*) from performance_schema.events_statements_history_long where THREAD_ID = $con4_thread_id; -echo "=========================== Stages user 1"; +echo ########################### Stages user 1 - 1; -eval select EVENT_NAME from performance_schema.events_stages_current - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; -eval select EVENT_NAME from performance_schema.events_stages_history - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; -eval select EVENT_NAME from performance_schema.events_stages_history_long - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; +evalp select /*1-1*/ EVENT_NAME from performance_schema.events_stages_current + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*1-1*/ EVENT_NAME from performance_schema.events_stages_history + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*1-1*/ EVENT_NAME from performance_schema.events_stages_history_long + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; -echo "=========================== Stages user 2"; +echo ########################### Stages user 2 - 1; -eval select EVENT_NAME from performance_schema.events_stages_current - where THREAD_ID = $con2_thread_id - order by THREAD_ID, EVENT_ID; -eval select count(*) from performance_schema.events_stages_history +evalp select /*2-1*/ EVENT_NAME from performance_schema.events_stages_current + where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*2-1*/ count(*) from performance_schema.events_stages_history where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_stages_history_long +evalp select /*2-1*/ count(*) from performance_schema.events_stages_history_long where THREAD_ID = $con2_thread_id; -echo "=========================== Stages user 3"; +echo ########################### Stages user 3 - 1; -eval select count(*) from performance_schema.events_stages_current +evalp select /*3-1*/ count(*) from performance_schema.events_stages_current where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_stages_history +evalp select /*3-1*/ count(*) from performance_schema.events_stages_history where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_stages_history_long +evalp select /*3-1*/ count(*) from performance_schema.events_stages_history_long where THREAD_ID = $con3_thread_id; -echo "=========================== Stages user 4"; +echo ########################### Stages user 4 - 1; -eval select count(*) from performance_schema.events_stages_current +evalp select /*4-1*/ count(*) from performance_schema.events_stages_current where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_stages_history +evalp select /*4-1*/ count(*) from performance_schema.events_stages_history where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_stages_history_long +evalp select /*4-1*/ count(*) from performance_schema.events_stages_history_long where THREAD_ID = $con4_thread_id; -echo "=========================== Waits user 1"; +echo ########################### Waits user 1 - 1; -eval select EVENT_NAME from performance_schema.events_waits_current - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; -eval select (count(*) > 5) as has_waits from performance_schema.events_waits_history +evalp select /*1-1*/ EVENT_NAME from performance_schema.events_waits_current + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*1-1*/ (count(*) > 5) as has_waits from performance_schema.events_waits_history where THREAD_ID = $con1_thread_id; -eval select (count(*) > 15) as has_waits from performance_schema.events_waits_history_long +evalp select /*1-1*/ (count(*) > 15) as has_waits from performance_schema.events_waits_history_long where THREAD_ID = $con1_thread_id; -echo "=========================== Waits user 2"; +echo ########################### Waits user 2 - 1; -eval select EVENT_NAME from performance_schema.events_waits_current - where THREAD_ID = $con2_thread_id - order by THREAD_ID, EVENT_ID; -eval select count(*) from performance_schema.events_waits_history +evalp select /*2-1*/ EVENT_NAME from performance_schema.events_waits_current + where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*2-1*/ count(*) from performance_schema.events_waits_history where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_waits_history_long +evalp select /*2-1*/ count(*) from performance_schema.events_waits_history_long where THREAD_ID = $con2_thread_id; -echo "=========================== Waits user 3"; +echo ########################### Waits user 3 - 1; -eval select count(*) from performance_schema.events_waits_current +evalp select /*3-1*/ count(*) from performance_schema.events_waits_current where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_waits_history +evalp select /*3-1*/ count(*) from performance_schema.events_waits_history where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_waits_history_long +evalp select /*3-1*/ count(*) from performance_schema.events_waits_history_long where THREAD_ID = $con3_thread_id; -echo "=========================== Waits user 4"; +echo ########################### Waits user 4 - 1; -eval select count(*) from performance_schema.events_waits_current +evalp select /*4-1*/ count(*) from performance_schema.events_waits_current where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_waits_history +evalp select /*4-1*/ count(*) from performance_schema.events_waits_history where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_waits_history_long +evalp select /*4-1*/ count(*) from performance_schema.events_waits_history_long where THREAD_ID = $con4_thread_id; ---enable_query_log - ---echo # Switch to connection default, disable consumers --connection default update performance_schema.setup_consumers @@ -296,7 +272,6 @@ truncate table performance_schema.events_waits_current; truncate table performance_schema.events_waits_history; truncate table performance_schema.events_waits_history_long; ---echo # Switch to connection con1 --connection con1 XA START 'XA_CON1', 'XA_BQUAL', 12; @@ -305,7 +280,6 @@ XA END 'XA_CON1', 'XA_BQUAL', 12; XA PREPARE 'XA_CON1', 'XA_BQUAL', 12; XA COMMIT 'XA_CON1', 'XA_BQUAL', 12; ---echo # Switch to connection con2 --connection con2 XA START 'XA_CON2', 'XA_BQUAL', 12; @@ -314,7 +288,6 @@ XA END 'XA_CON2', 'XA_BQUAL', 12; XA PREPARE 'XA_CON2', 'XA_BQUAL', 12; XA COMMIT 'XA_CON2', 'XA_BQUAL', 12; ---echo # Switch to connection con3 --connection con3 XA START 'XA_CON3', 'XA_BQUAL', 12; @@ -323,7 +296,6 @@ XA END 'XA_CON3', 'XA_BQUAL', 12; XA PREPARE 'XA_CON3', 'XA_BQUAL', 12; XA COMMIT 'XA_CON3', 'XA_BQUAL', 12; ---echo # Switch to connection con4 --connection con4 XA START 'XA_CON4', 'XA_BQUAL', 12; @@ -334,161 +306,150 @@ XA COMMIT 'XA_CON4', 'XA_BQUAL', 12; --connection default ---disable_query_log +echo ########################### Transactions user 1 - 2; -echo "=========================== Transactions user 1"; - -eval select XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current +evalp select /*1-2*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current where THREAD_ID = $con1_thread_id; -eval select count(*) from performance_schema.events_transactions_history +evalp select /*1-2*/ count(*) from performance_schema.events_transactions_history where THREAD_ID = $con1_thread_id; -eval select count(*) from performance_schema.events_transactions_history_long +evalp select /*1-2*/ count(*) from performance_schema.events_transactions_history_long where THREAD_ID = $con1_thread_id; -echo "=========================== Transactions user 2"; +echo ########################### Transactions user 2 - 2; -eval select XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current +evalp select /*2-2*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_transactions_history +evalp select /*2-2*/ count(*) from performance_schema.events_transactions_history where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_transactions_history_long +evalp select /*2-2*/ count(*) from performance_schema.events_transactions_history_long where THREAD_ID = $con2_thread_id; -echo "=========================== Transactions user 3"; +echo ########################### Transactions user 3 - 2; -eval select count(*) from performance_schema.events_transactions_current +evalp select /*3-2*/ count(*) from performance_schema.events_transactions_current where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_transactions_history +evalp select /*3-2*/ count(*) from performance_schema.events_transactions_history where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_transactions_history_long +evalp select /*3-2*/ count(*) from performance_schema.events_transactions_history_long where THREAD_ID = $con3_thread_id; -echo "=========================== Transactions user 4"; +echo ########################### Transactions user 4 - 2; -eval select count(*) from performance_schema.events_transactions_current +evalp select /*4-2*/ count(*) from performance_schema.events_transactions_current where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_transactions_history +evalp select /*4-2*/ count(*) from performance_schema.events_transactions_history where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_transactions_history_long +evalp select /*4-2*/ count(*) from performance_schema.events_transactions_history_long where THREAD_ID = $con4_thread_id; -echo "=========================== Statements user 1"; +echo ########################### Statements user 1 - 2; -eval select EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; -eval select count(*) from performance_schema.events_statements_history +evalp select /*1-2*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*1-2*/ count(*) from performance_schema.events_statements_history where THREAD_ID = $con1_thread_id; -eval select count(*) from performance_schema.events_statements_history_long +evalp select /*1-2*/ count(*) from performance_schema.events_statements_history_long where THREAD_ID = $con1_thread_id; -echo "=========================== Statements user 2"; +echo ########################### Statements user 2 - 2; -eval select EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current - where THREAD_ID = $con2_thread_id - order by THREAD_ID, EVENT_ID; -eval select count(*) from performance_schema.events_statements_history +evalp select /*2-2*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current + where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*2-2*/ count(*) from performance_schema.events_statements_history where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_statements_history_long +evalp select /*2-2*/ count(*) from performance_schema.events_statements_history_long where THREAD_ID = $con2_thread_id; -echo "=========================== Statements user 3"; +echo ########################### Statements user 3 - 2; -eval select count(*) from performance_schema.events_statements_current +evalp select /*3-2*/ count(*) from performance_schema.events_statements_current where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_statements_history +evalp select /*3-2*/ count(*) from performance_schema.events_statements_history where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_statements_history_long +evalp select /*3-2*/ count(*) from performance_schema.events_statements_history_long where THREAD_ID = $con3_thread_id; -echo "=========================== Statements user 4"; +echo ########################### Statements user 4 - 2; -eval select count(*) from performance_schema.events_statements_current +evalp select /*4-2*/ count(*) from performance_schema.events_statements_current where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_statements_history +evalp select /*4-2*/ count(*) from performance_schema.events_statements_history where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_statements_history_long +evalp select /*4-2*/ count(*) from performance_schema.events_statements_history_long where THREAD_ID = $con4_thread_id; -echo "=========================== Stages user 1"; +echo ########################### Stages user 1 - 2; -eval select EVENT_NAME from performance_schema.events_stages_current - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; -eval select count(*) from performance_schema.events_stages_history +evalp select /*1-2*/ EVENT_NAME from performance_schema.events_stages_current + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*1-2*/ count(*) from performance_schema.events_stages_history where THREAD_ID = $con1_thread_id; -eval select count(*) from performance_schema.events_stages_history_long +evalp select /*1-2*/ count(*) from performance_schema.events_stages_history_long where THREAD_ID = $con1_thread_id; -echo "=========================== Stages user 2"; +echo ########################### Stages user 2 - 2; -eval select EVENT_NAME from performance_schema.events_stages_current - where THREAD_ID = $con2_thread_id - order by THREAD_ID, EVENT_ID; -eval select count(*) from performance_schema.events_stages_history +evalp select /*2-2*/ EVENT_NAME from performance_schema.events_stages_current + where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*2-2*/ count(*) from performance_schema.events_stages_history where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_stages_history_long +evalp select /*2-2*/ count(*) from performance_schema.events_stages_history_long where THREAD_ID = $con2_thread_id; -echo "=========================== Stages user 3"; +echo ########################### Stages user 3 - 2; -eval select count(*) from performance_schema.events_stages_current +evalp select /*3-2*/ count(*) from performance_schema.events_stages_current where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_stages_history +evalp select /*3-2*/ count(*) from performance_schema.events_stages_history where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_stages_history_long +evalp select /*3-2*/ count(*) from performance_schema.events_stages_history_long where THREAD_ID = $con3_thread_id; -echo "=========================== Stages user 4"; +echo ########################### Stages user 4 - 2; -eval select count(*) from performance_schema.events_stages_current +evalp select /*4-2*/ count(*) from performance_schema.events_stages_current where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_stages_history +evalp select /*4-2*/ count(*) from performance_schema.events_stages_history where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_stages_history_long +evalp select /*4-2*/ count(*) from performance_schema.events_stages_history_long where THREAD_ID = $con4_thread_id; -echo "=========================== Waits user 1"; +echo ########################### Waits user 1 - 2; -eval select EVENT_NAME from performance_schema.events_waits_current - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; -eval select count(*) as has_waits from performance_schema.events_waits_history +evalp select /*1-2*/ EVENT_NAME from performance_schema.events_waits_current + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*1-2*/ count(*) as has_waits from performance_schema.events_waits_history where THREAD_ID = $con1_thread_id; -eval select count(*) as has_waits from performance_schema.events_waits_history_long +evalp select /*1-2*/ count(*) as has_waits from performance_schema.events_waits_history_long where THREAD_ID = $con1_thread_id; -echo "=========================== Waits user 2"; +echo ########################### Waits user 2 - 2; -eval select EVENT_NAME from performance_schema.events_waits_current - where THREAD_ID = $con2_thread_id - order by THREAD_ID, EVENT_ID; -eval select count(*) from performance_schema.events_waits_history +evalp select /*2-2*/ EVENT_NAME from performance_schema.events_waits_current + where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*2-2*/ count(*) from performance_schema.events_waits_history where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_waits_history_long +evalp select /*2-2*/ count(*) from performance_schema.events_waits_history_long where THREAD_ID = $con2_thread_id; -echo "=========================== Waits user 3"; +echo ########################### Waits user 3 - 2; -eval select count(*) from performance_schema.events_waits_current +evalp select /*3-2*/ count(*) from performance_schema.events_waits_current where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_waits_history +evalp select /*3-2*/ count(*) from performance_schema.events_waits_history where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_waits_history_long +evalp select /*3-2*/ count(*) from performance_schema.events_waits_history_long where THREAD_ID = $con3_thread_id; -echo "=========================== Waits user 4"; +echo ########################### Waits user 4 - 2; -eval select count(*) from performance_schema.events_waits_current +evalp select /*4-2*/ count(*) from performance_schema.events_waits_current where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_waits_history +evalp select /*4-2*/ count(*) from performance_schema.events_waits_history where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_waits_history_long +evalp select /*4-2*/ count(*) from performance_schema.events_waits_history_long where THREAD_ID = $con4_thread_id; ---enable_query_log - ---echo # Switch to connection default, enable consumers --connection default update performance_schema.setup_consumers @@ -509,7 +470,6 @@ truncate table performance_schema.events_waits_current; truncate table performance_schema.events_waits_history; truncate table performance_schema.events_waits_history_long; ---echo # Switch to connection con1 --connection con1 XA START 'XA_CON1', 'XA_BQUAL', 12; @@ -518,7 +478,6 @@ XA END 'XA_CON1', 'XA_BQUAL', 12; XA PREPARE 'XA_CON1', 'XA_BQUAL', 12; XA COMMIT 'XA_CON1', 'XA_BQUAL', 12; ---echo # Switch to connection con2 --connection con2 XA START 'XA_CON2', 'XA_BQUAL', 12; @@ -527,7 +486,6 @@ XA END 'XA_CON2', 'XA_BQUAL', 12; XA PREPARE 'XA_CON2', 'XA_BQUAL', 12; XA COMMIT 'XA_CON2', 'XA_BQUAL', 12; ---echo # Switch to connection con3 --connection con3 XA START 'XA_CON3', 'XA_BQUAL', 12; @@ -536,7 +494,6 @@ XA END 'XA_CON3', 'XA_BQUAL', 12; XA PREPARE 'XA_CON3', 'XA_BQUAL', 12; XA COMMIT 'XA_CON3', 'XA_BQUAL', 12; ---echo # Switch to connection con4 --connection con4 XA START 'XA_CON4', 'XA_BQUAL', 12; @@ -547,165 +504,150 @@ XA COMMIT 'XA_CON4', 'XA_BQUAL', 12; --connection default ---disable_query_log +echo ########################### Transactions user 1 - 3; -echo "=========================== Transactions user 1"; - -eval select XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current +evalp select /*1-3*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current where THREAD_ID = $con1_thread_id; -eval select XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_history +evalp select /*1-3*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_history where THREAD_ID = $con1_thread_id; -eval select XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_history_long +evalp select /*1-3*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_history_long where THREAD_ID = $con1_thread_id; -echo "=========================== Transactions user 2"; +echo ########################### Transactions user 2 - 3; -eval select XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current +evalp select /*2-3*/ XID_FORMAT_ID, XID_GTRID, XID_BQUAL from performance_schema.events_transactions_current where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_transactions_history +evalp select /*2-3*/ count(*) from performance_schema.events_transactions_history where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_transactions_history_long +evalp select /*2-3*/ count(*) from performance_schema.events_transactions_history_long where THREAD_ID = $con2_thread_id; -echo "=========================== Transactions user 3"; +echo ########################### Transactions user 3 - 3; -eval select count(*) from performance_schema.events_transactions_current +evalp select /*3-3*/ count(*) from performance_schema.events_transactions_current where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_transactions_history +evalp select /*3-3*/ count(*) from performance_schema.events_transactions_history where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_transactions_history_long +evalp select /*3-3*/ count(*) from performance_schema.events_transactions_history_long where THREAD_ID = $con3_thread_id; -echo "=========================== Transactions user 4"; +echo ########################### Transactions user 4 - 3; -eval select count(*) from performance_schema.events_transactions_current +evalp select /*4-3*/ count(*) from performance_schema.events_transactions_current where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_transactions_history +evalp select /*4-3*/ count(*) from performance_schema.events_transactions_history where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_transactions_history_long +evalp select /*4-3*/ count(*) from performance_schema.events_transactions_history_long where THREAD_ID = $con4_thread_id; -echo "=========================== Statements user 1"; +echo ########################### Statements user 1 - 3; -eval select EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; -eval select EVENT_NAME, SQL_TEXT from performance_schema.events_statements_history - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; -eval select EVENT_NAME, SQL_TEXT from performance_schema.events_statements_history_long - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; +evalp select /*1-3*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*1-3*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_history + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*1-3*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_history_long + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; -echo "=========================== Statements user 2"; +echo ########################### Statements user 2 - 3; -eval select EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current - where THREAD_ID = $con2_thread_id - order by THREAD_ID, EVENT_ID; -eval select count(*) from performance_schema.events_statements_history +evalp select /*2-3*/ EVENT_NAME, SQL_TEXT from performance_schema.events_statements_current + where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*2-3*/ count(*) from performance_schema.events_statements_history where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_statements_history_long +evalp select /*2-3*/ count(*) from performance_schema.events_statements_history_long where THREAD_ID = $con2_thread_id; -echo "=========================== Statements user 3"; +echo ########################### Statements user 3 - 3; -eval select count(*) from performance_schema.events_statements_current +evalp select /*3-3*/ count(*) from performance_schema.events_statements_current where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_statements_history +evalp select /*3-3*/ count(*) from performance_schema.events_statements_history where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_statements_history_long +evalp select /*3-3*/ count(*) from performance_schema.events_statements_history_long where THREAD_ID = $con3_thread_id; -echo "=========================== Statements user 4"; +echo ########################### Statements user 4 - 3; -eval select count(*) from performance_schema.events_statements_current +evalp select /*4-3*/ count(*) from performance_schema.events_statements_current where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_statements_history +evalp select /*4-3*/ count(*) from performance_schema.events_statements_history where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_statements_history_long +evalp select /*4-3*/ count(*) from performance_schema.events_statements_history_long where THREAD_ID = $con4_thread_id; -echo "=========================== Stages user 1"; +echo ########################### Stages user 1 - 3; -eval select EVENT_NAME from performance_schema.events_stages_current - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; -eval select EVENT_NAME from performance_schema.events_stages_history - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; -eval select EVENT_NAME from performance_schema.events_stages_history_long - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; +evalp select /*1-3*/ EVENT_NAME from performance_schema.events_stages_current + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*1-3*/ EVENT_NAME from performance_schema.events_stages_history + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*1-3*/ EVENT_NAME from performance_schema.events_stages_history_long + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; -echo "=========================== Stages user 2"; +echo ########################### Stages user 2 - 3; -eval select EVENT_NAME from performance_schema.events_stages_current - where THREAD_ID = $con2_thread_id - order by THREAD_ID, EVENT_ID; -eval select count(*) from performance_schema.events_stages_history +evalp select /*2-3*/ EVENT_NAME from performance_schema.events_stages_current + where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*2-3*/ count(*) from performance_schema.events_stages_history where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_stages_history_long +evalp select /*2-3*/ count(*) from performance_schema.events_stages_history_long where THREAD_ID = $con2_thread_id; -echo "=========================== Stages user 3"; +echo ########################### Stages user 3 - 3; -eval select count(*) from performance_schema.events_stages_current +evalp select /*3-3*/ count(*) from performance_schema.events_stages_current where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_stages_history +evalp select /*3-3*/ count(*) from performance_schema.events_stages_history where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_stages_history_long +evalp select /*3-3*/ count(*) from performance_schema.events_stages_history_long where THREAD_ID = $con3_thread_id; -echo "=========================== Stages user 4"; +echo ########################### Stages user 4 - 3; -eval select count(*) from performance_schema.events_stages_current +evalp select /*4-3*/ count(*) from performance_schema.events_stages_current where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_stages_history +evalp select /*4-3*/ count(*) from performance_schema.events_stages_history where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_stages_history_long +evalp select /*4-3*/ count(*) from performance_schema.events_stages_history_long where THREAD_ID = $con4_thread_id; -echo "=========================== Waits user 1"; +echo ########################### Waits user 1 - 3; -eval select EVENT_NAME from performance_schema.events_waits_current - where THREAD_ID = $con1_thread_id - order by THREAD_ID, EVENT_ID; -eval select (count(*) > 5) as has_waits from performance_schema.events_waits_history +evalp select /*1-3*/ EVENT_NAME from performance_schema.events_waits_current + where THREAD_ID = $con1_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*1-3*/ (count(*) > 5) as has_waits from performance_schema.events_waits_history where THREAD_ID = $con1_thread_id; -eval select (count(*) > 15) as has_waits from performance_schema.events_waits_history_long +evalp select /*1-3*/ (count(*) > 15) as has_waits from performance_schema.events_waits_history_long where THREAD_ID = $con1_thread_id; -echo "=========================== Waits user 2"; +echo ########################### Waits user 2 - 3; -eval select EVENT_NAME from performance_schema.events_waits_current - where THREAD_ID = $con2_thread_id - order by THREAD_ID, EVENT_ID; -eval select count(*) from performance_schema.events_waits_history +evalp select /*2-3*/ EVENT_NAME from performance_schema.events_waits_current + where THREAD_ID = $con2_thread_id order by THREAD_ID, EVENT_ID; +evalp select /*2-3*/ count(*) from performance_schema.events_waits_history where THREAD_ID = $con2_thread_id; -eval select count(*) from performance_schema.events_waits_history_long +evalp select /*2-3*/ count(*) from performance_schema.events_waits_history_long where THREAD_ID = $con2_thread_id; -echo "=========================== Waits user 3"; +echo ########################### Waits user 3 - 3; -eval select count(*) from performance_schema.events_waits_current +evalp select /*3-3*/ count(*) from performance_schema.events_waits_current where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_waits_history +evalp select /*3-3*/ count(*) from performance_schema.events_waits_history where THREAD_ID = $con3_thread_id; -eval select count(*) from performance_schema.events_waits_history_long +evalp select /*3-3*/ count(*) from performance_schema.events_waits_history_long where THREAD_ID = $con3_thread_id; -echo "=========================== Waits user 4"; +echo ########################### Waits user 4 - 3; -eval select count(*) from performance_schema.events_waits_current +evalp select /*4-3*/ count(*) from performance_schema.events_waits_current where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_waits_history +evalp select /*4-3*/ count(*) from performance_schema.events_waits_history where THREAD_ID = $con4_thread_id; -eval select count(*) from performance_schema.events_waits_history_long +evalp select /*4-3*/ count(*) from performance_schema.events_waits_history_long where THREAD_ID = $con4_thread_id; ---enable_query_log - ---echo # Switch to connection default --connection default revoke all privileges, grant option from user1@localhost; diff --git a/mysql-test/suite/period/r/overlaps.result b/mysql-test/suite/period/r/overlaps.result index f7a19752b99..1b0f6799ac8 100644 --- a/mysql-test/suite/period/r/overlaps.result +++ b/mysql-test/suite/period/r/overlaps.result @@ -463,3 +463,85 @@ VALUES ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc'); ERROR 23000: Duplicate entry 'abc-2001-01-01 00:00:00.000000-2000-01-01 00:00:00.000000' for key 'index_name' DROP TABLE t1; +# MDEV-25370 Update for portion changes autoincrement key in period table +create or replace table cars(id int auto_increment, +price int, s date, e date, +period for p(s,e), +primary key(id, p without overlaps)); +insert into cars(price, s, e) values (1000, '2018-01-01', '2020-01-01'); +select * from cars; +id price s e +1 1000 2018-01-01 2020-01-01 +update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100; +select * from cars; +id price s e +1 1000 2018-01-01 2019-01-01 +1 1000 2019-12-01 2020-01-01 +1 1100 2019-01-01 2019-12-01 +delete from cars for portion of p from '2019-12-10' to '2019-12-20'; +select * from cars; +id price s e +1 1000 2018-01-01 2019-01-01 +1 1000 2019-12-01 2019-12-10 +1 1000 2019-12-20 2020-01-01 +1 1100 2019-01-01 2019-12-01 +# AUTO_INCREMENT field is separate from WITHOUT OVERLAPS +create or replace table cars(id int primary key auto_increment, +car_id int, +price int, s date, e date, +period for p(s,e), +unique(car_id, p without overlaps)); +insert cars(car_id, price, s, e) values (1, 1000, '2018-01-01', '2020-01-01'); +select * from cars; +id car_id price s e +1 1 1000 2018-01-01 2020-01-01 +update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100; +select * from cars; +id car_id price s e +1 1 1100 2019-01-01 2019-12-01 +2 1 1000 2018-01-01 2019-01-01 +3 1 1000 2019-12-01 2020-01-01 +delete from cars for portion of p from '2019-12-10' to '2019-12-20'; +select * from cars; +id car_id price s e +1 1 1100 2019-01-01 2019-12-01 +2 1 1000 2018-01-01 2019-01-01 +4 1 1000 2019-12-01 2019-12-10 +5 1 1000 2019-12-20 2020-01-01 +# AUTO_INCREMENT field is both standalone and in WITHOUT OVERLAPS +create or replace table cars(id int primary key auto_increment, +price int, s date, e date, +period for p(s,e), +unique(id, p without overlaps)); +insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01'); +insert cars(price, s, e) values (1000, '2021-01-01', '2022-01-01'); +update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100; +# autoincrement index is: id int primary key +# id increments each time. +select * from cars; +id price s e +1 1100 2019-01-01 2019-12-01 +2 1000 2021-01-01 2022-01-01 +3 1000 2018-01-01 2019-01-01 +4 1000 2019-12-01 2020-01-01 +truncate cars; +insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01'); +delete from cars for portion of p from '2019-12-10' to '2019-12-20'; +select * from cars; +id price s e +2 1000 2018-01-01 2019-12-10 +3 1000 2019-12-20 2020-01-01 +create or replace table cars(id int unique auto_increment, +price int, s date, e date, +period for p(s,e), +primary key (id, p without overlaps)); +insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01'); +# autoincrement index is: primary key (id, p without overlaps) +# id is not incremented, hence duplication error +update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100; +ERROR 23000: Duplicate entry '1' for key 'id' +truncate cars; +insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01'); +delete from cars for portion of p from '2019-12-10' to '2019-12-20'; +ERROR 23000: Duplicate entry '1' for key 'id' +drop table cars; diff --git a/mysql-test/suite/period/t/overlaps.test b/mysql-test/suite/period/t/overlaps.test index b7aa531faa3..e20811c6096 100644 --- a/mysql-test/suite/period/t/overlaps.test +++ b/mysql-test/suite/period/t/overlaps.test @@ -469,3 +469,80 @@ VALUES ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc '), ('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc'); DROP TABLE t1; + +--echo # MDEV-25370 Update for portion changes autoincrement key in period table +create or replace table cars(id int auto_increment, + price int, s date, e date, + period for p(s,e), + primary key(id, p without overlaps)); + +insert into cars(price, s, e) values (1000, '2018-01-01', '2020-01-01'); +select * from cars; + +update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100; +--sorted_result +select * from cars; + +delete from cars for portion of p from '2019-12-10' to '2019-12-20'; +--sorted_result +select * from cars; + +--echo # AUTO_INCREMENT field is separate from WITHOUT OVERLAPS +create or replace table cars(id int primary key auto_increment, + car_id int, + price int, s date, e date, + period for p(s,e), + unique(car_id, p without overlaps)); + +insert cars(car_id, price, s, e) values (1, 1000, '2018-01-01', '2020-01-01'); +select * from cars; + +update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100; +--sorted_result +select * from cars; + +delete from cars for portion of p from '2019-12-10' to '2019-12-20'; +--sorted_result +select * from cars; + + +--echo # AUTO_INCREMENT field is both standalone and in WITHOUT OVERLAPS +create or replace table cars(id int primary key auto_increment, + price int, s date, e date, + period for p(s,e), + unique(id, p without overlaps)); + +insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01'); +insert cars(price, s, e) values (1000, '2021-01-01', '2022-01-01'); + +update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100; +--echo # autoincrement index is: id int primary key +--echo # id increments each time. +--sorted_result +select * from cars; + +truncate cars; +insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01'); + +delete from cars for portion of p from '2019-12-10' to '2019-12-20'; +--sorted_result +select * from cars; + +create or replace table cars(id int unique auto_increment, + price int, s date, e date, + period for p(s,e), + primary key (id, p without overlaps)); + +insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01'); +--echo # autoincrement index is: primary key (id, p without overlaps) +--echo # id is not incremented, hence duplication error +--error ER_DUP_ENTRY +update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100; + +truncate cars; +insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01'); + +--error ER_DUP_ENTRY +delete from cars for portion of p from '2019-12-10' to '2019-12-20'; + +drop table cars; diff --git a/mysql-test/suite/plugins/r/compression,innodb-lz4.rdiff b/mysql-test/suite/plugins/r/compression,innodb-lz4.rdiff index 791aecda080..00abc19647c 100644 --- a/mysql-test/suite/plugins/r/compression,innodb-lz4.rdiff +++ b/mysql-test/suite/plugins/r/compression,innodb-lz4.rdiff @@ -18,11 +18,11 @@ -# restart: --disable-provider-bzip2 +# restart: --disable-provider-lz4 select a, left(b, 9), length(b) from t1; - ERROR 42S02: Table 'test.t1' doesn't exist in engine + ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. show warnings; Level Code Message -Warning 4185 MariaDB tried to use the BZip2 compression, but its provider plugin is not loaded +Warning 4185 MariaDB tried to use the LZ4 compression, but its provider plugin is not loaded - Error 1932 Table 'test.t1' doesn't exist in engine + Error 1877 Table `test`.`t1` is corrupted. Please drop the table and recreate. drop table t1; # restart diff --git a/mysql-test/suite/plugins/r/compression,innodb-lzma.rdiff b/mysql-test/suite/plugins/r/compression,innodb-lzma.rdiff index 13c42f82b43..0119adc7482 100644 --- a/mysql-test/suite/plugins/r/compression,innodb-lzma.rdiff +++ b/mysql-test/suite/plugins/r/compression,innodb-lzma.rdiff @@ -18,11 +18,11 @@ -# restart: --disable-provider-bzip2 +# restart: --disable-provider-lzma select a, left(b, 9), length(b) from t1; - ERROR 42S02: Table 'test.t1' doesn't exist in engine + ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. show warnings; Level Code Message -Warning 4185 MariaDB tried to use the BZip2 compression, but its provider plugin is not loaded +Warning 4185 MariaDB tried to use the LZMA compression, but its provider plugin is not loaded - Error 1932 Table 'test.t1' doesn't exist in engine + Error 1877 Table `test`.`t1` is corrupted. Please drop the table and recreate. drop table t1; # restart diff --git a/mysql-test/suite/plugins/r/compression,innodb-lzo.rdiff b/mysql-test/suite/plugins/r/compression,innodb-lzo.rdiff index cc7783cc4f8..52a794a99d7 100644 --- a/mysql-test/suite/plugins/r/compression,innodb-lzo.rdiff +++ b/mysql-test/suite/plugins/r/compression,innodb-lzo.rdiff @@ -18,11 +18,11 @@ -# restart: --disable-provider-bzip2 +# restart: --disable-provider-lzo select a, left(b, 9), length(b) from t1; - ERROR 42S02: Table 'test.t1' doesn't exist in engine + ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. show warnings; Level Code Message -Warning 4185 MariaDB tried to use the BZip2 compression, but its provider plugin is not loaded +Warning 4185 MariaDB tried to use the LZO compression, but its provider plugin is not loaded - Error 1932 Table 'test.t1' doesn't exist in engine + Error 1877 Table `test`.`t1` is corrupted. Please drop the table and recreate. drop table t1; # restart diff --git a/mysql-test/suite/plugins/r/compression,innodb-snappy.rdiff b/mysql-test/suite/plugins/r/compression,innodb-snappy.rdiff index 98c4427a758..cbbd754aa17 100644 --- a/mysql-test/suite/plugins/r/compression,innodb-snappy.rdiff +++ b/mysql-test/suite/plugins/r/compression,innodb-snappy.rdiff @@ -18,11 +18,11 @@ -# restart: --disable-provider-bzip2 +# restart: --disable-provider-snappy select a, left(b, 9), length(b) from t1; - ERROR 42S02: Table 'test.t1' doesn't exist in engine + ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. show warnings; Level Code Message -Warning 4185 MariaDB tried to use the BZip2 compression, but its provider plugin is not loaded +Warning 4185 MariaDB tried to use the Snappy compression, but its provider plugin is not loaded - Error 1932 Table 'test.t1' doesn't exist in engine + Error 1877 Table `test`.`t1` is corrupted. Please drop the table and recreate. drop table t1; # restart diff --git a/mysql-test/suite/plugins/r/compression,mroonga-lz4.rdiff b/mysql-test/suite/plugins/r/compression,mroonga-lz4.rdiff index ac186d3c566..3f449220df5 100644 --- a/mysql-test/suite/plugins/r/compression,mroonga-lz4.rdiff +++ b/mysql-test/suite/plugins/r/compression,mroonga-lz4.rdiff @@ -23,11 +23,11 @@ -# restart: --disable-provider-bzip2 +# restart: --disable-provider-lz4 select a, left(b, 9), length(b) from t1; --ERROR 42S02: Table 'test.t1' doesn't exist in engine +-ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. -show warnings; -Level Code Message -Warning 4185 MariaDB tried to use the BZip2 compression, but its provider plugin is not loaded --Error 1932 Table 'test.t1' doesn't exist in engine +-Error 1877 Table `test`.`t1` is corrupted. Please drop the table and recreate. +a left(b, 9) length(b) +0 0 +1 0 diff --git a/mysql-test/suite/plugins/r/compression.result b/mysql-test/suite/plugins/r/compression.result index d7c11abc95b..07bfbc0b9bb 100644 --- a/mysql-test/suite/plugins/r/compression.result +++ b/mysql-test/suite/plugins/r/compression.result @@ -18,10 +18,10 @@ a left(b, 9) length(b) 2 ghighighi 30000 # restart: --disable-provider-bzip2 select a, left(b, 9), length(b) from t1; -ERROR 42S02: Table 'test.t1' doesn't exist in engine +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. show warnings; Level Code Message Warning 4185 MariaDB tried to use the BZip2 compression, but its provider plugin is not loaded -Error 1932 Table 'test.t1' doesn't exist in engine +Error 1877 Table `test`.`t1` is corrupted. Please drop the table and recreate. drop table t1; # restart diff --git a/mysql-test/suite/plugins/t/compression.test b/mysql-test/suite/plugins/t/compression.test index df892acfdc4..95ae2df9462 100644 --- a/mysql-test/suite/plugins/t/compression.test +++ b/mysql-test/suite/plugins/t/compression.test @@ -40,7 +40,7 @@ let $restart_parameters = --disable-provider-$alg; source include/restart_mysqld.inc; if ($engine == "innodb") { - error ER_NO_SUCH_TABLE_IN_ENGINE; + error ER_TABLE_CORRUPT; select a, left(b, 9), length(b) from t1; show warnings; } diff --git a/mysql-test/suite/roles/definer.result b/mysql-test/suite/roles/definer.result index 0ff6a67b966..08e72193bf9 100644 --- a/mysql-test/suite/roles/definer.result +++ b/mysql-test/suite/roles/definer.result @@ -280,6 +280,7 @@ a b c 111 4 0 2 20 200 delete from t1 where a=111; +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; diff --git a/mysql-test/suite/rpl/include/rpl_extra_col_master.test b/mysql-test/suite/rpl/include/rpl_extra_col_master.test index a7abe69db0a..3fef3cc1fd0 100644 --- a/mysql-test/suite/rpl/include/rpl_extra_col_master.test +++ b/mysql-test/suite/rpl/include/rpl_extra_col_master.test @@ -59,6 +59,10 @@ #VARCHAR(M) # +--disable_query_log +call mtr.add_suppression("Could not read packet:.* errno: 11"); +--enable_query_log + --let $_saved_conn= $CURRENT_CONNECTION let $binformat = `SHOW VARIABLES LIKE '%binlog_format%'`; diff --git a/mysql-test/suite/rpl/r/parallel_backup.result b/mysql-test/suite/rpl/r/parallel_backup.result index 83c7a916c13..361838927e9 100644 --- a/mysql-test/suite/rpl/r/parallel_backup.result +++ b/mysql-test/suite/rpl/r/parallel_backup.result @@ -125,7 +125,7 @@ include/save_master_gtid.inc connection slave; SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; -SET @@global.innodb_lock_wait_timeout =1; +SET @@global.innodb_lock_wait_timeout =5; SET @@global.slave_transaction_retries=0; include/start_slave.inc connection aux_slave; @@ -168,7 +168,7 @@ include/save_master_gtid.inc connection slave; SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; -SET @@global.innodb_lock_wait_timeout =1; +SET @@global.innodb_lock_wait_timeout =5; SET @@global.slave_transaction_retries=0; include/start_slave.inc connection aux_slave; diff --git a/mysql-test/suite/rpl/r/parallel_backup_lsu_off.result b/mysql-test/suite/rpl/r/parallel_backup_lsu_off.result index e1fd7701fcc..08955a77291 100644 --- a/mysql-test/suite/rpl/r/parallel_backup_lsu_off.result +++ b/mysql-test/suite/rpl/r/parallel_backup_lsu_off.result @@ -128,7 +128,7 @@ include/save_master_gtid.inc connection slave; SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; -SET @@global.innodb_lock_wait_timeout =1; +SET @@global.innodb_lock_wait_timeout =5; SET @@global.slave_transaction_retries=0; include/start_slave.inc connection aux_slave; @@ -171,7 +171,7 @@ include/save_master_gtid.inc connection slave; SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; -SET @@global.innodb_lock_wait_timeout =1; +SET @@global.innodb_lock_wait_timeout =5; SET @@global.slave_transaction_retries=0; include/start_slave.inc connection aux_slave; diff --git a/mysql-test/suite/rpl/r/parallel_backup_slave_binlog_off.result b/mysql-test/suite/rpl/r/parallel_backup_slave_binlog_off.result index 9e29e5a3875..bb00bf9cbf5 100644 --- a/mysql-test/suite/rpl/r/parallel_backup_slave_binlog_off.result +++ b/mysql-test/suite/rpl/r/parallel_backup_slave_binlog_off.result @@ -128,7 +128,7 @@ include/save_master_gtid.inc connection slave; SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; -SET @@global.innodb_lock_wait_timeout =1; +SET @@global.innodb_lock_wait_timeout =5; SET @@global.slave_transaction_retries=0; include/start_slave.inc connection aux_slave; @@ -171,7 +171,7 @@ include/save_master_gtid.inc connection slave; SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; -SET @@global.innodb_lock_wait_timeout =1; +SET @@global.innodb_lock_wait_timeout =5; SET @@global.slave_transaction_retries=0; include/start_slave.inc connection aux_slave; diff --git a/mysql-test/suite/rpl/r/rpl_auditing.result b/mysql-test/suite/rpl/r/rpl_auditing.result new file mode 100644 index 00000000000..1861beb4e8f --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_auditing.result @@ -0,0 +1,64 @@ +include/master-slave.inc +[connection master] +drop table if exists t1; +connection slave; +reset master; +CREATE TABLE IF NOT EXISTS mysql.server_audit_filters ( +filtername char(80) COLLATE utf8_bin NOT NULL DEFAULT '', +rule longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT 'true' CHECK (json_valid(rule)), +CONSTRAINT c_filtername UNIQUE (filtername) +) ENGINE=Aria; +CREATE TABLE IF NOT EXISTS mysql.server_audit_users (host char(60) COLLATE utf8_bin NOT NULL DEFAULT '', +user char(80) COLLATE utf8_bin NOT NULL DEFAULT '', +filtername char(80) NOT NULL DEFAULT '', +CONSTRAINT c_host_user UNIQUE (host, user) +) ENGINE=Aria; +INSERT INTO mysql.server_audit_filters VALUES ('ignore_sys', '{"ignore_tables" : "mysql.*"}'); +INSERT INTO mysql.server_audit_users VALUES ('%','','ignore_sys'); +INSERT INTO mysql.server_audit_users VALUES ('%','root','ignore_sys'); +install plugin server_audit soname 'server_audit2'; +set global server_audit_logging=on; +connection master; +create table t1 (a int); +insert into t1 values (1); +truncate t1; +drop table t1; +connection slave; +set global server_audit_logging=off; +truncate mysql.server_audit_filters; +truncate mysql.server_audit_users; +INSERT INTO mysql.server_audit_filters VALUES ('no_logging','false'); +INSERT INTO mysql.server_audit_users VALUES ('%','','no_logging'); +set global server_audit_logging=on; +connection master; +create table t1 (a int); +insert into t1 values (1); +truncate t1; +drop table t1; +connection slave; +set global server_audit_logging=off; +uninstall plugin server_audit; +Warnings: +Warning 1620 Plugin is busy and will be uninstalled on shutdown +truncate mysql.server_audit_filters; +truncate mysql.server_audit_users; +TIME,HOSTNAME,,,0,0,AUDIT_CONFIG,,file_path=server_audit.log,0 +TIME,HOSTNAME,,,0,0,AUDIT_CONFIG,,rotate_size=1000000,0 +TIME,HOSTNAME,,,0,0,AUDIT_CONFIG,,file_rotations=9,0 +TIME,HOSTNAME,root,localhost,ID,0,AUDIT_CONFIG,test,logging=ON,0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_logging=on',0 +TIME,HOSTNAME,,,ID,ID,CREATE,test,t1, +TIME,HOSTNAME,,,ID,ID,WRITE,test,t1, +TIME,HOSTNAME,,,ID,ID,CREATE,test,t1, +TIME,HOSTNAME,,,ID,ID,DROP,test,t1, +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select master_pos_wait(\'master-bin.#', POS, 300, \'\')',0 +TIME,HOSTNAME,root,localhost,ID,0,AUDIT_CONFIG,test,logging=OFF,0 +TIME,HOSTNAME,,,0,0,AUDIT_CONFIG,,file_path=server_audit.log,0 +TIME,HOSTNAME,,,0,0,AUDIT_CONFIG,,rotate_size=1000000,0 +TIME,HOSTNAME,,,0,0,AUDIT_CONFIG,,file_rotations=9,0 +TIME,HOSTNAME,root,localhost,ID,0,AUDIT_CONFIG,test,logging=ON,0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_logging=on',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select master_pos_wait(\'master-bin.#', POS, 300, \'\')',0 +TIME,HOSTNAME,root,localhost,ID,0,AUDIT_CONFIG,test,logging=OFF,0 +connection master; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result b/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result index af79b482b2f..20dd9076a5d 100644 --- a/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result +++ b/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result @@ -1,6 +1,7 @@ include/master-slave.inc [connection master] connection master; +SET @org_log_warnings=@@GLOBAL.LOG_WARNINGS; SET GLOBAL LOG_WARNINGS=2; connection slave; include/stop_slave.inc @@ -41,11 +42,11 @@ connection master; include/wait_for_pattern_in_file.inc FOUND 1 /using_gtid\(1\), gtid\(\'0-1-2,10-1-1\'\).*/ in mysqld.1.err "===== Clean up =====" +SET GLOBAL LOG_WARNINGS=@org_log_warnings; connection slave; include/stop_slave.inc CHANGE MASTER TO MASTER_USE_GTID=no; include/start_slave.inc connection master; DROP TABLE t; -SET GLOBAL LOG_WARNINGS=default; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_change_master.result b/mysql-test/suite/rpl/r/rpl_change_master.result index 59d83a1e385..48cec72d917 100644 --- a/mysql-test/suite/rpl/r/rpl_change_master.result +++ b/mysql-test/suite/rpl/r/rpl_change_master.result @@ -26,9 +26,4 @@ connection master; CHANGE MASTER TO MASTER_USER='root', MASTER_SSL=0, MASTER_SSL_CA='', MASTER_SSL_CERT='', MASTER_SSL_KEY='', MASTER_SSL_CRL='', MASTER_SSL_CRLPATH=''; CHANGE MASTER TO MASTER_USER='root', MASTER_PASSWORD='', MASTER_SSL=0; -"Usage of CURRENT_POS in CHANGE MASTER MASTER_USE_GTID is dreprecated. -CHANGE MASTER TO MASTER_USE_GTID=CURRENT_POS; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead -CHANGE MASTER TO MASTER_USE_GTID=SLAVE_POS; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_change_master_demote.result b/mysql-test/suite/rpl/r/rpl_change_master_demote.result index 36a2d4a03c3..5deb412c91b 100644 --- a/mysql-test/suite/rpl/r/rpl_change_master_demote.result +++ b/mysql-test/suite/rpl/r/rpl_change_master_demote.result @@ -683,6 +683,23 @@ connection master; CHANGE MASTER TO master_host='127.0.0.1', master_port=SLAVE_PORT, master_user='root', master_use_gtid=Slave_Pos, master_demote_to_slave=invalid; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'invalid' at line 1 # +# MDEV-31768 +# Ensure MASTER_DEMOTE_TO_REPLICA aliases MASTER_DEMOTE_TO_SLAVE +# +connection slave; +RESET MASTER; +include/reset_slave.inc +CREATE TABLE t_mdev_31768 (a int); +CHANGE MASTER TO master_use_gtid=Replica_Pos, master_demote_to_replica=1; +# Validating alias MASTER_DEMOTE_TO_REPLICA provides intended behavior.. +# ..success +DROP TABLE t_mdev_31768; +RESET MASTER; +include/reset_slave.inc +# Clear primary binlog state to match replica +connection master; +RESET MASTER; +# # Cleanup # connection master; diff --git a/mysql-test/suite/rpl/r/rpl_ddl.result b/mysql-test/suite/rpl/r/rpl_ddl.result index 2de5b0228b7..27d84fea1e4 100644 --- a/mysql-test/suite/rpl/r/rpl_ddl.result +++ b/mysql-test/suite/rpl/r/rpl_ddl.result @@ -343,7 +343,6 @@ TEST-INFO: SLAVE: The INSERT is committed (Succeeded) connection master; SHOW TABLES LIKE 't2'; Tables_in_mysqltest1 (t2) -t23 connection slave; SHOW TABLES LIKE 't2'; Tables_in_mysqltest1 (t2) diff --git a/mysql-test/suite/rpl/r/rpl_domain_id_filter_io_crash.result b/mysql-test/suite/rpl/r/rpl_domain_id_filter_io_crash.result index 5250c4bb36a..9d3b2ccdab7 100644 --- a/mysql-test/suite/rpl/r/rpl_domain_id_filter_io_crash.result +++ b/mysql-test/suite/rpl/r/rpl_domain_id_filter_io_crash.result @@ -11,6 +11,7 @@ SELECT * FROM t1; i 1 connection slave; +include/save_master_gtid.inc connection slave; call mtr.add_suppression("Slave I/O: Relay log write failure: could not queue event from master.*"); # Case 0 : Start slave with IGNORE_DOMAIN_IDS=(), then restart @@ -24,6 +25,7 @@ DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; include/start_slave.inc +include/sync_with_master_gtid.inc DO_DOMAIN_IDS (AFTER) : IGNORE_DOMAIN_IDS (AFTER) : SET @saved_dbug = @@GLOBAL.debug_dbug; @@ -33,6 +35,7 @@ START TRANSACTION; INSERT INTO t1 VALUES(2); INSERT INTO t1 VALUES(3); COMMIT; +include/save_master_gtid.inc SELECT * FROM t1; i 1 @@ -46,6 +49,7 @@ i SET @@global.debug_dbug=@saved_dbug; START SLAVE io_thread; include/wait_for_slave_io_to_start.inc +include/sync_with_master_gtid.inc SELECT * FROM t1; i 1 @@ -59,6 +63,7 @@ DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; include/start_slave.inc +include/sync_with_master_gtid.inc DO_DOMAIN_IDS (AFTER) : IGNORE_DOMAIN_IDS (AFTER) : 1 SET @@global.debug_dbug="d,kill_slave_io_before_commit"; @@ -67,6 +72,7 @@ START TRANSACTION; INSERT INTO t1 VALUES(4); INSERT INTO t1 VALUES(5); COMMIT; +include/save_master_gtid.inc SELECT * FROM t1; i 1 @@ -84,6 +90,7 @@ i SET @@global.debug_dbug=@saved_dbug; START SLAVE io_thread; include/wait_for_slave_io_to_start.inc +include/sync_with_master_gtid.inc SELECT * FROM t1; i 1 @@ -97,6 +104,7 @@ DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : 1 CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; include/start_slave.inc +include/sync_with_master_gtid.inc DO_DOMAIN_IDS (AFTER) : IGNORE_DOMAIN_IDS (AFTER) : SET @@global.debug_dbug="d,kill_slave_io_before_commit"; @@ -114,6 +122,7 @@ START TRANSACTION; INSERT INTO t1 VALUES(10); INSERT INTO t1 VALUES(11); COMMIT; +include/save_master_gtid.inc SELECT * FROM t1; i 1 @@ -140,6 +149,7 @@ DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; include/start_slave.inc +include/sync_with_master_gtid.inc DO_DOMAIN_IDS (AFTER) : IGNORE_DOMAIN_IDS (AFTER) : 1 SELECT * FROM t1; @@ -157,6 +167,7 @@ DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : 1 CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; include/start_slave.inc +include/sync_with_master_gtid.inc DO_DOMAIN_IDS (AFTER) : IGNORE_DOMAIN_IDS (AFTER) : 1 SET @@global.debug_dbug="d,kill_slave_io_before_commit"; @@ -166,6 +177,7 @@ START TRANSACTION; INSERT INTO t1 VALUES(12); INSERT INTO t1 VALUES(13); COMMIT; +include/save_master_gtid.inc START TRANSACTION; INSERT INTO t1 VALUES(14); INSERT INTO t1 VALUES(15); @@ -204,11 +216,16 @@ i 10 11 SET @@global.debug_dbug=@saved_dbug; +include/sync_with_master_gtid.inc include/stop_slave_sql.inc DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : 1 CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; +connection master; +include/save_master_gtid.inc +connection slave; include/start_slave.inc +include/sync_with_master_gtid.inc DO_DOMAIN_IDS (AFTER) : IGNORE_DOMAIN_IDS (AFTER) : SELECT * FROM t1; @@ -230,6 +247,7 @@ DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; include/start_slave.inc +include/sync_with_master_gtid.inc DO_DOMAIN_IDS (AFTER) : IGNORE_DOMAIN_IDS (AFTER) : 1 SET @@global.debug_dbug="d,kill_slave_io_after_2_events"; @@ -239,6 +257,7 @@ START TRANSACTION; INSERT INTO t1 VALUES(18); INSERT INTO t1 VALUES(19); COMMIT; +include/save_master_gtid.inc START TRANSACTION; INSERT INTO t1 VALUES(20); INSERT INTO t1 VALUES(21); @@ -287,11 +306,16 @@ i 16 17 SET @@global.debug_dbug=@saved_dbug; +include/sync_with_master_gtid.inc include/stop_slave_sql.inc DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : 1 CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; +connection master; +include/save_master_gtid.inc +connection slave; include/start_slave.inc +include/sync_with_master_gtid.inc DO_DOMAIN_IDS (AFTER) : IGNORE_DOMAIN_IDS (AFTER) : SELECT * FROM t1; @@ -317,6 +341,7 @@ DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; include/start_slave.inc +include/sync_with_master_gtid.inc DO_DOMAIN_IDS (AFTER) : IGNORE_DOMAIN_IDS (AFTER) : SET @@global.debug_dbug="d,kill_slave_io_after_2_events"; @@ -335,6 +360,7 @@ START TRANSACTION; INSERT INTO t1 VALUES(28); INSERT INTO t1 VALUES(29); COMMIT; +include/save_master_gtid.inc SELECT * FROM t1; i 1 @@ -389,6 +415,7 @@ DO_DOMAIN_IDS (BEFORE) : IGNORE_DOMAIN_IDS (BEFORE) : CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; include/start_slave.inc +include/sync_with_master_gtid.inc DO_DOMAIN_IDS (AFTER) : IGNORE_DOMAIN_IDS (AFTER) : 1 SELECT * FROM t1; diff --git a/mysql-test/suite/rpl/r/rpl_domain_id_filter_master_crash.result b/mysql-test/suite/rpl/r/rpl_domain_id_filter_master_crash.result index a54ff99b591..cd13590b61f 100644 --- a/mysql-test/suite/rpl/r/rpl_domain_id_filter_master_crash.result +++ b/mysql-test/suite/rpl/r/rpl_domain_id_filter_master_crash.result @@ -1,9 +1,6 @@ include/master-slave.inc [connection master] connection master; -call mtr.add_suppression("mysqld: Table '.*gtid_slave_pos' is marked as crashed and should be repaired"); -call mtr.add_suppression("Checking table: './mysql/gtid_slave_pos'"); -call mtr.add_suppression("mysql.gtid_slave_pos: 1 client is using or hasn't closed the table properly"); SET @@session.gtid_domain_id= 0; create table ti (a int auto_increment primary key) engine=innodb; create table tm (a int auto_increment primary key) engine=myisam; diff --git a/mysql-test/suite/rpl/r/rpl_domain_id_filter_restart.result b/mysql-test/suite/rpl/r/rpl_domain_id_filter_restart.result index f6eff3f9efc..948b4f48737 100644 --- a/mysql-test/suite/rpl/r/rpl_domain_id_filter_restart.result +++ b/mysql-test/suite/rpl/r/rpl_domain_id_filter_restart.result @@ -21,8 +21,9 @@ INSERT INTO t2 VALUES(1); SELECT * FROM t2; i 1 +include/save_master_gtid.inc connection slave; -connection slave; +include/sync_with_master_gtid.inc SELECT * FROM t1; i 1 diff --git a/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result b/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result index be98b7e3dcd..145b269aac9 100644 --- a/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result @@ -657,7 +657,7 @@ START SLAVE; STOP SLAVE; include/reset_slave.inc Warnings: -Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-103. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos +Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-104. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos CREATE TABLE t15 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) ) ENGINE='InnoDB'; @@ -697,7 +697,7 @@ Last_SQL_Error = 'Error 'Unknown column 'c7' in 't15'' on query. Default databas STOP SLAVE; include/reset_slave.inc Warnings: -Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-104. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos +Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-105. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos *** Drop t15 *** DROP TABLE t15; @@ -716,7 +716,7 @@ START SLAVE; STOP SLAVE; include/reset_slave.inc Warnings: -Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-105. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos +Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-106. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos CREATE TABLE t16 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) ) ENGINE='InnoDB'; @@ -756,7 +756,7 @@ Last_SQL_Error = 'Error 'Key column 'c6' doesn't exist in table' on query. Defau STOP SLAVE; include/reset_slave.inc Warnings: -Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-106. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos +Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-107. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos *** Drop t16 *** DROP TABLE t16; @@ -775,7 +775,7 @@ START SLAVE; STOP SLAVE; include/reset_slave.inc Warnings: -Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-107. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos +Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-108. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos CREATE TABLE t17 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) ) ENGINE='InnoDB'; diff --git a/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result b/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result index 53b20b188ba..dae497d5f29 100644 --- a/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result +++ b/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result @@ -657,7 +657,7 @@ START SLAVE; STOP SLAVE; include/reset_slave.inc Warnings: -Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-103. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos +Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-104. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos CREATE TABLE t15 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) ) ENGINE='MyISAM'; @@ -697,7 +697,7 @@ Last_SQL_Error = 'Error 'Unknown column 'c7' in 't15'' on query. Default databas STOP SLAVE; include/reset_slave.inc Warnings: -Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-104. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos +Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-105. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos *** Drop t15 *** DROP TABLE t15; @@ -716,7 +716,7 @@ START SLAVE; STOP SLAVE; include/reset_slave.inc Warnings: -Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-105. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos +Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-106. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos CREATE TABLE t16 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) ) ENGINE='MyISAM'; @@ -756,7 +756,7 @@ Last_SQL_Error = 'Error 'Key column 'c6' doesn't exist in table' on query. Defau STOP SLAVE; include/reset_slave.inc Warnings: -Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-106. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos +Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-107. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos *** Drop t16 *** DROP TABLE t16; @@ -775,7 +775,7 @@ START SLAVE; STOP SLAVE; include/reset_slave.inc Warnings: -Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-107. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos +Warning 1948 Specified value for @@gtid_slave_pos contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-108. If MASTER_GTID_POS=CURRENT_POS is used, the binlog position will override the new value of @@gtid_slave_pos CREATE TABLE t17 (c1 INT PRIMARY KEY, c4 BLOB, c5 CHAR(5) ) ENGINE='MyISAM'; diff --git a/mysql-test/suite/rpl/r/rpl_get_lock.result b/mysql-test/suite/rpl/r/rpl_get_lock.result index b852546e1bf..cbb02a32648 100644 --- a/mysql-test/suite/rpl/r/rpl_get_lock.result +++ b/mysql-test/suite/rpl/r/rpl_get_lock.result @@ -1,6 +1,6 @@ include/master-slave.inc [connection master] -CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +SET GLOBAL LOG_WARNINGS=4; create table t1(n int); insert into t1 values(get_lock("lock",2)); disconnect master; @@ -35,4 +35,5 @@ NULL connection master1; drop table t1; connection slave; +connection default; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_gtid_basic.result b/mysql-test/suite/rpl/r/rpl_gtid_basic.result index b2997cdfa3a..afc700a72c5 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_basic.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_basic.result @@ -69,8 +69,6 @@ INSERT INTO t2 VALUES (5, "i1a"); connection server_4; CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT, MASTER_USE_GTID=CURRENT_POS; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead include/start_slave.inc SELECT * FROM t1 ORDER BY a; a b @@ -91,8 +89,6 @@ connection server_2; include/stop_slave.inc CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_4, MASTER_USE_GTID=CURRENT_POS; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead include/start_slave.inc connection server_4; UPDATE t2 SET b="j1a" WHERE a=5; @@ -121,8 +117,6 @@ include/save_master_gtid.inc connection server_3; CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_4, MASTER_USE_GTID=CURRENT_POS; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead include/start_slave.inc include/sync_with_master_gtid.inc SELECT * FROM t2 ORDER BY a; diff --git a/mysql-test/suite/rpl/r/rpl_gtid_crash.result b/mysql-test/suite/rpl/r/rpl_gtid_crash.result index 179461adb8a..c47beacfb36 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_crash.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_crash.result @@ -4,6 +4,7 @@ connection server_1; call mtr.add_suppression("Checking table:"); call mtr.add_suppression("client is using or hasn't closed the table properly"); call mtr.add_suppression("Table .* is marked as crashed and should be repaired"); +call mtr.add_suppression("Could not read packet:.* errno: 11"); flush tables; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; diff --git a/mysql-test/suite/rpl/r/rpl_gtid_errorhandling.result b/mysql-test/suite/rpl/r/rpl_gtid_errorhandling.result index f832f3c5682..4c35d42d90a 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_errorhandling.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_errorhandling.result @@ -75,8 +75,6 @@ INSERT INTO t1 VALUES (2); SET sql_log_bin = 1; INSERT INTO t1 VALUES (3); CHANGE MASTER TO master_use_gtid=current_pos; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead BEGIN; SET GLOBAL gtid_slave_pos = "100-100-100"; ERROR 25000: You are not allowed to execute this command in a transaction diff --git a/mysql-test/suite/rpl/r/rpl_gtid_grouping.result b/mysql-test/suite/rpl/r/rpl_gtid_grouping.result index ad7d6116c49..1b4d86dd8e2 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_grouping.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_grouping.result @@ -50,5 +50,4 @@ CHANGE MASTER TO MASTER_USE_GTID=no; include/start_slave.inc connection master; DROP TABLE t; -SET GLOBAL LOG_WARNINGS=default; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_gtid_header_valid.result b/mysql-test/suite/rpl/r/rpl_gtid_header_valid.result new file mode 100644 index 00000000000..6731abc27b7 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_gtid_header_valid.result @@ -0,0 +1,146 @@ +include/master-slave.inc +[connection master] +# +# Initialize test data +connection master; +create table t1 (a int) engine=innodb; +include/save_master_gtid.inc +set @@SESSION.debug_dbug= "+d,binlog_force_commit_id"; +connection slave; +set SQL_LOG_BIN= 0; +call mtr.add_suppression('Found invalid event in binary log'); +call mtr.add_suppression('Slave SQL.*Relay log read failure: Could not parse relay log event entry.* 1594'); +set SQL_LOG_BIN= 1; +include/sync_with_master_gtid.inc +include/stop_slave.inc +include/start_slave.inc +# +# Test FL_PREPARED_XA +connection master; +set @@SESSION.debug_dbug= "+d,negate_xid_from_gtid"; +set @commit_id= 100; +XA START 'x1'; +insert into t1 values (1); +XA END 'x1'; +XA PREPARE 'x1'; +set @@SESSION.debug_dbug= "-d,negate_xid_from_gtid"; +XA COMMIT 'x1'; +include/save_master_gtid.inc +# Waiting for slave to find invalid event.. +connection slave; +include/wait_for_slave_sql_error.inc [errno=1594] +STOP SLAVE IO_THREAD; +# Reset master binlogs (as there is an invalid event) and slave state +connection master; +RESET MASTER; +connection slave; +RESET MASTER; +RESET SLAVE; +set @@global.gtid_slave_pos=""; +include/start_slave.inc +# +# Test FL_COMPLETED_XA +connection master; +set @commit_id= 101; +XA START 'x1'; +insert into t1 values (2); +XA END 'x1'; +XA PREPARE 'x1'; +set @@SESSION.debug_dbug= "+d,negate_xid_from_gtid"; +XA COMMIT 'x1'; +set @@SESSION.debug_dbug= "-d,negate_xid_from_gtid"; +include/save_master_gtid.inc +# Waiting for slave to find invalid event.. +connection slave; +include/wait_for_slave_sql_error.inc [errno=1594] +STOP SLAVE IO_THREAD; +# Cleanup hanging XA PREPARE on slave +set statement SQL_LOG_BIN=0 for XA COMMIT 'x1'; +# Reset master binlogs (as there is an invalid event) and slave state +connection master; +RESET MASTER; +connection slave; +RESET MASTER; +RESET SLAVE; +set @@global.gtid_slave_pos=""; +include/start_slave.inc +# +# Test Missing xid.data (but has format id and length description parts) +connection master; +set @commit_id= 101; +XA START 'x1'; +insert into t1 values (1); +XA END 'x1'; +XA PREPARE 'x1'; +set @@SESSION.debug_dbug= "+d,negate_xid_data_from_gtid"; +XA COMMIT 'x1'; +set @@SESSION.debug_dbug= "-d,negate_xid_data_from_gtid"; +include/save_master_gtid.inc +# Waiting for slave to find invalid event.. +connection slave; +include/wait_for_slave_sql_error.inc [errno=1594] +STOP SLAVE IO_THREAD; +# Cleanup hanging XA PREPARE on slave +set statement SQL_LOG_BIN=0 for XA COMMIT 'x1'; +# Reset master binlogs (as there is an invalid event) and slave state +connection master; +RESET MASTER; +connection slave; +RESET MASTER; +RESET SLAVE; +set @@global.gtid_slave_pos=""; +include/start_slave.inc +# +# Test FL_EXTRA_MULTI_ENGINE +connection master; +set @old_dbug= @@SESSION.debug_dbug; +set @@SESSION.debug_dbug= "+d,inject_fl_extra_multi_engine_into_gtid"; +set @commit_id= 102; +insert into t1 values (3); +include/save_master_gtid.inc +set @@SESSION.debug_dbug=@old_dbug; +connection slave; +# Waiting for slave to find invalid event.. +include/wait_for_slave_sql_error.inc [errno=1594] +STOP SLAVE IO_THREAD; +# Reset master binlogs (as there is an invalid event) and slave state +connection master; +RESET MASTER; +connection slave; +RESET SLAVE; +RESET MASTER; +set @@global.gtid_slave_pos=""; +include/start_slave.inc +# +# Test FL_COMMIT_ALTER +connection master; +set @old_dbug= @@SESSION.debug_dbug; +set @@SESSION.debug_dbug= "+d,negate_alter_fl_from_gtid"; +set @old_alter_tp= @@SESSION.binlog_alter_two_phase; +set @@SESSION.binlog_alter_two_phase= 1; +alter table t1 add column (nc int); +include/save_master_gtid.inc +set @@SESSION.debug_dbug=@old_dbug; +set @@SESSION.binlog_alter_two_phase=@old_alter_tp; +connection slave; +# Waiting for slave to find invalid event.. +include/wait_for_slave_sql_error.inc [errno=1594] +STOP SLAVE IO_THREAD; +# Reset master binlogs (as there is an invalid event) and slave state +connection master; +RESET MASTER; +connection slave; +SET STATEMENT sql_log_bin=0 FOR alter table t1 add column (nc int); +RESET SLAVE; +RESET MASTER; +set @@global.gtid_slave_pos=""; +include/start_slave.inc +# +# Cleanup +connection master; +drop table t1; +include/save_master_gtid.inc +connection slave; +include/sync_with_master_gtid.inc +include/rpl_end.inc +# End of rpl_gtid_header_valid.test diff --git a/mysql-test/suite/rpl/r/rpl_gtid_mdev4820.result b/mysql-test/suite/rpl/r/rpl_gtid_mdev4820.result index 01920c8ad89..5fba9966a43 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_mdev4820.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_mdev4820.result @@ -45,8 +45,6 @@ SET GLOBAL gtid_slave_pos= '0-2-10'; connection server_1; CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_2, master_user= 'root', master_ssl_verify_server_cert=0, master_use_gtid=CURRENT_POS; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead START SLAVE; connection server_2; INSERT INTO t1 VALUES (11); @@ -76,8 +74,6 @@ connection server_2; INSERT INTO t1 VALUES (22); CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_1, master_user= 'root', master_use_gtid=CURRENT_POS; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead START SLAVE; SET sql_log_bin= 0; CALL mtr.add_suppression("which is not in the master's binlog. Since the master's binlog contains GTIDs with higher sequence numbers, it probably means that the slave has diverged"); diff --git a/mysql-test/suite/rpl/r/rpl_gtid_stop_start.result b/mysql-test/suite/rpl/r/rpl_gtid_stop_start.result index ae0050c353a..e8633cd45bb 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_stop_start.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_stop_start.result @@ -111,6 +111,10 @@ a 6 7 *** MDEV-4486: Allow to start old-style replication even if mysql.gtid_slave_pos is unavailable +connection server_1; +INSERT INTO t1 VALUES (8); +DELETE FROM t1 WHERE a=8; +connection server_2; connection server_2; include/stop_slave.inc CHANGE MASTER TO master_use_gtid= no; diff --git a/mysql-test/suite/rpl/r/rpl_heartbeat.result b/mysql-test/suite/rpl/r/rpl_heartbeat.result index 887df2ee03b..42cf90bc738 100644 --- a/mysql-test/suite/rpl/r/rpl_heartbeat.result +++ b/mysql-test/suite/rpl/r/rpl_heartbeat.result @@ -1,8 +1,9 @@ -connect master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK; -connect slave,localhost,root,,test,$SLAVE_MYPORT,$SLAVE_MYSOCK; +include/master-slave.inc +[connection master] connection master; reset master; connection slave; +include/stop_slave.inc set @restore_slave_net_timeout= @@global.slave_net_timeout; set @@global.slave_net_timeout= 10; change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; @@ -68,5 +69,5 @@ connection master; drop table t1; connection slave; set @@global.slave_net_timeout= @restore_slave_net_timeout; -include/stop_slave.inc +include/rpl_end.inc End of tests diff --git a/mysql-test/suite/rpl/r/rpl_heartbeat_debug.result b/mysql-test/suite/rpl/r/rpl_heartbeat_debug.result index dc45c0b9ab3..a89010cd432 100644 --- a/mysql-test/suite/rpl/r/rpl_heartbeat_debug.result +++ b/mysql-test/suite/rpl/r/rpl_heartbeat_debug.result @@ -9,8 +9,6 @@ Variable_name Slave_heartbeat_period Value 60.000 SET @saved_dbug= @@GLOBAL.debug_dbug; SET GLOBAL debug_dbug="+d,simulate_slave_heartbeat_network_error"; -CALL mtr.add_suppression('SET @master_heartbeat_period to master failed with error'); -CALL mtr.add_suppression('Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again'); include/start_slave.inc connection master; drop table if exists t1; diff --git a/mysql-test/suite/rpl/r/rpl_mark_optimize_tbl_ddl.result b/mysql-test/suite/rpl/r/rpl_mark_optimize_tbl_ddl.result index 9aa31a73e49..09edd28827b 100644 --- a/mysql-test/suite/rpl/r/rpl_mark_optimize_tbl_ddl.result +++ b/mysql-test/suite/rpl/r/rpl_mark_optimize_tbl_ddl.result @@ -55,7 +55,6 @@ PARTITION pmax VALUES LESS THAN (MAXVALUE)); INSERT INTO t1 VALUES (1), (10), (100), (1000); ALTER TABLE t1 ANALYZE PARTITION p0; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK ALTER TABLE t1 OPTIMIZE PARTITION p0; Table Op Msg_type Msg_text diff --git a/mysql-test/suite/rpl/r/rpl_mdev33798.result b/mysql-test/suite/rpl/r/rpl_mdev33798.result new file mode 100644 index 00000000000..12431ed26e6 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_mdev33798.result @@ -0,0 +1,143 @@ +include/rpl_init.inc [topology=1->2,1->3] +connect server_2b,127.0.0.1,root,,,$SERVER_MYPORT_2; +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode= @@GLOBAL.slave_parallel_mode; +SET @old_timeout= @@GLOBAL.lock_wait_timeout; +SET @old_innodb_timeout= @@GLOBAL.innodb_lock_wait_timeout; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=5; +set global slave_parallel_mode= aggressive; +SET GLOBAL lock_wait_timeout= 86400; +SET GLOBAL innodb_lock_wait_timeout= 86400; +SET STATEMENT sql_log_bin=0 FOR ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +include/start_slave.inc +connection server_1; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0), (8, 0); +connection server_2; +include/stop_slave.inc +connection server_2b; +BEGIN; +SELECT * FROM t1 WHERE a=1 FOR UPDATE; +a b +1 0 +SELECT * FROM t1 WHERE a=5 FOR UPDATE; +a b +5 0 +connection server_1; +SET SESSION gtid_domain_id= 1; +BEGIN; +UPDATE t1 SET b=1 WHERE a=1; +UPDATE t1 SET b=1 WHERE a=7; +COMMIT; +UPDATE t1 SET b=2 WHERE a=3; +SET SESSION gtid_domain_id=2; +BEGIN; +UPDATE t1 SET b=3 WHERE a=5; +UPDATE t1 SET b=3 WHERE a=3; +COMMIT; +UPDATE t1 SET b=4 WHERE a=7; +SET SESSION gtid_domain_id= 0; +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +connection server_2b; +ROLLBACK; +connection server_2; +include/sync_with_master_gtid.inc +SELECT a, ( +(a=1 AND b=1) OR +(a=3 AND (b=2 OR b=3)) OR +(a=5 AND b=3) OR +(a=7 AND (b=1 OR b=4)) OR +((a MOD 2)=0 AND b=0)) AS `ok` + FROM t1 +ORDER BY a; +a ok +1 1 +2 1 +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +connection server_3; +include/sync_with_master_gtid.inc +include/stop_slave.inc +connection server_2; +include/stop_slave.inc +CHANGE MASTER 'm2' to master_port=MYPORT_3 , master_host='127.0.0.1', master_user='root', master_use_gtid=slave_pos, master_ssl_verify_server_cert=0; +connection server_1; +SET SESSION gtid_domain_id= 1; +BEGIN; +UPDATE t1 SET b=11 WHERE a=1; +UPDATE t1 SET b=11 WHERE a=7; +COMMIT; +UPDATE t1 SET b=12 WHERE a=3; +SET SESSION gtid_domain_id= 1; +connection server_3; +SET SESSION gtid_domain_id=3; +BEGIN; +UPDATE t1 SET b=13 WHERE a=5; +UPDATE t1 SET b=13 WHERE a=3; +COMMIT; +UPDATE t1 SET b=14 WHERE a=7; +include/save_master_gtid.inc +connection server_2b; +BEGIN; +SELECT * FROM t1 WHERE a=1 FOR UPDATE; +a b +1 1 +SELECT * FROM t1 WHERE a=5 FOR UPDATE; +a b +5 3 +START ALL SLAVES; +Warnings: +Note 1937 SLAVE 'm2' started +Note 1937 SLAVE '' started +connection server_2b; +ROLLBACK; +connection server_1; +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +connection server_3; +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +SELECT a, ( +(a=1 AND b=11) OR +(a=3 AND (b=12 OR b=13)) OR +(a=5 AND b=13) OR +(a=7 AND (b=11 OR b=14)) OR +((a MOD 2)=0 AND b=0)) AS `ok` + FROM t1 +ORDER BY a; +a ok +1 1 +2 1 +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +SET default_master_connection = 'm2'; +include/stop_slave.inc +RESET SLAVE 'm2' ALL; +SET default_master_connection = ''; +connection server_3; +include/start_slave.inc +disconnect server_2b; +connection server_1; +DROP TABLE t1; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +set global slave_parallel_mode= @old_parallel_mode; +SET GLOBAL lock_wait_timeout= @old_timeout; +SET GLOBAL innodb_lock_wait_timeout= @old_innodb_timeout; +include/start_slave.inc +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_mysql_manager_race_condition.result b/mysql-test/suite/rpl/r/rpl_mysql_manager_race_condition.result index 1172d8e39a9..740d1ddfcfa 100644 --- a/mysql-test/suite/rpl/r/rpl_mysql_manager_race_condition.result +++ b/mysql-test/suite/rpl/r/rpl_mysql_manager_race_condition.result @@ -17,6 +17,36 @@ include/sync_with_master_gtid.inc include/rpl_restart_server.inc [server_number=2 parameters: --debug_dbug="+d,delay_start_handle_manager"] include/start_slave.inc # +# MDEV-33799 +# Ensure that when the binary log is used for recovery (as tc log), that +# the recovery process cannot start the binlog background thread before +# the mysql handle manager has started. +connection slave; +# Add test suppresssions so crash recovery messages don't fail the test +set session sql_log_bin=0; +call mtr.add_suppression("mariadbd: Got error '145.*"); +call mtr.add_suppression("Checking table:.*"); +call mtr.add_suppression("mysql.gtid_slave_pos:.*hasn't closed the table properly"); +call mtr.add_suppression("Can't init tc log"); +call mtr.add_suppression("Aborting"); +set session sql_log_bin=1; +# Create slave-side only table +create table t2 (a int) engine=innodb; +# Crash mariadbd when binlogging transaction to corrupt database state +connection slave1; +set @@session.debug_dbug="+d,crash_before_writing_xid"; +insert into t2 values (1); +connection slave; +connection slave1; +Got one of the listed errors +# Restart mariadbd in recovery mode. Note --tc-heuristic-recover +# forces mysqld to exit with error, so we run mariadbd via CLI +# MYSQLD_LAST_CMD --debug_dbug="+d,delay_start_handle_manager" --tc-heuristic-recover=COMMIT +connection server_2; +connection slave1; +connection slave; +include/start_slave.inc +# # Cleanup # connection master; @@ -24,4 +54,5 @@ drop table t1; include/save_master_gtid.inc connection slave; include/sync_with_master_gtid.inc +drop table t2; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_packet.result b/mysql-test/suite/rpl/r/rpl_packet.result index 4a2a5d70d39..bb6269607fe 100644 --- a/mysql-test/suite/rpl/r/rpl_packet.result +++ b/mysql-test/suite/rpl/r/rpl_packet.result @@ -2,6 +2,8 @@ include/master-slave.inc [connection master] call mtr.add_suppression("Slave I/O: Got a packet bigger than 'slave_max_allowed_packet' bytes, .*error.* 1153"); call mtr.add_suppression("Log entry on master is longer than slave_max_allowed_packet"); +call mtr.add_suppression("Could not write packet:"); +call mtr.add_suppression("Got a packet bigger than 'max_allowed_packet' bytes"); drop database if exists DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________; create database DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________; connection master; diff --git a/mysql-test/suite/rpl/r/rpl_parallel_multi_domain_xa.result b/mysql-test/suite/rpl/r/rpl_parallel_multi_domain_xa.result new file mode 100644 index 00000000000..1993d09895a --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_multi_domain_xa.result @@ -0,0 +1,58 @@ +include/master-slave.inc +[connection master] +call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction"); +call mtr.add_suppression("WSREP: handlerton rollback failed"); +connection master; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +connection slave; +include/stop_slave.inc +SET @old_transaction_retries = @@GLOBAL.slave_transaction_retries; +SET @@global.slave_transaction_retries = 1000; +SET @old_parallel_threads = @@GLOBAL.slave_parallel_threads; +SET @old_slave_domain_parallel_threads = @@GLOBAL.slave_domain_parallel_threads; +SET @@global.slave_parallel_threads = 5; +SET @@global.slave_domain_parallel_threads = 3; +SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode; +CHANGE MASTER TO master_use_gtid=slave_pos; +connection master; +CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, 0); +include/save_master_gtid.inc +connection slave; +include/start_slave.inc +include/sync_with_master_gtid.inc +include/stop_slave.inc +SET @@global.slave_parallel_mode ='optimistic'; +connection master; +include/save_master_gtid.inc +connection slave; +include/start_slave.inc +include/sync_with_master_gtid.inc +include/stop_slave.inc +connection master; +include/save_master_gtid.inc +connection slave; +SET @@global.slave_parallel_mode ='conservative'; +include/start_slave.inc +include/sync_with_master_gtid.inc +include/stop_slave.inc +include/save_master_gtid.inc +connection slave; +SET @@global.slave_parallel_mode = 'optimistic'; +include/start_slave.inc +include/sync_with_master_gtid.inc +include/diff_tables.inc [master:t1, slave:t1] +connection slave; +include/stop_slave.inc +SET @@global.slave_parallel_mode = @old_parallel_mode; +SET @@global.slave_parallel_threads = @old_parallel_threads; +SET @@global.slave_domain_parallel_threads = @old_slave_domain_parallel_threads; +SET @@global.slave_transaction_retries = @old_transaction_retries; +include/start_slave.inc +connection master; +DROP TABLE t1; +include/save_master_gtid.inc +connection slave; +include/sync_with_master_gtid.inc +connection master; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result b/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result index e8d377d5d2d..45f708fbd11 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result @@ -626,6 +626,7 @@ include/save_master_gtid.inc connection server_2; include/sync_with_master_gtid.inc connection server_2; +SET @org_log_warnings=@@GLOBAL.LOG_WARNINGS; set global log_warnings=2; BEGIN; INSERT INTO t1 SET a=1; @@ -651,7 +652,7 @@ connection server_2; include/sync_with_master_gtid.inc connection server_2; include/stop_slave.inc -set global log_warnings=default; +set global log_warnings=@org_log_warnings; SET GLOBAL slave_parallel_mode=@old_parallel_mode; SET GLOBAL slave_parallel_threads=@old_parallel_threads; include/start_slave.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_optimistic_xa.result b/mysql-test/suite/rpl/r/rpl_parallel_optimistic_xa.result index 4136f1885db..90c3e5db614 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_optimistic_xa.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_optimistic_xa.result @@ -32,7 +32,6 @@ include/diff_tables.inc [master:t0, slave:t0] include/diff_tables.inc [master:t1, slave:t1] connection slave; include/stop_slave.inc -set global log_warnings=default; SET GLOBAL slave_parallel_mode=@old_parallel_mode; SET GLOBAL slave_parallel_threads=@old_parallel_threads; include/start_slave.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_optimistic_xa_lsu_off.result b/mysql-test/suite/rpl/r/rpl_parallel_optimistic_xa_lsu_off.result index 4136f1885db..90c3e5db614 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_optimistic_xa_lsu_off.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_optimistic_xa_lsu_off.result @@ -32,7 +32,6 @@ include/diff_tables.inc [master:t0, slave:t0] include/diff_tables.inc [master:t1, slave:t1] connection slave; include/stop_slave.inc -set global log_warnings=default; SET GLOBAL slave_parallel_mode=@old_parallel_mode; SET GLOBAL slave_parallel_threads=@old_parallel_threads; include/start_slave.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_retry.result b/mysql-test/suite/rpl/r/rpl_parallel_retry.result index 2cc4044a2cd..4c7effd737a 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_retry.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_retry.result @@ -339,6 +339,28 @@ connection server_1; DROP TABLE t1, t2, t3, t4; DROP function foo; connection server_2; +connection server_2; +include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=4; +connection server_1; +CREATE TABLE t1 (a INT, b VARCHAR(123)) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, 'asdf'); +UPDATE t1 SET b='zxf1' WHERE a=1; +UPDATE t1 SET b='\n' WHERE a=1; +connection server_2; +SET @old_dbug=@@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,write_row_inject_sleep_before_ha_write_row"; +include/start_slave.inc +connection server_1; +connection server_2; +connection server_1; +DROP TABLE t1; +connection server_2; +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc connection server_1; CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; INSERT INTO t1 VALUES(100, 100); diff --git a/mysql-test/suite/rpl/r/rpl_parallel_sbm.result b/mysql-test/suite/rpl/r/rpl_parallel_sbm.result index 7990a663f04..75012c93f3b 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_sbm.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_sbm.result @@ -27,12 +27,19 @@ connection slave; # delaying a transaction; then when the reciprocal START SLAVE occurs, # if the event is still to be delayed, SBM should resume accordingly include/stop_slave.inc +# Lock t1 on slave to ensure the event can't finish (and thereby update +# Seconds_Behind_Master) so slow running servers don't accidentally +# catch up to the master before checking SBM. +connection server_2; +LOCK TABLES t1 WRITE; include/start_slave.inc connection slave; -# Waiting for replica to resume the delay for the transaction +# Waiting for replica to get blocked by the table lock # Sleeping 1s to increment SBM # Ensuring Seconds_Behind_Master increases after sleeping.. # ..done +connection server_2; +UNLOCK TABLES; include/sync_with_master_gtid.inc # # Pt 2) If the worker threads have not entered an idle state, ensure diff --git a/mysql-test/suite/rpl/r/rpl_parallel_seq.result b/mysql-test/suite/rpl/r/rpl_parallel_seq.result index 8f55f52e54c..02287d54e33 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_seq.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_seq.result @@ -127,4 +127,14 @@ CREATE SEQUENCE s4; DROP SEQUENCE s2,s3,s4; DROP TABLE ti; connection slave; +connection master; +CREATE SEQUENCE s; +SELECT NEXTVAL(s); +NEXTVAL(s) +1 +flush binary logs; +DROP SEQUENCE s; +DROP SEQUENCE s; +connection slave; +connection master; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_slave_bgc_kill.result b/mysql-test/suite/rpl/r/rpl_parallel_slave_bgc_kill.result index ba131ea094f..6b75dbf6181 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_slave_bgc_kill.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_slave_bgc_kill.result @@ -206,10 +206,12 @@ RETURN x; END || SET sql_log_bin=1; +include/stop_slave_io.inc connection server_1; INSERT INTO t3 VALUES (49,0); connection server_2; -START SLAVE SQL_THREAD; +CHANGE MASTER TO master_use_gtid=no; +include/start_slave.inc SELECT * FROM t3 WHERE a >= 40 ORDER BY a; a b 41 41 @@ -239,10 +241,6 @@ SET GLOBAL slave_parallel_threads=0; SET GLOBAL slave_parallel_threads=10; include/start_slave.inc *** 3. Same as (2), but not using gtid mode *** -connection server_2; -include/stop_slave.inc -CHANGE MASTER TO master_use_gtid=no; -include/start_slave.inc connection server_1; connection con_temp3; SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; diff --git a/mysql-test/suite/rpl/r/rpl_parallel_stop_slave.result b/mysql-test/suite/rpl/r/rpl_parallel_stop_slave.result index 0c810d2a3f4..b0a4fa59c69 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_stop_slave.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_stop_slave.result @@ -37,7 +37,9 @@ connection con_temp1; BEGIN; INSERT INTO t2 VALUES (21); connection server_2; -START SLAVE; +START SLAVE IO_THREAD; +include/wait_for_slave_param.inc [Read_Master_Log_Pos] +START SLAVE SQL_THREAD; connection con_temp2; SET @old_dbug= @@GLOBAL.debug_dbug; SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; diff --git a/mysql-test/suite/rpl/r/rpl_parallel_temptable.result b/mysql-test/suite/rpl/r/rpl_parallel_temptable.result index e9bff03bd41..0f7af25303e 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_temptable.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_temptable.result @@ -202,6 +202,24 @@ a b include/stop_slave.inc SET GLOBAL slave_parallel_mode=@old_mode; include/start_slave.inc +*** MDEV33426: Memory allocation accounting incorrect for replicated temptable +connection server_1; +CREATE TEMPORARY TABLE t5 (a int) ENGINE=Aria; +CREATE TEMPORARY TABLE t6 (a int) ENGINE=Heap; +INSERT INTO t5 VALUES (1); +INSERT INTO t6 VALUES (2); +connection server_2; +include/stop_slave.inc +connection server_1; +INSERT INTO t1 SELECT a+40, 5 FROM t5; +INSERT INTO t1 SELECT a+40, 6 FROM t6; +DROP TABLE t5, t6; +connection server_2; +include/start_slave.inc +SELECT * FROM t1 WHERE a>=40 ORDER BY a; +a b +41 5 +42 6 connection server_2; include/stop_slave.inc SET GLOBAL slave_parallel_threads=@old_parallel_threads; diff --git a/mysql-test/suite/rpl/r/rpl_perfschema_connect_config.result b/mysql-test/suite/rpl/r/rpl_perfschema_connect_config.result index 027c3b14273..695ba3a9fe9 100644 --- a/mysql-test/suite/rpl/r/rpl_perfschema_connect_config.result +++ b/mysql-test/suite/rpl/r/rpl_perfschema_connect_config.result @@ -87,8 +87,6 @@ include/assert.inc [Value returned by SSS and PS table for Using_Gtid should be change master to master_user = 'root', master_use_gtid= CURRENT_POS; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead include/assert.inc [Value returned by SSS and PS table for Using_Gtid should be same.] # 3) Test for Auto_position= SLAVE_POS diff --git a/mysql-test/suite/rpl/r/rpl_rewrite_db_sys_vars.result b/mysql-test/suite/rpl/r/rpl_rewrite_db_sys_vars.result index f755ce7901e..e0e6681cd10 100644 --- a/mysql-test/suite/rpl/r/rpl_rewrite_db_sys_vars.result +++ b/mysql-test/suite/rpl/r/rpl_rewrite_db_sys_vars.result @@ -12,11 +12,9 @@ select @@session.server_id; create database replica_db1; create database y; create database test_replica; -SELECT @@GLOBAL.replicate_rewrite_db; -@@GLOBAL.replicate_rewrite_db -primary_db1->replica_db1,x->y -# Ensuring SHOW SLAVE STATUS produces correct value for Replicate_Rewrite_DB... -# ...success +SELECT @@GLOBAL.replicate_rewrite_db, 'primary_db1->replica_db1,x->y' as 'Replicate_Rewrite_DB from SHOW SLAVE STATUS'; +@@GLOBAL.replicate_rewrite_db Replicate_Rewrite_DB from SHOW SLAVE STATUS +primary_db1->replica_db1,x->y primary_db1->replica_db1,x->y # Create DBs and tables on primary connection master; create database primary_db1; @@ -60,15 +58,13 @@ SELECT @@GLOBAL.replicate_rewrite_db; @@GLOBAL.replicate_rewrite_db primary_db1->replica_db1,x->y SET @@GLOBAL.replicate_rewrite_db="test_master->test_replica"; -SELECT @@GLOBAL.replicate_rewrite_db; -@@GLOBAL.replicate_rewrite_db -test_master->test_replica SHOW DATABASES like 'test_replica'; Database (test_replica) test_replica include/start_slave.inc -# Ensuring SHOW SLAVE STATUS produces correct value for Replicate_Rewrite_DB... -# ...success +SELECT @@GLOBAL.replicate_rewrite_db, 'test_master->test_replica' as 'Replicate_Rewrite_DB from SHOW SLAVE STATUS'; +@@GLOBAL.replicate_rewrite_db Replicate_Rewrite_DB from SHOW SLAVE STATUS +test_master->test_replica test_master->test_replica # Create DB and tables on primary connection master; create database test_master; @@ -94,6 +90,8 @@ t 3 include/diff_tables.inc [master:test_master.my_table,slave:test_replica.my_table] # Update of values on primary for DB not set in replication_rewrite_db +include/stop_slave.inc +include/reset_slave.inc connection master; use x; insert into my_table values (314); @@ -104,8 +102,6 @@ t 314 include/save_master_gtid.inc connection slave; -include/stop_slave.inc -include/reset_slave.inc include/start_slave.inc SELECT @@GLOBAL.replicate_rewrite_db; @@GLOBAL.replicate_rewrite_db diff --git a/mysql-test/suite/rpl/r/rpl_row_find_row_debug.result b/mysql-test/suite/rpl/r/rpl_row_find_row_debug.result index f1a0059a04f..c2bb256a750 100644 --- a/mysql-test/suite/rpl/r/rpl_row_find_row_debug.result +++ b/mysql-test/suite/rpl/r/rpl_row_find_row_debug.result @@ -20,6 +20,5 @@ FOUND 1 /The slave is applying a ROW event on behalf of an UPDATE statement on t FOUND 1 /The slave is applying a ROW event on behalf of a DELETE statement on table t1 and is currently taking a considerable amount/ in mysqld.2.err include/stop_slave.inc SET @@GLOBAL.debug_dbug = @saved_dbug; -SET GLOBAL log_warnings = 2; include/start_slave.inc include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_cond_var_per_thd.result b/mysql-test/suite/rpl/r/rpl_semi_sync_cond_var_per_thd.result new file mode 100644 index 00000000000..dbea479bc12 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_cond_var_per_thd.result @@ -0,0 +1,51 @@ +include/master-slave.inc +[connection master] +connection master; +call mtr.add_suppression("Got an error reading communication packets"); +call mtr.add_suppression("Could not read packet:.* vio_errno: 1158"); +call mtr.add_suppression("Could not write packet:.* vio_errno: 1160"); +set @save_semi_sync_master_enabled= @@global.rpl_semi_sync_master_enabled; +set @save_semi_sync_wp= @@global.rpl_semi_sync_master_wait_point; +set @save_bgc_count= @@global.binlog_commit_wait_count; +set @save_bgc_usec= @@global.binlog_commit_wait_usec; +set @save_debug_dbug= @@global.debug_dbug; +set @@global.binlog_commit_wait_count=3; +set @@global.binlog_commit_wait_usec=10000000; +set @@global.debug_dbug="+d,testing_cond_var_per_thd"; +set @@global.rpl_semi_sync_master_enabled= 1; +set @@global.rpl_semi_sync_master_wait_point= AFTER_COMMIT; +# Ensure semi-sync is on +connection slave; +set @save_semi_sync_slave_enabled= @@global.rpl_semi_sync_master_enabled; +include/stop_slave.inc +set @@global.rpl_semi_sync_slave_enabled=1; +include/start_slave.inc +connection master; +# Create three transactions to binlog group commit together +connection master; +create table t1 (a int); +connection server_1; +create table t2 (a int); +connection default; +create table t3 (a int); +connection master; +connection server_1; +connection default; +include/assert_grep.inc [Check that there is no 'Thread awaiting semi-sync ACK was awoken before its ACK' warning in error log.] +connection slave; +# +# Cleanup +connection master; +set @@global.binlog_commit_wait_count=@save_bgc_count; +set @@global.binlog_commit_wait_usec=@save_bgc_usec; +set @@global.debug_dbug=@save_debug_dbug; +set @@global.rpl_semi_sync_master_enabled= @save_semi_sync_master_enabled; +set @@global.rpl_semi_sync_master_wait_point= @save_semi_sync_wp; +connection slave; +include/stop_slave.inc +set @@global.rpl_semi_sync_slave_enabled= @save_semi_sync_slave_enabled; +include/start_slave.inc +connection master; +drop table t1, t2, t3; +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_fail_over.result b/mysql-test/suite/rpl/r/rpl_semi_sync_fail_over.result index 4f0a8b421da..b881f69ad8a 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_fail_over.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_fail_over.result @@ -44,13 +44,19 @@ SET DEBUG_SYNC= "now WAIT_FOR con1_ready"; connection server_2; include/wait_for_slave_param.inc [Slave_SQL_Running_State] include/stop_slave.inc -include/assert.inc [Table t1 should have 2 rows.] +select count(*) 'on slave must be 2' from t1; +on slave must be 2 +2 SELECT @@GLOBAL.gtid_current_pos; @@GLOBAL.gtid_current_pos 0-1-4 # restart: --skip-slave-start=1 --rpl-semi-sync-slave-enabled=1 connection server_1; -include/assert.inc [Table t1 should have 1 rows.] +# Ensuring variable rpl_semi_sync_slave_enabled is ON.. +# Ensuring status rpl_semi_sync_slave_status is OFF.. +select count(*) 'on master must be 1' from t1; +on master must be 1 +1 FOUND 1 /truncated binlog file:.*master.*000001/ in mysqld.1.err disconnect conn_client; connection server_2; @@ -77,9 +83,9 @@ SHOW VARIABLES LIKE 'gtid_slave_pos'; Variable_name Value gtid_slave_pos 0-1-4 connection server_1; -SELECT COUNT(*) = 3 as 'true' FROM t1; -true -1 +SELECT COUNT(*) 'must be 3' FROM t1; +must be 3 +3 # ... the gtid states on the slave: SHOW VARIABLES LIKE 'gtid_slave_pos'; Variable_name Value @@ -111,24 +117,32 @@ connection server_2; #================================================================= connect conn_client,127.0.0.1,root,,test,$SERVER_MYPORT_2,; SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL con1_ready WAIT_FOR con1_go"; +SET DEBUG_SYNC= "commit_after_release_LOCK_after_binlog_sync WAIT_FOR con1_go1"; SET STATEMENT server_id=1 FOR INSERT INTO t1 VALUES (4, REPEAT("x", 4100)); connect conn_client_2,127.0.0.1,root,,test,$SERVER_MYPORT_2,; SET DEBUG_SYNC= "now WAIT_FOR con1_ready"; -SET GLOBAL debug_dbug="d,Notify_binlog_EOF"; +SET DEBUG_SYNC= "commit_before_get_LOCK_after_binlog_sync SIGNAL con1_go"; +SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL con2_ready"; INSERT INTO t1 VALUES (5, REPEAT("x", 4100)); connection server_2; -SET DEBUG_SYNC= "now WAIT_FOR eof_reached"; +SET DEBUG_SYNC= "now WAIT_FOR con2_ready"; # Kill the server connection server_1; include/wait_for_slave_param.inc [Slave_SQL_Running_State] include/stop_slave.inc -include/assert.inc [Table t1 should have 5 rows.] +select count(*) 'on slave must be 5' from t1; +on slave must be 5 +5 SELECT @@GLOBAL.gtid_current_pos; @@GLOBAL.gtid_current_pos 0-2-7 # restart: --skip-slave-start=1 --rpl-semi-sync-slave-enabled=1 connection server_2; -include/assert.inc [Table t1 should have 3 rows.] +# Ensuring variable rpl_semi_sync_slave_enabled is ON.. +# Ensuring status rpl_semi_sync_slave_status is OFF.. +select count(*) 'on master must be 3' from t1; +on master must be 3 +3 FOUND 1 /truncated binlog file:.*slave.*000002.* to remove transactions starting from GTID 0-1-6/ in mysqld.2.err disconnect conn_client; connection server_1; @@ -155,9 +169,9 @@ SHOW VARIABLES LIKE 'gtid_slave_pos'; Variable_name Value gtid_slave_pos 0-2-7 connection server_2; -SELECT COUNT(*) = 6 as 'true' FROM t1; -true -1 +SELECT COUNT(*) 'must be 6 as' FROM t1; +must be 6 as +6 # ... the gtid states on the slave: SHOW VARIABLES LIKE 'gtid_slave_pos'; Variable_name Value @@ -201,13 +215,19 @@ SET DEBUG_SYNC= "now WAIT_FOR con3_ready"; connection server_2; include/wait_for_slave_param.inc [Slave_SQL_Running_State] include/stop_slave.inc -include/assert.inc [Table t1 should have 7 rows.] +select count(*) 'on slave must be 7' from t1; +on slave must be 7 +7 SELECT @@GLOBAL.gtid_current_pos; @@GLOBAL.gtid_current_pos 0-1-9 # restart: --skip-slave-start=1 --rpl-semi-sync-slave-enabled=1 connection server_1; -include/assert.inc [Table t1 should have 6 rows.] +# Ensuring variable rpl_semi_sync_slave_enabled is ON.. +# Ensuring status rpl_semi_sync_slave_status is OFF.. +select count(*) 'on master must be 6' from t1; +on master must be 6 +6 FOUND 1 /truncated binlog file:.*master.*000002.* to remove transactions starting from GTID 0-1-9/ in mysqld.1.err disconnect conn_client; connection server_2; @@ -236,9 +256,9 @@ Variable_name Value gtid_slave_pos 0-1-9 connection server_1; include/sync_with_master_gtid.inc -SELECT COUNT(*) = 8 as 'true' FROM t1; -true -1 +SELECT COUNT(*) 'must be 8' FROM t1; +must be 8 +8 # ... the gtid states on the slave: SHOW VARIABLES LIKE 'gtid_slave_pos'; Variable_name Value diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_master_shutdown.result b/mysql-test/suite/rpl/r/rpl_semi_sync_master_shutdown.result index 6124ba01679..8803b4c3392 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_master_shutdown.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_master_shutdown.result @@ -4,7 +4,7 @@ connection master; SET @@GLOBAL.rpl_semi_sync_master_enabled = 1; connection slave; include/stop_slave.inc -SET @@GLOBAL. rpl_semi_sync_slave_enabled = 1; +SET @@GLOBAL.rpl_semi_sync_slave_enabled = 1; include/start_slave.inc connection master; CREATE TABLE t1 (a INT); @@ -21,7 +21,6 @@ connection slave; include/wait_for_slave_sql_to_start.inc include/wait_for_slave_io_to_start.inc connection master; -SET @@GLOBAL.debug_dbug=""; SET @@GLOBAL. rpl_semi_sync_master_enabled = 0; connection master; DROP TABLE t1; diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_shutdown_await_ack.result b/mysql-test/suite/rpl/r/rpl_semi_sync_shutdown_await_ack.result index 394a7acad41..3048b6b5635 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_shutdown_await_ack.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_shutdown_await_ack.result @@ -15,13 +15,17 @@ call mtr.add_suppression("reply failed"); call mtr.add_suppression("Replication event checksum verification"); call mtr.add_suppression("Relay log write failure"); call mtr.add_suppression("Failed to kill the active semi-sync connection"); +set @sav_enabled_server_2= @@GLOBAL.rpl_semi_sync_slave_enabled; +set @sav_server_2_dbug= @@GLOBAL.debug_dbug; connection server_3; call mtr.add_suppression("reply failed"); call mtr.add_suppression("Replication event checksum verification"); call mtr.add_suppression("Relay log write failure"); call mtr.add_suppression("Failed to kill the active semi-sync connection"); +set @sav_enabled_server_3= @@GLOBAL.rpl_semi_sync_slave_enabled; +set @sav_server_3_dbug= @@GLOBAL.debug_dbug; connection server_1; -CREATE TABLE t1 (a int); +CREATE TABLE t1 (a int) engine=innodb; connection server_2; connection server_3; connect server_1_con2, localhost, root,,; @@ -30,8 +34,8 @@ connect server_1_con2, localhost, root,,; ############################# # # Test Case 1) If both replicas simulate a delay that is within the -# allowed timeout, the primary should delay killing the suspended thread -# until an ACK is received (Rpl_semi_sync_master_yes_tx should be 1). +# allowed timeout, the primary should delay killing the Ack_thread +# until an ACK is received. # connection server_1; #-- @@ -40,15 +44,15 @@ connection server_1; #-- Enable semi-sync on slaves let slave_last= 3 connection server_2; -set global rpl_semi_sync_slave_enabled = 1; include/stop_slave.inc +set global rpl_semi_sync_slave_enabled = 1; include/start_slave.inc show status like 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status ON connection server_3; -set global rpl_semi_sync_slave_enabled = 1; include/stop_slave.inc +set global rpl_semi_sync_slave_enabled = 1; include/start_slave.inc show status like 'Rpl_semi_sync_slave_status'; Variable_name Value @@ -67,35 +71,22 @@ show status like 'Rpl_semi_sync_master_clients'; Variable_name Value Rpl_semi_sync_master_clients 2 #-- Prepare servers to simulate delay or error -connection server_1; -SET @@GLOBAL.debug_dbug= ""; connection server_2; SET @@GLOBAL.debug_dbug= "+d,simulate_delay_semisync_slave_reply"; connection server_3; SET @@GLOBAL.debug_dbug= "+d,simulate_delay_semisync_slave_reply"; #-- #-- Test begins +connection server_1_con2; connection server_1; #-- Begin semi-sync transaction INSERT INTO t1 VALUES (1); connection server_1_con2; #-- Wait until master recognizes a connection is awaiting semi-sync ACK -show status like 'Rpl_semi_sync_master_wait_sessions'; -Variable_name Value -Rpl_semi_sync_master_wait_sessions 1 -#-- Give enough time after timeout/ack received to query yes_tx/no_tx -SET @@GLOBAL.debug_dbug= "+d,delay_shutdown_phase_2_after_semisync_wait"; #-- Begin master shutdown SHUTDOWN WAIT FOR ALL SLAVES; connection server_1; -#-- Ensure either ACK was received (yes_tx=1) or timeout (no_tx=1) -show status like 'Rpl_semi_sync_master_yes_tx'; -Variable_name Value -Rpl_semi_sync_master_yes_tx 1 -show status like 'Rpl_semi_sync_master_no_tx'; -Variable_name Value -Rpl_semi_sync_master_no_tx 0 -connection server_1_con2; +ERROR HY000: Lost connection to server during query # Check logs to ensure shutdown was delayed FOUND 1 /Delaying shutdown to await semi-sync ACK/ in mysqld.1.err # Validate slave data is in correct state @@ -111,22 +102,19 @@ count(*)=1 #-- Re-synchronize slaves with master and disable semi-sync #-- Stop slaves connection server_2; -SET @@GLOBAL.debug_dbug= ""; -SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0; -include/stop_slave.inc +include/stop_slave_io.inc +include/stop_slave_sql.inc +SET @@GLOBAL.debug_dbug= @sav_server_2_dbug; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= @sav_enabled_server_2; connection server_3; -SET @@GLOBAL.debug_dbug= ""; -SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0; -include/stop_slave.inc +include/stop_slave_io.inc +include/stop_slave_sql.inc +SET @@GLOBAL.debug_dbug= @sav_server_3_dbug; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= @sav_enabled_server_3; #-- Bring the master back up connection server_1_con2; connection default; connection server_1; -SET @@GLOBAL.debug_dbug= ""; -SET @@GLOBAL.rpl_semi_sync_master_enabled = 0; -show status like 'Rpl_semi_sync_master_status'; -Variable_name Value -Rpl_semi_sync_master_status OFF TRUNCATE TABLE t1; #-- Bring slaves back up connection server_2; @@ -147,8 +135,8 @@ COUNT(*)=0 1 # # Test Case 2) If both replicas simulate an error before sending an ACK, -# the primary should delay killing the suspended thread until the -# timeout is reached (Rpl_semi_sync_master_no_tx should be 1). +# the primary should delay killing the Ack_thread until the +# timeout is reached. # connection server_1; #-- @@ -157,15 +145,15 @@ connection server_1; #-- Enable semi-sync on slaves let slave_last= 3 connection server_2; -set global rpl_semi_sync_slave_enabled = 1; include/stop_slave.inc +set global rpl_semi_sync_slave_enabled = 1; include/start_slave.inc show status like 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status ON connection server_3; -set global rpl_semi_sync_slave_enabled = 1; include/stop_slave.inc +set global rpl_semi_sync_slave_enabled = 1; include/start_slave.inc show status like 'Rpl_semi_sync_slave_status'; Variable_name Value @@ -184,35 +172,22 @@ show status like 'Rpl_semi_sync_master_clients'; Variable_name Value Rpl_semi_sync_master_clients 2 #-- Prepare servers to simulate delay or error -connection server_1; -SET @@GLOBAL.debug_dbug= "+d,mysqld_delay_kill_threads_phase_1"; connection server_2; -SET @@GLOBAL.debug_dbug= "+d,corrupt_queue_event"; +SET @@GLOBAL.debug_dbug= "+d,corrupt_queue_event,delay_semisync_kill_connection_for_mdev_28141"; connection server_3; -SET @@GLOBAL.debug_dbug= "+d,corrupt_queue_event"; +SET @@GLOBAL.debug_dbug= "+d,corrupt_queue_event,delay_semisync_kill_connection_for_mdev_28141"; #-- #-- Test begins +connection server_1_con2; connection server_1; #-- Begin semi-sync transaction INSERT INTO t1 VALUES (1); connection server_1_con2; #-- Wait until master recognizes a connection is awaiting semi-sync ACK -show status like 'Rpl_semi_sync_master_wait_sessions'; -Variable_name Value -Rpl_semi_sync_master_wait_sessions 1 -#-- Give enough time after timeout/ack received to query yes_tx/no_tx -SET @@GLOBAL.debug_dbug= "+d,delay_shutdown_phase_2_after_semisync_wait"; #-- Begin master shutdown SHUTDOWN WAIT FOR ALL SLAVES; connection server_1; -#-- Ensure either ACK was received (yes_tx=1) or timeout (no_tx=1) -show status like 'Rpl_semi_sync_master_yes_tx'; -Variable_name Value -Rpl_semi_sync_master_yes_tx 0 -show status like 'Rpl_semi_sync_master_no_tx'; -Variable_name Value -Rpl_semi_sync_master_no_tx 1 -connection server_1_con2; +ERROR HY000: Lost connection to server during query # Check logs to ensure shutdown was delayed FOUND 2 /Delaying shutdown to await semi-sync ACK/ in mysqld.1.err # Validate slave data is in correct state @@ -226,24 +201,33 @@ count(*)=0 1 # #-- Re-synchronize slaves with master and disable semi-sync +#-- FIXME: workaround for MDEV-28141, preventing errored replicas from +# killing their semi-sync connections +connection server_2; +set debug_sync= "now wait_for at_semisync_kill_connection"; +set debug_sync= "now signal continue_semisync_kill_connection"; +# Wait for debug_sync signal to have been received before issuing RESET +set debug_sync= "reset"; +connection server_3; +set debug_sync= "now wait_for at_semisync_kill_connection"; +set debug_sync= "now signal continue_semisync_kill_connection"; +# Wait for debug_sync signal to have been received before issuing RESET +set debug_sync= "reset"; #-- Stop slaves connection server_2; -SET @@GLOBAL.debug_dbug= ""; -SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0; -include/stop_slave.inc +include/stop_slave_io.inc +include/stop_slave_sql.inc +SET @@GLOBAL.debug_dbug= @sav_server_2_dbug; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= @sav_enabled_server_2; connection server_3; -SET @@GLOBAL.debug_dbug= ""; -SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0; -include/stop_slave.inc +include/stop_slave_io.inc +include/stop_slave_sql.inc +SET @@GLOBAL.debug_dbug= @sav_server_3_dbug; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= @sav_enabled_server_3; #-- Bring the master back up connection server_1_con2; connection default; connection server_1; -SET @@GLOBAL.debug_dbug= ""; -SET @@GLOBAL.rpl_semi_sync_master_enabled = 0; -show status like 'Rpl_semi_sync_master_status'; -Variable_name Value -Rpl_semi_sync_master_status OFF TRUNCATE TABLE t1; #-- Bring slaves back up connection server_2; @@ -265,8 +249,8 @@ COUNT(*)=0 # # Test Case 3) If one replica simulates a delay within the allowed # timeout and the other simulates an error before sending an ACK, the -# primary should delay killing the suspended thread until it receives an -# ACK from the delayed slave (Rpl_semi_sync_master_yes_tx should be 1). +# primary should delay killing the Ack_thread until it receives an +# ACK from the delayed slave. # connection server_1; #-- @@ -275,15 +259,15 @@ connection server_1; #-- Enable semi-sync on slaves let slave_last= 3 connection server_2; -set global rpl_semi_sync_slave_enabled = 1; include/stop_slave.inc +set global rpl_semi_sync_slave_enabled = 1; include/start_slave.inc show status like 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status ON connection server_3; -set global rpl_semi_sync_slave_enabled = 1; include/stop_slave.inc +set global rpl_semi_sync_slave_enabled = 1; include/start_slave.inc show status like 'Rpl_semi_sync_slave_status'; Variable_name Value @@ -302,35 +286,22 @@ show status like 'Rpl_semi_sync_master_clients'; Variable_name Value Rpl_semi_sync_master_clients 2 #-- Prepare servers to simulate delay or error -connection server_1; -SET @@GLOBAL.debug_dbug= "+d,mysqld_delay_kill_threads_phase_1"; connection server_2; -SET @@GLOBAL.debug_dbug= "+d,corrupt_queue_event"; +SET @@GLOBAL.debug_dbug= "+d,corrupt_queue_event,delay_semisync_kill_connection_for_mdev_28141"; connection server_3; SET @@GLOBAL.debug_dbug= "+d,simulate_delay_semisync_slave_reply"; #-- #-- Test begins +connection server_1_con2; connection server_1; #-- Begin semi-sync transaction INSERT INTO t1 VALUES (1); connection server_1_con2; #-- Wait until master recognizes a connection is awaiting semi-sync ACK -show status like 'Rpl_semi_sync_master_wait_sessions'; -Variable_name Value -Rpl_semi_sync_master_wait_sessions 1 -#-- Give enough time after timeout/ack received to query yes_tx/no_tx -SET @@GLOBAL.debug_dbug= "+d,delay_shutdown_phase_2_after_semisync_wait"; #-- Begin master shutdown SHUTDOWN WAIT FOR ALL SLAVES; connection server_1; -#-- Ensure either ACK was received (yes_tx=1) or timeout (no_tx=1) -show status like 'Rpl_semi_sync_master_yes_tx'; -Variable_name Value -Rpl_semi_sync_master_yes_tx 1 -show status like 'Rpl_semi_sync_master_no_tx'; -Variable_name Value -Rpl_semi_sync_master_no_tx 0 -connection server_1_con2; +ERROR HY000: Lost connection to server during query # Check logs to ensure shutdown was delayed FOUND 3 /Delaying shutdown to await semi-sync ACK/ in mysqld.1.err # Validate slave data is in correct state @@ -344,24 +315,28 @@ count(*)=1 1 # #-- Re-synchronize slaves with master and disable semi-sync +#-- FIXME: workaround for MDEV-28141, preventing errored replicas from +# killing their semi-sync connections +connection server_2; +set debug_sync= "now wait_for at_semisync_kill_connection"; +set debug_sync= "now signal continue_semisync_kill_connection"; +# Wait for debug_sync signal to have been received before issuing RESET +set debug_sync= "reset"; #-- Stop slaves connection server_2; -SET @@GLOBAL.debug_dbug= ""; -SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0; -include/stop_slave.inc +include/stop_slave_io.inc +include/stop_slave_sql.inc +SET @@GLOBAL.debug_dbug= @sav_server_2_dbug; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= @sav_enabled_server_2; connection server_3; -SET @@GLOBAL.debug_dbug= ""; -SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0; -include/stop_slave.inc +include/stop_slave_io.inc +include/stop_slave_sql.inc +SET @@GLOBAL.debug_dbug= @sav_server_3_dbug; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= @sav_enabled_server_3; #-- Bring the master back up connection server_1_con2; connection default; connection server_1; -SET @@GLOBAL.debug_dbug= ""; -SET @@GLOBAL.rpl_semi_sync_master_enabled = 0; -show status like 'Rpl_semi_sync_master_status'; -Variable_name Value -Rpl_semi_sync_master_status OFF TRUNCATE TABLE t1; #-- Bring slaves back up connection server_2; @@ -389,8 +364,7 @@ COUNT(*)=0 # active semi-sync connection in-tact. The slave should notice this, and # not issue a `QUIT` command to the primary, which would otherwise be # sent to kill an active connection. This test case validates that the -# slave does not send a `QUIT` in this case (Rpl_semi_sync_master_yes_tx -# should be 1 because server_3 will send the ACK within a valid timeout). +# slave does not send a `QUIT` in this case. # connection server_1; #-- @@ -399,15 +373,15 @@ connection server_1; #-- Enable semi-sync on slaves let slave_last= 3 connection server_2; -set global rpl_semi_sync_slave_enabled = 1; include/stop_slave.inc +set global rpl_semi_sync_slave_enabled = 1; include/start_slave.inc show status like 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status ON connection server_3; -set global rpl_semi_sync_slave_enabled = 1; include/stop_slave.inc +set global rpl_semi_sync_slave_enabled = 1; include/start_slave.inc show status like 'Rpl_semi_sync_slave_status'; Variable_name Value @@ -426,35 +400,22 @@ show status like 'Rpl_semi_sync_master_clients'; Variable_name Value Rpl_semi_sync_master_clients 2 #-- Prepare servers to simulate delay or error -connection server_1; -SET @@GLOBAL.debug_dbug= "+d,mysqld_delay_kill_threads_phase_1"; connection server_2; -SET @@GLOBAL.debug_dbug= "+d,corrupt_queue_event,slave_delay_killing_semisync_connection"; +SET @@GLOBAL.debug_dbug= "+d,corrupt_queue_event,delay_semisync_kill_connection_for_mdev_28141"; connection server_3; SET @@GLOBAL.debug_dbug= "+d,simulate_delay_semisync_slave_reply"; #-- #-- Test begins +connection server_1_con2; connection server_1; #-- Begin semi-sync transaction INSERT INTO t1 VALUES (1); connection server_1_con2; #-- Wait until master recognizes a connection is awaiting semi-sync ACK -show status like 'Rpl_semi_sync_master_wait_sessions'; -Variable_name Value -Rpl_semi_sync_master_wait_sessions 1 -#-- Give enough time after timeout/ack received to query yes_tx/no_tx -SET @@GLOBAL.debug_dbug= "+d,delay_shutdown_phase_2_after_semisync_wait"; #-- Begin master shutdown SHUTDOWN WAIT FOR ALL SLAVES; connection server_1; -#-- Ensure either ACK was received (yes_tx=1) or timeout (no_tx=1) -show status like 'Rpl_semi_sync_master_yes_tx'; -Variable_name Value -Rpl_semi_sync_master_yes_tx 1 -show status like 'Rpl_semi_sync_master_no_tx'; -Variable_name Value -Rpl_semi_sync_master_no_tx 0 -connection server_1_con2; +ERROR HY000: Lost connection to server during query # Check logs to ensure shutdown was delayed FOUND 4 /Delaying shutdown to await semi-sync ACK/ in mysqld.1.err # Validate slave data is in correct state @@ -468,24 +429,28 @@ count(*)=1 1 # #-- Re-synchronize slaves with master and disable semi-sync +#-- FIXME: workaround for MDEV-28141, preventing errored replicas from +# killing their semi-sync connections +connection server_2; +set debug_sync= "now wait_for at_semisync_kill_connection"; +set debug_sync= "now signal continue_semisync_kill_connection"; +# Wait for debug_sync signal to have been received before issuing RESET +set debug_sync= "reset"; #-- Stop slaves connection server_2; -SET @@GLOBAL.debug_dbug= ""; -SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0; -include/stop_slave.inc +include/stop_slave_io.inc +include/stop_slave_sql.inc +SET @@GLOBAL.debug_dbug= @sav_server_2_dbug; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= @sav_enabled_server_2; connection server_3; -SET @@GLOBAL.debug_dbug= ""; -SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0; -include/stop_slave.inc +include/stop_slave_io.inc +include/stop_slave_sql.inc +SET @@GLOBAL.debug_dbug= @sav_server_3_dbug; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= @sav_enabled_server_3; #-- Bring the master back up connection server_1_con2; connection default; connection server_1; -SET @@GLOBAL.debug_dbug= ""; -SET @@GLOBAL.rpl_semi_sync_master_enabled = 0; -show status like 'Rpl_semi_sync_master_status'; -Variable_name Value -Rpl_semi_sync_master_status OFF TRUNCATE TABLE t1; #-- Bring slaves back up connection server_2; @@ -504,14 +469,62 @@ Rpl_semi_sync_slave_status OFF SELECT COUNT(*)=0 from t1; COUNT(*)=0 1 +# +# Test Case 5) If a waiting-for-ACK user thread is killed (disconnected) +# during SHUTDOWN WAIT FOR ALL SLAVES, ensure the primary will still +# await the ACK from the replica before killing the Ack_receiver thread +# +connection server_1; +insert into t1 values (1); +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +include/stop_slave.inc +SET GLOBAL rpl_semi_sync_slave_enabled= 1; +include/start_slave.inc +connection server_1; +SET GLOBAL rpl_semi_sync_master_enabled= 1; +SET GLOBAL rpl_semi_sync_master_timeout= 2000; +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status ON +show status like 'Rpl_semi_sync_master_clients'; +Variable_name Value +Rpl_semi_sync_master_clients 1 +connection server_2; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,simulate_delay_semisync_slave_reply"; +connect con1, localhost, root,,; +connect con2, localhost, root,,; +connection con1; +insert into t1 values (2); +connection server_1; +# Wait for thd to begin semi-sync wait.. +# ..done +disconnect con1; +connection default; +connection con2; +SHUTDOWN WAIT FOR ALL SLAVES; +# Ensure the primary waited for the ACK of the killed thread +FOUND 5 /Delaying shutdown to await semi-sync ACK/ in mysqld.1.err +connection default; +connection server_1; +connection server_2; +include/stop_slave.inc +connection server_3; +include/stop_slave.inc +connection default; +connection server_1; ############################# # Cleanup ############################# connection server_2; -include/stop_slave.inc +SET @@GLOBAL.rpl_semi_sync_slave_enabled = @sav_enabled_server_2; +SET @@GLOBAL.debug_dbug= @sav_server_2_dbug; include/start_slave.inc connection server_3; -include/stop_slave.inc +SET @@GLOBAL.rpl_semi_sync_slave_enabled = @sav_enabled_server_3; +SET @@GLOBAL.debug_dbug= @sav_server_3_dbug; include/start_slave.inc connection server_1; drop table t1; diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_slave_enabled_consistent.result b/mysql-test/suite/rpl/r/rpl_semi_sync_slave_enabled_consistent.result index 99c3124957f..4195acb931d 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_slave_enabled_consistent.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_slave_enabled_consistent.result @@ -2,6 +2,9 @@ include/master-slave.inc [connection master] call mtr.add_suppression("Replication event checksum verification failed"); call mtr.add_suppression("could not queue event from master"); +call mtr.add_suppression("Semisync ack receiver.*error reading communication packets"); +call mtr.add_suppression("Semisync ack receiver got hangup"); +connection slave; # # Set up a semisync connection connection master; diff --git a/mysql-test/suite/rpl/r/rpl_show_slave_status.result b/mysql-test/suite/rpl/r/rpl_show_slave_status.result new file mode 100644 index 00000000000..e32b2f554ce --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_show_slave_status.result @@ -0,0 +1,75 @@ +include/master-slave.inc +[connection master] +* +* The purpose of this test is to prevent incorrect additions to SHOW +* SLAVE STATUS, which has happened several times in the past. +* +* We must never, _ever_, add extra rows to this output of SHOW SLAVE +* STATUS, except at the very end, as this breaks backwards compatibility +* with applications or scripts that parse the output. This also means that +* we cannot add _any_ new rows in a GA version if a different row was +* already added in a later MariaDB version, as this would make it impossible +* to merge the change up while preserving the order of rows. +* +connection slave; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host # +Master_User # +Master_Port # +Connect_Retry # +Master_Log_File # +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File # +Slave_IO_Running # +Slave_SQL_Running # +Replicate_Do_DB # +Replicate_Ignore_DB # +Replicate_Do_Table # +Replicate_Ignore_Table # +Replicate_Wild_Do_Table # +Replicate_Wild_Ignore_Table # +Last_Errno # +Last_Error # +Skip_Counter # +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition # +Until_Log_File # +Until_Log_Pos # +Master_SSL_Allowed # +Master_SSL_CA_File # +Master_SSL_CA_Path # +Master_SSL_Cert # +Master_SSL_Cipher # +Master_SSL_Key # +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert # +Last_IO_Errno # +Last_IO_Error # +Last_SQL_Errno # +Last_SQL_Error # +Replicate_Ignore_Server_Ids # +Master_Server_Id # +Master_SSL_Crl # +Master_SSL_Crlpath # +Using_Gtid # +Gtid_IO_Pos # +Replicate_Do_Domain_Ids # +Replicate_Ignore_Domain_Ids # +Parallel_Mode # +SQL_Delay # +SQL_Remaining_Delay # +Slave_SQL_Running_State # +Slave_DDL_Groups # +Slave_Non_Transactional_Groups # +Slave_Transactional_Groups # +Replicate_Rewrite_DB # +* +* When modifying this test after adding a column to SHOW SLAVE STATUS, +* _only_ additions at the end are allowed, the column number of existing +* columns must _not_ change! +* +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_shutdown_sighup.result b/mysql-test/suite/rpl/r/rpl_shutdown_sighup.result new file mode 100644 index 00000000000..01b35f1dc58 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_shutdown_sighup.result @@ -0,0 +1,50 @@ +include/master-slave.inc +[connection master] +connection slave; +set statement sql_log_bin=0 for call mtr.add_suppression("Signal handler thread did not exit in a timely manner"); +# +# Main test +connection master; +create table t1 (a int); +insert into t1 values (1); +include/save_master_gtid.inc +connection slave; +include/sync_with_master_gtid.inc +set @@global.debug_dbug= "+d,hold_sighup_log_refresh"; +# Waiting for sighup to reach reload_acl_and_cache.. +set debug_sync="now wait_for in_reload_acl_and_cache"; +# Signalling signal handler to proceed to sleep before REFRESH_HOSTS +set debug_sync="now signal refresh_logs"; +# Starting shutdown (note this will take 3+ seconds due to DBUG my_sleep in reload_acl_and_cache) +shutdown; +connection server_2; +connection slave; +include/assert_grep.inc [Ensure Mariadbd did not segfault when shutting down] +connection master; +connection slave; +# +# Error testcase to ensure an error message is shown if the signal +# takes longer than the timeout while processing the SIGHUP +connection slave; +set @@global.debug_dbug= "+d,force_sighup_processing_timeout"; +set @@global.debug_dbug= "+d,hold_sighup_log_refresh"; +connection master; +insert into t1 values (1); +include/save_master_gtid.inc +connection slave; +include/sync_with_master_gtid.inc +# Waiting for sighup to reach reload_acl_and_cache.. +set debug_sync="now wait_for in_reload_acl_and_cache"; +# Signalling signal handler to proceed to sleep before REFRESH_HOSTS +set debug_sync="now signal refresh_logs"; +# Starting shutdown (note this will take 3+ seconds due to DBUG my_sleep in reload_acl_and_cache) +shutdown; +connection server_2; +connection slave; +include/assert_grep.inc [Ensure warning is issued that signal handler thread is still processing] +# +# Cleanup +connection master; +drop table t1; +include/rpl_end.inc +# End of rpl_shutdown_sighup.test diff --git a/mysql-test/suite/rpl/r/rpl_skip_error.result b/mysql-test/suite/rpl/r/rpl_skip_error.result index eb6324ff987..03fc8a7836f 100644 --- a/mysql-test/suite/rpl/r/rpl_skip_error.result +++ b/mysql-test/suite/rpl/r/rpl_skip_error.result @@ -122,6 +122,31 @@ connection slave; # Slave_skipped_errros = 5 **** We cannot execute a select as there are differences in the **** behavior between STMT and RBR. +**** +**** Ensure transactions which are skipped due to encountering a +**** non-deadlock error which is present in --slave-skip-errors result +**** in partially committed transactions +connection master; +CREATE TABLE t3 (a INT UNIQUE) ENGINE=InnoDB; +connection slave; +connection slave; +INSERT INTO t3 VALUES (3); +connection master; +BEGIN; +INSERT INTO t3 VALUES (1); +INSERT INTO t3 VALUES (2); +INSERT INTO t3 VALUES (3); +INSERT INTO t3 VALUES (4); +COMMIT; +connection slave; +**** Master and slave tables should have the same data, due to the +**** partially replicated transaction's data overlapping with the data +**** that pre-existed on the slave. That is, despite the transaction +**** consisting of 4 statements, the errored statement should be ignored +**** and the other 3 should commit successfully. +include/diff_tables.inc [master:t3,slave:t3] +connection master; +DROP TABLE t3; ==== Clean Up ==== connection master; DROP TABLE t1; diff --git a/mysql-test/suite/rpl/r/rpl_start_alter_options.result b/mysql-test/suite/rpl/r/rpl_start_alter_options.result index 9a6388412d6..c150c18ad80 100644 --- a/mysql-test/suite/rpl/r/rpl_start_alter_options.result +++ b/mysql-test/suite/rpl/r/rpl_start_alter_options.result @@ -3,8 +3,6 @@ include/master-slave.inc connection slave; stop slave; change master to master_use_gtid= current_pos; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead SET GLOBAL slave_parallel_threads=4; set global slave_parallel_mode=optimistic; set global gtid_strict_mode=1; @@ -96,8 +94,6 @@ include/start_slave.inc connection slave; stop slave; change master to master_use_gtid= current_pos; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead SET GLOBAL slave_parallel_threads=4; set global slave_parallel_mode=optimistic; set global gtid_strict_mode=1; @@ -189,8 +185,6 @@ include/start_slave.inc connection slave; stop slave; change master to master_use_gtid= current_pos; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead SET GLOBAL slave_parallel_threads=4; set global slave_parallel_mode=optimistic; set global gtid_strict_mode=1; @@ -321,8 +315,6 @@ include/start_slave.inc connection slave; stop slave; change master to master_use_gtid= current_pos; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead SET GLOBAL slave_parallel_threads=4; set global slave_parallel_mode=optimistic; set global gtid_strict_mode=1; @@ -377,8 +369,6 @@ connection master; alter table t1 add column f varchar(100) after b,add column g varchar(100) first ,add column h char, force , algorithm=instant; alter table t1 add index if not exists index_1(f), force , algorithm=instant; alter table t1 disable keys, force , algorithm=copy; -Warnings: -Note 1031 Storage engine InnoDB of the table `test`.`t1` doesn't have this option alter table t1 enable keys, force , algorithm=copy; Warnings: Note 1031 Storage engine InnoDB of the table `test`.`t1` doesn't have this option @@ -414,8 +404,6 @@ include/start_slave.inc connection slave; stop slave; change master to master_use_gtid= current_pos; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead SET GLOBAL slave_parallel_threads=4; set global slave_parallel_mode=optimistic; set global gtid_strict_mode=1; @@ -470,8 +458,6 @@ connection master; alter table t1 add column f varchar(100) after b,add column g varchar(100) first ,add column h char, force , algorithm=nocopy; alter table t1 add index if not exists index_1(f), force , algorithm=nocopy; alter table t1 disable keys, force , algorithm=copy; -Warnings: -Note 1031 Storage engine InnoDB of the table `test`.`t1` doesn't have this option alter table t1 enable keys, force , algorithm=copy; Warnings: Note 1031 Storage engine InnoDB of the table `test`.`t1` doesn't have this option diff --git a/mysql-test/suite/rpl/r/rpl_temporary_error2_skip_all.result b/mysql-test/suite/rpl/r/rpl_temporary_error2_skip_all.result new file mode 100644 index 00000000000..9819aafa5cf --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_temporary_error2_skip_all.result @@ -0,0 +1,64 @@ +include/master-slave.inc +[connection master] +call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction"); +*** Provoke a deadlock on the slave, check that transaction retry succeeds. *** +connection master; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +INSERT INTO t1(a) VALUES (1), (2), (3), (4), (5); +connection slave; +SELECT * FROM t1 ORDER BY a; +a b +1 NULL +2 NULL +3 NULL +4 NULL +5 NULL +SET sql_log_bin=0; +ALTER TABLE t2 ENGINE=MyISAM; +SET sql_log_bin=1; +connect con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +connection con_temp1; +BEGIN; +UPDATE t1 SET b=2 WHERE a=4; +INSERT INTO t2 VALUES (2); +DELETE FROM t2 WHERE a=2; +connection master; +BEGIN; +UPDATE t1 SET b=1 WHERE a=2; +INSERT INTO t2 VALUES (1); +UPDATE t1 SET b=1 WHERE a=4; +COMMIT; +connection slave; +connection con_temp1; +UPDATE t1 SET b=2 WHERE a=2; +SELECT * FROM t1 WHERE a<10 ORDER BY a; +a b +1 NULL +2 2 +3 NULL +4 2 +5 NULL +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +connection slave; +SELECT * FROM t1 ORDER BY a; +a b +1 NULL +2 NULL +3 NULL +4 NULL +5 NULL +* There will be one row in t2 because the ignored deadlock does not retry. +SELECT * FROM t2 ORDER BY a; +a +1 +retries +0 +Last_SQL_Errno = '0' +Last_SQL_Error = '' +connection master; +DROP TABLE t1; +DROP TABLE t2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_using_gtid_default.result b/mysql-test/suite/rpl/r/rpl_using_gtid_default.result index 5a7b0cd84ef..24a316de1bd 100644 --- a/mysql-test/suite/rpl/r/rpl_using_gtid_default.result +++ b/mysql-test/suite/rpl/r/rpl_using_gtid_default.result @@ -58,8 +58,6 @@ include/start_slave.inc # to its default of Slave_Pos after RESET SLAVE. include/stop_slave.inc CHANGE MASTER TO MASTER_USE_GTID=Current_Pos; -Warnings: -Warning 1287 'master_use_gtid=current_pos' is deprecated and will be removed in a future release. Please use master_demote_to_slave=1 instead include/start_slave.inc include/stop_slave.inc RESET SLAVE; diff --git a/mysql-test/suite/rpl/r/show_status_stop_slave_race-7126.result b/mysql-test/suite/rpl/r/show_status_stop_slave_race-7126.result index 298a3daf64a..c38d1343226 100644 --- a/mysql-test/suite/rpl/r/show_status_stop_slave_race-7126.result +++ b/mysql-test/suite/rpl/r/show_status_stop_slave_race-7126.result @@ -1,6 +1,5 @@ include/master-slave.inc [connection master] -call mtr.add_suppression("Master is configured to log replication events"); connection slave; connection slave; include/wait_for_slave_to_stop.inc diff --git a/mysql-test/suite/rpl/t/parallel_backup_xa.inc b/mysql-test/suite/rpl/t/parallel_backup_xa.inc index 83a6fb79345..5f287aa0ca6 100644 --- a/mysql-test/suite/rpl/t/parallel_backup_xa.inc +++ b/mysql-test/suite/rpl/t/parallel_backup_xa.inc @@ -41,7 +41,7 @@ if ($slave_ooo_error) { SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; - SET @@global.innodb_lock_wait_timeout =1; + SET @@global.innodb_lock_wait_timeout =5; SET @@global.slave_transaction_retries=0; } --source include/start_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_auditing.test b/mysql-test/suite/rpl/t/rpl_auditing.test new file mode 100644 index 00000000000..3d3cee9a7a0 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_auditing.test @@ -0,0 +1,77 @@ +if (!$SERVER_AUDIT2_SO) { + skip No SERVER_AUDIT2 plugin; +} + +source include/master-slave.inc; + +--disable_warnings +drop table if exists t1; +sync_slave_with_master; +reset master; +--enable_warnings + +--disable_warnings +CREATE TABLE IF NOT EXISTS mysql.server_audit_filters ( + filtername char(80) COLLATE utf8_bin NOT NULL DEFAULT '', + rule longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT 'true' CHECK (json_valid(rule)), + CONSTRAINT c_filtername UNIQUE (filtername) +) ENGINE=Aria; + +CREATE TABLE IF NOT EXISTS mysql.server_audit_users (host char(60) COLLATE utf8_bin NOT NULL DEFAULT '', + user char(80) COLLATE utf8_bin NOT NULL DEFAULT '', + filtername char(80) NOT NULL DEFAULT '', + CONSTRAINT c_host_user UNIQUE (host, user) +) ENGINE=Aria; +--enable_warnings + +INSERT INTO mysql.server_audit_filters VALUES ('ignore_sys', '{"ignore_tables" : "mysql.*"}'); +INSERT INTO mysql.server_audit_users VALUES ('%','','ignore_sys'); +INSERT INTO mysql.server_audit_users VALUES ('%','root','ignore_sys'); + +install plugin server_audit soname 'server_audit2'; +set global server_audit_logging=on; + +# this is done to make test deterministic +# so the above 'set' command is always logged before the 'create table t1' +-- disable_query_log +-- disable_result_log +select * from mysql.server_audit_filters; +select * from mysql.server_audit_users; +-- enable_result_log +-- enable_query_log + +connection master; +create table t1 (a int); +insert into t1 values (1); +truncate t1; +drop table t1; +sync_slave_with_master; + +set global server_audit_logging=off; + +truncate mysql.server_audit_filters; +truncate mysql.server_audit_users; +INSERT INTO mysql.server_audit_filters VALUES ('no_logging','false'); +INSERT INTO mysql.server_audit_users VALUES ('%','','no_logging'); + +set global server_audit_logging=on; + +connection master; +create table t1 (a int); +insert into t1 values (1); +truncate t1; +drop table t1; +sync_slave_with_master; + +set global server_audit_logging=off; +uninstall plugin server_audit; +truncate mysql.server_audit_filters; +truncate mysql.server_audit_users; +let $MYSQLD_DATADIR= `SELECT @@datadir`; +# replace the timestamp and the hostname with constant values +--replace_regex /[0-9]* [0-9][0-9]:[0-9][0-9]:[0-9][0-9]\,[^,]*\,/TIME,HOSTNAME,/ /\,[1-9][0-9]*\,/,1,/ /\,[1-9][0-9]*/,ID/ /000001\\', [0-9]*,/#', POS,/ +cat_file $MYSQLD_DATADIR/server_audit.log; +remove_file $MYSQLD_DATADIR/server_audit.log; + +connection master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test b/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test index 02b31c065f9..4f0eafc4020 100644 --- a/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test +++ b/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test @@ -39,6 +39,7 @@ --source include/master-slave.inc --connection master +SET @org_log_warnings=@@GLOBAL.LOG_WARNINGS; SET GLOBAL LOG_WARNINGS=2; --connection slave @@ -110,6 +111,7 @@ CHANGE MASTER TO MASTER_USE_GTID=slave_pos; --source include/wait_for_pattern_in_file.inc --echo "===== Clean up =====" +SET GLOBAL LOG_WARNINGS=@org_log_warnings; --connection slave --source include/stop_slave.inc CHANGE MASTER TO MASTER_USE_GTID=no; @@ -117,5 +119,4 @@ CHANGE MASTER TO MASTER_USE_GTID=no; --connection master DROP TABLE t; -SET GLOBAL LOG_WARNINGS=default; --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_change_master.test b/mysql-test/suite/rpl/t/rpl_change_master.test index 2758f9d6e27..992e23906e5 100644 --- a/mysql-test/suite/rpl/t/rpl_change_master.test +++ b/mysql-test/suite/rpl/t/rpl_change_master.test @@ -109,9 +109,4 @@ CHANGE MASTER TO MASTER_USER='root', MASTER_SSL=0, MASTER_SSL_CA='', MASTER_SSL_ CHANGE MASTER TO MASTER_USER='root', MASTER_PASSWORD='', MASTER_SSL=0; -# MDEV-20122: Deprecate MASTER_USE_GTID=Current_Pos to favor new MASTER_DEMOTE_TO_SLAVE option ---echo "Usage of CURRENT_POS in CHANGE MASTER MASTER_USE_GTID is dreprecated. -CHANGE MASTER TO MASTER_USE_GTID=CURRENT_POS; -CHANGE MASTER TO MASTER_USE_GTID=SLAVE_POS; - --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_change_master_demote.test b/mysql-test/suite/rpl/t/rpl_change_master_demote.test index 15b55014975..6304d3526d1 100644 --- a/mysql-test/suite/rpl/t/rpl_change_master_demote.test +++ b/mysql-test/suite/rpl/t/rpl_change_master_demote.test @@ -73,6 +73,9 @@ # non-boolean value. # # +# Additionally ensure MASTER_DEMOTE_TO_REPLICA aliases MASTER_DEMOTE_TO_SLAVE +# +# # References: # MDEV-19801: Change defaults for CHANGE MASTER TO so that GTID-based # replication is used by default if master supports it @@ -454,6 +457,37 @@ EOF --eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SLAVE_MYPORT, master_user='root', master_use_gtid=Slave_Pos, master_demote_to_slave=invalid +--echo # +--echo # MDEV-31768 +--echo # Ensure MASTER_DEMOTE_TO_REPLICA aliases MASTER_DEMOTE_TO_SLAVE +--echo # +--connection slave +RESET MASTER; +--source include/reset_slave.inc +CREATE TABLE t_mdev_31768 (a int); +--let $gtid_binlog_pos= `SELECT @@GLOBAL.gtid_binlog_pos` +CHANGE MASTER TO master_use_gtid=Replica_Pos, master_demote_to_replica=1; +--let $gtid_slave_pos= `SELECT @@GLOBAL.gtid_slave_pos` + +--echo # Validating alias MASTER_DEMOTE_TO_REPLICA provides intended behavior.. +if (`SELECT strcmp("$gtid_binlog_pos","$gtid_slave_pos") != 0`) +{ + --echo # ..failed + --echo # Binlog pos: $gtid_binlog_pos + --echo # Replica pos: $gtid_slave_pos + die MASTER_DEMOTE_TO_REPLICA does not alias MASTER_DEMOTE_TO_SLAVE correctly; +} +--echo # ..success + +DROP TABLE t_mdev_31768; +RESET MASTER; +--source include/reset_slave.inc + +--echo # Clear primary binlog state to match replica +--connection master +RESET MASTER; + + --echo # --echo # Cleanup --echo # diff --git a/mysql-test/suite/rpl/t/rpl_domain_id_filter_io_crash.test b/mysql-test/suite/rpl/t/rpl_domain_id_filter_io_crash.test index 95fac6c2edb..c7ef3a4eff9 100644 --- a/mysql-test/suite/rpl/t/rpl_domain_id_filter_io_crash.test +++ b/mysql-test/suite/rpl/t/rpl_domain_id_filter_io_crash.test @@ -9,6 +9,7 @@ CREATE TABLE t1(i INT) ENGINE=INNODB; INSERT INTO t1 VALUES(1); SELECT * FROM t1; sync_slave_with_master; +--source include/save_master_gtid.inc connection slave; @@ -28,7 +29,7 @@ let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Igno CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; --source include/start_slave.inc -sync_with_master; +--source include/sync_with_master_gtid.inc let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); @@ -44,7 +45,7 @@ START TRANSACTION; INSERT INTO t1 VALUES(2); INSERT INTO t1 VALUES(3); COMMIT; -save_master_pos; +--source include/save_master_gtid.inc SELECT * FROM t1; connection slave; @@ -55,7 +56,7 @@ SET @@global.debug_dbug=@saved_dbug; START SLAVE io_thread; --source include/wait_for_slave_io_to_start.inc -sync_with_master; +--source include/sync_with_master_gtid.inc SELECT * FROM t1; --echo # Case 1 : Start slave with IGNORE_DOMAIN_IDS=(1), then restart @@ -70,7 +71,7 @@ let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Igno CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; --source include/start_slave.inc -sync_with_master; +--source include/sync_with_master_gtid.inc let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); @@ -86,7 +87,7 @@ INSERT INTO t1 VALUES(4); INSERT INTO t1 VALUES(5); COMMIT; -save_master_pos; +--source include/save_master_gtid.inc SELECT * FROM t1; connection slave; @@ -97,7 +98,7 @@ SET @@global.debug_dbug=@saved_dbug; START SLAVE io_thread; --source include/wait_for_slave_io_to_start.inc -sync_with_master; +--source include/sync_with_master_gtid.inc SELECT * FROM t1; --echo # Case 2 : Start slave with IGNORE_DOMAIN_IDS=(), then restart @@ -112,7 +113,7 @@ let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Igno CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; --source include/start_slave.inc -sync_with_master; +--source include/sync_with_master_gtid.inc let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); @@ -140,7 +141,7 @@ INSERT INTO t1 VALUES(10); INSERT INTO t1 VALUES(11); COMMIT; -save_master_pos; +--source include/save_master_gtid.inc SELECT * FROM t1; connection slave; @@ -157,7 +158,7 @@ let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Igno CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; --source include/start_slave.inc -sync_with_master; +--source include/sync_with_master_gtid.inc let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); @@ -178,7 +179,7 @@ let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Igno CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; --source include/start_slave.inc -sync_with_master; +--source include/sync_with_master_gtid.inc let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); @@ -196,6 +197,15 @@ INSERT INTO t1 VALUES(12); INSERT INTO t1 VALUES(13); COMMIT; # IO thread gets killed here. +# MDEV-14357 +# As the prior transaction will be ignored on slave because its domain id is +# ignored, the replica's gtid_slave_pos will be updated to have seen it, +# despite its eventual failure to queue the whole transaction to the relay log. +# So for test consistency, we need to synchronize the SQL thread with this +# position; otherwise, when restarting the server after resetting +# IGNORE_DOMAIN_IDS, we will re-fetch this event and execute it. +--source include/save_master_gtid.inc + START TRANSACTION; INSERT INTO t1 VALUES(14); INSERT INTO t1 VALUES(15); @@ -207,7 +217,6 @@ INSERT INTO t1 VALUES(16); INSERT INTO t1 VALUES(17); COMMIT; -save_master_pos; SELECT * FROM t1; connection slave; @@ -217,6 +226,11 @@ SELECT * FROM t1; SET @@global.debug_dbug=@saved_dbug; +# MDEV-14357 +# Ensure the SQL thread is updated with the GTID of the ignored transaction +# so we don't fetch it and execute it after restarting without any ignored +# domain ids. +--source include/sync_with_master_gtid.inc --source include/stop_slave_sql.inc let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); @@ -224,8 +238,12 @@ let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Igno --echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; + +--connection master +--source include/save_master_gtid.inc +--connection slave --source include/start_slave.inc -sync_with_master; +--source include/sync_with_master_gtid.inc let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); @@ -246,7 +264,7 @@ let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Igno CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; --source include/start_slave.inc -sync_with_master; +--source include/sync_with_master_gtid.inc let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); @@ -264,6 +282,11 @@ INSERT INTO t1 VALUES(18); INSERT INTO t1 VALUES(19); # IO thread gets killed here. COMMIT; +# MDEV-14357 +# Synchronize gtid_slave_pos with the ignored event. See prior comments about +# MDEV-14357 for details. +--source include/save_master_gtid.inc + START TRANSACTION; INSERT INTO t1 VALUES(20); INSERT INTO t1 VALUES(21); @@ -275,7 +298,6 @@ INSERT INTO t1 VALUES(22); INSERT INTO t1 VALUES(23); COMMIT; -save_master_pos; SELECT * FROM t1; connection slave; @@ -285,6 +307,10 @@ SELECT * FROM t1; SET @@global.debug_dbug=@saved_dbug; +# MDEV-14357 +# Synchronize gtid_slave_pos with the ignored event. See prior comments about +# MDEV-14357 for details. +--source include/sync_with_master_gtid.inc --source include/stop_slave_sql.inc let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); @@ -292,8 +318,12 @@ let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Igno --echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; + +--connection master +--source include/save_master_gtid.inc +--connection slave --source include/start_slave.inc -sync_with_master; +--source include/sync_with_master_gtid.inc let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); @@ -314,7 +344,7 @@ let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Igno CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; --source include/start_slave.inc -sync_with_master; +--source include/sync_with_master_gtid.inc let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); @@ -343,7 +373,7 @@ INSERT INTO t1 VALUES(28); INSERT INTO t1 VALUES(29); COMMIT; -save_master_pos; +--source include/save_master_gtid.inc SELECT * FROM t1; connection slave; @@ -361,7 +391,7 @@ let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Igno CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; --source include/start_slave.inc -sync_with_master; +--source include/sync_with_master_gtid.inc let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); diff --git a/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test b/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test index cdfdc098f5a..19074ce9a84 100644 --- a/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test +++ b/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test @@ -6,9 +6,12 @@ connection master; +--disable_query_log call mtr.add_suppression("mysqld: Table '.*gtid_slave_pos' is marked as crashed and should be repaired"); call mtr.add_suppression("Checking table: './mysql/gtid_slave_pos'"); call mtr.add_suppression("mysql.gtid_slave_pos: 1 client is using or hasn't closed the table properly"); +call mtr.add_suppression("Could not read packet:.* errno: 11"); +--enable_query_log SET @@session.gtid_domain_id= 0; create table ti (a int auto_increment primary key) engine=innodb; @@ -39,7 +42,7 @@ insert into ti set a=null; insert into tm set a=null; set @@global.debug_dbug="+d,crash_before_send_xid"; ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect connection slave; let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); @@ -61,7 +64,7 @@ connection master; --enable_reconnect --let $rpl_server_number=1 --source include/rpl_start_server.inc -#--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +#--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --source include/wait_until_connected_again.inc --echo # Master has restarted successfully save_master_pos; diff --git a/mysql-test/suite/rpl/t/rpl_domain_id_filter_restart.test b/mysql-test/suite/rpl/t/rpl_domain_id_filter_restart.test index 8083b8f232f..38cbbdec7f3 100644 --- a/mysql-test/suite/rpl/t/rpl_domain_id_filter_restart.test +++ b/mysql-test/suite/rpl/t/rpl_domain_id_filter_restart.test @@ -35,9 +35,10 @@ SET @@session.gtid_domain_id= 1; INSERT INTO t2 VALUES(1); SELECT * FROM t2; -sync_slave_with_master; +source include/save_master_gtid.inc; connection slave; +source include/sync_with_master_gtid.inc; SELECT * FROM t1; SELECT * FROM t2; diff --git a/mysql-test/suite/rpl/t/rpl_dump_request_retry_warning.test b/mysql-test/suite/rpl/t/rpl_dump_request_retry_warning.test index 1ee043623ae..633071a89b3 100644 --- a/mysql-test/suite/rpl/t/rpl_dump_request_retry_warning.test +++ b/mysql-test/suite/rpl/t/rpl_dump_request_retry_warning.test @@ -30,6 +30,10 @@ --let $rpl_skip_start_slave=1 --source include/master-slave.inc +--disable_query_log +call mtr.add_suppression("Could not read packet:.* errno: 11"); +--enable_query_log + # Do an insert on master CREATE TABLE t1(a int); INSERT INTO t1 VALUES(1); diff --git a/mysql-test/suite/rpl/t/rpl_get_lock.test b/mysql-test/suite/rpl/t/rpl_get_lock.test index b5c08858055..c6f2f6ec83b 100644 --- a/mysql-test/suite/rpl/t/rpl_get_lock.test +++ b/mysql-test/suite/rpl/t/rpl_get_lock.test @@ -1,6 +1,17 @@ source include/master-slave.inc; +--disable_query_log CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +call mtr.add_suppression("Could not read packet:.* errno: 11 "); +# The following one comes from calling dirty_close on client side +call mtr.add_suppression("Could not read packet:.* errno: 2 "); +call mtr.add_suppression("Could not read packet:.* errno: 35 "); +--enable_query_log + +let $org_log_warnings=`select @@global.log_warnings`; + +# Test extended warnings +SET GLOBAL LOG_WARNINGS=4; create table t1(n int); # Use of get_lock gives a warning for unsafeness if binlog_format=statement @@ -41,6 +52,10 @@ connection master1; drop table t1; sync_slave_with_master; +connection default; +--disable_query_log +--eval SET GLOBAL LOG_WARNINGS=$org_log_warnings; +--enable_query_log --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash-slave.opt b/mysql-test/suite/rpl/t/rpl_gtid_crash-slave.opt index 69c1a64e388..5b3fb44c910 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_crash-slave.opt +++ b/mysql-test/suite/rpl/t/rpl_gtid_crash-slave.opt @@ -1 +1 @@ ---master-retry-count=100 +--master-retry-count=100 --slave-net-timeout=10 diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash.test b/mysql-test/suite/rpl/t/rpl_gtid_crash.test index 283298318be..e1a57f4b725 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_crash.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_crash.test @@ -12,6 +12,7 @@ call mtr.add_suppression("Checking table:"); call mtr.add_suppression("client is using or hasn't closed the table properly"); call mtr.add_suppression("Table .* is marked as crashed and should be repaired"); +call mtr.add_suppression("Could not read packet:.* errno: 11"); flush tables; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam.test b/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam.test index faf388f5bed..e113e17b7ec 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam.test @@ -5,6 +5,10 @@ --let $rpl_topology=1->2 --source include/rpl_init.inc +--disable_query_log +call mtr.add_suppression("Could not read packet:.* errno: 11"); +--enable_query_log + --echo *** Test crashing master with InnoDB disabled, the binlog gtid state should still be correctly recovered. *** --connection server_1 diff --git a/mysql-test/suite/rpl/t/rpl_gtid_grouping.test b/mysql-test/suite/rpl/t/rpl_gtid_grouping.test index 66448c4f96c..bb1057a6e4f 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_grouping.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_grouping.test @@ -93,5 +93,4 @@ CHANGE MASTER TO MASTER_USE_GTID=no; --connection master DROP TABLE t; -SET GLOBAL LOG_WARNINGS=default; --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_header_valid.test b/mysql-test/suite/rpl/t/rpl_gtid_header_valid.test new file mode 100644 index 00000000000..d4d75ba8928 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_header_valid.test @@ -0,0 +1,213 @@ +# +# This test ensures that, when a GTID event is constructed by reading its +# content from a binlog file, the reader (e.g. replica, in this test) cannot +# read beyond the length of the GTID event. That is, we ensure that the +# structure indicated by its flags and extra_flags are consistent with the +# actual content of the event. +# +# To spoof a broken GTID log event, we use the DEBUG_DBUG mechanism to inject +# the master to write invalid GTID events for each flag. The transaction is +# given a commit id to ensure the event is not shorter than GTID_HEADER_LEN, +# which would result in zero padding up to GTID_HEADER_LEN. +# +# +# References: +# MDEV-33672: Gtid_log_event Construction from File Should Ensure Event +# Length When Using Extra Flags +# + +--source include/have_debug.inc + +# GTID event extra_flags are format independent +--source include/have_binlog_format_row.inc +--source include/have_innodb.inc +--source include/master-slave.inc + +--echo # +--echo # Initialize test data +--connection master +create table t1 (a int) engine=innodb; +--source include/save_master_gtid.inc +set @@SESSION.debug_dbug= "+d,binlog_force_commit_id"; + +--connection slave +set SQL_LOG_BIN= 0; +call mtr.add_suppression('Found invalid event in binary log'); +call mtr.add_suppression('Slave SQL.*Relay log read failure: Could not parse relay log event entry.* 1594'); +set SQL_LOG_BIN= 1; +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +--source include/start_slave.inc +--let $cid_ctr= 100 + + +--echo # +--echo # Test FL_PREPARED_XA +--connection master +set @@SESSION.debug_dbug= "+d,negate_xid_from_gtid"; +--eval set @commit_id= $cid_ctr + +XA START 'x1'; +insert into t1 values (1); +XA END 'x1'; +XA PREPARE 'x1'; +set @@SESSION.debug_dbug= "-d,negate_xid_from_gtid"; +XA COMMIT 'x1'; +--source include/save_master_gtid.inc + +--echo # Waiting for slave to find invalid event.. +--connection slave +let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE +source include/wait_for_slave_sql_error.inc; +STOP SLAVE IO_THREAD; + +--echo # Reset master binlogs (as there is an invalid event) and slave state +--connection master +RESET MASTER; +--connection slave +RESET MASTER; +RESET SLAVE; +set @@global.gtid_slave_pos=""; +--source include/start_slave.inc + + +--echo # +--echo # Test FL_COMPLETED_XA +--connection master +--inc $cid_ctr +--eval set @commit_id= $cid_ctr +XA START 'x1'; +--let $next_val = `SELECT max(a)+1 FROM t1` +--eval insert into t1 values ($next_val) +XA END 'x1'; +XA PREPARE 'x1'; +set @@SESSION.debug_dbug= "+d,negate_xid_from_gtid"; +XA COMMIT 'x1'; +set @@SESSION.debug_dbug= "-d,negate_xid_from_gtid"; +--source include/save_master_gtid.inc + +--echo # Waiting for slave to find invalid event.. +--connection slave +let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE +source include/wait_for_slave_sql_error.inc; +STOP SLAVE IO_THREAD; + +--echo # Cleanup hanging XA PREPARE on slave +set statement SQL_LOG_BIN=0 for XA COMMIT 'x1'; + +--echo # Reset master binlogs (as there is an invalid event) and slave state +--connection master +RESET MASTER; +--connection slave +RESET MASTER; +RESET SLAVE; +set @@global.gtid_slave_pos=""; +--source include/start_slave.inc + + +--echo # +--echo # Test Missing xid.data (but has format id and length description parts) + +--connection master +--eval set @commit_id= $cid_ctr + +XA START 'x1'; +insert into t1 values (1); +XA END 'x1'; +XA PREPARE 'x1'; +set @@SESSION.debug_dbug= "+d,negate_xid_data_from_gtid"; +XA COMMIT 'x1'; +set @@SESSION.debug_dbug= "-d,negate_xid_data_from_gtid"; +--source include/save_master_gtid.inc + +--echo # Waiting for slave to find invalid event.. +--connection slave +let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE +source include/wait_for_slave_sql_error.inc; +STOP SLAVE IO_THREAD; + +--echo # Cleanup hanging XA PREPARE on slave +set statement SQL_LOG_BIN=0 for XA COMMIT 'x1'; + +--echo # Reset master binlogs (as there is an invalid event) and slave state +--connection master +RESET MASTER; +--connection slave +RESET MASTER; +RESET SLAVE; +set @@global.gtid_slave_pos=""; +--source include/start_slave.inc + + +--echo # +--echo # Test FL_EXTRA_MULTI_ENGINE +--connection master +set @old_dbug= @@SESSION.debug_dbug; +set @@SESSION.debug_dbug= "+d,inject_fl_extra_multi_engine_into_gtid"; +--inc $cid_ctr +--eval set @commit_id= $cid_ctr +--let $next_val = `SELECT max(a)+1 FROM t1` +--eval insert into t1 values ($next_val) +--source include/save_master_gtid.inc +set @@SESSION.debug_dbug=@old_dbug; + +--connection slave +--echo # Waiting for slave to find invalid event.. +let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE +source include/wait_for_slave_sql_error.inc; +STOP SLAVE IO_THREAD; + +--echo # Reset master binlogs (as there is an invalid event) and slave state +--connection master +RESET MASTER; + +--connection slave +RESET SLAVE; +RESET MASTER; +set @@global.gtid_slave_pos=""; +--source include/start_slave.inc + + +--echo # +--echo # Test FL_COMMIT_ALTER +--connection master +set @old_dbug= @@SESSION.debug_dbug; +set @@SESSION.debug_dbug= "+d,negate_alter_fl_from_gtid"; +set @old_alter_tp= @@SESSION.binlog_alter_two_phase; +set @@SESSION.binlog_alter_two_phase= 1; +alter table t1 add column (nc int); +--source include/save_master_gtid.inc +set @@SESSION.debug_dbug=@old_dbug; +set @@SESSION.binlog_alter_two_phase=@old_alter_tp; + +--connection slave +--echo # Waiting for slave to find invalid event.. +let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE +source include/wait_for_slave_sql_error.inc; +STOP SLAVE IO_THREAD; + +--echo # Reset master binlogs (as there is an invalid event) and slave state +--connection master +RESET MASTER; + +--connection slave +# Just to keep tables consistent between master/slave +SET STATEMENT sql_log_bin=0 FOR alter table t1 add column (nc int); +RESET SLAVE; +RESET MASTER; +set @@global.gtid_slave_pos=""; +--source include/start_slave.inc + + +--echo # +--echo # Cleanup + +--connection master +drop table t1; +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc + +--source include/rpl_end.inc +--echo # End of rpl_gtid_header_valid.test diff --git a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test index b5ff294908b..acce6651b8d 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test @@ -173,6 +173,24 @@ SELECT * FROM t1 ORDER BY a; --echo *** MDEV-4486: Allow to start old-style replication even if mysql.gtid_slave_pos is unavailable +# In GTID mode, the old-style replication position is also updated. But during +# GTID connect, the old-style position is not known until receiving the fake +# GTID list event, which contains the required position value. If we happened +# to stop the slave above before this fake GTID list event, the test could fail +# with duplicate key errors due to switching to non-GTID mode at a wrong +# position too far back in the binlog. +# +# Work-around this by injecting an extra dummt event and syncing the slave to +# it, ensuring the old-style position will be updated. +# +# This work-around could be removed after MDEV-33996 is fixed. +--connection server_1 +INSERT INTO t1 VALUES (8); +DELETE FROM t1 WHERE a=8; +--save_master_pos +--connection server_2 +--sync_with_master + --connection server_2 --source include/stop_slave.inc CHANGE MASTER TO master_use_gtid= no; diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat.test b/mysql-test/suite/rpl/t/rpl_heartbeat.test index a04ba4c58e4..a34cf761c8a 100644 --- a/mysql-test/suite/rpl/t/rpl_heartbeat.test +++ b/mysql-test/suite/rpl/t/rpl_heartbeat.test @@ -8,14 +8,13 @@ # - SHOW STATUS like 'Slave_heartbeat_period' report -- source include/have_log_bin.inc - -connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); -connect (slave,localhost,root,,test,$SLAVE_MYPORT,$SLAVE_MYSOCK); +-- source include/master-slave.inc connection master; reset master; connection slave; +-- source include/stop_slave.inc set @restore_slave_net_timeout= @@global.slave_net_timeout; --disable_warnings set @@global.slave_net_timeout= 10; @@ -170,6 +169,5 @@ set @@global.slave_net_timeout= @restore_slave_net_timeout; --disable_prepare_warnings ---source include/stop_slave.inc - +--source include/rpl_end.inc --echo End of tests diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test b/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test index bd66a249ada..e593786655b 100644 --- a/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test +++ b/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test @@ -3,6 +3,12 @@ --source include/have_debug.inc --source include/master-slave.inc +--disable_query_log +CALL mtr.add_suppression('SET @master_heartbeat_period to master failed with error'); +CALL mtr.add_suppression('Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again'); +call mtr.add_suppression("Could not read packet:.* errno: 11"); +--enable_query_log + connection slave; --source include/stop_slave.inc set @restore_slave_net_timeout= @@global.slave_net_timeout; @@ -14,14 +20,13 @@ set @@global.slave_net_timeout= 10; ### Checking the range ### -# + # default period slave_net_timeout/2 # --query_vertical show status like 'Slave_heartbeat_period'; SET @saved_dbug= @@GLOBAL.debug_dbug; SET GLOBAL debug_dbug="+d,simulate_slave_heartbeat_network_error"; -CALL mtr.add_suppression('SET @master_heartbeat_period to master failed with error'); -CALL mtr.add_suppression('Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again'); + --source include/start_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_mdev33798.cnf b/mysql-test/suite/rpl/t/rpl_mdev33798.cnf new file mode 100644 index 00000000000..8e5125ea6ca --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev33798.cnf @@ -0,0 +1,17 @@ +!include suite/rpl/my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb + +[mysqld.3] +log-slave-updates +loose-innodb + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket diff --git a/mysql-test/suite/rpl/t/rpl_mdev33798.test b/mysql-test/suite/rpl/t/rpl_mdev33798.test new file mode 100644 index 00000000000..76d2de261db --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev33798.test @@ -0,0 +1,182 @@ +--source include/have_innodb.inc +--source include/have_log_bin.inc +--let $rpl_topology=1->2,1->3 +--source include/rpl_init.inc +--connect (server_2b,127.0.0.1,root,,,$SERVER_MYPORT_2) + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode= @@GLOBAL.slave_parallel_mode; +SET @old_timeout= @@GLOBAL.lock_wait_timeout; +SET @old_innodb_timeout= @@GLOBAL.innodb_lock_wait_timeout; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=5; +set global slave_parallel_mode= aggressive; +# High timeout so we get replication sync error and test failure if the +# conflict handling is insufficient and lock wait timeout occurs. +SET GLOBAL lock_wait_timeout= 86400; +SET GLOBAL innodb_lock_wait_timeout= 86400; +SET STATEMENT sql_log_bin=0 FOR ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +--source include/start_slave.inc + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0), (8, 0); +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc + +# Test the following scenario: +# +# Transactions T1, T2 in domain 1, U1, U2 in domain 2. +# Wait cycle T1->U2->U1->T2->T1 as follows: +# T1 row lock wait on U2 +# U2 wait_for_prior_commit on U1 +# U1 row lock wait on T2 +# T2 wait_for_prior_commit on T1 +# +# Test that the wait cycle is broken correctly with deadlock kill. + +--connection server_2b +# Temporarily block T1 and U1. +BEGIN; +SELECT * FROM t1 WHERE a=1 FOR UPDATE; +SELECT * FROM t1 WHERE a=5 FOR UPDATE; + +--connection server_1 + +SET SESSION gtid_domain_id= 1; +# T1 in domain 1 +BEGIN; +UPDATE t1 SET b=1 WHERE a=1; +UPDATE t1 SET b=1 WHERE a=7; +COMMIT; +# T2 in domain 1 +UPDATE t1 SET b=2 WHERE a=3; + +SET SESSION gtid_domain_id=2; +# U1 in domain 2 +BEGIN; +UPDATE t1 SET b=3 WHERE a=5; +UPDATE t1 SET b=3 WHERE a=3; +COMMIT; +# U2 in domain 2 +UPDATE t1 SET b=4 WHERE a=7; +SET SESSION gtid_domain_id= 0; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +# Wait until T2, U2 are holding the row locks. +--let $wait_condition= SELECT COUNT(*)=2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE state LIKE '%Waiting for prior transaction to commit%' +--source include/wait_condition.inc + +# Then let T1, U1 continue to conflict on the row locks, and check that +# replication correctly handles the conflict. +--connection server_2b +ROLLBACK; + +--connection server_2 +--source include/sync_with_master_gtid.inc + +# Allow either domain to "win" on the conflicting updates. +SELECT a, ( + (a=1 AND b=1) OR + (a=3 AND (b=2 OR b=3)) OR + (a=5 AND b=3) OR + (a=7 AND (b=1 OR b=4)) OR + ((a MOD 2)=0 AND b=0)) AS `ok` + FROM t1 + ORDER BY a; + +# Now try the same thing with multi-source replication. + +# Make server_3 a second master +--connection server_3 +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc + +--connection server_2 +--source include/stop_slave.inc +--replace_result $SERVER_MYPORT_3 MYPORT_3 +eval CHANGE MASTER 'm2' to master_port=$SERVER_MYPORT_3 , master_host='127.0.0.1', master_user='root', master_use_gtid=slave_pos, master_ssl_verify_server_cert=0; + +--connection server_1 + +SET SESSION gtid_domain_id= 1; +# T1 in domain 1 +BEGIN; +UPDATE t1 SET b=11 WHERE a=1; +UPDATE t1 SET b=11 WHERE a=7; +COMMIT; +# T2 in domain 1 +UPDATE t1 SET b=12 WHERE a=3; +SET SESSION gtid_domain_id= 1; + +--connection server_3 +SET SESSION gtid_domain_id=3; +# U1 in domain 3 +BEGIN; +UPDATE t1 SET b=13 WHERE a=5; +UPDATE t1 SET b=13 WHERE a=3; +COMMIT; +# U2 in domain 3 +UPDATE t1 SET b=14 WHERE a=7; +--source include/save_master_gtid.inc + +--connection server_2b +# Temporarily block T1 and U1. +BEGIN; +SELECT * FROM t1 WHERE a=1 FOR UPDATE; +SELECT * FROM t1 WHERE a=5 FOR UPDATE; + +START ALL SLAVES; +# Wait until T2, U2 are holding the row locks. +--let $wait_condition= SELECT COUNT(*)=2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE state LIKE '%Waiting for prior transaction to commit%' +--source include/wait_condition.inc + +--connection server_2b +ROLLBACK; + +--connection server_1 +--source include/save_master_gtid.inc +--connection server_2 +--source include/sync_with_master_gtid.inc +--connection server_3 +--source include/save_master_gtid.inc +--connection server_2 +--source include/sync_with_master_gtid.inc + +SELECT a, ( + (a=1 AND b=11) OR + (a=3 AND (b=12 OR b=13)) OR + (a=5 AND b=13) OR + (a=7 AND (b=11 OR b=14)) OR + ((a MOD 2)=0 AND b=0)) AS `ok` + FROM t1 + ORDER BY a; + +SET default_master_connection = 'm2'; +--source include/stop_slave.inc +RESET SLAVE 'm2' ALL; +SET default_master_connection = ''; + +--connection server_3 +--source include/start_slave.inc + +# Cleanup + +--disconnect server_2b +--connection server_1 +DROP TABLE t1; +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +set global slave_parallel_mode= @old_parallel_mode; +SET GLOBAL lock_wait_timeout= @old_timeout; +SET GLOBAL innodb_lock_wait_timeout= @old_innodb_timeout; +--source include/start_slave.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mysql_manager_race_condition.test b/mysql-test/suite/rpl/t/rpl_mysql_manager_race_condition.test index 751da3158b7..dd4a0fbbc99 100644 --- a/mysql-test/suite/rpl/t/rpl_mysql_manager_race_condition.test +++ b/mysql-test/suite/rpl/t/rpl_mysql_manager_race_condition.test @@ -18,8 +18,14 @@ # associated with this test should enforce that the binlog background thread is # not created before the handle manager is initialized. # +# Addendum 1) This test is extended for MDEV-33799, as the original fix +# left out the possibility that the binlog background thread can be +# started during recovery if the binary log is used as the transaction +# coordinator. This resulted in similar segfaults as seen by MDEV-26473. +# # References: # MDEV-26473 mysqld got exception 0xc0000005 (rpl_slave_state/rpl_load_gtid_slave_state) +# MDEV-33799 mysql_manager_submit Segfault at Startup Still Possible During Recovery # --source include/have_debug.inc @@ -53,6 +59,63 @@ create table t1 (a int); --source include/start_slave.inc +--echo # +--echo # MDEV-33799 +--echo # Ensure that when the binary log is used for recovery (as tc log), that +--echo # the recovery process cannot start the binlog background thread before +--echo # the mysql handle manager has started. +--connection slave + +--echo # Add test suppresssions so crash recovery messages don't fail the test +set session sql_log_bin=0; +call mtr.add_suppression("mariadbd: Got error '145.*"); +call mtr.add_suppression("Checking table:.*"); +call mtr.add_suppression("mysql.gtid_slave_pos:.*hasn't closed the table properly"); +call mtr.add_suppression("Can't init tc log"); +call mtr.add_suppression("Aborting"); +set session sql_log_bin=1; + +--echo # Create slave-side only table +create table t2 (a int) engine=innodb; + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF + +--echo # Crash mariadbd when binlogging transaction to corrupt database state +--connection slave1 +set @@session.debug_dbug="+d,crash_before_writing_xid"; +--send insert into t2 values (1) + +--connection slave +--source include/wait_until_disconnected.inc + +--connection slave1 +--error 2013,ER_CONNECTION_KILLED +--reap + +--echo # Restart mariadbd in recovery mode. Note --tc-heuristic-recover +--echo # forces mysqld to exit with error, so we run mariadbd via CLI +--echo # MYSQLD_LAST_CMD --debug_dbug="+d,delay_start_handle_manager" --tc-heuristic-recover=COMMIT +--error 1 +--exec $MYSQLD_LAST_CMD --debug_dbug="+d,delay_start_handle_manager" --tc-heuristic-recover=COMMIT + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart +EOF + +--connection server_2 +--enable_reconnect +--source include/wait_until_connected_again.inc +--connection slave1 +--enable_reconnect +--source include/wait_until_connected_again.inc +--connection slave +--enable_reconnect +--source include/wait_until_connected_again.inc +--source include/start_slave.inc + + --echo # --echo # Cleanup --echo # @@ -63,5 +126,6 @@ drop table t1; --connection slave --source include/sync_with_master_gtid.inc +drop table t2; --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_packet.test b/mysql-test/suite/rpl/t/rpl_packet.test index cbde486bcbb..f1814e61f9b 100644 --- a/mysql-test/suite/rpl/t/rpl_packet.test +++ b/mysql-test/suite/rpl/t/rpl_packet.test @@ -20,6 +20,9 @@ source include/master-slave.inc; call mtr.add_suppression("Slave I/O: Got a packet bigger than 'slave_max_allowed_packet' bytes, .*error.* 1153"); call mtr.add_suppression("Log entry on master is longer than slave_max_allowed_packet"); +call mtr.add_suppression("Could not write packet:"); +call mtr.add_suppression("Got a packet bigger than 'max_allowed_packet' bytes"); + let $db= DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________; disable_warnings; eval drop database if exists $db; diff --git a/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test b/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test index c5d2b85cf34..c34c4f20dc0 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test @@ -300,7 +300,7 @@ SET GLOBAL slave_parallel_threads=10; # Find the thread id of the driver SQL thread that we want to kill. --let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%Slave has read all relay log%' --source include/wait_condition.inc ---let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%Slave has read all relay log%'` +--let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%relay log%'` SET @old_max_queued= @@GLOBAL.slave_parallel_max_queued; SET GLOBAL slave_parallel_max_queued=9000; diff --git a/mysql-test/suite/rpl/t/rpl_parallel_multi_domain_xa.test b/mysql-test/suite/rpl/t/rpl_parallel_multi_domain_xa.test new file mode 100644 index 00000000000..f17634d4df8 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_multi_domain_xa.test @@ -0,0 +1,181 @@ +# Similar to rpl_parallel_optimistic_xa to verify XA +# parallel execution with multiple gtid domain. +# References: +# MDEV-33668 Adapt parallel slave's round-robin scheduling to XA events + +--source include/have_innodb.inc +--source include/have_perfschema.inc +--source include/master-slave.inc + +# Tests' global declarations +--let $trx = _trx_ +--let $slave_timeout= -1 + +call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction"); +call mtr.add_suppression("WSREP: handlerton rollback failed"); + +--connection master +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +--save_master_pos + +# Prepare to restart slave into optimistic parallel mode +--connection slave +--sync_with_master +--source include/stop_slave.inc +# This test runs huge number of transactions independently in parallel that +# all conflict on a single row. This requires a large number of retries, as a +# transaction can repeatedly conflict/deadlock with a large number of other +# transactions (in a different domain) one by one. +SET @old_transaction_retries = @@GLOBAL.slave_transaction_retries; +SET @@global.slave_transaction_retries = 1000; +SET @old_parallel_threads = @@GLOBAL.slave_parallel_threads; +SET @old_slave_domain_parallel_threads = @@GLOBAL.slave_domain_parallel_threads; +SET @@global.slave_parallel_threads = 5; +SET @@global.slave_domain_parallel_threads = 3; +SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode; + +CHANGE MASTER TO master_use_gtid=slave_pos; + +--connection master +CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, 0); +--source include/save_master_gtid.inc + +--connection slave +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc + +--let $mode = 2 +# mode = 2 is optimistic +SET @@global.slave_parallel_mode ='optimistic'; +while ($mode) +{ + --connection master + # + # create XA events alternating gtid domains to run them in parallel on slave. + # + --let $domain_num = 3 + --let $trx_num = 777 + --let $i = $trx_num + --let $conn = master + --disable_query_log + while($i > 0) + { + --let $domain_id = `SELECT $i % $domain_num` + --eval set @@gtid_domain_id = $domain_id + # 'decision' to commit 0, or rollback 1 + --let $decision = `SELECT $i % 2` + --eval XA START '$conn$trx$i' + --eval UPDATE t1 SET b = 1 - 2 * $decision WHERE a = 1 + --eval XA END '$conn$trx$i' + --eval XA PREPARE '$conn$trx$i' + --let $term = COMMIT + if ($decision) + { + --let $term = ROLLBACK + } + --eval XA $term '$conn$trx$i' + + --dec $i + } + --enable_query_log + --source include/save_master_gtid.inc + + --connection slave + if (`select $mode = 1`) + { + SET @@global.slave_parallel_mode ='conservative'; + } + --source include/start_slave.inc + --source include/sync_with_master_gtid.inc + --source include/stop_slave.inc + + --dec $mode +} + + +# Generations test. +# Create few ranges of XAP groups length of greater than +# 3 * slave_parallel_threads + 1 +# terminated upon each range. +--let $iter = 3 +--let $generation_len = @@global.slave_parallel_threads +--let $domain_num = 3 +--disable_query_log +--connection master +while ($iter) +{ + --let $k = `select 3 * 3 * $generation_len` + --let $_k = $k + while ($k) + { + --source include/count_sessions.inc + --connect(con$k,localhost,root,,) + # + # create XA events alternating gtid domains to run them in parallel on slave. + # + --let $domain_id = `SELECT $k % $domain_num` + --eval set @@gtid_domain_id = $domain_id + --eval XA START '$trx$k' + --eval INSERT INTO t1 VALUES ($k + 1, $iter) + --eval XA END '$trx$k' + --eval XA PREPARE '$trx$k' + + --disconnect con$k + --connection master + --source include/wait_until_count_sessions.inc + + --dec $k + } + + --connection master + --let $k = $_k + while ($k) + { + --let $term = COMMIT + --let $decision = `SELECT $k % 2` + if ($decision) + { + --let $term = ROLLBACK + } + --eval XA $term '$trx$k' + } + --dec $iter +} +--enable_query_log +--source include/save_master_gtid.inc + +--connection slave +SET @@global.slave_parallel_mode = 'optimistic'; +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + + +# +# Overall consistency check +# +--let $diff_tables= master:t1, slave:t1 +--source include/diff_tables.inc + + +# +# Clean up. +# +--connection slave +--source include/stop_slave.inc +SET @@global.slave_parallel_mode = @old_parallel_mode; +SET @@global.slave_parallel_threads = @old_parallel_threads; +SET @@global.slave_domain_parallel_threads = @old_slave_domain_parallel_threads; +SET @@global.slave_transaction_retries = @old_transaction_retries; +--source include/start_slave.inc + +--connection master +DROP TABLE t1; +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc + +--connection master +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test b/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test index 81c787bba5b..2cf18cd2756 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test @@ -508,6 +508,7 @@ DELETE FROM t2; # The 1st of the following two trx:s a blocker on slave --connection server_2 +SET @org_log_warnings=@@GLOBAL.LOG_WARNINGS; set global log_warnings=2; BEGIN; INSERT INTO t1 SET a=1; @@ -555,7 +556,7 @@ DELETE FROM t2; # --connection server_2 --source include/stop_slave.inc -set global log_warnings=default; +set global log_warnings=@org_log_warnings; SET GLOBAL slave_parallel_mode=@old_parallel_mode; SET GLOBAL slave_parallel_threads=@old_parallel_threads; --source include/start_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa.test b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa.test index 35c22d1e92e..6e5cf4367a7 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa.test @@ -206,7 +206,6 @@ while($i > 0) # --connection slave --source include/stop_slave.inc -set global log_warnings=default; SET GLOBAL slave_parallel_mode=@old_parallel_mode; SET GLOBAL slave_parallel_threads=@old_parallel_threads; --source include/start_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_retry.test b/mysql-test/suite/rpl/t/rpl_parallel_retry.test index fe6f40d2c85..1e87c85cd6c 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_retry.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_retry.test @@ -410,6 +410,44 @@ DROP function foo; --sync_slave_with_master server_2 +# +# MDEV-33303: slave_parallel_mode=optimistic should not report the mode's +# specific temporary errors. +# + +--connection server_2 +--source include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=4; + +--connection server_1 +# The problem occurred in the code path for row-based updates in tables +# with no primary/unique key, where a scan is needed. +CREATE TABLE t1 (a INT, b VARCHAR(123)) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, 'asdf'); +UPDATE t1 SET b='zxf1' WHERE a=1; +UPDATE t1 SET b='\n' WHERE a=1; + +--connection server_2 +# Inject a small sleep in the code that makes the race easier to hit. +SET @old_dbug=@@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,write_row_inject_sleep_before_ha_write_row"; +--source include/start_slave.inc + +--connection server_1 +# Here, we would get errors in the slave's error log: +# [ERROR] mariadbd: Can't find record in 't1' +--sync_slave_with_master server_2 + +--connection server_1 +DROP TABLE t1; +--sync_slave_with_master server_2 +--source include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + + # # MDEV-12746 rpl.rpl_parallel_optimistic_nobinlog fails committing out of order at retry # diff --git a/mysql-test/suite/rpl/t/rpl_parallel_sbm.test b/mysql-test/suite/rpl/t/rpl_parallel_sbm.test index 58c0db15e47..90753caf143 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_sbm.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_sbm.test @@ -1,9 +1,9 @@ # # Ensure that Seconds_Behind_Master works correctly on the parallel replica. # ---source include/master-slave.inc --source include/have_log_bin.inc --source include/have_debug.inc +--source include/master-slave.inc --echo # --echo # MDEV-29639: Seconds_Behind_Master is incorrect for Delayed, Parallel Replicas @@ -67,11 +67,18 @@ if (`SELECT $sbm_trx1_arrive > ($seconds_since_idling + 1)`) --echo # if the event is still to be delayed, SBM should resume accordingly --source include/stop_slave.inc + +--echo # Lock t1 on slave to ensure the event can't finish (and thereby update +--echo # Seconds_Behind_Master) so slow running servers don't accidentally +--echo # catch up to the master before checking SBM. +--connection server_2 +LOCK TABLES t1 WRITE; + --source include/start_slave.inc --connection slave ---echo # Waiting for replica to resume the delay for the transaction ---let $wait_condition= SELECT count(*) FROM information_schema.processlist WHERE state LIKE 'Waiting until MASTER_DELAY seconds after master executed event'; +--echo # Waiting for replica to get blocked by the table lock +--let $wait_condition= SELECT count(*) FROM information_schema.processlist WHERE state LIKE 'Waiting for table metadata lock'; --source include/wait_condition.inc --echo # Sleeping 1s to increment SBM @@ -86,6 +93,9 @@ if (`SELECT $sbm_trx1_after_1s_sleep <= $sbm_trx1_arrive`) } --echo # ..done +--connection server_2 +UNLOCK TABLES; + --source include/sync_with_master_gtid.inc --echo # diff --git a/mysql-test/suite/rpl/t/rpl_parallel_seq.test b/mysql-test/suite/rpl/t/rpl_parallel_seq.test index b1b15412b16..cc361a7b35b 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_seq.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_seq.test @@ -195,4 +195,22 @@ DROP TABLE ti; --sync_slave_with_master +# MDEV-31779 server crash in Rows_log_event::update_sequence at replaying binlog +--connection master +--let $binlog_file = query_get_value(SHOW MASTER STATUS, File, 1) +--let $binlog_start = query_get_value(SHOW MASTER STATUS, Position, 1) +CREATE SEQUENCE s; +--disable_ps2_protocol +SELECT NEXTVAL(s); +--enable_ps2_protocol +flush binary logs; +DROP SEQUENCE s; +--exec $MYSQL_BINLOG $datadir/$binlog_file | $MYSQL test +DROP SEQUENCE s; + +--sync_slave_with_master + +--connection master + + --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_slave_bgc_kill.test b/mysql-test/suite/rpl/t/rpl_parallel_slave_bgc_kill.test index efb998b0443..94f19a6cdd7 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_slave_bgc_kill.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_slave_bgc_kill.test @@ -295,13 +295,14 @@ CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) || --delimiter ; SET sql_log_bin=1; - +--source include/stop_slave_io.inc --connection server_1 INSERT INTO t3 VALUES (49,0); --save_master_pos --connection server_2 -START SLAVE SQL_THREAD; +CHANGE MASTER TO master_use_gtid=no; +--source include/start_slave.inc --sync_with_master SELECT * FROM t3 WHERE a >= 40 ORDER BY a; # Restore the foo() function. @@ -334,11 +335,6 @@ SET GLOBAL slave_parallel_threads=10; --echo *** 3. Same as (2), but not using gtid mode *** ---connection server_2 ---source include/stop_slave.inc -CHANGE MASTER TO master_use_gtid=no; ---source include/start_slave.inc - --connection server_1 # Set up three transactions on the master that will be group-committed # together so they can be replicated in parallel on the slave. diff --git a/mysql-test/suite/rpl/t/rpl_parallel_stop_slave.test b/mysql-test/suite/rpl/t/rpl_parallel_stop_slave.test index 35879e98e66..1610292ecb7 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_stop_slave.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_stop_slave.test @@ -57,6 +57,7 @@ COMMIT; INSERT INTO t3 VALUES(21, 21); INSERT INTO t3 VALUES(22, 22); --save_master_pos +--let $master_pos= query_get_value(SHOW MASTER STATUS, Position, 1) # Start a connection that will block the replicated transaction halfway. --connection con_temp1 @@ -64,7 +65,27 @@ BEGIN; INSERT INTO t2 VALUES (21); --connection server_2 -START SLAVE; + +# +# Parallel replication will complete any in-progress event group at STOP SLAVE, +# but only if the event group is already queued up for the worker thread. If +# the SQL driver thread is delayed in queueing up events, the parallel worker +# thread can abort the event group, leaving the non-transactional update to the +# MyISAM table that cannot be rolled back (MDEV-7432). If this happens the test +# would fail with duplicate key error after slave restart. +# +# To avoid this, we here wait for the IO thread to read all master events, and +# for the SQL driver thread to queue all the events for workers. This wait +# should be removed if/when MDEV-7432 is fixed. +# +START SLAVE IO_THREAD; +--let $slave_param= Read_Master_Log_Pos +--let $slave_param_value= $master_pos +--source include/wait_for_slave_param.inc +START SLAVE SQL_THREAD; +--let $wait_condition= SELECT COUNT(*)=1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE State LIKE '%Slave has read all relay log; waiting for more updates%' +--source include/wait_condition.inc + # Wait for the MyISAM change to be visible, after which replication will wait # for con_temp1 to roll back. --let $wait_condition= SELECT COUNT(*) = 1 FROM t1 WHERE a=20 diff --git a/mysql-test/suite/rpl/t/rpl_parallel_temptable.test b/mysql-test/suite/rpl/t/rpl_parallel_temptable.test index 3684763dad7..8bab4af2b43 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_temptable.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_temptable.test @@ -264,6 +264,30 @@ SET GLOBAL slave_parallel_mode=@old_mode; --source include/start_slave.inc +--echo *** MDEV33426: Memory allocation accounting incorrect for replicated temptable +--connection server_1 +CREATE TEMPORARY TABLE t5 (a int) ENGINE=Aria; +CREATE TEMPORARY TABLE t6 (a int) ENGINE=Heap; +INSERT INTO t5 VALUES (1); +INSERT INTO t6 VALUES (2); +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc + +--connection server_1 +INSERT INTO t1 SELECT a+40, 5 FROM t5; +INSERT INTO t1 SELECT a+40, 6 FROM t6; +DROP TABLE t5, t6; + +--save_master_pos + +--connection server_2 +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 WHERE a>=40 ORDER BY a; + # Clean up. --connection server_2 diff --git a/mysql-test/suite/rpl/t/rpl_relay_max_extension.test b/mysql-test/suite/rpl/t/rpl_relay_max_extension.test index acca2f6954c..b6a8ccb545c 100644 --- a/mysql-test/suite/rpl/t/rpl_relay_max_extension.test +++ b/mysql-test/suite/rpl/t/rpl_relay_max_extension.test @@ -47,7 +47,7 @@ RESET SLAVE; --echo # --let $datadir = `select @@datadir` ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.2.expect --shutdown_server 10 --source include/wait_until_disconnected.inc @@ -64,7 +64,7 @@ RESET SLAVE; --echo # Restart slave server --echo # ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.2.expect --enable_reconnect --source include/wait_until_connected_again.inc SET @save_slave_parallel_threads= @@GLOBAL.slave_parallel_threads; diff --git a/mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars.test b/mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars.test index b64c2e1a7df..1b2d2be18ce 100644 --- a/mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars.test +++ b/mysql-test/suite/rpl/t/rpl_rewrite_db_sys_vars.test @@ -19,15 +19,8 @@ create database replica_db1; create database y; # This DB will be rewrited from test case create database test_replica; -SELECT @@GLOBAL.replicate_rewrite_db; let $rewrite_db_sss= query_get_value(SHOW SLAVE STATUS, Replicate_Rewrite_DB, 1); ---echo # Ensuring SHOW SLAVE STATUS produces correct value for Replicate_Rewrite_DB... -if (`SELECT strcmp(@@global.replicate_rewrite_db, "$rewrite_db_sss") != 0`) -{ - die SHOW SLAVE STATUS Replicate_Rewrite_DB value $rewrite_db_sss does not match variable @@GLOBAL.replicate_rewrite_db; -} ---echo # ...success - +eval SELECT @@GLOBAL.replicate_rewrite_db, '$rewrite_db_sss' as 'Replicate_Rewrite_DB from SHOW SLAVE STATUS'; --echo # Create DBs and tables on primary connection master; @@ -63,16 +56,10 @@ source include/stop_slave.inc; SET @save_replicate_rewrite_db = @@GLOBAL.replicate_rewrite_db; SELECT @@GLOBAL.replicate_rewrite_db; SET @@GLOBAL.replicate_rewrite_db="test_master->test_replica"; -SELECT @@GLOBAL.replicate_rewrite_db; SHOW DATABASES like 'test_replica'; source include/start_slave.inc; let $rewrite_db_sss= query_get_value(SHOW SLAVE STATUS, Replicate_Rewrite_DB, 1); ---echo # Ensuring SHOW SLAVE STATUS produces correct value for Replicate_Rewrite_DB... -if (`SELECT strcmp(@@global.replicate_rewrite_db, "$rewrite_db_sss") != 0`) -{ - die SHOW SLAVE STATUS Replicate_Rewrite_DB value $rewrite_db_sss does not match variable @@GLOBAL.replicate_rewrite_db; -} ---echo # ...success +eval SELECT @@GLOBAL.replicate_rewrite_db, '$rewrite_db_sss' as 'Replicate_Rewrite_DB from SHOW SLAVE STATUS'; --echo # Create DB and tables on primary connection master; @@ -101,6 +88,9 @@ select * from test_replica.my_table; --source include/diff_tables.inc --echo # Update of values on primary for DB not set in replication_rewrite_db +--source include/stop_slave.inc +--source include/reset_slave.inc + connection master; use x; insert into my_table values (314); @@ -108,9 +98,6 @@ select * from my_table; --source include/save_master_gtid.inc connection slave; ---let $rpl_only_running_threads=1 ---source include/stop_slave.inc ---source include/reset_slave.inc --source include/start_slave.inc SELECT @@GLOBAL.replicate_rewrite_db; --source include/sync_with_master_gtid.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_find_row_debug.test b/mysql-test/suite/rpl/t/rpl_row_find_row_debug.test index e3edabe239d..f06b2982ec5 100644 --- a/mysql-test/suite/rpl/t/rpl_row_find_row_debug.test +++ b/mysql-test/suite/rpl/t/rpl_row_find_row_debug.test @@ -51,7 +51,9 @@ DROP TABLE t1; # cleanup --source include/stop_slave.inc SET @@GLOBAL.debug_dbug = @saved_dbug; +--disable_query_log --eval SET GLOBAL log_warnings = $log_warnings_save +--enable_query_log --source include/start_slave.inc --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_cond_var_per_thd.cnf b/mysql-test/suite/rpl/t/rpl_semi_sync_cond_var_per_thd.cnf new file mode 100644 index 00000000000..1f7fa7b4428 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_cond_var_per_thd.cnf @@ -0,0 +1,7 @@ +!include ../my.cnf + +[mysqld.1] +log-warnings=9 + +[mysqld.2] +log-warnings=9 diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_cond_var_per_thd.test b/mysql-test/suite/rpl/t/rpl_semi_sync_cond_var_per_thd.test new file mode 100644 index 00000000000..0567d8a5700 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_cond_var_per_thd.test @@ -0,0 +1,101 @@ +# +# This test ensures that, when using semi-sync with the wait_point +# AFTER_COMMIT, each thread awaiting an ACK is only woken up when its ACK (or +# an ACK for a later commit in binlog) has been received from the slave. +# +# Prior to MDEV-33551, all threads would be woken up for each ACK received, +# leading to large slowdowns, as each thread would check if the ACK was for it +# in mutual exclusion from the others. +# +# To ensure this, a debug-build-only log warning is added into +# Repl_semi_sync_master::commit_trx() at wakeup time, which will complain if +# the awoken thread's binlog wait coordinates are after the coordinate of the +# last ACK coordinates. Then, we use binlog group commit to commit a series of +# transactions, such that each will await an ACK concurrently. After all +# transactions have been finished (i.e. ACKed and committed), we check the log +# for the expected absence of the added debug warning message. +# +# +# References: +# MDEV-33551: Semi-sync Wait Point AFTER_COMMIT Slow on Workloads with Heavy +# Concurrency +# +--source include/have_binlog_format_row.inc +--source include/have_debug.inc +--source include/master-slave.inc + +--connection master +call mtr.add_suppression("Got an error reading communication packets"); +call mtr.add_suppression("Could not read packet:.* vio_errno: 1158"); +call mtr.add_suppression("Could not write packet:.* vio_errno: 1160"); +set @save_semi_sync_master_enabled= @@global.rpl_semi_sync_master_enabled; +set @save_semi_sync_wp= @@global.rpl_semi_sync_master_wait_point; +set @save_bgc_count= @@global.binlog_commit_wait_count; +set @save_bgc_usec= @@global.binlog_commit_wait_usec; +set @save_debug_dbug= @@global.debug_dbug; +set @@global.binlog_commit_wait_count=3; +set @@global.binlog_commit_wait_usec=10000000; +set @@global.debug_dbug="+d,testing_cond_var_per_thd"; +set @@global.rpl_semi_sync_master_enabled= 1; +set @@global.rpl_semi_sync_master_wait_point= AFTER_COMMIT; + +--echo # Ensure semi-sync is on +--connection slave +set @save_semi_sync_slave_enabled= @@global.rpl_semi_sync_master_enabled; +--source include/stop_slave.inc +set @@global.rpl_semi_sync_slave_enabled=1; +--source include/start_slave.inc + +let $status_var= rpl_semi_sync_slave_status; +let $status_var_value= ON; +source include/wait_for_status_var.inc; + +--connection master +let $status_var= rpl_semi_sync_master_status; +let $status_var_value= ON; +source include/wait_for_status_var.inc; + +--echo # Create three transactions to binlog group commit together +--connection master +--send create table t1 (a int) +--connection server_1 +--send create table t2 (a int) +--connection default +--send create table t3 (a int) + +--connection master +--reap +--connection server_1 +--reap +--connection default +--reap + +--let $assert_text= Check that there is no 'Thread awaiting semi-sync ACK was awoken before its ACK' warning in error log. +--let $assert_select=Thread awaiting semi-sync ACK was awoken before its ACK +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_count= 0 +--let $assert_only_after=CURRENT_TEST +--source include/assert_grep.inc + +--sync_slave_with_master + + +--echo # +--echo # Cleanup +--connection master +set @@global.binlog_commit_wait_count=@save_bgc_count; +set @@global.binlog_commit_wait_usec=@save_bgc_usec; +set @@global.debug_dbug=@save_debug_dbug; +set @@global.rpl_semi_sync_master_enabled= @save_semi_sync_master_enabled; +set @@global.rpl_semi_sync_master_wait_point= @save_semi_sync_wp; + +--connection slave +--source include/stop_slave.inc +set @@global.rpl_semi_sync_slave_enabled= @save_semi_sync_slave_enabled; +--source include/start_slave.inc + +--connection master +drop table t1, t2, t3; +--sync_slave_with_master + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_crash.inc b/mysql-test/suite/rpl/t/rpl_semi_sync_crash.inc index 0cedefd7dd7..1bb5ff9fd4a 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_crash.inc +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_crash.inc @@ -34,14 +34,16 @@ if ($case == 1) if ($case == 2) { SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL con1_ready WAIT_FOR con1_go"; + SET DEBUG_SYNC= "commit_after_release_LOCK_after_binlog_sync WAIT_FOR con1_go1"; --send_eval $query_to_crash --connect (conn_client_2,127.0.0.1,root,,test,$SERVER_MYPORT_2,) # use the same signal with $query_to_crash SET DEBUG_SYNC= "now WAIT_FOR con1_ready"; - SET GLOBAL debug_dbug="d,Notify_binlog_EOF"; + SET DEBUG_SYNC= "commit_before_get_LOCK_after_binlog_sync SIGNAL con1_go"; + SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL con2_ready"; --send_eval $query2_to_crash --connection server_$server_to_crash - SET DEBUG_SYNC= "now WAIT_FOR eof_reached"; + SET DEBUG_SYNC= "now WAIT_FOR con2_ready"; --source include/kill_mysqld.inc } @@ -68,9 +70,7 @@ source include/wait_for_slave_param.inc; --error 2003 --source include/stop_slave.inc ---let $assert_cond= COUNT(*) = $expected_rows_on_slave FROM t1 ---let $assert_text= Table t1 should have $expected_rows_on_slave rows. ---source include/assert.inc +--eval select count(*) 'on slave must be $expected_rows_on_slave' from t1 SELECT @@GLOBAL.gtid_current_pos; @@ -81,9 +81,21 @@ SELECT @@GLOBAL.gtid_current_pos; --enable_reconnect --source include/wait_until_connected_again.inc ---let $assert_cond= COUNT(*) = $expected_rows_on_master FROM t1 ---let $assert_text= Table t1 should have $expected_rows_on_master rows. ---source include/assert.inc +--let $slave_semi_sync_enabled= query_get_value(SHOW VARIABLES LIKE 'Rpl_semi_sync_slave_enabled', Value, 1) +--echo # Ensuring variable rpl_semi_sync_slave_enabled is ON.. +if (`SELECT strcmp("ON", "$slave_semi_sync_enabled") != 0`) +{ + --die Slave started with rpl_semi_sync_slave_enabled=1 yet it is OFF in the variable output +} + +--let $slave_semi_sync_status= query_get_value(SHOW STATUS LIKE 'Rpl_semi_sync_slave_status', Value, 1) +--echo # Ensuring status rpl_semi_sync_slave_status is OFF.. +if (`SELECT strcmp("OFF", "$slave_semi_sync_status") != 0`) +{ + --die Slave started with skip-slave-start yet started with rpl_semi_sync_slave_status=ON +} + +--eval select count(*) 'on master must be $expected_rows_on_master' from t1 # Check error log for correct messages. let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.$server_to_crash.err; diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_fail_over.test b/mysql-test/suite/rpl/t/rpl_semi_sync_fail_over.test index 17d7b50d614..e4d0bc0acd1 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_fail_over.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_fail_over.test @@ -10,6 +10,11 @@ --source include/have_binlog_format_row.inc --source include/master-slave.inc +--disable_query_log +call mtr.add_suppression("Could not read packet:.* errno: 11"); +flush tables; +--enable_query_log + # Initial slave --connection server_2 --source include/stop_slave.inc @@ -78,7 +83,7 @@ SHOW VARIABLES LIKE 'gtid_slave_pos'; --connection server_1 --sync_with_master ---eval SELECT COUNT(*) = $rows_so_far as 'true' FROM t1 +--eval SELECT COUNT(*) 'must be $rows_so_far' FROM t1 --echo # ... the gtid states on the slave: SHOW VARIABLES LIKE 'gtid_slave_pos'; SHOW VARIABLES LIKE 'gtid_binlog_pos'; @@ -129,7 +134,7 @@ SHOW VARIABLES LIKE 'gtid_slave_pos'; --connection server_2 --sync_with_master ---eval SELECT COUNT(*) = $rows_so_far as 'true' FROM t1 +--eval SELECT COUNT(*) 'must be $rows_so_far as' FROM t1 --echo # ... the gtid states on the slave: SHOW VARIABLES LIKE 'gtid_slave_pos'; SHOW VARIABLES LIKE 'gtid_binlog_pos'; @@ -180,7 +185,7 @@ SHOW VARIABLES LIKE 'gtid_slave_pos'; --connection server_1 --source include/sync_with_master_gtid.inc ---eval SELECT COUNT(*) = $rows_so_far as 'true' FROM t1 +--eval SELECT COUNT(*) 'must be $rows_so_far' FROM t1 --echo # ... the gtid states on the slave: SHOW VARIABLES LIKE 'gtid_slave_pos'; SHOW VARIABLES LIKE 'gtid_binlog_pos'; diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_master_shutdown.test b/mysql-test/suite/rpl/t/rpl_semi_sync_master_shutdown.test index 05e6fcca143..d653d84c3b4 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_master_shutdown.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_master_shutdown.test @@ -4,19 +4,17 @@ # finishes off as specified in particular trying to connect even to a shut down # master for a semisync firewell routine. -source include/not_embedded.inc; -source include/have_debug.inc; source include/master-slave.inc; --connection master ---let $sav_enabled_master=`SELECT @@GLOBAL.rpl_semi_sync_master_enabled ` +--let $sav_enabled_master=`SELECT @@GLOBAL.rpl_semi_sync_master_enabled` SET @@GLOBAL.rpl_semi_sync_master_enabled = 1; --connection slave source include/stop_slave.inc; ---let $sav_enabled_slave=`SELECT @@GLOBAL.rpl_semi_sync_slave_enabled ` -SET @@GLOBAL. rpl_semi_sync_slave_enabled = 1; +--let $sav_enabled_slave=`SELECT @@GLOBAL.rpl_semi_sync_slave_enabled` +SET @@GLOBAL.rpl_semi_sync_slave_enabled = 1; source include/start_slave.inc; --connection master @@ -52,7 +50,6 @@ source include/rpl_start_server.inc; #--source include/start_slave.inc --connection master -SET @@GLOBAL.debug_dbug=""; --eval SET @@GLOBAL. rpl_semi_sync_master_enabled = $sav_enabled_master --connection master diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.cnf b/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.cnf index 2cf1b1786bd..5f69b557188 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.cnf +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.cnf @@ -1,13 +1,13 @@ !include ../my.cnf [mysqld.1] -log_warnings=9 +log_warnings=3 [mysqld.2] -log_warnings=9 +log_warnings=3 [mysqld.3] -log_warnings=9 +log_warnings=3 [ENV] SERVER_MYPORT_3= @mysqld.3.port diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.inc b/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.inc index 252541ae13b..d20ef628327 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.inc +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.inc @@ -3,7 +3,6 @@ # replicas before shutting down. # # Parameters: -# server_1_dbug (string) Debug setting for primary (server 1) # server_2_dbug (string) Debug setting to simulate delay or error on # the first replica (server 2) # server_3_dbug (string) Debug setting to simulate delay or error on @@ -32,8 +31,8 @@ while (`SELECT $i <= $slave_last`) --connection server_$i --sync_with_master - set global rpl_semi_sync_slave_enabled = 1; source include/stop_slave.inc; + set global rpl_semi_sync_slave_enabled = 1; source include/start_slave.inc; show status like 'Rpl_semi_sync_slave_status'; @@ -56,8 +55,6 @@ show status like 'Rpl_semi_sync_master_status'; show status like 'Rpl_semi_sync_master_clients'; --echo #-- Prepare servers to simulate delay or error ---connection server_1 ---eval SET @@GLOBAL.debug_dbug= $server_1_dbug --connection server_2 --eval SET @@GLOBAL.debug_dbug= $server_2_dbug --connection server_3 @@ -66,6 +63,11 @@ show status like 'Rpl_semi_sync_master_clients'; --echo #-- --echo #-- Test begins +--connection server_1_con2 +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + --connection server_1 --echo #-- Begin semi-sync transaction --send INSERT INTO t1 VALUES (1) @@ -75,25 +77,13 @@ show status like 'Rpl_semi_sync_master_clients'; let $status_var= Rpl_semi_sync_master_wait_sessions; let $status_var_value= 1; source include/wait_for_status_var.inc; -show status like 'Rpl_semi_sync_master_wait_sessions'; - ---write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -wait -EOF - ---echo #-- Give enough time after timeout/ack received to query yes_tx/no_tx -SET @@GLOBAL.debug_dbug= "+d,delay_shutdown_phase_2_after_semisync_wait"; --echo #-- Begin master shutdown ---send SHUTDOWN WAIT FOR ALL SLAVES +SHUTDOWN WAIT FOR ALL SLAVES; +--source include/wait_until_disconnected.inc --connection server_1 ---reap ---echo #-- Ensure either ACK was received (yes_tx=1) or timeout (no_tx=1) -show status like 'Rpl_semi_sync_master_yes_tx'; -show status like 'Rpl_semi_sync_master_no_tx'; - ---connection server_1_con2 +--error 2013 --reap --source include/wait_until_disconnected.inc @@ -111,19 +101,72 @@ show status like 'Rpl_semi_sync_master_no_tx'; --echo # --echo #-- Re-synchronize slaves with master and disable semi-sync +if (`SELECT ($server_2_expect_row_count + $server_3_expect_row_count) < 2`) +{ +--echo #-- FIXME: workaround for MDEV-28141, preventing errored replicas from +--echo # killing their semi-sync connections +# I.e. we can't create a new kill connection to the primary if we know that the +# primary is shutting down for risk of Packets out of order error. So we wait +# to hit a debug_sync point before the creation of the new kill_connection, and +# don't progress until the primary has been shutdown, so no new connection can +# be formed. +# Note this is only needed in the error case (using corrupt_queue_event), as +# the running io_thread will otherwise automatically detect that the primary +# has shutdown before progressing to the cleanup of the io thread. +} + +if (!$server_2_expect_row_count) +{ + --connection server_2 + set debug_sync= "now wait_for at_semisync_kill_connection"; + set debug_sync= "now signal continue_semisync_kill_connection"; + --echo # Wait for debug_sync signal to have been received before issuing RESET + let $wait_condition= select count(*)=0 from information_schema.processlist where state like "debug sync point%"; + source include/wait_condition.inc; + set debug_sync= "reset"; +} +if (!$server_3_expect_row_count) +{ + --connection server_3 + set debug_sync= "now wait_for at_semisync_kill_connection"; + set debug_sync= "now signal continue_semisync_kill_connection"; + --echo # Wait for debug_sync signal to have been received before issuing RESET + let $wait_condition= select count(*)=0 from information_schema.processlist where state like "debug sync point%"; + source include/wait_condition.inc; + set debug_sync= "reset"; +} + --echo #-- Stop slaves --connection server_2 ---eval SET @@GLOBAL.debug_dbug= "$sav_server_2_dbug" ---eval SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0 ---let $rpl_only_running_threads= 1 -source include/stop_slave.inc; +# If server_2_expect_row_count is 0, we are simulating an error on the replica +# and the IO thread will end with errno 1595. +# Otherwise, we still expect error, because the master has shutdown at this +# point, and the IO thread may or may not have realized the shutdown, and +# started to try to automatically reconnect. This may result in the IO thread +# giving a 2003 error if the slave tries to reconnect to a shutdown master. +# Additionally disable warnings because the slave may have stopped in err +# automatically, and we don't want a sporadic "Slave is already stopped" +# warning. +--disable_warnings +--let $rpl_allow_error= 1 +--source include/stop_slave_io.inc +--enable_warnings +--let $rpl_allow_error= +--source include/stop_slave_sql.inc +SET @@GLOBAL.debug_dbug= @sav_server_2_dbug; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= @sav_enabled_server_2; --connection server_3 ---eval SET @@GLOBAL.debug_dbug= "$sav_server_3_dbug" ---eval SET @@GLOBAL.rpl_semi_sync_slave_enabled= 0 ---let $rpl_only_running_threads= 1 -source include/stop_slave.inc; +# Expect error for IO thread, see above comment for stopping server_2 +--disable_warnings +--let $rpl_allow_error= 1 +--source include/stop_slave_io.inc +--enable_warnings +--let $rpl_allow_error= +--source include/stop_slave_sql.inc +SET @@GLOBAL.debug_dbug= @sav_server_3_dbug; +SET @@GLOBAL.rpl_semi_sync_slave_enabled= @sav_enabled_server_3; --echo #-- Bring the master back up --connection server_1_con2 @@ -142,13 +185,6 @@ EOF --enable_reconnect --source include/wait_until_connected_again.inc ---eval SET @@GLOBAL.debug_dbug= "$sav_master_dbug" -let $status_var= Rpl_semi_sync_master_clients; -let $status_var_value= 0; -source include/wait_for_status_var.inc; ---eval SET @@GLOBAL.rpl_semi_sync_master_enabled = 0 -show status like 'Rpl_semi_sync_master_status'; - TRUNCATE TABLE t1; --save_master_pos diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.test b/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.test index 6c088c571f2..4ed9ca0aa7c 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_await_ack.test @@ -5,7 +5,7 @@ # This test validates that data is consistent between a primary and replica # in semi-sync mode when the primary is issued `SHUTDOWN WAIT FOR SLAVES` # during an active communication. More specifically, the primary should not -# kill the connection until it is sure a replica has received all binlog +# kill the Ack_thread until it is sure a replica has received all binlog # data, i.e. once the primary receives the ACK. If a primary is issued a # shutdown before receiving an ACK, it should wait until either 1) the ACK is # received, or 2) the configured timeout (rpl_semi_sync_master_timeout) is @@ -15,23 +15,18 @@ # Using a topology consisting of one primary with two replicas, all in # semi-sync mode, we use DEBUG_DBUG to simulate an error or delay on the # replicas during an active communication while the primary is issued -# `SHUTDOWN WAIT FOR SLAVES`. We create four test cases to ensure the primary -# will correctly wait for the communication to finish, and use the semi-sync -# status variables Rpl_semi_sync_master_yes_tx and Rpl_semi_sync_master_no_tx -# to ensure the connection was not prematurely killed due to the shutdown. +# `SHUTDOWN WAIT FOR SLAVES`. We create four test cases to ensure the +# Ack_thread is not prematurely killed due to the shutdown. # Test Case 1) If both replicas simulate a delay that is within the allowed -# timeout, the primary should delay killing the suspended thread -# until an ACK is received (Rpl_semi_sync_master_yes_tx should -# be 1). +# timeout, the primary should delay killing the Ack_thread +# until an ACK is received. # Test Case 2) If both replicas simulate an error before sending an ACK, the -# primary should delay killing the suspended thread until the -# the timeout is reached (Rpl_semi_sync_master_no_tx should be -# 1). +# primary should delay killing the Ack_thread until the +# the timeout is reached. # Test Case 3) If one replica simulates a delay within the allowed timeout # and the other simulates an error before sending an ACK, the -# primary should delay killing the suspended thread until it -# receives an ACK from the delayed slave -# (Rpl_semi_sync_master_yes_tx should be 1). +# primary should delay killing the Ack_thread until it +# receives an ACK from the delayed slave. # Test Case 4) If a replica errors before sending an ACK, it will cause the # IO thread to stop and handle the error. During error handling, # if semi-sync is active, the replica will form a new connection @@ -41,9 +36,11 @@ # slave should notice this, and not issue a `QUIT` command to # the primary, which would otherwise be sent to kill an active # connection. This test case validates that the slave does not -# send a `QUIT` in this case (Rpl_semi_sync_master_yes_tx should -# be 1 because server_3 will send the ACK within a valid -# timeout). +# send a `QUIT` in this case. +# Test Case 5) If a waiting-for-ACK user thread is killed (disconnected) +# during SHUTDOWN WAIT FOR ALL SLAVES, ensure the primary will +# still await the ACK from the replica before killing the +# Ack_thread. # # References: # MDEV-11853: semisync thread can be killed after sync binlog but before ACK @@ -58,6 +55,7 @@ --echo # Note: Simulated slave delay is hardcoded to 800 milliseconds --echo # Note: Simulated master shutdown delay is hardcoded to 500 milliseconds +--source include/have_innodb.inc --source include/have_debug.inc --let $rpl_topology=1->2, 1->3 --source include/rpl_init.inc @@ -69,9 +67,8 @@ call mtr.add_suppression("Timeout waiting"); call mtr.add_suppression("did not exit"); call mtr.add_suppression("Got an error reading communication packets"); ---let $sav_master_timeout= `SELECT @@global.rpl_semi_sync_master_timeout` +--let $sav_master_timeout= `SELECT @@GLOBAL.rpl_semi_sync_master_timeout` --let $sav_enabled_master= `SELECT @@GLOBAL.rpl_semi_sync_master_enabled` ---let $sav_master_dbug= `SELECT @@GLOBAL.debug_dbug` --echo # Suppress slave errors related to the simulated error --connection server_2 @@ -79,19 +76,19 @@ call mtr.add_suppression("reply failed"); call mtr.add_suppression("Replication event checksum verification"); call mtr.add_suppression("Relay log write failure"); call mtr.add_suppression("Failed to kill the active semi-sync connection"); ---let $sav_enabled_server_2=`SELECT @@GLOBAL.rpl_semi_sync_slave_enabled` ---let $sav_server_2_dbug= `SELECT @@GLOBAL.debug_dbug` +set @sav_enabled_server_2= @@GLOBAL.rpl_semi_sync_slave_enabled; +set @sav_server_2_dbug= @@GLOBAL.debug_dbug; --connection server_3 call mtr.add_suppression("reply failed"); call mtr.add_suppression("Replication event checksum verification"); call mtr.add_suppression("Relay log write failure"); call mtr.add_suppression("Failed to kill the active semi-sync connection"); ---let $sav_enabled_server_3=`SELECT @@GLOBAL.rpl_semi_sync_slave_enabled` ---let $sav_server_3_dbug= `SELECT @@GLOBAL.debug_dbug` +set @sav_enabled_server_3= @@GLOBAL.rpl_semi_sync_slave_enabled; +set @sav_server_3_dbug= @@GLOBAL.debug_dbug; --connection server_1 -CREATE TABLE t1 (a int); +CREATE TABLE t1 (a int) engine=innodb; --save_master_pos --let i= 2 @@ -113,10 +110,9 @@ while (`SELECT $i <= $slave_last`) --echo # --echo # Test Case 1) If both replicas simulate a delay that is within the ---echo # allowed timeout, the primary should delay killing the suspended thread ---echo # until an ACK is received (Rpl_semi_sync_master_yes_tx should be 1). +--echo # allowed timeout, the primary should delay killing the Ack_thread +--echo # until an ACK is received. --echo # ---let server_1_dbug= "" --let server_2_dbug= "+d,simulate_delay_semisync_slave_reply" --let server_3_dbug= "+d,simulate_delay_semisync_slave_reply" --let semisync_timeout= 1600 @@ -126,12 +122,11 @@ while (`SELECT $i <= $slave_last`) --echo # --echo # Test Case 2) If both replicas simulate an error before sending an ACK, ---echo # the primary should delay killing the suspended thread until the ---echo # timeout is reached (Rpl_semi_sync_master_no_tx should be 1). +--echo # the primary should delay killing the Ack_thread until the +--echo # timeout is reached. --echo # ---let server_1_dbug= "+d,mysqld_delay_kill_threads_phase_1" ---let server_2_dbug= "+d,corrupt_queue_event" ---let server_3_dbug= "+d,corrupt_queue_event" +--let server_2_dbug= "+d,corrupt_queue_event,delay_semisync_kill_connection_for_mdev_28141" +--let server_3_dbug= "+d,corrupt_queue_event,delay_semisync_kill_connection_for_mdev_28141" --let semisync_timeout= 500 --let server_2_expect_row_count= 0 --let server_3_expect_row_count= 0 @@ -140,11 +135,10 @@ while (`SELECT $i <= $slave_last`) --echo # --echo # Test Case 3) If one replica simulates a delay within the allowed --echo # timeout and the other simulates an error before sending an ACK, the ---echo # primary should delay killing the suspended thread until it receives an ---echo # ACK from the delayed slave (Rpl_semi_sync_master_yes_tx should be 1). +--echo # primary should delay killing the Ack_thread until it receives an +--echo # ACK from the delayed slave. --echo # ---let server_1_dbug= "+d,mysqld_delay_kill_threads_phase_1" ---let server_2_dbug= "+d,corrupt_queue_event" +--let server_2_dbug= "+d,corrupt_queue_event,delay_semisync_kill_connection_for_mdev_28141" --let server_3_dbug= "+d,simulate_delay_semisync_slave_reply" --let semisync_timeout= 1600 --let server_2_expect_row_count= 0 @@ -160,56 +154,123 @@ while (`SELECT $i <= $slave_last`) --echo # active semi-sync connection in-tact. The slave should notice this, and --echo # not issue a `QUIT` command to the primary, which would otherwise be --echo # sent to kill an active connection. This test case validates that the ---echo # slave does not send a `QUIT` in this case (Rpl_semi_sync_master_yes_tx ---echo # should be 1 because server_3 will send the ACK within a valid timeout). +--echo # slave does not send a `QUIT` in this case. --echo # - -# mysqld_delay_kill_threads_phase1 ensures that server_2 will have enough time -# to start a new connection that has the intent to kill the active semi-sync -# connection ---let server_1_dbug= "+d,mysqld_delay_kill_threads_phase_1" - -# slave_delay_killing_semisync_connection ensures that the primary has force -# killed its current connection before it is able to issue `KILL` ---let server_2_dbug= "+d,corrupt_queue_event,slave_delay_killing_semisync_connection" +--let server_2_dbug= "+d,corrupt_queue_event,delay_semisync_kill_connection_for_mdev_28141" --let server_3_dbug= "+d,simulate_delay_semisync_slave_reply" --let semisync_timeout= 1600 --let server_2_expect_row_count= 0 --let server_3_expect_row_count= 1 --source rpl_semi_sync_shutdown_await_ack.inc +# +# Added with MDEV-33551 +# +--echo # +--echo # Test Case 5) If a waiting-for-ACK user thread is killed (disconnected) +--echo # during SHUTDOWN WAIT FOR ALL SLAVES, ensure the primary will still +--echo # await the ACK from the replica before killing the Ack_receiver thread +--echo # +--connection server_1 +insert into t1 values (1); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +SET GLOBAL rpl_semi_sync_slave_enabled= 1; +--source include/start_slave.inc + +--connection server_1 +SET GLOBAL rpl_semi_sync_master_enabled= 1; +SET GLOBAL rpl_semi_sync_master_timeout= 2000; + +--let $status_var= Rpl_semi_sync_master_clients +--let $status_var_value= 1 +source include/wait_for_status_var.inc; + +show status like 'Rpl_semi_sync_master_status'; +show status like 'Rpl_semi_sync_master_clients'; + +--connection server_2 +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,simulate_delay_semisync_slave_reply"; + +--connect(con1, localhost, root,,) +--connect(con2, localhost, root,,) + +--connection con1 +--send insert into t1 values (2) + +--connection server_1 +--echo # Wait for thd to begin semi-sync wait.. +--let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state = 'Waiting for semi-sync ACK from slave' +--source include/wait_condition.inc +--echo # ..done + +--disconnect con1 + +--connection default +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +--connection con2 +SHUTDOWN WAIT FOR ALL SLAVES; +--source include/wait_until_disconnected.inc + +--echo # Ensure the primary waited for the ACK of the killed thread +--let $SEARCH_PATTERN= Delaying shutdown to await semi-sync ACK +--let $SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err +--source include/search_pattern_in_file.inc + +--connection default +--source include/wait_until_disconnected.inc + +--connection server_1 +--source include/wait_until_disconnected.inc + +--connection server_2 +--let $rpl_allow_error= 1 +source include/stop_slave.inc; +--connection server_3 +source include/stop_slave.inc; +--let $rpl_allow_error= + +--connection default +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart +EOF +--enable_reconnect +--source include/wait_until_connected_again.inc + +--connection server_1 +--enable_reconnect +--source include/wait_until_connected_again.inc + + --echo ############################# --echo # Cleanup --echo ############################# --connection server_2 -source include/stop_slave.inc; +SET @@GLOBAL.rpl_semi_sync_slave_enabled = @sav_enabled_server_2; +SET @@GLOBAL.debug_dbug= @sav_server_2_dbug; source include/start_slave.inc; ---disable_query_log ---eval SET @@GLOBAL.rpl_semi_sync_slave_enabled = $sav_enabled_server_2 ---eval SET @@GLOBAL.debug_dbug= "$sav_server_2_dbug" ---enable_query_log - --connection server_3 -source include/stop_slave.inc; +SET @@GLOBAL.rpl_semi_sync_slave_enabled = @sav_enabled_server_3; +SET @@GLOBAL.debug_dbug= @sav_server_3_dbug; source include/start_slave.inc; ---disable_query_log ---eval SET @@GLOBAL.rpl_semi_sync_slave_enabled = $sav_enabled_server_3 ---eval SET @@GLOBAL.debug_dbug= "$sav_server_3_dbug" ---enable_query_log - - --connection server_1 let $status_var= Rpl_semi_sync_master_clients; let $status_var_value= 0; source include/wait_for_status_var.inc; --disable_query_log ---eval SET @@GLOBAL.rpl_semi_sync_master_timeout= $sav_master_timeout ---eval SET @@GLOBAL.rpl_semi_sync_master_enabled= $sav_enabled_master ---eval SET @@GLOBAL.debug_dbug= "$sav_master_dbug" +--eval SET @@GLOBAL.rpl_semi_sync_master_timeout= $sav_master_timeout; +--eval SET @@GLOBAL.rpl_semi_sync_master_enabled= $sav_enabled_master; --enable_query_log drop table t1; diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_slave_enabled_consistent.test b/mysql-test/suite/rpl/t/rpl_semi_sync_slave_enabled_consistent.test index 9e388ab4419..ca7e788780c 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_slave_enabled_consistent.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_slave_enabled_consistent.test @@ -14,6 +14,9 @@ call mtr.add_suppression("Replication event checksum verification failed"); call mtr.add_suppression("could not queue event from master"); +call mtr.add_suppression("Semisync ack receiver.*error reading communication packets"); +call mtr.add_suppression("Semisync ack receiver got hangup"); +--sync_slave_with_master --echo # --echo # Set up a semisync connection diff --git a/mysql-test/suite/rpl/t/rpl_show_slave_status.test b/mysql-test/suite/rpl/t/rpl_show_slave_status.test new file mode 100644 index 00000000000..f4bbb5faeab --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_show_slave_status.test @@ -0,0 +1,27 @@ +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +--echo * +--echo * The purpose of this test is to prevent incorrect additions to SHOW +--echo * SLAVE STATUS, which has happened several times in the past. +--echo * +--echo * We must never, _ever_, add extra rows to this output of SHOW SLAVE +--echo * STATUS, except at the very end, as this breaks backwards compatibility +--echo * with applications or scripts that parse the output. This also means that +--echo * we cannot add _any_ new rows in a GA version if a different row was +--echo * already added in a later MariaDB version, as this would make it impossible +--echo * to merge the change up while preserving the order of rows. +--echo * + +--connection slave +--replace_column 1 # 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 11 # 12 # 13 # 14 # 15 # 16 # 17 # 18 # 19 # 20 # 21 # 22 # 23 # 24 # 25 # 26 # 27 # 28 # 29 # 30 # 31 # 32 # 33 # 34 # 35 # 36 # 37 # 38 # 39 # 40 # 41 # 42 # 43 # 44 # 45 # 46 # 47 # 48 # 49 # 50 # 51 # 52 # 53 # 54 # +query_vertical +SHOW SLAVE STATUS; + +--echo * +--echo * When modifying this test after adding a column to SHOW SLAVE STATUS, +--echo * _only_ additions at the end are allowed, the column number of existing +--echo * columns must _not_ change! +--echo * + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_shutdown_sighup.test b/mysql-test/suite/rpl/t/rpl_shutdown_sighup.test new file mode 100644 index 00000000000..d1940f81a85 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_shutdown_sighup.test @@ -0,0 +1,154 @@ +# +# The signal handler thread can use various different runtime resources when +# processing a SIGHUP (e.g. master-info information), as the logic calls into +# reload_acl_and_cache(). This test ensures that SIGHUP processing, when +# concurrent with server shutdown, the shutdown logic must wait for the SIGHUP +# processing to finish before cleaning up any resources. +# +# Additionally, the error case is tested such that the signal handler thread +# takes too long processing a SIGHUP, and the main mysqld thread must skip its +# wait and output a warning. +# +# Note the SIGHUP is sent via the command-line kill program via a perl script. +# +# References: +# MDEV-30260: Slave crashed:reload_acl_and_cache during shutdown +# + +--source include/not_windows.inc +--source include/not_embedded.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +# Binlog format doesn't matter +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +# For error test case which forces timeout +--connection slave +set statement sql_log_bin=0 for call mtr.add_suppression("Signal handler thread did not exit in a timely manner"); + + +--echo # +--echo # Main test +--connection master +create table t1 (a int); +insert into t1 values (1); +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc + +# Make signal handler handle SIGHUP.. +set @@global.debug_dbug= "+d,hold_sighup_log_refresh"; +--let KILL_NODE_PIDFILE = `SELECT @@pid_file` +--perl + my $kill_sig = $ENV{'KILL_SIGNAL_VALUE'}; + my $pid_filename = $ENV{'KILL_NODE_PIDFILE'}; + my $mysqld_pid = `cat $pid_filename`; + chomp($mysqld_pid); + system("kill -HUP $mysqld_pid"); + exit(0); +EOF + +--echo # Waiting for sighup to reach reload_acl_and_cache.. +set debug_sync="now wait_for in_reload_acl_and_cache"; +--echo # Signalling signal handler to proceed to sleep before REFRESH_HOSTS +set debug_sync="now signal refresh_logs"; + +# ..while we are shutting down +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--echo # Starting shutdown (note this will take 3+ seconds due to DBUG my_sleep in reload_acl_and_cache) +shutdown; + +--source include/wait_until_disconnected.inc +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=0 +EOF + +--connection server_2 +--enable_reconnect +--source include/wait_until_connected_again.inc + +--connection slave +--enable_reconnect +--source include/wait_until_connected_again.inc + +--let $assert_text= Ensure Mariadbd did not segfault when shutting down +--let $assert_select= got signal 11 +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.2.err +--let $assert_count= 0 +--let $assert_only_after = CURRENT_TEST: rpl.rpl_shutdown_sighup +--source include/assert_grep.inc + +--connection master +--sync_slave_with_master + + +--echo # +--echo # Error testcase to ensure an error message is shown if the signal +--echo # takes longer than the timeout while processing the SIGHUP + +--connection slave +set @@global.debug_dbug= "+d,force_sighup_processing_timeout"; +set @@global.debug_dbug= "+d,hold_sighup_log_refresh"; + +--connection master +insert into t1 values (1); +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc + +# Make signal handler handle SIGHUP.. +--let KILL_NODE_PIDFILE = `SELECT @@pid_file` +--perl + my $kill_sig = $ENV{'KILL_SIGNAL_VALUE'}; + my $pid_filename = $ENV{'KILL_NODE_PIDFILE'}; + my $mysqld_pid = `cat $pid_filename`; + chomp($mysqld_pid); + system("kill -HUP $mysqld_pid"); + exit(0); +EOF +--echo # Waiting for sighup to reach reload_acl_and_cache.. +set debug_sync="now wait_for in_reload_acl_and_cache"; +--echo # Signalling signal handler to proceed to sleep before REFRESH_HOSTS +set debug_sync="now signal refresh_logs"; + +# ..while we are shutting down +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--echo # Starting shutdown (note this will take 3+ seconds due to DBUG my_sleep in reload_acl_and_cache) +shutdown; + +--source include/wait_until_disconnected.inc +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=0 +EOF + +--connection server_2 +--enable_reconnect +--source include/wait_until_connected_again.inc + +--connection slave +--enable_reconnect +--source include/wait_until_connected_again.inc + +--let $assert_text= Ensure warning is issued that signal handler thread is still processing +--let $assert_select= Signal handler thread did not exit in a timely manner. +--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.2.err +--let $assert_count= 1 +--let $assert_only_after = CURRENT_TEST: rpl.rpl_shutdown_sighup +--source include/assert_grep.inc + + +--echo # +--echo # Cleanup +--connection master +drop table t1; + +--source include/rpl_end.inc +--echo # End of rpl_shutdown_sighup.test diff --git a/mysql-test/suite/rpl/t/rpl_skip_error.test b/mysql-test/suite/rpl/t/rpl_skip_error.test index d3ef834e8ec..ee11ce5ac92 100644 --- a/mysql-test/suite/rpl/t/rpl_skip_error.test +++ b/mysql-test/suite/rpl/t/rpl_skip_error.test @@ -3,7 +3,11 @@ # Verify that --slave-skip-errors works correctly. The error messages # specified by --slave-skip-errors on slave should be ignored. If # such errors occur, they should not be reported and not cause the -# slave to stop. +# slave to stop. If a skipped-due-to-error statement is a part of a +# larger transaction, and the error is not a deadlock error, the rest +# of the transaction should still commit, with just the errored statement +# ignored (note transactions which are skipped due to deadlocks are +# rolled back fully, see rpl_temporary_error2_skip_all.test). # # ==== Method ==== # @@ -164,6 +168,42 @@ let $current_skipped_error= query_get_value(show global status like "Slave_skipp --echo **** We cannot execute a select as there are differences in the --echo **** behavior between STMT and RBR. + +--echo **** +--echo **** Ensure transactions which are skipped due to encountering a +--echo **** non-deadlock error which is present in --slave-skip-errors result +--echo **** in partially committed transactions +# Slave will insert 3 first, and master will insert 3 within a larger trx +--let $value_preexisting_on_slave= 3 + +--connection master +CREATE TABLE t3 (a INT UNIQUE) ENGINE=InnoDB; + +--sync_slave_with_master +--connection slave +--eval INSERT INTO t3 VALUES ($value_preexisting_on_slave) + +--connection master +BEGIN; +INSERT INTO t3 VALUES (1); +INSERT INTO t3 VALUES (2); +--eval INSERT INTO t3 VALUES ($value_preexisting_on_slave) +INSERT INTO t3 VALUES (4); +COMMIT; +--sync_slave_with_master + +--echo **** Master and slave tables should have the same data, due to the +--echo **** partially replicated transaction's data overlapping with the data +--echo **** that pre-existed on the slave. That is, despite the transaction +--echo **** consisting of 4 statements, the errored statement should be ignored +--echo **** and the other 3 should commit successfully. +let $diff_tables=master:t3,slave:t3; +source include/diff_tables.inc; + +--connection master +DROP TABLE t3; + + --echo ==== Clean Up ==== connection master; diff --git a/mysql-test/suite/rpl/t/rpl_sync.test b/mysql-test/suite/rpl/t/rpl_sync.test index 1e2ec2ca83b..3dd99e736f2 100644 --- a/mysql-test/suite/rpl/t/rpl_sync.test +++ b/mysql-test/suite/rpl/t/rpl_sync.test @@ -82,7 +82,7 @@ print FILE "failure"; close ($file); EOF ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.2.expect SET SESSION debug_dbug="d,crash_before_rotate_relaylog"; --error 2013 FLUSH LOGS; @@ -130,7 +130,7 @@ print FILE @content; close FILE; EOF ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--write_line restart $MYSQLTEST_VARDIR/tmp/mysqld.2.expect SET SESSION debug_dbug="d,crash_before_rotate_relaylog"; --error 2013 FLUSH LOGS; diff --git a/mysql-test/suite/rpl/t/rpl_temporary_error2.test b/mysql-test/suite/rpl/t/rpl_temporary_error2.test index 49194c5d914..3537499d562 100644 --- a/mysql-test/suite/rpl/t/rpl_temporary_error2.test +++ b/mysql-test/suite/rpl/t/rpl_temporary_error2.test @@ -64,7 +64,14 @@ ROLLBACK; --connection slave --sync_with_master SELECT * FROM t1 ORDER BY a; ---echo * There will be two rows in t2 due to the retry. +if (!$ignored_db_deadlock) +{ + --echo * There will be two rows in t2 due to the retry. +} +if ($ignored_db_deadlock) +{ + --echo * There will be one row in t2 because the ignored deadlock does not retry. +} SELECT * FROM t2 ORDER BY a; let $new_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); --disable_query_log diff --git a/mysql-test/suite/rpl/t/rpl_temporary_error2_skip_all-slave.opt b/mysql-test/suite/rpl/t/rpl_temporary_error2_skip_all-slave.opt new file mode 100644 index 00000000000..a9ddd73510c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_temporary_error2_skip_all-slave.opt @@ -0,0 +1 @@ +--slave-skip-errors=all diff --git a/mysql-test/suite/rpl/t/rpl_temporary_error2_skip_all.test b/mysql-test/suite/rpl/t/rpl_temporary_error2_skip_all.test new file mode 100644 index 00000000000..6801bf184d5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_temporary_error2_skip_all.test @@ -0,0 +1,3 @@ +--source include/have_binlog_format_row.inc +--let $ignored_db_deadlock= 1 +--source rpl_temporary_error2.test diff --git a/mysql-test/suite/rpl/t/rpl_using_gtid_default.test b/mysql-test/suite/rpl/t/rpl_using_gtid_default.test index c14695f98cb..1557fcdcef8 100644 --- a/mysql-test/suite/rpl/t/rpl_using_gtid_default.test +++ b/mysql-test/suite/rpl/t/rpl_using_gtid_default.test @@ -42,10 +42,9 @@ # replication is used by default if master supports it # --source include/have_debug.inc ---source include/master-slave.inc - # Format independent test so just use one --source include/have_binlog_format_mixed.inc +--source include/master-slave.inc --echo # --echo # Slave default configuration should be Slave_Pos diff --git a/mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test b/mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test index ac4c9249c02..a350d09329e 100644 --- a/mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test +++ b/mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test @@ -3,7 +3,10 @@ # --source include/master-slave.inc +--disable_query_log call mtr.add_suppression("Master is configured to log replication events"); +call mtr.add_suppression("Could not read packet:.* errno: 11"); +--enable_query_log --connection slave diff --git a/mysql-test/suite/s3/mysqldump.result b/mysql-test/suite/s3/mysqldump.result index 3f4c2081388..e0c0caf634e 100644 --- a/mysql-test/suite/s3/mysqldump.result +++ b/mysql-test/suite/s3/mysqldump.result @@ -4,6 +4,7 @@ alter table t1 engine=S3; ##### # mysqldump with --copy-s3-tables=0 (by default) ### +/*!999999\- enable the sandbox mode */ ##### # mysqldump with --copy-s3-tables=0 (by default) XML ### @@ -15,6 +16,7 @@ alter table t1 engine=S3; ##### # mysqldump with --copy-s3-tables=1 ### +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( diff --git a/mysql-test/suite/s3/partition.result b/mysql-test/suite/s3/partition.result index 9face3ec947..20530bd399a 100644 --- a/mysql-test/suite/s3/partition.result +++ b/mysql-test/suite/s3/partition.result @@ -55,8 +55,6 @@ ERROR HY000: Table 't2' is read only ALTER TABLE t2 ANALYZE PARTITION p3; Table Op Msg_type Msg_text s3.t2 analyze status Table 's3.t2' is read only -s3.t2 analyze status Engine-independent statistics collected -s3.t2 analyze status OK SELECT count(*) FROM t2; count(*) 6 diff --git a/mysql-test/suite/sql_sequence/mysqldump.result b/mysql-test/suite/sql_sequence/mysqldump.result index 0199bb7162f..7282804340c 100644 --- a/mysql-test/suite/sql_sequence/mysqldump.result +++ b/mysql-test/suite/sql_sequence/mysqldump.result @@ -3,6 +3,7 @@ CREATE TABLE t1(a INT, KEY (a)) KEY_BLOCK_SIZE=1024; insert into t1 values (1),(2); CREATE SEQUENCE x1 engine=innodb; # dump whole database +/*!999999\- enable the sandbox mode */ CREATE SEQUENCE `a1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=Aria; SELECT SETVAL(`a1`, 1, 0); CREATE SEQUENCE `x1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB; @@ -18,6 +19,7 @@ INSERT INTO `t1` VALUES (1), (2); # dump by tables order 1 +/*!999999\- enable the sandbox mode */ CREATE SEQUENCE `a1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=Aria; SELECT SETVAL(`a1`, 1, 0); CREATE SEQUENCE `x1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB; @@ -33,6 +35,7 @@ INSERT INTO `t1` VALUES (1), (2); # dump by tables order 2 +/*!999999\- enable the sandbox mode */ CREATE SEQUENCE `a1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=Aria; SELECT SETVAL(`a1`, 1, 0); CREATE SEQUENCE `x1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB; @@ -48,6 +51,7 @@ INSERT INTO `t1` VALUES (1), (2); # dump by tables only tables +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -59,6 +63,7 @@ INSERT INTO `t1` VALUES (1), (2); # dump by tables only sequences +/*!999999\- enable the sandbox mode */ CREATE SEQUENCE `a1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=Aria; SELECT SETVAL(`a1`, 1, 0); CREATE SEQUENCE `x1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB; diff --git a/mysql-test/suite/sys_vars/r/binlog_do_db.result b/mysql-test/suite/sys_vars/r/binlog_do_db.result deleted file mode 100644 index cdcfe406b64..00000000000 --- a/mysql-test/suite/sys_vars/r/binlog_do_db.result +++ /dev/null @@ -1,12 +0,0 @@ -# -# MDEV-30188 Show "--binlog_do_db" state in SYSTEM VARIABLES -# -SELECT @@binlog_do_db AS EXPECT_NULL; -EXPECT_NULL - -SET @@GLOBAL.binlog_do_db='database1'; -ERROR HY000: Variable 'binlog_do_db' is a read only variable -# restart: --binlog_do_db=database1 --binlog_do_db=database2 -SELECT @@binlog_do_db AS EXPECT_database1_database2; -EXPECT_database1_database2 -database1,database2 diff --git a/mysql-test/suite/sys_vars/r/binlog_ignore_db.result b/mysql-test/suite/sys_vars/r/binlog_ignore_db.result deleted file mode 100644 index bd1ff69744e..00000000000 --- a/mysql-test/suite/sys_vars/r/binlog_ignore_db.result +++ /dev/null @@ -1,12 +0,0 @@ -# -# MDEV-30188 Show "--binlog_ignore_db" state in SYSTEM VARIABLES -# -SELECT @@binlog_ignore_db AS EXPECT_NULL; -EXPECT_NULL - -SET @@GLOBAL.binlog_ignore_db='database1'; -ERROR HY000: Variable 'binlog_ignore_db' is a read only variable -# restart: --binlog_ignore_db=database1 --binlog_ignore_db=database2 -SELECT @@binlog_ignore_db AS EXPECT_database1_database2; -EXPECT_database1_database2 -database1,database2 diff --git a/mysql-test/suite/sys_vars/r/binlog_row_event_max_size.result b/mysql-test/suite/sys_vars/r/binlog_row_event_max_size.result deleted file mode 100644 index a68267fe5e6..00000000000 --- a/mysql-test/suite/sys_vars/r/binlog_row_event_max_size.result +++ /dev/null @@ -1,12 +0,0 @@ -# -# MDEV-30188 Show "--binlog_row_event_max_size" state in SYSTEM VARIABLES -# -SELECT @@binlog_row_event_max_size AS EXPECT_8192; -EXPECT_8192 -8192 -SET @@GLOBAL.binlog_row_event_max_size=128; -ERROR HY000: Variable 'binlog_row_event_max_size' is a read only variable -# restart: --binlog_row_event_max_size=4096 -SELECT @@binlog_row_event_max_size AS EXPECT_4096; -EXPECT_4096 -4096 diff --git a/mysql-test/suite/sys_vars/r/debug_dbug_utf16le.result b/mysql-test/suite/sys_vars/r/debug_dbug_utf16le.result new file mode 100644 index 00000000000..83b378f2adf --- /dev/null +++ b/mysql-test/suite/sys_vars/r/debug_dbug_utf16le.result @@ -0,0 +1,31 @@ +# +# Start of 10.5 tests +# +# +# MDEV-28366 GLOBAL debug_dbug setting affected by collation_connection=utf16... +# +SET NAMES utf8; +SET collation_connection=utf16le_general_ci; +SET debug_dbug='d,any_random_string'; +SELECT @@debug_dbug; +@@debug_dbug +d,any_random_string +SET debug_dbug=CONCAT('d,', _latin1 0xDF); +SELECT @@debug_dbug; +@@debug_dbug +d,ß +SELECT HEX(@@debug_dbug); +HEX(@@debug_dbug) +642CC39F +SET @@debug_dbug=NULL; +SELECT @@debug_dbug; +@@debug_dbug + +SET @@debug_dbug=DEFAULT; +SELECT @@debug_dbug; +@@debug_dbug + +SET NAMES latin1; +# +# End of 10.5 tests +# diff --git a/mysql-test/suite/sys_vars/r/innodb_doublewrite_basic.result b/mysql-test/suite/sys_vars/r/innodb_doublewrite_basic.result index 4a5baf0aeda..9e93d943c9f 100644 --- a/mysql-test/suite/sys_vars/r/innodb_doublewrite_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_doublewrite_basic.result @@ -1,33 +1,25 @@ -'#---------------------BS_STVARS_026_01----------------------#' -SELECT COUNT(@@GLOBAL.innodb_doublewrite); -COUNT(@@GLOBAL.innodb_doublewrite) -1 -1 Expected -'#---------------------BS_STVARS_026_02----------------------#' +SELECT @@GLOBAL.innodb_doublewrite; +@@GLOBAL.innodb_doublewrite +ON +SET @@GLOBAL.innodb_doublewrite=0; +SELECT @@GLOBAL.innodb_doublewrite; +@@GLOBAL.innodb_doublewrite +OFF +SET @@GLOBAL.innodb_doublewrite=2; +SET @@GLOBAL.innodb_doublewrite=3; +ERROR 42000: Variable 'innodb_doublewrite' can't be set to the value of '3' +SELECT @@GLOBAL.innodb_doublewrite; +@@GLOBAL.innodb_doublewrite +fast SET @@GLOBAL.innodb_doublewrite=1; -ERROR HY000: Variable 'innodb_doublewrite' is a read only variable -Expected error 'Read only variable' -SELECT COUNT(@@GLOBAL.innodb_doublewrite); -COUNT(@@GLOBAL.innodb_doublewrite) -1 -1 Expected -'#---------------------BS_STVARS_026_03----------------------#' -SELECT IF(@@GLOBAL.innodb_doublewrite, "ON", "OFF") = VARIABLE_VALUE -FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES -WHERE VARIABLE_NAME='innodb_doublewrite'; -IF(@@GLOBAL.innodb_doublewrite, "ON", "OFF") = VARIABLE_VALUE -1 -1 Expected -SELECT COUNT(@@GLOBAL.innodb_doublewrite); -COUNT(@@GLOBAL.innodb_doublewrite) -1 -1 Expected +SELECT @@GLOBAL.innodb_doublewrite; +@@GLOBAL.innodb_doublewrite +ON SELECT COUNT(VARIABLE_VALUE) -FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_doublewrite'; COUNT(VARIABLE_VALUE) 1 -1 Expected '#---------------------BS_STVARS_026_04----------------------#' SELECT @@innodb_doublewrite = @@GLOBAL.innodb_doublewrite; @@innodb_doublewrite = @@GLOBAL.innodb_doublewrite @@ -48,6 +40,5 @@ SELECT COUNT(@@GLOBAL.innodb_doublewrite); COUNT(@@GLOBAL.innodb_doublewrite) 1 1 Expected -SELECT innodb_doublewrite = @@SESSION.innodb_doublewrite; -ERROR 42S22: Unknown column 'innodb_doublewrite' in 'field list' -Expected error 'Readonly variable' +SELECT @@innodb_doublewrite = @@SESSION.innodb_doublewrite; +ERROR HY000: Variable 'innodb_doublewrite' is a GLOBAL variable diff --git a/mysql-test/suite/sys_vars/r/innodb_fil_make_page_dirty_debug_basic.result b/mysql-test/suite/sys_vars/r/innodb_fil_make_page_dirty_debug_basic.result index abf2cdaf1c4..8bea17482c0 100644 --- a/mysql-test/suite/sys_vars/r/innodb_fil_make_page_dirty_debug_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_fil_make_page_dirty_debug_basic.result @@ -20,7 +20,4 @@ where name = 'test/t1' into @space_id; set global innodb_saved_page_number_debug = 0; set global innodb_fil_make_page_dirty_debug = @space_id; drop table t1; -# Must always be 0. -SELECT @@global.innodb_fil_make_page_dirty_debug; -@@global.innodb_fil_make_page_dirty_debug -0 +set global innodb_fil_make_page_dirty_debug = 0; diff --git a/mysql-test/suite/sys_vars/r/innodb_saved_page_number_debug_basic.result b/mysql-test/suite/sys_vars/r/innodb_saved_page_number_debug_basic.result index 20e2b78e640..1fc959f419d 100644 --- a/mysql-test/suite/sys_vars/r/innodb_saved_page_number_debug_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_saved_page_number_debug_basic.result @@ -21,6 +21,7 @@ set global innodb_saved_page_number_debug = 0; set global innodb_fil_make_page_dirty_debug = @space_id; drop table t1; set global innodb_saved_page_number_debug = 0; +set global innodb_fil_make_page_dirty_debug = 0; SELECT @@global.innodb_saved_page_number_debug; @@global.innodb_saved_page_number_debug 0 diff --git a/mysql-test/suite/sys_vars/r/replicate_rewrite_db.result b/mysql-test/suite/sys_vars/r/replicate_rewrite_db.result index 2dfe3a65133..7a15a270e15 100644 --- a/mysql-test/suite/sys_vars/r/replicate_rewrite_db.result +++ b/mysql-test/suite/sys_vars/r/replicate_rewrite_db.result @@ -85,15 +85,13 @@ SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate VARIABLE_NAME VARIABLE_VALUE REPLICATE_REWRITE_DB db1->db2,db3->db4 # Check restart with appending the value -# restart: --replicate_rewrite_db=X->Y +# restart: --replicate_rewrite_db='X->Y' SELECT @@GLOBAL.replicate_rewrite_db; @@GLOBAL.replicate_rewrite_db -test->rewrite,mysqltest1->test,a->b,X->Y +test->rewrite,mysqltest1->test,a->b,'X->Y' # Check restart with wrong value on CLI [ERROR] Bad syntax in replicate-rewrite-db.Expected syntax is FROM->TO. -# restart: +# restart SELECT @@GLOBAL.replicate_rewrite_db; @@GLOBAL.replicate_rewrite_db test->rewrite,mysqltest1->test,a->b -# Cleanup. -SET @@GLOBAL.replicate_rewrite_db = @save_replicate_rewrite_db; diff --git a/mysql-test/suite/sys_vars/r/slave_transaction_retry_errors.result b/mysql-test/suite/sys_vars/r/slave_transaction_retry_errors.result index 72b4041599a..43988a81f4f 100644 --- a/mysql-test/suite/sys_vars/r/slave_transaction_retry_errors.result +++ b/mysql-test/suite/sys_vars/r/slave_transaction_retry_errors.result @@ -1,20 +1,20 @@ select @@global.slave_transaction_retry_errors; @@global.slave_transaction_retry_errors -1158,1159,1160,1161,1205,1213,1429,2013,12701,10,20,5000,400 +1158,1159,1160,1161,1205,1213,1020,1429,2013,12701,10,20,5000,400 select @@session.slave_transaction_retry_errors; ERROR HY000: Variable 'slave_transaction_retry_errors' is a GLOBAL variable show global variables like 'slave_transaction_retry_errors'; Variable_name Value -slave_transaction_retry_errors 1158,1159,1160,1161,1205,1213,1429,2013,12701,10,20,5000,400 +slave_transaction_retry_errors 1158,1159,1160,1161,1205,1213,1020,1429,2013,12701,10,20,5000,400 show session variables like 'slave_transaction_retry_errors'; Variable_name Value -slave_transaction_retry_errors 1158,1159,1160,1161,1205,1213,1429,2013,12701,10,20,5000,400 +slave_transaction_retry_errors 1158,1159,1160,1161,1205,1213,1020,1429,2013,12701,10,20,5000,400 select * from information_schema.global_variables where variable_name='slave_transaction_retry_errors'; VARIABLE_NAME VARIABLE_VALUE -SLAVE_TRANSACTION_RETRY_ERRORS 1158,1159,1160,1161,1205,1213,1429,2013,12701,10,20,5000,400 +SLAVE_TRANSACTION_RETRY_ERRORS 1158,1159,1160,1161,1205,1213,1020,1429,2013,12701,10,20,5000,400 select * from information_schema.session_variables where variable_name='slave_transaction_retry_errors'; VARIABLE_NAME VARIABLE_VALUE -SLAVE_TRANSACTION_RETRY_ERRORS 1158,1159,1160,1161,1205,1213,1429,2013,12701,10,20,5000,400 +SLAVE_TRANSACTION_RETRY_ERRORS 1158,1159,1160,1161,1205,1213,1020,1429,2013,12701,10,20,5000,400 set global slave_transaction_retry_errors=1; ERROR HY000: Variable 'slave_transaction_retry_errors' is a read only variable set session slave_transaction_retry_errors=1; diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit.rdiff index f87c9413739..81db8629d19 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit.rdiff @@ -1,5 +1,5 @@ ---- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result -+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result +--- sysvars_innodb.result ++++ sysvars_innodb.result,32bit @@ -47,7 +47,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 8 @@ -49,7 +49,7 @@ VARIABLE_COMMENT A number between [0, 100] that tells how oftern buffer pool dump status in percentages should be printed. E.g. 10 means that buffer pool dump status is printed when every 10% of number of buffer pool pages are dumped. Default is 0 (only start and end status is printed). NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 100 -@@ -275,7 +275,7 @@ +@@ -323,7 +323,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 5 VARIABLE_SCOPE GLOBAL @@ -58,7 +58,7 @@ VARIABLE_COMMENT If the compression failure rate of a table is greater than this number more padding is added to the pages to reduce the failures. A value of zero implies no padding NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 100 -@@ -299,7 +299,7 @@ +@@ -347,7 +347,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 50 VARIABLE_SCOPE GLOBAL @@ -67,7 +67,7 @@ VARIABLE_COMMENT Percentage of empty space on a data page that can be reserved to make the page compressible. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 75 -@@ -527,7 +527,7 @@ +@@ -623,7 +623,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 600 VARIABLE_SCOPE GLOBAL @@ -76,7 +76,7 @@ VARIABLE_COMMENT Maximum number of seconds that semaphore times out in InnoDB. NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 4294967295 -@@ -575,7 +575,7 @@ +@@ -671,7 +671,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 30 VARIABLE_SCOPE GLOBAL @@ -85,7 +85,7 @@ VARIABLE_COMMENT Number of iterations over which the background flushing is averaged. NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 1000 -@@ -599,7 +599,7 @@ +@@ -695,7 +695,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 1 VARIABLE_SCOPE GLOBAL @@ -94,7 +94,7 @@ VARIABLE_COMMENT Controls the durability/speed trade-off for commits. Set to 0 (write and flush redo log to disk only once per second), 1 (flush to disk at each commit), 2 (write to log at commit but flush to disk only once per second) or 3 (flush to disk at prepare and at commit, slower and usually redundant). 1 and 3 guarantees that after a crash, committed transactions will not be lost and will be consistent with the binlog and other transactional engines. 2 can get inconsistent and lose transactions if there is a power failure or kernel crash but not if mysqld crashes. 0 has no guarantees in case of crash. 0 and 2 can be faster than 1 or 3. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 3 -@@ -623,7 +623,7 @@ +@@ -719,7 +719,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 1 VARIABLE_SCOPE GLOBAL @@ -103,7 +103,7 @@ VARIABLE_COMMENT Set to 0 (don't flush neighbors from buffer pool), 1 (flush contiguous neighbors from buffer pool) or 2 (flush neighbors from buffer pool), when flushing a block NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 2 -@@ -659,7 +659,7 @@ +@@ -755,7 +755,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 0 VARIABLE_SCOPE GLOBAL @@ -112,7 +112,7 @@ VARIABLE_COMMENT Helps to save your data in case the disk image of the database becomes corrupt. Value 5 can return bogus data, and 6 can permanently corrupt data. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 6 -@@ -683,10 +683,10 @@ +@@ -779,10 +779,10 @@ SESSION_VALUE NULL DEFAULT_VALUE 8000000 VARIABLE_SCOPE GLOBAL @@ -125,7 +125,7 @@ NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -719,7 +719,7 @@ +@@ -815,7 +815,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 84 VARIABLE_SCOPE GLOBAL @@ -134,7 +134,7 @@ VARIABLE_COMMENT InnoDB Fulltext search maximum token size in characters NUMERIC_MIN_VALUE 10 NUMERIC_MAX_VALUE 84 -@@ -731,7 +731,7 @@ +@@ -827,7 +827,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 3 VARIABLE_SCOPE GLOBAL @@ -143,7 +143,7 @@ VARIABLE_COMMENT InnoDB Fulltext search minimum token size in characters NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16 -@@ -743,7 +743,7 @@ +@@ -839,7 +839,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 2000 VARIABLE_SCOPE GLOBAL @@ -152,7 +152,7 @@ VARIABLE_COMMENT InnoDB Fulltext search number of words to optimize for each optimize table call NUMERIC_MIN_VALUE 1000 NUMERIC_MAX_VALUE 10000 -@@ -755,10 +755,10 @@ +@@ -851,10 +851,10 @@ SESSION_VALUE NULL DEFAULT_VALUE 2000000000 VARIABLE_SCOPE GLOBAL @@ -165,7 +165,7 @@ NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -779,7 +779,7 @@ +@@ -875,7 +875,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 2 VARIABLE_SCOPE GLOBAL @@ -174,7 +174,7 @@ VARIABLE_COMMENT InnoDB Fulltext search parallel sort degree, will round up to nearest power of 2 number NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 16 -@@ -791,10 +791,10 @@ +@@ -887,10 +887,10 @@ SESSION_VALUE NULL DEFAULT_VALUE 640000000 VARIABLE_SCOPE GLOBAL @@ -187,7 +187,7 @@ NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -839,22 +839,22 @@ +@@ -935,22 +935,22 @@ SESSION_VALUE NULL DEFAULT_VALUE 200 VARIABLE_SCOPE GLOBAL @@ -215,20 +215,7 @@ NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -887,10 +887,10 @@ - SESSION_VALUE NULL - DEFAULT_VALUE 16777216 - VARIABLE_SCOPE GLOBAL --VARIABLE_TYPE BIGINT UNSIGNED -+VARIABLE_TYPE INT UNSIGNED - VARIABLE_COMMENT Redo log buffer size in bytes. - NUMERIC_MIN_VALUE 2097152 --NUMERIC_MAX_VALUE 18446744073709551615 -+NUMERIC_MAX_VALUE 4294967295 - NUMERIC_BLOCK_SIZE 4096 - ENUM_VALUE_LIST NULL - READ_ONLY YES -@@ -947,10 +947,10 @@ +@@ -1043,10 +1043,10 @@ SESSION_VALUE NULL DEFAULT_VALUE 32 VARIABLE_SCOPE GLOBAL @@ -241,7 +228,7 @@ NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -959,10 +959,10 @@ +@@ -1055,10 +1055,10 @@ SESSION_VALUE NULL DEFAULT_VALUE 1536 VARIABLE_SCOPE GLOBAL @@ -254,7 +241,7 @@ NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -995,10 +995,10 @@ +@@ -1091,10 +1091,10 @@ SESSION_VALUE NULL DEFAULT_VALUE 0 VARIABLE_SCOPE GLOBAL @@ -267,7 +254,7 @@ NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -1007,7 +1007,7 @@ +@@ -1103,7 +1103,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 0 VARIABLE_SCOPE GLOBAL @@ -276,7 +263,7 @@ VARIABLE_COMMENT Maximum delay of user threads in micro-seconds NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 10000000 -@@ -1139,10 +1139,10 @@ +@@ -1235,10 +1235,10 @@ SESSION_VALUE NULL DEFAULT_VALUE 0 VARIABLE_SCOPE GLOBAL @@ -289,7 +276,7 @@ NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY YES -@@ -1163,7 +1163,7 @@ +@@ -1259,7 +1259,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 16384 VARIABLE_SCOPE GLOBAL @@ -298,7 +285,7 @@ VARIABLE_COMMENT Page size to use for all InnoDB tablespaces. NUMERIC_MIN_VALUE 4096 NUMERIC_MAX_VALUE 65536 -@@ -1199,7 +1199,7 @@ +@@ -1295,7 +1295,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 1000 VARIABLE_SCOPE GLOBAL @@ -307,7 +294,7 @@ VARIABLE_COMMENT Number of UNDO log pages to purge in one batch from the history list. NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 5000 -@@ -1211,7 +1211,7 @@ +@@ -1307,7 +1307,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 128 VARIABLE_SCOPE GLOBAL @@ -316,7 +303,7 @@ VARIABLE_COMMENT Deprecated parameter with no effect NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 128 -@@ -1247,7 +1247,7 @@ +@@ -1343,7 +1343,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 56 VARIABLE_SCOPE GLOBAL @@ -325,7 +312,7 @@ VARIABLE_COMMENT Number of pages that must be accessed sequentially for InnoDB to trigger a readahead. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 64 -@@ -1319,7 +1319,7 @@ +@@ -1427,7 +1427,7 @@ SESSION_VALUE NULL DEFAULT_VALUE 1048576 VARIABLE_SCOPE GLOBAL @@ -334,7 +321,7 @@ VARIABLE_COMMENT Memory buffer size for index creation NUMERIC_MIN_VALUE 65536 NUMERIC_MAX_VALUE 67108864 -@@ -1487,10 +1487,10 @@ +@@ -1595,10 +1595,10 @@ SESSION_VALUE NULL DEFAULT_VALUE 30 VARIABLE_SCOPE GLOBAL diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index 8f4201e9f80..cfd035be188 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -431,14 +431,14 @@ VARIABLE_NAME INNODB_DOUBLEWRITE SESSION_VALUE NULL DEFAULT_VALUE ON VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BOOLEAN -VARIABLE_COMMENT Enable InnoDB doublewrite buffer (enabled by default). Disable with --skip-innodb-doublewrite. +VARIABLE_TYPE ENUM +VARIABLE_COMMENT Whether and how to use the doublewrite buffer. OFF=Assume that writes of innodb_page_size are atomic; ON=Prevent torn writes (the default); fast=Like ON, but do not synchronize writes to data files NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST OFF,ON -READ_ONLY YES -COMMAND_LINE_ARGUMENT NONE +ENUM_VALUE_LIST OFF,ON,fast +READ_ONLY NO +COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME INNODB_ENCRYPTION_ROTATE_KEY_AGE SESSION_VALUE NULL DEFAULT_VALUE 1 @@ -887,10 +887,10 @@ VARIABLE_NAME INNODB_LOG_BUFFER_SIZE SESSION_VALUE NULL DEFAULT_VALUE 16777216 VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_TYPE INT UNSIGNED VARIABLE_COMMENT Redo log buffer size in bytes. NUMERIC_MIN_VALUE 2097152 -NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_MAX_VALUE 2147479552 NUMERIC_BLOCK_SIZE 4096 ENUM_VALUE_LIST NULL READ_ONLY YES @@ -943,6 +943,18 @@ NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST NULL READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME INNODB_LOG_SPIN_WAIT_DELAY +SESSION_VALUE NULL +DEFAULT_VALUE 0 +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE INT UNSIGNED +VARIABLE_COMMENT Delay between log buffer spin lock polls (0 to use a blocking latch) +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 6000 +NUMERIC_BLOCK_SIZE 0 +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME INNODB_LRU_FLUSH_SIZE SESSION_VALUE NULL DEFAULT_VALUE 32 @@ -1315,6 +1327,18 @@ NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL +VARIABLE_NAME INNODB_SNAPSHOT_ISOLATION +SESSION_VALUE OFF +DEFAULT_VALUE OFF +VARIABLE_SCOPE SESSION +VARIABLE_TYPE BOOLEAN +VARIABLE_COMMENT Use snapshot isolation (write-write conflict detection). +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST OFF,ON +READ_ONLY NO +COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME INNODB_SORT_BUFFER_SIZE SESSION_VALUE NULL DEFAULT_VALUE 1048576 diff --git a/mysql-test/suite/sys_vars/t/allow_suspicious_udfs.test b/mysql-test/suite/sys_vars/t/allow_suspicious_udfs.test index 9179cfbef4d..f5645e01229 100644 --- a/mysql-test/suite/sys_vars/t/allow_suspicious_udfs.test +++ b/mysql-test/suite/sys_vars/t/allow_suspicious_udfs.test @@ -5,10 +5,10 @@ SELECT @@allow_suspicious_udfs AS EXPECT_0; # Restart the server the server with "--allow-suspicious-udfs" option ---let $restart_parameters = "--allow-suspicious-udfs" +--let $restart_parameters = --allow-suspicious-udfs --source include/restart_mysqld.inc SELECT @@allow_suspicious_udfs AS EXPECT_1; # Disable "--allow-suspicious-udfs" to restore the original state ---let $restart_parameters = "--skip-allow-suspicious-udfs" +--let $restart_parameters = --skip-allow-suspicious-udfs --source include/restart_mysqld.inc diff --git a/mysql-test/suite/sys_vars/t/binlog_do_db.test b/mysql-test/suite/sys_vars/t/binlog_do_db.test deleted file mode 100644 index 548f8bd6172..00000000000 --- a/mysql-test/suite/sys_vars/t/binlog_do_db.test +++ /dev/null @@ -1,16 +0,0 @@ ---echo # ---echo # MDEV-30188 Show "--binlog_do_db" state in SYSTEM VARIABLES ---echo # - -# Confirm that "--binlog_do_db" option has the default value. -SELECT @@binlog_do_db AS EXPECT_NULL; - -# `READ ONLY` variables must not be able to be reset. ---Error ER_INCORRECT_GLOBAL_LOCAL_VAR (1238): Variable 'binlog_do_db' is a read only variable -SET @@GLOBAL.binlog_do_db='database1'; - -# Restart the server with "--binlog_do_db='database1' --binlog_do_db='database2'" option ---let $restart_parameters = "--binlog_do_db='database1' --binlog_do_db='database2'" ---source include/restart_mysqld.inc -SELECT @@binlog_do_db AS EXPECT_database1_database2; - diff --git a/mysql-test/suite/sys_vars/t/binlog_ignore_db.test b/mysql-test/suite/sys_vars/t/binlog_ignore_db.test deleted file mode 100644 index 52d49683d9d..00000000000 --- a/mysql-test/suite/sys_vars/t/binlog_ignore_db.test +++ /dev/null @@ -1,16 +0,0 @@ ---echo # ---echo # MDEV-30188 Show "--binlog_ignore_db" state in SYSTEM VARIABLES ---echo # - -# Confirm that "--binlog_ignore_db" option has the default value. -SELECT @@binlog_ignore_db AS EXPECT_NULL; - -# `READ ONLY` variables must not be able to be reset. ---Error ER_INCORRECT_GLOBAL_LOCAL_VAR (1238): Variable 'binlog_ignore_db' is a read only variable -SET @@GLOBAL.binlog_ignore_db='database1'; - -# Restart the server with "--binlog_ignore_db='database1' --binlog_ignore_db='database2'" option ---let $restart_parameters = "--binlog_ignore_db='database1' --binlog_ignore_db='database2'" ---source include/restart_mysqld.inc -SELECT @@binlog_ignore_db AS EXPECT_database1_database2; - diff --git a/mysql-test/suite/sys_vars/t/binlog_row_event_max_size.test b/mysql-test/suite/sys_vars/t/binlog_row_event_max_size.test deleted file mode 100644 index fa1e5da7011..00000000000 --- a/mysql-test/suite/sys_vars/t/binlog_row_event_max_size.test +++ /dev/null @@ -1,16 +0,0 @@ ---echo # ---echo # MDEV-30188 Show "--binlog_row_event_max_size" state in SYSTEM VARIABLES ---echo # - -SELECT @@binlog_row_event_max_size AS EXPECT_8192; - -# `READ ONLY` variables must not be able to be reset. ---Error ER_INCORRECT_GLOBAL_LOCAL_VAR (1238): Variable 'binlog_row_event_max_size' is a read only variable -SET @@GLOBAL.binlog_row_event_max_size=128; - -# Restart the server the server with "--binlog_row_event_max_size=4096" option ---let $restart_parameters = "--binlog_row_event_max_size=4096" ---source include/restart_mysqld.inc -SELECT @@binlog_row_event_max_size AS EXPECT_4096; - - diff --git a/mysql-test/suite/sys_vars/t/debug_dbug_utf16le.test b/mysql-test/suite/sys_vars/t/debug_dbug_utf16le.test new file mode 100644 index 00000000000..0c4d8f92e93 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/debug_dbug_utf16le.test @@ -0,0 +1,29 @@ +--source include/have_debug.inc +--source include/have_utf16.inc + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-28366 GLOBAL debug_dbug setting affected by collation_connection=utf16... +--echo # + +SET NAMES utf8; +SET collation_connection=utf16le_general_ci; +SET debug_dbug='d,any_random_string'; +SELECT @@debug_dbug; +SET debug_dbug=CONCAT('d,', _latin1 0xDF); +SELECT @@debug_dbug; +SELECT HEX(@@debug_dbug); + +SET @@debug_dbug=NULL; +SELECT @@debug_dbug; + +SET @@debug_dbug=DEFAULT; +SELECT @@debug_dbug; +SET NAMES latin1; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/suite/sys_vars/t/innodb_doublewrite_basic.opt b/mysql-test/suite/sys_vars/t/innodb_doublewrite_basic.opt new file mode 100644 index 00000000000..2bea5a22cde --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_doublewrite_basic.opt @@ -0,0 +1 @@ +--innodb-doublewrite diff --git a/mysql-test/suite/sys_vars/t/innodb_doublewrite_basic.test b/mysql-test/suite/sys_vars/t/innodb_doublewrite_basic.test index 1ae10d0f7cf..4e76c0ac33d 100644 --- a/mysql-test/suite/sys_vars/t/innodb_doublewrite_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_doublewrite_basic.test @@ -1,75 +1,20 @@ - - -################## mysql-test\t\innodb_doublewrite_basic.test ################# -# # -# Variable Name: innodb_doublewrite # -# Scope: Global # -# Access Type: Static # -# Data Type: boolean # -# # -# # -# Creation Date: 2008-02-07 # -# Author : Sharique Abdullah # -# # -# # -# Description:Test Cases of Dynamic System Variable innodb_doublewrite # -# that checks the behavior of this variable in the following ways # -# * Value Check # -# * Scope Check # -# # -# Reference: http://dev.mysql.com/doc/refman/5.1/en/ # -# server-system-variables.html # -# # -############################################################################### - --source include/have_innodb.inc ---echo '#---------------------BS_STVARS_026_01----------------------#' -#################################################################### -# Displaying default value # -#################################################################### -SELECT COUNT(@@GLOBAL.innodb_doublewrite); ---echo 1 Expected +SELECT @@GLOBAL.innodb_doublewrite; +SET @@GLOBAL.innodb_doublewrite=0; +SELECT @@GLOBAL.innodb_doublewrite; ---echo '#---------------------BS_STVARS_026_02----------------------#' -#################################################################### -# Check if Value can set # -#################################################################### - ---error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET @@GLOBAL.innodb_doublewrite=2; +--error ER_WRONG_VALUE_FOR_VAR +SET @@GLOBAL.innodb_doublewrite=3; +SELECT @@GLOBAL.innodb_doublewrite; SET @@GLOBAL.innodb_doublewrite=1; ---echo Expected error 'Read only variable' +SELECT @@GLOBAL.innodb_doublewrite; -SELECT COUNT(@@GLOBAL.innodb_doublewrite); ---echo 1 Expected - - - - ---echo '#---------------------BS_STVARS_026_03----------------------#' -################################################################# -# Check if the value in GLOBAL Table matches value in variable # -################################################################# - ---disable_warnings -SELECT IF(@@GLOBAL.innodb_doublewrite, "ON", "OFF") = VARIABLE_VALUE +SELECT COUNT(VARIABLE_VALUE) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='innodb_doublewrite'; ---enable_warnings ---echo 1 Expected - -SELECT COUNT(@@GLOBAL.innodb_doublewrite); ---echo 1 Expected - ---disable_warnings -SELECT COUNT(VARIABLE_VALUE) -FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES -WHERE VARIABLE_NAME='innodb_doublewrite'; ---enable_warnings ---echo 1 Expected - - --echo '#---------------------BS_STVARS_026_04----------------------#' ################################################################################ @@ -78,8 +23,6 @@ WHERE VARIABLE_NAME='innodb_doublewrite'; SELECT @@innodb_doublewrite = @@GLOBAL.innodb_doublewrite; --echo 1 Expected - - --echo '#---------------------BS_STVARS_026_05----------------------#' ################################################################################ # Check if innodb_doublewrite can be accessed with and without @@ sign # @@ -99,8 +42,5 @@ SELECT COUNT(@@SESSION.innodb_doublewrite); SELECT COUNT(@@GLOBAL.innodb_doublewrite); --echo 1 Expected ---Error ER_BAD_FIELD_ERROR -SELECT innodb_doublewrite = @@SESSION.innodb_doublewrite; ---echo Expected error 'Readonly variable' - - +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@innodb_doublewrite = @@SESSION.innodb_doublewrite; diff --git a/mysql-test/suite/sys_vars/t/innodb_fil_make_page_dirty_debug_basic.test b/mysql-test/suite/sys_vars/t/innodb_fil_make_page_dirty_debug_basic.test index 396d30c76c8..8bc7bd2dc4b 100644 --- a/mysql-test/suite/sys_vars/t/innodb_fil_make_page_dirty_debug_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_fil_make_page_dirty_debug_basic.test @@ -31,6 +31,4 @@ set global innodb_saved_page_number_debug = 0; set global innodb_fil_make_page_dirty_debug = @space_id; drop table t1; ---echo # Must always be 0. -SELECT @@global.innodb_fil_make_page_dirty_debug; - +set global innodb_fil_make_page_dirty_debug = 0; diff --git a/mysql-test/suite/sys_vars/t/innodb_saved_page_number_debug_basic.test b/mysql-test/suite/sys_vars/t/innodb_saved_page_number_debug_basic.test index d0996ae9a24..29b8451867a 100644 --- a/mysql-test/suite/sys_vars/t/innodb_saved_page_number_debug_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_saved_page_number_debug_basic.test @@ -32,6 +32,7 @@ set global innodb_fil_make_page_dirty_debug = @space_id; drop table t1; set global innodb_saved_page_number_debug = 0; +set global innodb_fil_make_page_dirty_debug = 0; SELECT @@global.innodb_saved_page_number_debug; diff --git a/mysql-test/suite/sys_vars/t/replicate_rewrite_db.test b/mysql-test/suite/sys_vars/t/replicate_rewrite_db.test index 7fbaab1f260..5a9537f1da2 100644 --- a/mysql-test/suite/sys_vars/t/replicate_rewrite_db.test +++ b/mysql-test/suite/sys_vars/t/replicate_rewrite_db.test @@ -63,7 +63,7 @@ SELECT @@GLOBAL.replicate_rewrite_db; SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='replicate_rewrite_db'; --echo # Check restart with appending the value ---let $restart_parameters = "--replicate_rewrite_db='X->Y'" +--let $restart_parameters = --replicate_rewrite_db='X->Y' --source include/restart_mysqld.inc SELECT @@GLOBAL.replicate_rewrite_db; @@ -76,9 +76,6 @@ SELECT @@GLOBAL.replicate_rewrite_db; --replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // --cat_file $MYSQL_TMP_DIR/mysqld--replicate.err # Restart the server with the default options ---let $restart_parameters = "" +--let $restart_parameters = --source include/start_mysqld.inc SELECT @@GLOBAL.replicate_rewrite_db; - ---echo # Cleanup. -SET @@GLOBAL.replicate_rewrite_db = @save_replicate_rewrite_db; diff --git a/mysql-test/suite/sysschema/t/fn_ps_thread_trx_info.test b/mysql-test/suite/sysschema/t/fn_ps_thread_trx_info.test index ddf462473ca..19ea013f500 100644 --- a/mysql-test/suite/sysschema/t/fn_ps_thread_trx_info.test +++ b/mysql-test/suite/sysschema/t/fn_ps_thread_trx_info.test @@ -78,7 +78,7 @@ SELECT JSON_CONTAINS(@json_doc, '"COMMIT"', '$[0].statements_executed[1].sql_tex SET @sys.ps_thread_trx_info.max_length = 100; # Should return an error JSON object ---replace_regex /Row 1[1-2] was/Row 1X was/ +--replace_regex /Row \d+ was/Row 1X was/ SELECT sys.ps_thread_trx_info(@ps_thread_id); # Setting the user variable back to NULL should reset to 65535 from sys_config, and no truncation diff --git a/mysql-test/suite/vcol/r/func_regexp.result b/mysql-test/suite/vcol/r/func_regexp.result new file mode 100644 index 00000000000..f7ae11f79b1 --- /dev/null +++ b/mysql-test/suite/vcol/r/func_regexp.result @@ -0,0 +1,24 @@ +# +# Start of 10.5 tests +# +# +# MDEV-21058 CREATE TABLE with generated column and RLIKE results in sigabrt +# +CREATE TABLE t1 (c0 INT AS(('' RLIKE '['))); +ERROR 42000: Regex error 'missing terminating ] for character class at offset 1' +CREATE TABLE t1 (c0 INT AS(REGEXP_INSTR('','['))); +ERROR 42000: Regex error 'missing terminating ] for character class at offset 1' +CREATE TABLE t1 +( +c0 INT, +c1 INT AS(('' RLIKE NULL)), +c2 INT AS(REGEXP_INSTR('',NULL)) +); +INSERT INTO t1 (c0) VALUES (0); +SELECT * FROM t1; +c0 c1 c2 +0 NULL NULL +DROP TABLE t1; +# +# End of 10.5 tests +# diff --git a/mysql-test/suite/vcol/t/func_regexp.test b/mysql-test/suite/vcol/t/func_regexp.test new file mode 100644 index 00000000000..5e97009ab7b --- /dev/null +++ b/mysql-test/suite/vcol/t/func_regexp.test @@ -0,0 +1,30 @@ +--source inc/vcol_init_vars.pre +--source inc/vcol_cleanup.inc + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-21058 CREATE TABLE with generated column and RLIKE results in sigabrt +--echo # + +--error ER_REGEXP_ERROR +CREATE TABLE t1 (c0 INT AS(('' RLIKE '['))); + +--error ER_REGEXP_ERROR +CREATE TABLE t1 (c0 INT AS(REGEXP_INSTR('','['))); + +CREATE TABLE t1 +( + c0 INT, + c1 INT AS(('' RLIKE NULL)), + c2 INT AS(REGEXP_INSTR('',NULL)) +); +INSERT INTO t1 (c0) VALUES (0); +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index fed410f0157..bc7273c499d 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -844,8 +844,17 @@ Note 1060 Duplicate column name 'v' alter table `b` add column if not exists ( p bit ); drop table `b`; # -# End of 10.4 tests +# MDEV-30528 Assertion !mbmaxlen || ... failed +# in dtype_get_at_most_n_mbchars() # +CREATE TABLE t(f TEXT) WITH SYSTEM VERSIONING CHARACTER SET utf8 ENGINE=InnoDB; +INSERT INTO t VALUES ('foo'); +DELETE FROM t; +ALTER TABLE t ADD FULLTEXT (f); +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 +DROP TABLE t; +# End of 10.4 tests # # MDEV-21941 RENAME doesn't work for system time or period fields # @@ -869,6 +878,4 @@ t1 CREATE TABLE `t1` ( PERIOD FOR SYSTEM_TIME (`x`, `y`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING drop table t1; -# # End of 10.5 tests -# diff --git a/mysql-test/suite/versioning/r/data.result b/mysql-test/suite/versioning/r/data.result index c7fe141c19e..08ab03ffcd4 100644 --- a/mysql-test/suite/versioning/r/data.result +++ b/mysql-test/suite/versioning/r/data.result @@ -10,6 +10,7 @@ set timestamp=unix_timestamp('1991-01-02 00:00'); delete from t1 where x=2; set timestamp=default; #MYSQL_DUMP --compact test +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -19,6 +20,7 @@ CREATE TABLE `t1` ( INSERT INTO `t1` VALUES (3); #MYSQL_DUMP --compact --as-of="1990-01-02 00:00" test +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -30,6 +32,7 @@ INSERT INTO `t1` VALUES (2), (3); #MYSQL_DUMP --compact --as-of="1990-08-02 00:00" --databases test +/*!999999\- enable the sandbox mode */ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; @@ -45,6 +48,7 @@ INSERT INTO `t1` VALUES (2), (3); #MYSQL_DUMP --compact --as-of="1990-08-04 00:00" test t1 +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -87,6 +91,7 @@ select x, check_fields(x, row_start, row_end) from t2 for system_time all order x check_fields(x, row_start, row_end) 1 [CORRECT] 2 [CORRECT] +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( @@ -194,6 +199,7 @@ insert t1 (x) values (2); delete from t1 where x=1; mariadb-dump: Cannot use --dump-history for table `t1` with transaction-precise history mariadb-dump: Cannot use --dump-history for table `t1` with transaction-precise history +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t1` ( diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 7b0edd42a68..228ed14f44a 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -3431,4 +3431,27 @@ ERROR HY000: Maybe missing parameters: no rotation condition for multiple HISTOR # # End of 10.5 tests # +# +# MDEV-31903 Server crashes in _ma_reset_history upon UNLOCK table with auto-create history partitions +# +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create table t1 (x int) engine=aria with system versioning partition by system_time interval 1 hour auto partitions 3; +insert into t1 values (1); +create table t2 (x int) engine=aria; +create trigger tr after insert on t2 for each row update t1 set x= x + 11; +lock tables t1 write, t2 write; +update t1 set x= x + 1; +set timestamp= unix_timestamp('2000-01-01 13:00:00'); +insert into t2 values (5); +unlock tables; +drop table t1, t2; +set timestamp= default; +# +# MDEV-29872 MSAN/Valgrind uninitialised value errors in TABLE::vers_switch_partition +# +create table t (a int) with system versioning partition by system_time limit 100 partitions 3; +drop table t; +# +# End of 10.9 tests +# set global innodb_stats_persistent= @save_persistent; diff --git a/mysql-test/suite/versioning/r/rpl.result b/mysql-test/suite/versioning/r/rpl.result index 62dd9798a95..ebcce457f5f 100644 --- a/mysql-test/suite/versioning/r/rpl.result +++ b/mysql-test/suite/versioning/r/rpl.result @@ -528,4 +528,17 @@ a check_row_ts(rs,re) set sql_mode=default; connection master; drop tables t1, t2, t3; +# +# MDEV-33330 Server crash or assertion failure in +# binlog_get_pending_rows_event +# +create or replace table t (x int) with system versioning +partition by system_time interval 1 minute auto partitions 3; +insert into t values (1); +connect con1,localhost,root,,; +set timestamp= @@timestamp+120; +update t set x= x + 1; +connection default; +disconnect con1; +drop table t; include/rpl_end.inc diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index 44f52ddf747..85448d21346 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -743,9 +743,20 @@ alter table `b` add column if not exists ( p bit ); drop table `b`; --echo # ---echo # End of 10.4 tests +--echo # MDEV-30528 Assertion !mbmaxlen || ... failed +--echo # in dtype_get_at_most_n_mbchars() --echo # +CREATE TABLE t(f TEXT) WITH SYSTEM VERSIONING CHARACTER SET utf8 ENGINE=InnoDB; +INSERT INTO t VALUES ('foo'); +DELETE FROM t; +--enable_info +ALTER TABLE t ADD FULLTEXT (f); +--disable_info +DROP TABLE t; + +--echo # End of 10.4 tests + --echo # --echo # MDEV-21941 RENAME doesn't work for system time or period fields --echo # @@ -767,6 +778,4 @@ show create table t1; # cleanup drop table t1; ---echo # --echo # End of 10.5 tests ---echo # diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index 3699ac286c8..5707746f96c 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -2673,5 +2673,43 @@ create table t (a int) with system versioning partition by system_time partition --echo # End of 10.5 tests --echo # +--echo # +--echo # MDEV-31903 Server crashes in _ma_reset_history upon UNLOCK table with auto-create history partitions +--echo # +set timestamp= unix_timestamp('2000-01-01 00:00:00'); +create table t1 (x int) engine=aria with system versioning partition by system_time interval 1 hour auto partitions 3; +insert into t1 values (1); + +create table t2 (x int) engine=aria; +create trigger tr after insert on t2 for each row update t1 set x= x + 11; +lock tables t1 write, t2 write; +update t1 set x= x + 1; +set timestamp= unix_timestamp('2000-01-01 13:00:00'); +insert into t2 values (5); +unlock tables; +drop table t1, t2; +set timestamp= default; + +--echo # +--echo # MDEV-29872 MSAN/Valgrind uninitialised value errors in TABLE::vers_switch_partition +--echo # +create table t (a int) with system versioning partition by system_time limit 100 partitions 3; +let $emb= `select if(version() like '%embedded%', 1, 0)`; +if (!$emb) +{ + --disable_result_log + --disable_query_log + --error ER_DELAYED_NOT_SUPPORTED + insert delayed into t () values (); + --enable_query_log + --enable_result_log +} +# cleanup +drop table t; + +--echo # +--echo # End of 10.9 tests +--echo # + set global innodb_stats_persistent= @save_persistent; --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/rpl.test b/mysql-test/suite/versioning/t/rpl.test index c723751a060..d804fe03fe5 100644 --- a/mysql-test/suite/versioning/t/rpl.test +++ b/mysql-test/suite/versioning/t/rpl.test @@ -442,5 +442,28 @@ set sql_mode=default; connection master; drop tables t1, t2, t3; + +--echo # +--echo # MDEV-33330 Server crash or assertion failure in +--echo # binlog_get_pending_rows_event +--echo # + +create or replace table t (x int) with system versioning +partition by system_time interval 1 minute auto partitions 3; +insert into t values (1); + +connect (con1,localhost,root,,); +set timestamp= @@timestamp+120; +update t set x= x + 1; +connection default; + +# Cleanup +disconnect con1; +drop table t; + +# +# End of 11.2 tests +# + --source suite/versioning/common_finish.inc --source include/rpl_end.inc diff --git a/mysql-test/suite/wsrep/r/wsrep_provider_plugin_defaults.result b/mysql-test/suite/wsrep/r/wsrep_provider_plugin_defaults.result index ce164f66a22..cefeb85d3e3 100644 --- a/mysql-test/suite/wsrep/r/wsrep_provider_plugin_defaults.result +++ b/mysql-test/suite/wsrep/r/wsrep_provider_plugin_defaults.result @@ -8,9 +8,11 @@ SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIK 'wsrep_provider_dbug', 'wsrep_provider_gcache_debug', 'wsrep_provider_signal', +'wsrep_provider_protonet_backend', +'wsrep_provider_repl_proto_max', 'wsrep_provider_gmcast_listen_addr'); COUNT(*) -83 +82 SELECT * FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep_provider_%' AND VARIABLE_NAME NOT IN ( 'wsrep_provider', @@ -21,6 +23,8 @@ WHERE VARIABLE_NAME LIKE 'wsrep_provider_%' AND VARIABLE_NAME NOT IN ( 'wsrep_provider_dbug', 'wsrep_provider_gcache_debug', 'wsrep_provider_signal', +'wsrep_provider_protonet_backend', +'wsrep_provider_repl_proto_max', 'wsrep_provider_gmcast_listen_addr') ORDER BY VARIABLE_NAME; VARIABLE_NAME WSREP_PROVIDER_BASE_HOST @@ -1073,21 +1077,6 @@ ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED GLOBAL_VALUE_PATH NULL -VARIABLE_NAME WSREP_PROVIDER_REPL_PROTO_MAX -SESSION_VALUE NULL -GLOBAL_VALUE 10 -GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE 10 -VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE VARCHAR -VARIABLE_COMMENT Wsrep provider option -NUMERIC_MIN_VALUE NULL -NUMERIC_MAX_VALUE NULL -NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST NULL -READ_ONLY NO -COMMAND_LINE_ARGUMENT REQUIRED -GLOBAL_VALUE_PATH NULL VARIABLE_NAME WSREP_PROVIDER_SOCKET_CHECKSUM SESSION_VALUE NULL GLOBAL_VALUE 2 diff --git a/mysql-test/suite/wsrep/t/pool_of_threads.test b/mysql-test/suite/wsrep/t/pool_of_threads.test index 8e95d0ca495..f035236da0e 100644 --- a/mysql-test/suite/wsrep/t/pool_of_threads.test +++ b/mysql-test/suite/wsrep/t/pool_of_threads.test @@ -1,3 +1,4 @@ +--source include/have_innodb.inc --source include/have_wsrep_enabled.inc --source include/have_binlog_format_row.inc diff --git a/mysql-test/suite/wsrep/t/wsrep_provider_plugin_defaults.test b/mysql-test/suite/wsrep/t/wsrep_provider_plugin_defaults.test index 16ecabfa182..e65d5130cbe 100644 --- a/mysql-test/suite/wsrep/t/wsrep_provider_plugin_defaults.test +++ b/mysql-test/suite/wsrep/t/wsrep_provider_plugin_defaults.test @@ -13,6 +13,8 @@ SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIK 'wsrep_provider_dbug', 'wsrep_provider_gcache_debug', 'wsrep_provider_signal', + 'wsrep_provider_protonet_backend', + 'wsrep_provider_repl_proto_max', 'wsrep_provider_gmcast_listen_addr'); --vertical_results @@ -26,5 +28,7 @@ WHERE VARIABLE_NAME LIKE 'wsrep_provider_%' AND VARIABLE_NAME NOT IN ( 'wsrep_provider_dbug', 'wsrep_provider_gcache_debug', 'wsrep_provider_signal', + 'wsrep_provider_protonet_backend', + 'wsrep_provider_repl_proto_max', 'wsrep_provider_gmcast_listen_addr') ORDER BY VARIABLE_NAME; diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index ad79480e710..646a8bae174 100644 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -14,7 +14,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA -INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/mysys) +INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/mysys) SET(MYSYS_SOURCES array.c charset-def.c charset.c my_default.c get_password.c @@ -60,32 +60,24 @@ IF (WIN32) ENDIF() IF(MSVC_INTEL) - SET(MYSYS_SOURCES ${MYSYS_SOURCES} crc32/crc32_x86.c) + SET(MYSYS_SOURCES ${MYSYS_SOURCES} crc32/crc32_x86.c crc32/crc32c_x86.cc) IF(CMAKE_SIZEOF_VOID_P EQUAL 8) SET (MYSYS_SOURCES ${MYSYS_SOURCES} crc32/crc32c_amd64.cc) ENDIF() - ADD_DEFINITIONS(-DHAVE_SSE42 -DHAVE_PCLMUL) - IF(CLANG_CL) - SET_SOURCE_FILES_PROPERTIES(crc32/crc32_x86.c PROPERTIES COMPILE_FLAGS "-msse4.2 -mpclmul") - ENDIF() ELSEIF(MSVC_ARM64) SET (MYSYS_SOURCES ${MYSYS_SOURCES} crc32/crc32_arm64.c) ADD_DEFINITIONS(-DHAVE_ARMV8_CRC -DHAVE_ARMV8_CRC_CRYPTO_INTRINSICS) ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|i386|i686") - MY_CHECK_CXX_COMPILER_FLAG(-msse4.2) - MY_CHECK_CXX_COMPILER_FLAG(-mpclmul) - CHECK_INCLUDE_FILE(cpuid.h HAVE_CPUID_H) - CHECK_INCLUDE_FILE(x86intrin.h HAVE_X86INTRIN_H) - IF(have_CXX__msse4.2 AND HAVE_CPUID_H) - ADD_DEFINITIONS(-DHAVE_SSE42) - IF (have_CXX__mpclmul AND HAVE_X86INTRIN_H) - ADD_DEFINITIONS(-DHAVE_PCLMUL) - SET(MYSYS_SOURCES ${MYSYS_SOURCES} crc32/crc32_x86.c) - SET_SOURCE_FILES_PROPERTIES(crc32/crc32_x86.c PROPERTIES COMPILE_FLAGS "-msse4.2 -mpclmul") - IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - SET(MYSYS_SOURCES ${MYSYS_SOURCES} crc32/crc32c_amd64.cc) - SET_SOURCE_FILES_PROPERTIES(crc32/crc32c_amd64.cc PROPERTIES COMPILE_FLAGS "-msse4.2 -mpclmul") - ENDIF() + SET(MYSYS_SOURCES ${MYSYS_SOURCES} crc32/crc32_x86.c crc32/crc32c_x86.cc) + IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "5") + SET_SOURCE_FILES_PROPERTIES(crc32/crc32_x86.c PROPERTIES + COMPILE_FLAGS "-msse4.2 -mpclmul") + ENDIF() + IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(MYSYS_SOURCES ${MYSYS_SOURCES} crc32/crc32c_amd64.cc) + IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "5") + SET_SOURCE_FILES_PROPERTIES(crc32/crc32c_amd64.cc PROPERTIES + COMPILE_FLAGS "-msse4.2 -mpclmul") ENDIF() ENDIF() ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64") @@ -164,7 +156,7 @@ ENDIF() ADD_CONVENIENCE_LIBRARY(mysys ${MYSYS_SOURCES}) MAYBE_DISABLE_IPO(mysys) -TARGET_LINK_LIBRARIES(mysys dbug strings ${ZLIB_LIBRARY} +TARGET_LINK_LIBRARIES(mysys dbug strings ${ZLIB_LIBRARIES} ${LIBNSL} ${LIBM} ${LIBRT} ${CMAKE_DL_LIBS} ${LIBSOCKET} ${LIBEXECINFO}) DTRACE_INSTRUMENT(mysys) IF(WIN32) diff --git a/mysys/crc32/crc32_arm64.c b/mysys/crc32/crc32_arm64.c index 79404874d60..df7e69366aa 100644 --- a/mysys/crc32/crc32_arm64.c +++ b/mysys/crc32/crc32_arm64.c @@ -1,10 +1,11 @@ #include #include #include +#include -static int pmull_supported; +typedef unsigned (*my_crc32_t)(unsigned, const void *, size_t); -#if defined(HAVE_ARMV8_CRC) +#ifdef HAVE_ARMV8_CRC #ifdef _WIN32 #include @@ -20,9 +21,14 @@ const char *crc32c_aarch64_available(void) /* TODO : pmull seems supported, but does not compile*/ return "Using ARMv8 crc32 instructions"; } +#endif /* _WIN32 */ -#elif defined(__APPLE__) -#include +#ifdef HAVE_ARMV8_CRYPTO +static unsigned crc32c_aarch64_pmull(unsigned, const void *, size_t); +# endif + +# ifdef __APPLE__ +# include int crc32_aarch64_available(void) { @@ -33,17 +39,18 @@ int crc32_aarch64_available(void) return ret; } -const char *crc32c_aarch64_available(void) +my_crc32_t crc32c_aarch64_available(void) { - if (crc32_aarch64_available() == 0) - return NULL; - pmull_supported = 1; - return "Using ARMv8 crc32 + pmull instructions"; +# ifdef HAVE_ARMV8_CRYPTO + if (crc32_aarch64_available()) + return crc32c_aarch64_pmull; +# endif + return NULL; } -#else -#include -#if defined(__FreeBSD__) +# else /* __APPLE__ */ +# include +# ifdef __FreeBSD__ static unsigned long getauxval(unsigned int key) { unsigned long val; @@ -51,17 +58,17 @@ static unsigned long getauxval(unsigned int key) return 0ul; return val; } -#else -# include -#endif +# else +# include +# endif -#ifndef HWCAP_CRC32 -# define HWCAP_CRC32 (1 << 7) -#endif +# ifndef HWCAP_CRC32 +# define HWCAP_CRC32 (1 << 7) +# endif -#ifndef HWCAP_PMULL -# define HWCAP_PMULL (1 << 4) -#endif +# ifndef HWCAP_PMULL +# define HWCAP_PMULL (1 << 4) +# endif /* ARM made crc32 default from ARMv8.1 but optional in ARMv8A * Runtime check API. @@ -71,22 +78,37 @@ int crc32_aarch64_available(void) unsigned long auxv= getauxval(AT_HWCAP); return (auxv & HWCAP_CRC32) != 0; } +# endif /* __APPLE__ */ -const char *crc32c_aarch64_available(void) +# ifndef __APPLE__ +static unsigned crc32c_aarch64(unsigned, const void *, size_t); + +my_crc32_t crc32c_aarch64_available(void) { unsigned long auxv= getauxval(AT_HWCAP); - if (!(auxv & HWCAP_CRC32)) return NULL; - - pmull_supported= (auxv & HWCAP_PMULL) != 0; - if (pmull_supported) - return "Using ARMv8 crc32 + pmull instructions"; - else - return "Using ARMv8 crc32 instructions"; +# ifdef HAVE_ARMV8_CRYPTO + /* Raspberry Pi 4 supports crc32 but doesn't support pmull (MDEV-23030). */ + if (auxv & HWCAP_PMULL) + return crc32c_aarch64_pmull; +# endif + return crc32c_aarch64; } +# endif /* __APPLE__ */ -#endif /* __APPLE__ */ +const char *crc32c_aarch64_impl(my_crc32_t c) +{ +# ifdef HAVE_ARMV8_CRYPTO + if (c == crc32c_aarch64_pmull) + return "Using ARMv8 crc32 + pmull instructions"; +# endif +# ifndef __APPLE__ + if (c == crc32c_aarch64) + return "Using ARMv8 crc32 instructions"; +# endif + return NULL; +} #endif /* HAVE_ARMV8_CRC */ #ifndef HAVE_ARMV8_CRC_CRYPTO_INTRINSICS @@ -175,129 +197,14 @@ asm(".arch_extension crypto"); PREF4X64L2(buffer,(PREF_OFFSET), 8) \ PREF4X64L2(buffer,(PREF_OFFSET), 12) -uint32_t crc32c_aarch64(uint32_t crc, const unsigned char *buffer, uint64_t len) +#ifndef __APPLE__ +static unsigned crc32c_aarch64(unsigned crc, const void *buf, size_t len) { int64_t length= (int64_t)len; + const unsigned char *buffer= buf; crc^= 0xffffffff; -#ifdef HAVE_ARMV8_CRYPTO - /* Pmull runtime check here. - * Raspberry Pi 4 supports crc32 but doesn't support pmull (MDEV-23030). - * - * Consider the condition that the target platform does support hardware crc32 - * but not support PMULL. In this condition, it should leverage the aarch64 - * crc32 instruction (__crc32c) and just only skip parallel computation (pmull/vmull) - * rather than skip all hardware crc32 instruction of computation. - */ - if (pmull_supported) - { - uint32_t crc0, crc1, crc2; -/* The following Macro (HAVE_ARMV8_CRYPTO) is used for compiling check */ - -/* Crypto extension Support - * Parallel computation with 1024 Bytes (per block) - * Intrinsics Support - */ -# ifdef HAVE_ARMV8_CRC_CRYPTO_INTRINSICS - const poly64_t k1= 0xe417f38a, k2= 0x8f158014; - uint64_t t0, t1; - - /* Process per block size of 1024 Bytes - * A block size = 8 + 42*3*sizeof(uint64_t) + 8 - */ - while ((length-= 1024) >= 0) - { - /* Prefetch 3*1024 data for avoiding L2 cache miss */ - PREF1KL2(buffer, 1024*3); - /* Do first 8 bytes here for better pipelining */ - crc0= __crc32cd(crc, *(const uint64_t *)buffer); - crc1= 0; - crc2= 0; - buffer+= sizeof(uint64_t); - - /* Process block inline - * Process crc0 last to avoid dependency with above - */ - CRC32C7X3X8(buffer, 0); - CRC32C7X3X8(buffer, 1); - CRC32C7X3X8(buffer, 2); - CRC32C7X3X8(buffer, 3); - CRC32C7X3X8(buffer, 4); - CRC32C7X3X8(buffer, 5); - - buffer+= 42*3*sizeof(uint64_t); - /* Prefetch data for following block to avoid L1 cache miss */ - PREF1KL1(buffer, 1024); - - /* Last 8 bytes - * Merge crc0 and crc1 into crc2 - * crc1 multiply by K2 - * crc0 multiply by K1 - */ - t1= (uint64_t)vmull_p64(crc1, k2); - t0= (uint64_t)vmull_p64(crc0, k1); - crc= __crc32cd(crc2, *(const uint64_t *)buffer); - crc1= __crc32cd(0, t1); - crc^= crc1; - crc0= __crc32cd(0, t0); - crc^= crc0; - - buffer+= sizeof(uint64_t); - } - -# else /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */ - - /*No intrinsics*/ - __asm__("mov x16, #0xf38a \n\t" - "movk x16, #0xe417, lsl 16 \n\t" - "mov v1.2d[0], x16 \n\t" - "mov x16, #0x8014 \n\t" - "movk x16, #0x8f15, lsl 16 \n\t" - "mov v0.2d[0], x16 \n\t" - :::"x16"); - - while ((length-= 1024) >= 0) - { - PREF1KL2(buffer, 1024*3); - __asm__("crc32cx %w[c0], %w[c], %x[v]\n\t" - :[c0]"=r"(crc0):[c]"r"(crc), [v]"r"(*(const uint64_t *)buffer):); - crc1= 0; - crc2= 0; - buffer+= sizeof(uint64_t); - - CRC32C7X3X8(buffer, 0); - CRC32C7X3X8(buffer, 1); - CRC32C7X3X8(buffer, 2); - CRC32C7X3X8(buffer, 3); - CRC32C7X3X8(buffer, 4); - CRC32C7X3X8(buffer, 5); - - buffer+= 42*3*sizeof(uint64_t); - PREF1KL1(buffer, 1024); - __asm__("mov v2.2d[0], %x[c1] \n\t" - "pmull v2.1q, v2.1d, v0.1d \n\t" - "mov v3.2d[0], %x[c0] \n\t" - "pmull v3.1q, v3.1d, v1.1d \n\t" - "crc32cx %w[c], %w[c2], %x[v] \n\t" - "mov %x[c1], v2.2d[0] \n\t" - "crc32cx %w[c1], wzr, %x[c1] \n\t" - "eor %w[c], %w[c], %w[c1] \n\t" - "mov %x[c0], v3.2d[0] \n\t" - "crc32cx %w[c0], wzr, %x[c0] \n\t" - "eor %w[c], %w[c], %w[c0] \n\t" - :[c1]"+r"(crc1), [c0]"+r"(crc0), [c2]"+r"(crc2), [c]"+r"(crc) - :[v]"r"(*((const uint64_t *)buffer))); - buffer+= sizeof(uint64_t); - } -# endif /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */ - - /* Done if Input data size is aligned with 1024 */ - if (!(length+= 1024)) - return ~crc; - } // end if pmull_supported -#endif /* HAVE_ARMV8_CRYPTO */ - while ((length-= sizeof(uint64_t)) >= 0) { CRC32CX(crc, *(uint64_t *)buffer); @@ -322,6 +229,143 @@ uint32_t crc32c_aarch64(uint32_t crc, const unsigned char *buffer, uint64_t len) return ~crc; } +#endif + +#ifdef HAVE_ARMV8_CRYPTO +static unsigned crc32c_aarch64_pmull(unsigned crc, const void *buf, size_t len) +{ + int64_t length= (int64_t)len; + const unsigned char *buffer= buf; + + crc^= 0xffffffff; + + /* Crypto extension Support + * Parallel computation with 1024 Bytes (per block) + * Intrinsics Support + */ +# ifdef HAVE_ARMV8_CRC_CRYPTO_INTRINSICS + /* Process per block size of 1024 Bytes + * A block size = 8 + 42*3*sizeof(uint64_t) + 8 + */ + for (const poly64_t k1= 0xe417f38a, k2= 0x8f158014; (length-= 1024) >= 0; ) + { + uint32_t crc0, crc1, crc2; + uint64_t t0, t1; + /* Prefetch 3*1024 data for avoiding L2 cache miss */ + PREF1KL2(buffer, 1024*3); + /* Do first 8 bytes here for better pipelining */ + crc0= __crc32cd(crc, *(const uint64_t *)buffer); + crc1= 0; + crc2= 0; + buffer+= sizeof(uint64_t); + + /* Process block inline + * Process crc0 last to avoid dependency with above + */ + CRC32C7X3X8(buffer, 0); + CRC32C7X3X8(buffer, 1); + CRC32C7X3X8(buffer, 2); + CRC32C7X3X8(buffer, 3); + CRC32C7X3X8(buffer, 4); + CRC32C7X3X8(buffer, 5); + + buffer+= 42*3*sizeof(uint64_t); + /* Prefetch data for following block to avoid L1 cache miss */ + PREF1KL1(buffer, 1024); + + /* Last 8 bytes + * Merge crc0 and crc1 into crc2 + * crc1 multiply by K2 + * crc0 multiply by K1 + */ + t1= (uint64_t)vmull_p64(crc1, k2); + t0= (uint64_t)vmull_p64(crc0, k1); + crc= __crc32cd(crc2, *(const uint64_t *)buffer); + crc1= __crc32cd(0, t1); + crc^= crc1; + crc0= __crc32cd(0, t0); + crc^= crc0; + + buffer+= sizeof(uint64_t); + } + +# else /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */ + /*No intrinsics*/ + __asm__("mov x16, #0xf38a \n\t" + "movk x16, #0xe417, lsl 16 \n\t" + "mov v1.2d[0], x16 \n\t" + "mov x16, #0x8014 \n\t" + "movk x16, #0x8f15, lsl 16 \n\t" + "mov v0.2d[0], x16 \n\t" + :::"x16"); + + while ((length-= 1024) >= 0) + { + uint32_t crc0, crc1, crc2; + + PREF1KL2(buffer, 1024*3); + __asm__("crc32cx %w[c0], %w[c], %x[v]\n\t" + :[c0]"=r"(crc0):[c]"r"(crc), [v]"r"(*(const uint64_t *)buffer):); + crc1= 0; + crc2= 0; + buffer+= sizeof(uint64_t); + + CRC32C7X3X8(buffer, 0); + CRC32C7X3X8(buffer, 1); + CRC32C7X3X8(buffer, 2); + CRC32C7X3X8(buffer, 3); + CRC32C7X3X8(buffer, 4); + CRC32C7X3X8(buffer, 5); + + buffer+= 42*3*sizeof(uint64_t); + PREF1KL1(buffer, 1024); + __asm__("mov v2.2d[0], %x[c1] \n\t" + "pmull v2.1q, v2.1d, v0.1d \n\t" + "mov v3.2d[0], %x[c0] \n\t" + "pmull v3.1q, v3.1d, v1.1d \n\t" + "crc32cx %w[c], %w[c2], %x[v] \n\t" + "mov %x[c1], v2.2d[0] \n\t" + "crc32cx %w[c1], wzr, %x[c1] \n\t" + "eor %w[c], %w[c], %w[c1] \n\t" + "mov %x[c0], v3.2d[0] \n\t" + "crc32cx %w[c0], wzr, %x[c0] \n\t" + "eor %w[c], %w[c], %w[c0] \n\t" + :[c1]"+r"(crc1), [c0]"+r"(crc0), [c2]"+r"(crc2), [c]"+r"(crc) + :[v]"r"(*((const uint64_t *)buffer))); + buffer+= sizeof(uint64_t); + } +# endif /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */ + + /* Done if Input data size is aligned with 1024 */ + length+= 1024; + if (length) + { + while ((length-= sizeof(uint64_t)) >= 0) + { + CRC32CX(crc, *(uint64_t *)buffer); + buffer+= sizeof(uint64_t); + } + + /* The following is more efficient than the straight loop */ + if (length & sizeof(uint32_t)) + { + CRC32CW(crc, *(uint32_t *)buffer); + buffer+= sizeof(uint32_t); + } + + if (length & sizeof(uint16_t)) + { + CRC32CH(crc, *(uint16_t *)buffer); + buffer+= sizeof(uint16_t); + } + + if (length & sizeof(uint8_t)) + CRC32CB(crc, *buffer); + } + + return ~crc; +} +#endif /* HAVE_ARMV8_CRYPTO */ /* There are multiple approaches to calculate crc. Approach-1: Process 8 bytes then 4 bytes then 2 bytes and then 1 bytes diff --git a/mysys/crc32/crc32_x86.c b/mysys/crc32/crc32_x86.c index f077399caca..ab2522d61cf 100644 --- a/mysys/crc32/crc32_x86.c +++ b/mysys/crc32/crc32_x86.c @@ -56,11 +56,16 @@ #include #ifdef __GNUC__ -#include +# include +# include +# include +# include +# define USE_PCLMUL __attribute__((target("sse4.2,pclmul"))) #elif defined(_MSC_VER) -#include +# include +# define USE_PCLMUL /* nothing */ #else -#error "unknown compiler" +# error "unknown compiler" #endif /** @@ -71,6 +76,7 @@ * * @return \a reg << (\a num * 8) */ +USE_PCLMUL static inline __m128i xmm_shift_left(__m128i reg, const unsigned int num) { static const MY_ALIGNED(16) uint8_t crc_xmm_shift_tab[48]= { @@ -111,6 +117,7 @@ struct crcr_pclmulqdq_ctx * * @return New 16 byte folded data */ +USE_PCLMUL static inline __m128i crcr32_folding_round(const __m128i data_block, const __m128i precomp, const __m128i fold) { @@ -128,6 +135,7 @@ static inline __m128i crcr32_folding_round(const __m128i data_block, * * @return data reduced to 64 bits */ +USE_PCLMUL static inline __m128i crcr32_reduce_128_to_64(__m128i data128, const __m128i precomp) { __m128i tmp0, tmp1, tmp2; @@ -152,6 +160,7 @@ static inline __m128i crcr32_reduce_128_to_64(__m128i data128, const __m128i pre * * @return data reduced to 32 bits */ +USE_PCLMUL static inline uint32_t crcr32_reduce_64_to_32(__m128i data64, const __m128i precomp) { static const MY_ALIGNED(16) uint32_t mask1[4]= { @@ -188,6 +197,7 @@ static inline uint32_t crcr32_reduce_64_to_32(__m128i data64, const __m128i prec * * @return CRC for given \a data block (32 bits wide). */ +USE_PCLMUL static inline uint32_t crcr32_calc_pclmulqdq(const uint8_t *data, uint32_t data_len, uint32_t crc, const struct crcr_pclmulqdq_ctx *params) diff --git a/mysys/crc32/crc32c.cc b/mysys/crc32/crc32c.cc index 2bec041e278..32a45478e94 100644 --- a/mysys/crc32/crc32c.cc +++ b/mysys/crc32/crc32c.cc @@ -19,52 +19,23 @@ #include #include #include -#include -static inline uint32_t DecodeFixed32(const char *ptr) -{ - return uint4korr(ptr); -} -#include -#ifdef _MSC_VER -#include -#endif +#ifdef __powerpc64__ +# include "crc32c_ppc.h" +# ifdef __linux__ +# include -#ifdef HAVE_SSE42 -# ifdef __GNUC__ -# include -# if __GNUC__ < 5 && !defined __clang__ -/* the headers do not really work in GCC before version 5 */ -# define _mm_crc32_u8(crc,data) __builtin_ia32_crc32qi(crc,data) -# define _mm_crc32_u32(crc,data) __builtin_ia32_crc32si(crc,data) -# define _mm_crc32_u64(crc,data) __builtin_ia32_crc32di(crc,data) -# else -# include +# ifndef PPC_FEATURE2_VEC_CRYPTO +# define PPC_FEATURE2_VEC_CRYPTO 0x02000000 +# endif + +# ifndef AT_HWCAP2 +# define AT_HWCAP2 26 # endif -# define USE_SSE42 __attribute__((target("sse4.2"))) -# else -# define USE_SSE42 /* nothing */ # endif #endif - -#ifdef __powerpc64__ -#include "crc32c_ppc.h" - -#if __linux__ -#include - -#ifndef PPC_FEATURE2_VEC_CRYPTO -#define PPC_FEATURE2_VEC_CRYPTO 0x02000000 -#endif - -#ifndef AT_HWCAP2 -#define AT_HWCAP2 26 -#endif - -#endif /* __linux__ */ - -#endif +typedef unsigned (*my_crc32_t)(unsigned, const void *, size_t); namespace mysys_namespace { namespace crc32c { @@ -75,6 +46,7 @@ static int arch_ppc_crc32 = 0; #endif /* __powerpc64__ */ #endif +alignas(CPU_LEVEL1_DCACHE_LINESIZE) static const uint32_t table0_[256] = { 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb, @@ -341,8 +313,9 @@ static const uint32_t table3_[256] = { }; // Used to fetch a naturally-aligned 32-bit word in little endian byte-order -static inline uint32_t LE_LOAD32(const uint8_t *p) { - return DecodeFixed32(reinterpret_cast(p)); +static inline uint32_t LE_LOAD32(const uint8_t *p) +{ + return uint4korr(reinterpret_cast(p)); } static inline void Slow_CRC32(uint64_t* l, uint8_t const **p) @@ -362,10 +335,7 @@ static inline void Slow_CRC32(uint64_t* l, uint8_t const **p) table0_[c >> 24]; } -#ifdef ALIGN #undef ALIGN -#endif - // Align n to (1 << m) byte boundary #define ALIGN(n, m) ((n + ((1 << m) - 1)) & ~((1 << m) - 1)) @@ -374,70 +344,30 @@ static inline void Slow_CRC32(uint64_t* l, uint8_t const **p) l = table0_[c] ^ (l >> 8); \ } while (0) -static uint32_t crc32c_slow(uint32_t crc, const char* buf, size_t size) -{ - const uint8_t *p = reinterpret_cast(buf); - const uint8_t *e = p + size; - uint64_t l = crc ^ 0xffffffffu; - - // Point x at first 16-byte aligned byte in string. This might be - // just past the end of the string. - const uintptr_t pval = reinterpret_cast(p); - const uint8_t* x = reinterpret_cast(ALIGN(pval, 4)); - if (x <= e) - // Process bytes until finished or p is 16-byte aligned - while (p != x) - STEP1; - // Process bytes 16 at a time - while ((e-p) >= 16) - { - Slow_CRC32(&l, &p); - Slow_CRC32(&l, &p); - } - // Process bytes 8 at a time - while ((e-p) >= 8) - Slow_CRC32(&l, &p); - // Process the last few bytes - while (p != e) - STEP1; - return static_cast(l ^ 0xffffffffu); -} - -#if defined HAVE_POWER8 -#elif defined HAVE_ARMV8_CRC -#elif defined HAVE_SSE42 -constexpr uint32_t cpuid_ecx_SSE42= 1U << 20; -constexpr uint32_t cpuid_ecx_SSE42_AND_PCLMUL= cpuid_ecx_SSE42 | 1U<<1; - -static uint32_t cpuid_ecx() -{ -#ifdef __GNUC__ - uint32_t reax= 0, rebx= 0, recx= 0, redx= 0; - __cpuid(1, reax, rebx, recx, redx); - return recx; -#elif defined _MSC_VER - int regs[4]; - __cpuid(regs, 1); - return regs[2]; -#else -# error "unknown compiler" +#undef USE_SSE42 +#if defined _MSC_VER && (defined _M_X64 || defined _M_IX86) +# include +# include +# define USE_SSE42 /* nothing */ +#elif defined __GNUC__ && (defined __i386__||defined __x86_64__) +# if __GNUC__ < 5 && !defined __clang_major__ +/* the headers do not really work in GCC before version 5 */ +# define _mm_crc32_u8(crc,data) __builtin_ia32_crc32qi(crc,data) +# define _mm_crc32_u32(crc,data) __builtin_ia32_crc32si(crc,data) +# define _mm_crc32_u64(crc,data) __builtin_ia32_crc32di(crc,data) +# else +# include +# endif +# define USE_SSE42 __attribute__((target("sse4.2"))) #endif -} -extern "C" int crc32_pclmul_enabled(void) -{ - return !(~cpuid_ecx() & cpuid_ecx_SSE42_AND_PCLMUL); -} - -#if SIZEOF_SIZE_T == 8 -extern "C" uint32_t crc32c_3way(uint32_t crc, const char *buf, size_t len); - -USE_SSE42 +#ifdef USE_SSE42 +# if SIZEOF_SIZE_T == 8 static inline uint64_t LE_LOAD64(const uint8_t *ptr) { return uint8korr(reinterpret_cast(ptr)); } -#endif +# endif USE_SSE42 static inline void Fast_CRC32(uint64_t* l, uint8_t const **p) @@ -453,10 +383,11 @@ static inline void Fast_CRC32(uint64_t* l, uint8_t const **p) # endif } +extern "C" USE_SSE42 -static uint32_t crc32c_sse42(uint32_t crc, const char* buf, size_t size) +unsigned crc32c_sse42(unsigned crc, const void* buf, size_t size) { - const uint8_t *p = reinterpret_cast(buf); + const uint8_t *p = static_cast(buf); const uint8_t *e = p + size; uint64_t l = crc ^ 0xffffffffu; @@ -484,107 +415,111 @@ static uint32_t crc32c_sse42(uint32_t crc, const char* buf, size_t size) } #endif -typedef uint32_t (*Function)(uint32_t, const char*, size_t); +static unsigned crc32c_slow(unsigned crc, const void* buf, size_t size) +{ + const uint8_t *p = static_cast(buf); + const uint8_t *e = p + size; + uint64_t l = crc ^ 0xffffffffu; -#if defined(HAVE_POWER8) && defined(HAS_ALTIVEC) -uint32_t ExtendPPCImpl(uint32_t crc, const char *buf, size_t size) { - return crc32c_ppc(crc, (const unsigned char *)buf, size); + // Point x at first 16-byte aligned byte in string. This might be + // just past the end of the string. + const uintptr_t pval = reinterpret_cast(p); + const uint8_t* x = reinterpret_cast(ALIGN(pval, 4)); + if (x <= e) + // Process bytes until finished or p is 16-byte aligned + while (p != x) + STEP1; + // Process bytes 16 at a time + while ((e-p) >= 16) + { + Slow_CRC32(&l, &p); + Slow_CRC32(&l, &p); + } + // Process bytes 8 at a time + while ((e-p) >= 8) + Slow_CRC32(&l, &p); + // Process the last few bytes + while (p != e) + STEP1; + return static_cast(l ^ 0xffffffffu); } -#if __linux__ +#if defined(HAVE_POWER8) && defined(HAS_ALTIVEC) +# ifdef __linux__ static int arch_ppc_probe(void) { arch_ppc_crc32 = 0; -#if defined(__powerpc64__) +# if defined(__powerpc64__) if (getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) arch_ppc_crc32 = 1; -#endif /* __powerpc64__ */ +# endif /* __powerpc64__ */ return arch_ppc_crc32; } -#elif __FreeBSD_version >= 1200000 -#include -#include -#include +# elif defined __FreeBSD_version && __FreeBSD_version >= 1200000 +# include +# include +# include static int arch_ppc_probe(void) { unsigned long cpufeatures; arch_ppc_crc32 = 0; -#if defined(__powerpc64__) +# if defined(__powerpc64__) elf_aux_info(AT_HWCAP2, &cpufeatures, sizeof(cpufeatures)); if (cpufeatures & PPC_FEATURE2_HAS_VEC_CRYPTO) arch_ppc_crc32 = 1; -#endif /* __powerpc64__ */ +# endif /* __powerpc64__ */ return arch_ppc_crc32; } -#elif defined(_AIX) || defined(__OpenBSD__) +# elif defined(_AIX) || defined(__OpenBSD__) static int arch_ppc_probe(void) { arch_ppc_crc32 = 0; -#if defined(__powerpc64__) +# if defined(__powerpc64__) // AIX 7.1+/OpenBSD has vector crypto features on all POWER 8+ arch_ppc_crc32 = 1; -#endif /* __powerpc64__ */ +# endif /* __powerpc64__ */ return arch_ppc_crc32; } -#endif // __linux__ +# endif #endif #if defined(HAVE_ARMV8_CRC) -extern "C" const char *crc32c_aarch64_available(void); -extern "C" uint32_t crc32c_aarch64(uint32_t crc, const unsigned char *buffer, uint64_t len); - -static uint32_t ExtendARMImpl(uint32_t crc, const char *buf, size_t size) { - return crc32c_aarch64(crc, (const unsigned char *)buf, (size_t) size); -} +extern "C" my_crc32_t crc32c_aarch64_available(void); +extern "C" const char *crc32c_aarch64_impl(my_crc32_t); +#elif defined __i386__||defined __x86_64__||defined _M_X64||defined _M_IX86 +extern "C" my_crc32_t crc32c_x86_available(void); +extern "C" const char *crc32c_x86_impl(my_crc32_t); #endif -static inline Function Choose_Extend() +static inline my_crc32_t Choose_Extend() { #if defined HAVE_POWER8 && defined HAS_ALTIVEC if (arch_ppc_probe()) - return ExtendPPCImpl; -#elif defined(HAVE_ARMV8_CRC) - if (crc32c_aarch64_available()) - return ExtendARMImpl; -#elif HAVE_SSE42 -# if defined HAVE_PCLMUL && SIZEOF_SIZE_T == 8 - switch (cpuid_ecx() & cpuid_ecx_SSE42_AND_PCLMUL) { - case cpuid_ecx_SSE42_AND_PCLMUL: - return crc32c_3way; - case cpuid_ecx_SSE42: - return crc32c_sse42; - } -# else - if (cpuid_ecx() & cpuid_ecx_SSE42) - return crc32c_sse42; -# endif + return crc32c_ppc; +#elif defined HAVE_ARMV8_CRC + if (my_crc32_t crc= crc32c_aarch64_available()) + return crc; +#elif defined __i386__||defined __x86_64__||defined _M_X64||defined _M_IX86 + if (my_crc32_t crc= crc32c_x86_available()) + return crc; #endif return crc32c_slow; } -static const Function ChosenExtend= Choose_Extend(); - -static inline uint32_t Extend(uint32_t crc, const char* buf, size_t size) -{ - return ChosenExtend(crc, buf, size); -} +static const my_crc32_t ChosenExtend= Choose_Extend(); extern "C" const char *my_crc32c_implementation() { -#if defined(HAVE_POWER8) && defined(HAS_ALTIVEC) - if (ChosenExtend == ExtendPPCImpl) +#if defined HAVE_POWER8 && defined HAS_ALTIVEC + if (ChosenExtend == crc32c_ppc) return "Using POWER8 crc32 instructions"; -#elif defined(HAVE_ARMV8_CRC) - if (const char *ret= crc32c_aarch64_available()) +#elif defined HAVE_ARMV8_CRC + if (const char *ret= crc32c_aarch64_impl(ChosenExtend)) + return ret; +#elif defined __i386__||defined __x86_64__||defined _M_X64||defined _M_IX86 + if (const char *ret= crc32c_x86_impl(ChosenExtend)) return ret; -#elif HAVE_SSE42 -# if defined HAVE_PCLMUL && SIZEOF_SIZE_T == 8 - if (ChosenExtend == crc32c_3way) - return "Using crc32 + pclmulqdq instructions"; -# endif - if (ChosenExtend == crc32c_sse42) - return "Using SSE4.2 crc32 instructions"; #endif return "Using generic crc32 instructions"; } @@ -593,5 +528,5 @@ extern "C" const char *my_crc32c_implementation() extern "C" unsigned my_crc32c(unsigned int crc, const char *buf, size_t size) { - return mysys_namespace::crc32c::Extend(crc,buf, size); + return mysys_namespace::crc32c::ChosenExtend(crc,buf, size); } diff --git a/mysys/crc32/crc32c_amd64.cc b/mysys/crc32/crc32c_amd64.cc index 22c492b457f..147c0ccaba6 100644 --- a/mysys/crc32/crc32c_amd64.cc +++ b/mysys/crc32/crc32c_amd64.cc @@ -47,6 +47,11 @@ #include #include +#ifdef _MSC_VER +# define USE_PCLMUL /* nothing */ +#else +# define USE_PCLMUL __attribute__((target("sse4.2,pclmul"))) +#endif #define CRCtriplet(crc, buf, offset) \ crc##0 = _mm_crc32_u64(crc##0, *(buf##0 + offset)); \ @@ -131,6 +136,7 @@ static const uint64_t clmul_constants alignas(16) [] = { }; // Compute the crc32c value for buffer smaller than 8 +USE_PCLMUL static inline void align_to_8( size_t len, uint64_t& crc0, // crc so far, updated on return @@ -155,6 +161,7 @@ static inline void align_to_8( // CombineCRC performs pclmulqdq multiplication of 2 partial CRC's and a well // chosen constant and xor's these with the remaining CRC. // +USE_PCLMUL static inline uint64_t CombineCRC( size_t block_size, uint64_t crc0, @@ -176,6 +183,7 @@ static inline uint64_t CombineCRC( // Compute CRC-32C using the Intel hardware instruction. extern "C" +USE_PCLMUL uint32_t crc32c_3way(uint32_t crc, const char *buf, size_t len) { const unsigned char* next = (const unsigned char*)buf; diff --git a/mysys/crc32/crc32c_ppc.h b/mysys/crc32/crc32c_ppc.h index c359061c610..797e849b685 100644 --- a/mysys/crc32/crc32c_ppc.h +++ b/mysys/crc32/crc32c_ppc.h @@ -11,8 +11,7 @@ extern "C" { #endif -extern uint32_t crc32c_ppc(uint32_t crc, unsigned char const *buffer, - unsigned len); +extern unsigned crc32c_ppc(unsigned crc, const void *buffer, size_t len); #ifdef __cplusplus } diff --git a/mysys/crc32/crc32c_x86.cc b/mysys/crc32/crc32c_x86.cc new file mode 100644 index 00000000000..02dbf2920eb --- /dev/null +++ b/mysys/crc32/crc32c_x86.cc @@ -0,0 +1,457 @@ +/* Copyright (c) 2024, MariaDB plc + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ + +#include +#include +#include + +#ifdef _MSC_VER +# include +# if 0 /* So far, we have no environment where this could be tested. */ +# define USE_VPCLMULQDQ /* nothing */ +# endif +#else +# include +# if __GNUC__ >= 11 || (defined __clang_major__ && __clang_major__ >= 8) +# define TARGET "pclmul,avx512f,avx512dq,avx512bw,avx512vl,vpclmulqdq" +# define USE_VPCLMULQDQ __attribute__((target(TARGET))) +# endif +#endif + +extern "C" unsigned crc32c_sse42(unsigned crc, const void* buf, size_t size); + +constexpr uint32_t cpuid_ecx_SSE42= 1U << 20; +constexpr uint32_t cpuid_ecx_SSE42_AND_PCLMUL= cpuid_ecx_SSE42 | 1U << 1; + +static uint32_t cpuid_ecx() +{ +#ifdef __GNUC__ + uint32_t reax= 0, rebx= 0, recx= 0, redx= 0; + __cpuid(1, reax, rebx, recx, redx); + return recx; +#elif defined _MSC_VER + int regs[4]; + __cpuid(regs, 1); + return regs[2]; +#else +# error "unknown compiler" +#endif +} + +typedef unsigned (*my_crc32_t)(unsigned, const void *, size_t); +extern "C" unsigned int crc32_pclmul(unsigned int, const void *, size_t); +extern "C" unsigned int crc32c_3way(unsigned int, const void *, size_t); + +#ifdef USE_VPCLMULQDQ +# include + +# ifdef _MSC_VER +/* MSVC does not seem to define this intrinsic for vmovdqa */ +# define _mm_load_epi32(x) *reinterpret_cast(x) +# endif + +/* + This implementation is based on + crc32_by16_vclmul_avx512 and crc32_refl_by16_vclmul_avx512 + in https://github.com/intel/intel-ipsec-mb/ with some optimizations. + The // comments in crc32_avx512() correspond to assembler labels. +*/ + +/** table of constants corresponding to a CRC polynomial up to degree 32 */ +struct alignas(64) crc32_tab +{ + const uint64_t b2048[2], b1024[2]; + alignas(64) const uint64_t b896[6]; /* includes b786, b640 */ + const uint64_t b512[2]; + const uint64_t b384[2], b256[2], b128[2], zeropad_for_b384[2]; + const uint64_t b64[2], b32[2]; +}; + +/** ISO 3309 CRC-32 (reflected polynomial 0x04C11DB7); zlib crc32() */ +static const crc32_tab refl32 = { + { 0x00000000e95c1271, 0x00000000ce3371cb }, + { 0x00000000910eeec1, 0x0000000033fff533 }, + { 0x000000000cbec0ed, 0x0000000031f8303f, + 0x0000000057c54819, 0x00000000df068dc2, + 0x00000000ae0b5394, 0x000000001c279815 }, + { 0x000000001d9513d7, 0x000000008f352d95 }, + { 0x00000000af449247, 0x000000003db1ecdc }, + { 0x0000000081256527, 0x00000000f1da05aa }, + { 0x00000000ccaa009e, 0x00000000ae689191 }, + { 0, 0 }, + { 0x00000000ccaa009e, 0x00000000b8bc6765 }, + { 0x00000001f7011640, 0x00000001db710640 } +}; + +/** Castagnoli CRC-32C (reflected polynomial 0x1EDC6F41) */ +static const crc32_tab refl32c = { + { 0x00000000b9e02b86, 0x00000000dcb17aa4 }, + { 0x000000000d3b6092, 0x000000006992cea2 }, + { 0x0000000047db8317, 0x000000002ad91c30, + 0x000000000715ce53, 0x00000000c49f4f67, + 0x0000000039d3b296, 0x00000000083a6eec }, + { 0x000000009e4addf8, 0x00000000740eef02 }, + { 0x00000000ddc0152b, 0x000000001c291d04 }, + { 0x00000000ba4fc28e, 0x000000003da6d0cb }, + { 0x00000000493c7d27, 0x00000000f20c0dfe }, + { 0, 0 }, + { 0x00000000493c7d27, 0x00000000dd45aab8 }, + { 0x00000000dea713f0, 0x0000000105ec76f0 } +}; + +/** Some ternary functions */ +class ternary +{ + static constexpr uint8_t A = 0b11110000; + static constexpr uint8_t B = 0b11001100; + static constexpr uint8_t C = 0b10101010; +public: + static constexpr uint8_t XOR3 = A ^ B ^ C; + static constexpr uint8_t XNOR3 = uint8_t(~(A ^ B ^ C)); + static constexpr uint8_t XOR2_AND = (A ^ B) & C; +}; + +USE_VPCLMULQDQ +/** @return a^b^c */ +static inline __m128i xor3_128(__m128i a, __m128i b, __m128i c) +{ + return _mm_ternarylogic_epi64(a, b, c, ternary::XOR3); +} + +USE_VPCLMULQDQ +/** @return ~(a^b^c) */ +static inline __m128i xnor3_128(__m128i a, __m128i b, __m128i c) +{ + return _mm_ternarylogic_epi64(a, b, c, ternary::XNOR3); +} + +USE_VPCLMULQDQ +/** @return a^b^c */ +static inline __m512i xor3_512(__m512i a, __m512i b, __m512i c) +{ + return _mm512_ternarylogic_epi64(a, b, c, ternary::XOR3); +} + +USE_VPCLMULQDQ +/** @return (a^b)&c */ +static inline __m128i xor2_and_128(__m128i a, __m128i b, __m128i c) +{ + return _mm_ternarylogic_epi64(a, b, c, ternary::XOR2_AND); +} + +USE_VPCLMULQDQ +/** Load 64 bytes */ +static inline __m512i load512(const char *b) { return _mm512_loadu_epi8(b); } + +USE_VPCLMULQDQ +/** Load 16 bytes */ +static inline __m128i load128(const char *b) { return _mm_loadu_epi64(b); } + +/** Combine 512 data bits with CRC */ +USE_VPCLMULQDQ +static inline __m512i combine512(__m512i a, __m512i tab, __m512i b) +{ + return xor3_512(b, _mm512_clmulepi64_epi128(a, tab, 0x01), + _mm512_clmulepi64_epi128(a, tab, 0x10)); +} + +# define xor512(a, b) _mm512_xor_epi64(a, b) +# define xor256(a, b) _mm256_xor_epi64(a, b) +# define xor128(a, b) _mm_xor_epi64(a, b) +# define and128(a, b) _mm_and_si128(a, b) + +template USE_VPCLMULQDQ +/** Pick a 128-bit component of a 512-bit vector */ +static inline __m512i extract512_128(__m512i a) +{ + static_assert(bits <= 3, "usage"); +# if defined __GNUC__ && __GNUC__ >= 11 + /* While technically incorrect, this would seem to translate into a + vextracti32x4 instruction, which actually outputs a ZMM register + (anything above the XMM range is cleared). */ + return _mm512_castsi128_si512(_mm512_extracti64x2_epi64(a, bits)); +# else + /* On clang, this is needed in order to get a correct result. */ + return _mm512_maskz_shuffle_i64x2(3, a, a, bits); +# endif +} + +alignas(16) static const uint64_t shuffle128[4] = { + 0x8786858483828100, 0x8f8e8d8c8b8a8988, + 0x0706050403020100, 0x000e0d0c0b0a0908 +}; + +static const __mmask16 size_mask[16] = { + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + +alignas(16) static const uint64_t shift128[4] = { + 0x8786858483828100, 0x8f8e8d8c8b8a8988, + 0x0706050403020100, 0x000e0d0c0b0a0908 +}; + +static const char shift_1_to_3_reflect[7 + 11] = { + -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 +}; + +USE_VPCLMULQDQ +static unsigned crc32_avx512(unsigned crc, const char *buf, size_t size, + const crc32_tab &tab) +{ + const __m512i crc_in = _mm512_castsi128_si512(_mm_cvtsi32_si128(~crc)), + b512 = _mm512_broadcast_i32x4(_mm_load_epi32(tab.b512)); + __m128i crc_out; + __m512i lo; + + if (size >= 256) { + lo = xor512(load512(buf), crc_in); + __m512i l1 = load512(buf + 64); + + const __m512i b1024 = _mm512_broadcast_i32x4(_mm_load_epi32(&tab.b1024)); + size -= 256; + if (size >= 256) { + __m512i h0 = load512(buf + 128), + hi = load512(buf + 192); + const __m512i b2048 = _mm512_broadcast_i32x4(_mm_load_epi32(&tab.b2048)); + size -= 256; + do { + buf += 256; + lo = combine512(lo, b2048, load512(buf)); + l1 = combine512(l1, b2048, load512(buf + 64)); + h0 = combine512(h0, b2048, load512(buf + 128)); + hi = combine512(hi, b2048, load512(buf + 192)); + size -= 256; + } while (ssize_t(size) >= 0); + + buf += 256; + lo = combine512(lo, b1024, h0); + l1 = combine512(l1, b1024, hi); + size += 128; + } else { + do { + buf += 128; + lo = combine512(lo, b1024, load512(buf)); + l1 = combine512(l1, b1024, load512(buf + 64)); + size -= 128; + } while (ssize_t(size) >= 0); + + buf += 128; + } + + if (ssize_t(size) >= -64) { + size += 128; + lo = combine512(lo, b512, l1); + goto fold_64_B_loop; + } + + const __m512i + b896 = _mm512_load_epi32(&tab.b896), + b384 = _mm512_load_epi32(&tab.b384); + + __m512i c4 = xor3_512(_mm512_clmulepi64_epi128(lo, b896, 1), + _mm512_clmulepi64_epi128(lo, b896, 0x10), + _mm512_clmulepi64_epi128(l1, b384, 1)); + c4 = xor3_512(c4, _mm512_clmulepi64_epi128(l1, b384, 0x10), + extract512_128<3>(l1)); + + __m256i c2 = _mm512_castsi512_si256(_mm512_shuffle_i64x2(c4, c4, 0b01001110)); + c2 = xor256(c2, _mm512_castsi512_si256(c4)); + crc_out = xor128(_mm256_extracti64x2_epi64(c2, 1), + _mm256_castsi256_si128(c2)); + size += 128 - 16; + goto final_reduction; + } + + __m128i b; + + // less_than_256 + if (size >= 32) { + if (size >= 64) { + lo = xor512(load512(buf), crc_in); + + while (buf += 64, (size -= 64) >= 64) + fold_64_B_loop: + lo = combine512(lo, b512, load512(buf)); + + // reduce_64B + const __m512i b384 = _mm512_load_epi32(&tab.b384); + __m512i crc512 = + xor3_512(_mm512_clmulepi64_epi128(lo, b384, 1), + _mm512_clmulepi64_epi128(lo, b384, 0x10), + extract512_128<3>(lo)); + crc512 = xor512(crc512, _mm512_shuffle_i64x2(crc512, crc512, 0b01001110)); + const __m256i crc256 = _mm512_castsi512_si256(crc512); + crc_out = xor128(_mm256_extracti64x2_epi64(crc256, 1), + _mm256_castsi256_si128(crc256)); + size -= 16; + } else { + // less_than_64 + crc_out = xor128(load128(buf), + _mm512_castsi512_si128(crc_in)); + buf += 16; + size -= 32; + } + + final_reduction: + b = _mm_load_epi32(&tab.b128); + + while (ssize_t(size) >= 0) { + // reduction_loop_16B + crc_out = xor3_128(load128(buf), + _mm_clmulepi64_si128(crc_out, b, 1), + _mm_clmulepi64_si128(crc_out, b, 0x10)); + buf += 16; + size -= 16; + } + // final_reduction_for_128 + + size += 16; + if (size) { + get_last_two_xmms: + const __m128i crc2 = crc_out, d = load128(buf + (size - 16)); + __m128i S = load128(reinterpret_cast(shuffle128) + size); + crc_out = _mm_shuffle_epi8(crc_out, S); + S = xor128(S, _mm_set1_epi32(0x80808080)); + crc_out = xor3_128(_mm_blendv_epi8(_mm_shuffle_epi8(crc2, S), d, S), + _mm_clmulepi64_si128(crc_out, b, 1), + _mm_clmulepi64_si128(crc_out, b, 0x10)); + } + + done_128: + __m128i crc_tmp; + b = _mm_load_epi32(&tab.b64); + crc_tmp = xor128(_mm_clmulepi64_si128(crc_out, b, 0x00), + _mm_srli_si128(crc_out, 8)); + crc_out = _mm_slli_si128(crc_tmp, 4); + crc_out = _mm_clmulepi64_si128(crc_out, b, 0x10); + crc_out = xor128(crc_out, crc_tmp); + + barrett: + b = _mm_load_epi32(&tab.b32); + crc_tmp = crc_out; + crc_out = and128(crc_out, _mm_set_epi64x(~0ULL, ~0xFFFFFFFFULL)); + crc_out = _mm_clmulepi64_si128(crc_out, b, 0); + crc_out = xor2_and_128(crc_out, crc_tmp, _mm_set_epi64x(0, ~0ULL)); + crc_out = xnor3_128(crc_out, crc_tmp, + _mm_clmulepi64_si128(crc_out, b, 0x10)); + return _mm_extract_epi32(crc_out, 2); + } else { + // less_than_32 + if (size > 0) { + if (size > 16) { + crc_out = xor128(load128(buf), + _mm512_castsi512_si128(crc_in)); + buf += 16; + size -= 16; + b = _mm_load_epi32(&tab.b128); + goto get_last_two_xmms; + } else if (size < 16) { + crc_out = _mm_maskz_loadu_epi8(size_mask[size - 1], buf); + crc_out = xor128(crc_out, _mm512_castsi512_si128(crc_in)); + + if (size >= 4) { + crc_out = _mm_shuffle_epi8 + (crc_out, + load128(reinterpret_cast(shift128) + size)); + goto done_128; + } else { + // only_less_than_4 + /* Shift, zero-filling 5 to 7 of the 8-byte crc_out */ + crc_out = _mm_shuffle_epi8(crc_out, + load128(shift_1_to_3_reflect + size - 1)); + goto barrett; + } + } else { + crc_out = xor128(load128(buf), _mm512_castsi512_si128(crc_in)); + goto done_128; + } + } else + return crc; + } +} + +static ATTRIBUTE_NOINLINE int have_vpclmulqdq() +{ +# ifdef _MSC_VER + int regs[4]; + __cpuidex(regs, 7, 0); + uint32_t ebx = regs[1], ecx = regs[2]; +# else + uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0; + __cpuid_count(7, 0, eax, ebx, ecx, edx); +# endif + return ecx & 1U<<10/*VPCLMULQDQ*/ && + !(~ebx & ((1U<<16/*AVX512F*/ | 1U<<17/*AVX512DQ*/ | + 1U<<30/*AVX512BW*/ | 1U<<31/*AVX512VL*/))); +} + +static unsigned crc32_vpclmulqdq(unsigned crc, const void *buf, size_t size) +{ + return crc32_avx512(crc, static_cast(buf), size, refl32); +} + +static unsigned crc32c_vpclmulqdq(unsigned crc, const void *buf, size_t size) +{ + return crc32_avx512(crc, static_cast(buf), size, refl32c); +} +#endif + +extern "C" my_crc32_t crc32_pclmul_enabled(void) +{ + if (~cpuid_ecx() & cpuid_ecx_SSE42_AND_PCLMUL) + return nullptr; +#ifdef USE_VPCLMULQDQ + if (have_vpclmulqdq()) + return crc32_vpclmulqdq; +#endif + return crc32_pclmul; +} + +extern "C" my_crc32_t crc32c_x86_available(void) +{ +#ifdef USE_VPCLMULQDQ + if (have_vpclmulqdq()) + return crc32c_vpclmulqdq; +#endif +#if SIZEOF_SIZE_T == 8 + switch (cpuid_ecx() & cpuid_ecx_SSE42_AND_PCLMUL) { + case cpuid_ecx_SSE42_AND_PCLMUL: + return crc32c_3way; + case cpuid_ecx_SSE42: + return crc32c_sse42; + } +#else + if (cpuid_ecx() & cpuid_ecx_SSE42) + return crc32c_sse42; +#endif + return nullptr; +} + +extern "C" const char *crc32c_x86_impl(my_crc32_t c) +{ +#ifdef USE_VPCLMULQDQ + if (c == crc32c_vpclmulqdq) + return "Using AVX512 instructions"; +#endif +#if SIZEOF_SIZE_T == 8 + if (c == crc32c_3way) + return "Using crc32 + pclmulqdq instructions"; +#endif + if (c == crc32c_sse42) + return "Using SSE4.2 crc32 instructions"; + return nullptr; +} diff --git a/mysys/crc32/crc_ppc64.h b/mysys/crc32/crc_ppc64.h index eb9379abc6c..81bbc16dfed 100644 --- a/mysys/crc32/crc_ppc64.h +++ b/mysys/crc32/crc_ppc64.h @@ -28,7 +28,7 @@ * any later version, or * b) the Apache License, Version 2.0 */ - +#include #include @@ -57,12 +57,13 @@ static unsigned int __attribute__ ((aligned (32))) __crc32_vpmsum(unsigned int crc, const void* p, unsigned long len); -unsigned int CRC32_FUNCTION(unsigned int crc, const unsigned char *p, - unsigned long len) +unsigned CRC32_FUNCTION(unsigned crc, const void *buffer, size_t len) { unsigned int prealign; unsigned int tail; + const unsigned char *p = buffer; + #ifdef CRC_XOR crc ^= 0xffffffff; #endif diff --git a/mysys/crc32ieee.cc b/mysys/crc32ieee.cc index 14e8017de4b..c11bdacf77a 100644 --- a/mysys/crc32ieee.cc +++ b/mysys/crc32ieee.cc @@ -26,23 +26,22 @@ static unsigned int my_crc32_zlib(unsigned int crc, const void *data, return (unsigned int) crc32(crc, (const Bytef *)data, (unsigned int) len); } -#ifdef HAVE_PCLMUL -extern "C" int crc32_pclmul_enabled(); -extern "C" unsigned int crc32_pclmul(unsigned int, const void *, size_t); -#elif defined(__GNUC__) && defined(HAVE_ARMV8_CRC) +typedef unsigned int (*my_crc32_t)(unsigned int, const void *, size_t); + +#if defined _M_IX86 || defined _M_X64 || defined __i386__ || defined __x86_64__ +extern "C" my_crc32_t crc32_pclmul_enabled(); +#elif defined HAVE_ARMV8_CRC extern "C" int crc32_aarch64_available(); extern "C" unsigned int crc32_aarch64(unsigned int, const void *, size_t); #endif -typedef unsigned int (*my_crc32_t)(unsigned int, const void *, size_t); - static my_crc32_t init_crc32() { -#ifdef HAVE_PCLMUL - if (crc32_pclmul_enabled()) - return crc32_pclmul; -#elif defined(__GNUC__) && defined(HAVE_ARMV8_CRC) +#if defined _M_IX86 || defined _M_X64 || defined __i386__ || defined __x86_64__ + if (my_crc32_t crc= crc32_pclmul_enabled()) + return crc; +#elif defined HAVE_ARMV8_CRC if (crc32_aarch64_available()) return crc32_aarch64; #endif diff --git a/mysys/errors.c b/mysys/errors.c index b522590ae7b..76ca70fc3b5 100644 --- a/mysys/errors.c +++ b/mysys/errors.c @@ -114,6 +114,13 @@ void init_glob_errs() } #endif +static void my_space_sleep(uint seconds) +{ + sleep(seconds); +} + +void (*my_sleep_for_space)(uint seconds)= my_space_sleep; + void wait_for_free_space(const char *filename, int errors) { if (errors == 0) @@ -125,7 +132,7 @@ void wait_for_free_space(const char *filename, int errors) MYF(ME_BELL | ME_ERROR_LOG | ME_WARNING), MY_WAIT_FOR_USER_TO_FIX_PANIC, MY_WAIT_GIVE_USER_A_MESSAGE * MY_WAIT_FOR_USER_TO_FIX_PANIC ); - (void) sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC); + my_sleep_for_space(MY_WAIT_FOR_USER_TO_FIX_PANIC); } const char **get_global_errmsgs(int nr __attribute__((unused))) diff --git a/mysys/lf_alloc-pin.c b/mysys/lf_alloc-pin.c index fc3f320a623..4dc41645530 100644 --- a/mysys/lf_alloc-pin.c +++ b/mysys/lf_alloc-pin.c @@ -291,7 +291,7 @@ static int harvest_pins(LF_PINS *el, struct st_harvester *hv) { for (i= 0; i < LF_PINBOX_PINS; i++) { - void *p= el->pin[i]; + void *p= my_atomic_loadptr((void **)&el->pin[i]); if (p) *hv->granary++= p; } @@ -316,7 +316,7 @@ static int match_pins(LF_PINS *el, void *addr) LF_PINS *el_end= el+LF_DYNARRAY_LEVEL_LENGTH; for (; el < el_end; el++) for (i= 0; i < LF_PINBOX_PINS; i++) - if (el->pin[i] == addr) + if (my_atomic_loadptr((void **)&el->pin[i]) == addr) return 1; return 0; } @@ -501,7 +501,8 @@ void *lf_alloc_new(LF_PINS *pins) { node= allocator->top; lf_pin(pins, 0, node); - } while (node != allocator->top && LF_BACKOFF()); + } while (node != my_atomic_loadptr((void **)(char *)&allocator->top) + && LF_BACKOFF()); if (!node) { node= (void *)my_malloc(key_memory_lf_node, allocator->element_size, diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c index 0f1c6d6b1bc..3393b610570 100644 --- a/mysys/mf_tempfile.c +++ b/mysys/mf_tempfile.c @@ -66,7 +66,11 @@ File create_temp_file(char *to, const char *dir, const char *prefix, DBUG_ENTER("create_temp_file"); DBUG_PRINT("enter", ("dir: %s, prefix: %s", dir ? dir : "(null)", prefix)); +#if !defined _WIN32 && defined O_DIRECT + DBUG_ASSERT((mode & (O_EXCL | O_TRUNC | O_CREAT | O_RDWR | O_DIRECT)) == 0); +#else DBUG_ASSERT((mode & (O_EXCL | O_TRUNC | O_CREAT | O_RDWR)) == 0); +#endif mode|= O_TRUNC | O_CREAT | O_RDWR; /* not O_EXCL, see Windows code below */ @@ -118,16 +122,41 @@ File create_temp_file(char *to, const char *dir, const char *prefix, if ((MyFlags & MY_TEMPORARY) && O_TMPFILE_works) { - /* explictly don't use O_EXCL here has it has a different - meaning with O_TMPFILE + /* + explicitly don't use O_EXCL here has it has a different + meaning with O_TMPFILE */ - if ((file= open(dir, (mode & ~O_CREAT) | O_TMPFILE | O_CLOEXEC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) >= 0) + const int flags= (mode & ~O_CREAT) | O_TMPFILE | O_CLOEXEC; + const mode_t open_mode= S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; +# ifdef O_DIRECT + static int O_TMPFILE_works_with_O_DIRECT= O_DIRECT; + const int try_O_DIRECT= mode & O_TMPFILE_works_with_O_DIRECT; + if (try_O_DIRECT) + file= open(dir, flags | O_DIRECT, open_mode); + else +# endif + file= open(dir, flags, open_mode); + + if (file >= 0) { +# ifdef O_DIRECT + O_TMPFILE_works: +# endif my_snprintf(to, FN_REFLEN, "%s/#sql/fd=%d", dir, file); file=my_register_filename(file, to, FILE_BY_O_TMPFILE, EE_CANTCREATEFILE, MyFlags); } +# ifdef O_DIRECT + else if (errno == EINVAL && try_O_DIRECT) + { + file= open(dir, flags, open_mode); + if (file >= 0) + { + O_TMPFILE_works_with_O_DIRECT= 0; + goto O_TMPFILE_works; + } + } +# endif else if (errno == EOPNOTSUPP || errno == EINVAL) { my_printf_error(EE_CANTCREATEFILE, "O_TMPFILE is not supported on %s " diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c index 229e512dc1e..af102ab0696 100644 --- a/mysys/my_bitmap.c +++ b/mysys/my_bitmap.c @@ -13,17 +13,28 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 + USA + */ /* - Handling of uchar arrays as large bitmaps. + Handling of my_bitmap_map (ulonglong) arrays as large bitmaps. API limitations (or, rather asserted safety assumptions, to encourage correct programming) - * the internal size is a set of 32 bit words + * the internal storage is a set of 64 bit words * the number of bits specified in creation can be any number > 0 + Implementation notes: + * MY_BITMAP includes a pointer, last_word_ptr, to the last word. + The implication is that if one copies bitmaps to another memory + location, one has to call create_last_bit_mask() on the bitmap to + fix the internal pointer. + * The not used part of a the last word should always be 0. + This avoids special handling of the last bitmap in several cases. + This is checked for most calls to bitmap functions. + TODO: Make assembler thread safe versions of these using test-and-set instructions @@ -31,117 +42,97 @@ New version written and test program added and some changes to the interface was made by Mikael Ronstrom 2005, with assistance of Tomas Ulin and Mats Kindahl. + Updated to 64 bits and use my_find_first_bit() to speed up + bitmap_get_next_set() by Monty in 2024 */ #include "mysys_priv.h" #include #include #include +#include + + +/* Defines to check bitmaps */ + +#define DBUG_ASSERT_BITMAP(M) \ + DBUG_ASSERT((M)->bitmap); \ + DBUG_ASSERT((M)->n_bits > 0); \ + DBUG_ASSERT((M)->last_word_ptr == (M)->bitmap + no_words_in_map(M)-1); \ + DBUG_ASSERT((*(M)->last_word_ptr & (M)->last_bit_mask) == 0); + +#define DBUG_ASSERT_BITMAP_AND_BIT(M,B) \ + DBUG_ASSERT_BITMAP(M); \ + DBUG_ASSERT((B) < (M)->n_bits); + +#define DBUG_ASSERT_DIFFERENT_BITMAPS(M,N) \ + DBUG_ASSERT_BITMAP(M); \ + DBUG_ASSERT_BITMAP(N); + +#define DBUG_ASSERT_IDENTICAL_BITMAPS(M,N) \ + DBUG_ASSERT_BITMAP(M); \ + DBUG_ASSERT_BITMAP(N); \ + DBUG_ASSERT((M)->n_bits == (N)->n_bits); /* - Create a mask with the upper 'unused' bits set and the lower 'used' - bits clear. The bits within each byte is stored in big-endian order. + Create a mask for the usable bits on the LAST my_bitmap_map position for + a bitmap with 'bits' number of bits. + + The lowest 'bits' bits are set to zero and the rest bits are set to 1. + For (bits & 63) == 0 , 0 is returned as in this case all bits in the + my_bitmap_position are significant. (This example assumes the + storage is ulonglong). + + For 'bits & 63' it will return values from the series + 0, 0xfffffffffffffffe,.... 0x8000000000000000 */ -static inline uchar invers_last_byte_mask(uint bits) +static inline my_bitmap_map last_bit_mask(uint bits) { - return last_byte_mask(bits) ^ 255; + uint bits_in_last_map= (bits & (my_bitmap_map_bits-1)); + return bits_in_last_map ? ~((1ULL << bits_in_last_map)-1) : 0ULL; } -void create_last_word_mask(MY_BITMAP *map) +/* + Get a mask of the bits that are to be considered as 'on' at location + starting with 'bits'. + This function has _inv in it's name as it's usage is invers compared + to last_bit_mask(). + + For (bits & 63) it will return values from the series + 0xffffffffffffffff, 0xfffffffffffffffe,.... 0x8000000000000000 +*/ + +static inline my_bitmap_map first_bit_mask_inv(uint bits) { - unsigned char const mask= invers_last_byte_mask(map->n_bits); - - /* - The first bytes are to be set to zero since they represent real bits - in the bitvector. The last bytes are set to 0xFF since they represent - bytes not used by the bitvector. Finally the last byte contains bits - as set by the mask above. - */ - unsigned char *ptr= (unsigned char*)&map->last_word_mask; - - map->last_word_ptr= map->bitmap + no_words_in_map(map)-1; - switch (no_bytes_in_map(map) & 3) { - case 1: - map->last_word_mask= ~0U; - ptr[0]= mask; - return; - case 2: - map->last_word_mask= ~0U; - ptr[0]= 0; - ptr[1]= mask; - return; - case 3: - map->last_word_mask= 0U; - ptr[2]= mask; - ptr[3]= 0xFFU; - return; - case 0: - map->last_word_mask= 0U; - ptr[3]= mask; - return; - } + uint bits_in_last_map= (bits & (my_bitmap_map_bits-1)); + return ~((1ULL << bits_in_last_map)-1); } -static inline my_bitmap_map last_word_mask(uint bit) +/* + Update the bitmap's last_word_ptr and last_bit_mask + Also ensure that the last world is all zero to make it + easy to find the next set bit. + + Note that if n_bits is 0, then last_word_ptr will point to + bitmap (safely). The bitmap will not be usable for almost any operation. +*/ + +void create_last_bit_mask(MY_BITMAP *map) { - my_bitmap_map last_word_mask; - uint n_bits= bit + 1; - unsigned char const mask= invers_last_byte_mask(n_bits); - - /* - The first bytes are to be set to zero since they represent real bits - in the bitvector. The last bytes are set to 0xFF since they represent - bytes not used by the bitvector. Finally the last byte contains bits - as set by the mask above. - */ - unsigned char *ptr= (unsigned char*)&last_word_mask; - - switch ((n_bits + 7)/8 & 3) { - case 1: - last_word_mask= ~0U; - ptr[0]= mask; - break; - case 2: - last_word_mask= ~0U; - ptr[0]= 0; - ptr[1]= mask; - break; - case 3: - last_word_mask= 0U; - ptr[2]= mask; - ptr[3]= 0xFFU; - break; - case 0: - last_word_mask= 0U; - ptr[3]= mask; - break; - } - return last_word_mask; -} - - -static inline uint get_first_set(my_bitmap_map value, uint word_pos) -{ - uchar *byte_ptr= (uchar*)&value; - uchar byte_value; - uint byte_pos, bit_pos; - - DBUG_ASSERT(value); - for (byte_pos=0; ; byte_pos++, byte_ptr++) + my_bitmap_map mask= last_bit_mask(map->n_bits); + map->last_bit_mask= mask; + map->last_word_ptr= map->bitmap + MY_MAX(no_words_in_map(map),1) -1; + if (map->n_bits > 0) { - if ((byte_value= *byte_ptr)) - { - for (bit_pos=0; ; bit_pos++) - if (byte_value & (1 << bit_pos)) - return (word_pos*32) + (byte_pos*8) + bit_pos; - } + *map->last_word_ptr&= ~mask; /* Set not used bits to 0 */ + DBUG_ASSERT_BITMAP(map); } - return MY_BIT_NONE; /* Impossible */ } + /* Initialize a bitmap object. All bits will be set to zero */ @@ -149,17 +140,24 @@ static inline uint get_first_set(my_bitmap_map value, uint word_pos) my_bool my_bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits) { DBUG_ENTER("my_bitmap_init"); + if (!buf) { uint size_in_bytes= bitmap_buffer_size(n_bits); if (!(buf= (my_bitmap_map*) my_malloc(key_memory_MY_BITMAP_bitmap, size_in_bytes, MYF(MY_WME)))) + { + map->bitmap= 0; DBUG_RETURN(1); + } + map->bitmap_allocated= 1; } + else + map->bitmap_allocated= 0; map->bitmap= buf; map->n_bits= n_bits; - create_last_word_mask(map); + create_last_bit_mask(map); bitmap_clear_all(map); DBUG_RETURN(0); } @@ -170,7 +168,8 @@ void my_bitmap_free(MY_BITMAP *map) DBUG_ENTER("my_bitmap_free"); if (map->bitmap) { - my_free(map->bitmap); + if (map->bitmap_allocated) + my_free(map->bitmap); map->bitmap=0; } DBUG_VOID_RETURN; @@ -192,11 +191,14 @@ void my_bitmap_free(MY_BITMAP *map) my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit) { - uchar *value= ((uchar*) map->bitmap) + (bitmap_bit / 8); - uchar bit= 1 << ((bitmap_bit) & 7); - uchar res= (*value) & bit; + my_bitmap_map *value, bit, res; + DBUG_ASSERT_BITMAP_AND_BIT(map, bitmap_bit); + + value= map->bitmap + (bitmap_bit/my_bitmap_map_bits); + bit= 1ULL << (bitmap_bit & (my_bitmap_map_bits-1)); + res= *value & bit; *value|= bit; - return res; + return MY_TEST(res); } @@ -215,8 +217,7 @@ my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit) my_bool bitmap_test_and_set(MY_BITMAP *map, uint bitmap_bit) { - DBUG_ASSERT(map->bitmap); - DBUG_ASSERT(bitmap_bit < map->n_bits); + DBUG_ASSERT_BITMAP_AND_BIT(map, bitmap_bit); return bitmap_fast_test_and_set(map, bitmap_bit); } @@ -235,18 +236,20 @@ my_bool bitmap_test_and_set(MY_BITMAP *map, uint bitmap_bit) my_bool bitmap_fast_test_and_clear(MY_BITMAP *map, uint bitmap_bit) { - uchar *byte= (uchar*) map->bitmap + (bitmap_bit / 8); - uchar bit= 1 << ((bitmap_bit) & 7); - uchar res= (*byte) & bit; - *byte&= ~bit; - return res; + my_bitmap_map *value, bit, res; + DBUG_ASSERT_BITMAP_AND_BIT(map, bitmap_bit); + + value= map->bitmap + (bitmap_bit/my_bitmap_map_bits); + bit= 1ULL << (bitmap_bit & (my_bitmap_map_bits-1)); + res= *value & bit; + *value&= ~bit; + return MY_TEST(res); } my_bool bitmap_test_and_clear(MY_BITMAP *map, uint bitmap_bit) { - DBUG_ASSERT(map->bitmap); - DBUG_ASSERT(bitmap_bit < map->n_bits); + DBUG_ASSERT_BITMAP_AND_BIT(map, bitmap_bit); return bitmap_fast_test_and_clear(map, bitmap_bit); } @@ -254,8 +257,8 @@ my_bool bitmap_test_and_clear(MY_BITMAP *map, uint bitmap_bit) uint bitmap_set_next(MY_BITMAP *map) { uint bit_found; - DBUG_ASSERT(map->bitmap); - if ((bit_found= bitmap_get_first(map)) != MY_BIT_NONE) + DBUG_ASSERT_BITMAP(map); + if ((bit_found= bitmap_get_first_clear(map)) != MY_BIT_NONE) bitmap_set_bit(map, bit_found); return bit_found; } @@ -265,58 +268,69 @@ uint bitmap_set_next(MY_BITMAP *map) Set the specified number of bits in the bitmap buffer. @param map [IN] Bitmap - @param prefix_size [IN] Number of bits to be set + @param prefix_size [IN] Number of bits to be set or (uint) ~0 for all */ + void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size) { - uint prefix_bytes, prefix_bits, d; - uchar *m= (uchar *)map->bitmap; - - DBUG_ASSERT(map->bitmap); + uint prefix, prefix_bits; + my_bitmap_map *value= map->bitmap; + DBUG_ASSERT_BITMAP(map); DBUG_ASSERT(prefix_size <= map->n_bits || prefix_size == (uint) ~0); set_if_smaller(prefix_size, map->n_bits); - if ((prefix_bytes= prefix_size / 8)) - memset(m, 0xff, prefix_bytes); - m+= prefix_bytes; - if ((prefix_bits= prefix_size & 7)) + + if ((prefix= prefix_size / my_bitmap_map_bits)) { - *(m++)= (1 << prefix_bits)-1; - // As the prefix bits are set, lets count this byte too as a prefix byte. - prefix_bytes ++; + my_bitmap_map *end= value+prefix; + do + { + *value++= ~(my_bitmap_map) 0; + } while (value < end); } - if ((d= no_bytes_in_map(map)-prefix_bytes)) - memset(m, 0, d); + if ((prefix_bits= prefix_size & (my_bitmap_map_bits-1))) + *value++= (1ULL << prefix_bits)-1; + while (value <= map->last_word_ptr) + *value++= 0; + DBUG_ASSERT_BITMAP(map); } +/** + Check if bitmap is a bitmap of prefix bits set in the beginning + + @param map bitmap + @param prefix_size number of bits that should be set. 0 is allowed. + + @return 1 Yes, prefix bits where set or prefix_size == 0. + @return 0 No +*/ + my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size) { - uint prefix_mask= last_byte_mask(prefix_size); - uchar *m= (uchar*) map->bitmap; - uchar *end_prefix= m+(prefix_size-1)/8; - uchar *end; - DBUG_ASSERT(m); - DBUG_ASSERT(prefix_size <= map->n_bits); + my_bitmap_map *value= map->bitmap; + my_bitmap_map *end= value+ (prefix_size/my_bitmap_map_bits); + uint prefix_bits; /* Empty prefix is always true */ if (!prefix_size) return 1; - while (m < end_prefix) - if (*m++ != 0xff) + DBUG_ASSERT_BITMAP_AND_BIT(map, prefix_size-1); + + while (value < end) + if (*value++ != ~(my_bitmap_map) 0) return 0; - end= ((uchar*) map->bitmap) + no_bytes_in_map(map) - 1; - if (m == end) - return ((*m & last_byte_mask(map->n_bits)) == prefix_mask); - - if (*m != prefix_mask) - return 0; - - while (++m < end) - if (*m != 0) + if ((prefix_bits= prefix_size & (my_bitmap_map_bits-1))) + { + if (*value++ != (1ULL << prefix_bits)-1) return 0; - return ((*m & last_byte_mask(map->n_bits)) == 0); + } + end= map->last_word_ptr; + while (value <= end) + if (*value++ != 0) + return 0; + return 1; } @@ -324,10 +338,12 @@ my_bool bitmap_is_set_all(const MY_BITMAP *map) { my_bitmap_map *data_ptr= map->bitmap; my_bitmap_map *end= map->last_word_ptr; + DBUG_ASSERT_BITMAP(map); + for (; data_ptr < end; data_ptr++) - if (*data_ptr != 0xFFFFFFFF) + if (*data_ptr != ~(my_bitmap_map)0) return FALSE; - return (*data_ptr | map->last_word_mask) == 0xFFFFFFFF; + return (*data_ptr | map->last_bit_mask) == ~(my_bitmap_map)0; } @@ -335,61 +351,58 @@ my_bool bitmap_is_clear_all(const MY_BITMAP *map) { my_bitmap_map *data_ptr= map->bitmap; my_bitmap_map *end= map->last_word_ptr; + DBUG_ASSERT_BITMAP(map); - DBUG_ASSERT(map->n_bits > 0); - for (; data_ptr < end; data_ptr++) + for (; data_ptr <= end; data_ptr++) if (*data_ptr) return FALSE; - return (*data_ptr & ~map->last_word_mask) == 0; + return TRUE; } + /* Return TRUE if map1 is a subset of map2 */ my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2) { - my_bitmap_map *m1= map1->bitmap, *m2= map2->bitmap, *end; + my_bitmap_map *m1= map1->bitmap, *m2= map2->bitmap, *end= map1->last_word_ptr; + DBUG_ASSERT_IDENTICAL_BITMAPS(map1,map2); - DBUG_ASSERT(map1->bitmap && map2->bitmap); - DBUG_ASSERT(map1->n_bits==map2->n_bits); - - end= map1->last_word_ptr; - while (m1 < end) + while (m1 <= end) { if ((*m1++) & ~(*m2++)) return 0; } - /* here both maps have the same number of bits - see assert above */ - return ((*m1 & ~*m2 & ~map1->last_word_mask) ? 0 : 1); + return 1; } /* True if bitmaps has any common bits */ my_bool bitmap_is_overlapping(const MY_BITMAP *map1, const MY_BITMAP *map2) { - my_bitmap_map *m1= map1->bitmap, *m2= map2->bitmap, *end; + my_bitmap_map *m1= map1->bitmap, *m2= map2->bitmap, *end= map1->last_word_ptr; + DBUG_ASSERT_IDENTICAL_BITMAPS(map1,map2); - DBUG_ASSERT(map1->bitmap); - DBUG_ASSERT(map2->bitmap); - DBUG_ASSERT(map1->n_bits==map2->n_bits); - - end= map1->last_word_ptr; - while (m1 < end) + while (m1 <= end) { if ((*m1++) & (*m2++)) return 1; } - /* here both maps have the same number of bits - see assert above */ - return ((*m1 & *m2 & ~map1->last_word_mask) ? 1 : 0); + return 0; } +/* + Create intersection of two bitmaps + + @param map map1. Result is stored here + @param map2 map2 +*/ + void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2) { my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end; uint len= no_words_in_map(map), len2 = no_words_in_map(map2); - - DBUG_ASSERT(map->bitmap); - DBUG_ASSERT(map2->bitmap); + DBUG_ASSERT_DIFFERENT_BITMAPS(map,map2); end= to+MY_MIN(len,len2); while (to < end) @@ -397,7 +410,7 @@ void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2) if (len2 <= len) { - to[-1]&= ~map2->last_word_mask; /* Clear last not relevant bits */ + to[-1]&= ~map2->last_bit_mask; /* Clear last not relevant bits */ end+= len-len2; while (to < end) *to++= 0; @@ -407,50 +420,51 @@ void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2) /* Check if there is some bit index between start_bit and end_bit, such that - this is bit is set for all bitmaps in bitmap_list. + this is at least on bit that set for all bitmaps in bitmap_list. SYNOPSIS bitmap_exists_intersection() bitmpap_array [in] a set of MY_BITMAPs - bitmap_count [in] number of elements in bitmpap_array + bitmap_count [in] number of elements in bitmap_array start_bit [in] beginning (inclusive) of the range of bits to search end_bit [in] end (inclusive) of the range of bits to search, must be no bigger than the bits of the shortest bitmap. - NOTES - This function assumes that for at least one of the bitmaps in bitmap_array all - bits outside the range [start_bit, end_bit] are 0. As a result is not - necessary to take care of the bits outside the range [start_bit, end_bit]. - RETURN TRUE if an intersecion exists FALSE no intersection */ -my_bool bitmap_exists_intersection(const MY_BITMAP **bitmap_array, +my_bool bitmap_exists_intersection(MY_BITMAP **bitmap_array, uint bitmap_count, uint start_bit, uint end_bit) { uint i, j, start_idx, end_idx; - my_bitmap_map cur_res; + my_bitmap_map cur_res, first_map; DBUG_ASSERT(bitmap_count); DBUG_ASSERT(end_bit >= start_bit); for (j= 0; j < bitmap_count; j++) - DBUG_ASSERT(end_bit < bitmap_array[j]->n_bits); + { + DBUG_ASSERT_BITMAP_AND_BIT(bitmap_array[j], end_bit); + } start_idx= start_bit/8/sizeof(my_bitmap_map); end_idx= end_bit/8/sizeof(my_bitmap_map); + first_map= first_bit_mask_inv(start_bit); + cur_res= first_map; for (i= start_idx; i < end_idx; i++) { - cur_res= ~0; for (j= 0; cur_res && j < bitmap_count; j++) cur_res &= bitmap_array[j]->bitmap[i]; if (cur_res) return TRUE; + cur_res= ~(my_bitmap_map) 0; } - cur_res= ~last_word_mask(end_bit); + cur_res= ~last_bit_mask(end_bit+1); + if (start_idx == end_idx) + cur_res&= first_map; for (j= 0; cur_res && j < bitmap_count; j++) cur_res &= bitmap_array[j]->bitmap[end_idx]; return cur_res != 0; @@ -461,60 +475,21 @@ my_bool bitmap_exists_intersection(const MY_BITMAP **bitmap_array, my_bool bitmap_union_is_set_all(const MY_BITMAP *map1, const MY_BITMAP *map2) { - my_bitmap_map *m1= map1->bitmap, *m2= map2->bitmap, *end; + my_bitmap_map *m1= map1->bitmap, *m2= map2->bitmap, *end= map1->last_word_ptr; + DBUG_ASSERT_IDENTICAL_BITMAPS(map1,map2); - DBUG_ASSERT(map1->bitmap); - DBUG_ASSERT(map2->bitmap); - DBUG_ASSERT(map1->n_bits==map2->n_bits); - end= map1->last_word_ptr; while ( m1 < end) - if ((*m1++ | *m2++) != 0xFFFFFFFF) + if ((*m1++ | *m2++) != ~(my_bitmap_map)0) return FALSE; /* here both maps have the same number of bits - see assert above */ - return ((*m1 | *m2 | map1->last_word_mask) != 0xFFFFFFFF); -} - - - -/* - Set/clear all bits above a bit. - - SYNOPSIS - bitmap_set_above() - map RETURN The bitmap to change. - from_byte The bitmap buffer byte offset to start with. - use_bit The bit value (1/0) to use for all upper bits. - - NOTE - You can only set/clear full bytes. - The function is meant for the situation that you copy a smaller bitmap - to a bigger bitmap. Bitmap lengths are always multiple of eigth (the - size of a byte). Using 'from_byte' saves multiplication and division - by eight during parameter passing. - - RETURN - void -*/ - -void bitmap_set_above(MY_BITMAP *map, uint from_byte, uint use_bit) -{ - uchar use_byte= use_bit ? 0xff : 0; - uchar *to= (uchar *)map->bitmap + from_byte; - uchar *end= (uchar *)map->bitmap + (map->n_bits+7)/8; - - while (to < end) - *to++= use_byte; + return ((*m1 | *m2 | map1->last_bit_mask) != ~(my_bitmap_map)0); } void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2) { - my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end; - DBUG_ASSERT(map->bitmap); - DBUG_ASSERT(map2->bitmap); - DBUG_ASSERT(map->n_bits==map2->n_bits); - - end= map->last_word_ptr; + my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end= map->last_word_ptr; + DBUG_ASSERT_IDENTICAL_BITMAPS(map,map2); while (to <= end) *to++ &= ~(*from++); @@ -523,12 +498,8 @@ void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2) void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2) { - my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end; - - DBUG_ASSERT(map->bitmap); - DBUG_ASSERT(map2->bitmap); - DBUG_ASSERT(map->n_bits == map2->n_bits); - end= map->last_word_ptr; + my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end= map->last_word_ptr; + DBUG_ASSERT_IDENTICAL_BITMAPS(map,map2); while (to <= end) *to++ |= *from++; @@ -538,9 +509,8 @@ void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2) void bitmap_xor(MY_BITMAP *map, const MY_BITMAP *map2) { my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end= map->last_word_ptr; - DBUG_ASSERT(map->bitmap); - DBUG_ASSERT(map2->bitmap); - DBUG_ASSERT(map->n_bits == map2->n_bits); + DBUG_ASSERT_IDENTICAL_BITMAPS(map,map2); + while (to <= end) *to++ ^= *from++; } @@ -548,13 +518,14 @@ void bitmap_xor(MY_BITMAP *map, const MY_BITMAP *map2) void bitmap_invert(MY_BITMAP *map) { - my_bitmap_map *to= map->bitmap, *end; + my_bitmap_map *to= map->bitmap, *end= map->last_word_ptr; + DBUG_ASSERT_BITMAP(map); - DBUG_ASSERT(map->bitmap); - end= map->last_word_ptr; + while (to < end) + *to++ ^= ~(my_bitmap_map)0; - while (to <= end) - *to++ ^= 0xFFFFFFFF; + *to ^= (~(my_bitmap_map)0 & ~map->last_bit_mask); + DBUG_ASSERT_BITMAP(map); } @@ -563,48 +534,55 @@ uint bitmap_bits_set(const MY_BITMAP *map) my_bitmap_map *data_ptr= map->bitmap; my_bitmap_map *end= map->last_word_ptr; uint res= 0; - DBUG_ASSERT(map->bitmap); + DBUG_ASSERT_BITMAP(map); - for (; data_ptr < end; data_ptr++) - res+= my_count_bits_uint32(*data_ptr); + for (; data_ptr <= end; data_ptr++) + res+= my_count_bits(*data_ptr); - /*Reset last bits to zero*/ - res+= my_count_bits_uint32(*map->last_word_ptr & ~map->last_word_mask); return res; } + +/** + Copy bitmaps (if source bigger tail is left unchanged) + + @param map to-bitmap + @param map2 from-bitmap + + @notes + Code will work even of the bitmaps are of different size. + In this case, only up to to->n_bits will be copied. +*/ + void bitmap_copy(MY_BITMAP *map, const MY_BITMAP *map2) { my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end; uint len= no_words_in_map(map), len2 = no_words_in_map(map2); - - DBUG_ASSERT(map->bitmap); - DBUG_ASSERT(map2->bitmap); + DBUG_ASSERT_DIFFERENT_BITMAPS(map, map2); end= to + MY_MIN(len, len2 - 1); while (to < end) *to++ = *from++; if (len2 <= len) - *to= (*from & ~map2->last_word_mask) | (*to & map2->last_word_mask); + *to= (*from & ~map2->last_bit_mask) | (*to & map2->last_bit_mask); + *(map->last_word_ptr)&= ~map->last_bit_mask; } +/* + Find first set bit in the bitmap +*/ + uint bitmap_get_first_set(const MY_BITMAP *map) { - uint i; my_bitmap_map *data_ptr= map->bitmap, *end= map->last_word_ptr; + DBUG_ASSERT_BITMAP(map); - DBUG_ASSERT(map->bitmap); - - for (i=0; data_ptr < end; data_ptr++, i++) + for (uint i=0; data_ptr <= end; data_ptr++, i++) if (*data_ptr) - goto found; - if (!(*data_ptr & ~map->last_word_mask)) - return MY_BIT_NONE; - -found: - return get_first_set(*data_ptr, i); + return my_find_first_bit(*data_ptr) + i * sizeof(my_bitmap_map)*8; + return MY_BIT_NONE; } @@ -619,80 +597,113 @@ found: uint bitmap_get_next_set(const MY_BITMAP *map, uint bitmap_bit) { - uint word_pos, byte_to_mask, i; - union { my_bitmap_map bitmap ; uchar bitmap_buff[sizeof(my_bitmap_map)]; } - first_word; - uchar *ptr= &first_word.bitmap_buff[0]; - my_bitmap_map *data_ptr, *end= map->last_word_ptr; - - DBUG_ASSERT(map->bitmap); + uint word_pos; + my_bitmap_map first_word, *data_ptr, *end= map->last_word_ptr; + DBUG_ASSERT_BITMAP(map); /* Look for the next bit */ bitmap_bit++; if (bitmap_bit >= map->n_bits) return MY_BIT_NONE; - word_pos= bitmap_bit / 32; + + word_pos= bitmap_bit / 64; data_ptr= map->bitmap + word_pos; - first_word.bitmap= *data_ptr; - /* Mask out previous bits from first_word */ - byte_to_mask= (bitmap_bit % 32) / 8; - for (i= 0; i < byte_to_mask; i++) - ptr[i]= 0; - ptr[byte_to_mask]&= 0xFFU << (bitmap_bit & 7); + first_word= *data_ptr & first_bit_mask_inv(bitmap_bit); - if (data_ptr == end) + if (first_word) { - if (first_word.bitmap & ~map->last_word_mask) - return get_first_set(first_word.bitmap, word_pos); - else - return MY_BIT_NONE; + /* Optimize common case when most bits are set */ + if (first_word & (1ULL << ((bitmap_bit & (my_bitmap_map_bits-1))))) + return bitmap_bit; + return my_find_first_bit(first_word) + (bitmap_bit & ~(my_bitmap_map_bits-1)); } - - if (first_word.bitmap) - return get_first_set(first_word.bitmap, word_pos); - for (data_ptr++, word_pos++; data_ptr < end; data_ptr++, word_pos++) + for (data_ptr++; data_ptr <= end; data_ptr++) + { + bitmap_bit+= 64; if (*data_ptr) - return get_first_set(*data_ptr, word_pos); - - if (!(*end & ~map->last_word_mask)) - return MY_BIT_NONE; - return get_first_set(*end, word_pos); -} - - -/* Get first free bit */ - -uint bitmap_get_first(const MY_BITMAP *map) -{ - uchar *byte_ptr; - uint i,j,k; - my_bitmap_map *data_ptr, *end= map->last_word_ptr; - - DBUG_ASSERT(map->bitmap); - data_ptr= map->bitmap; - *map->last_word_ptr|= map->last_word_mask; - - for (i=0; data_ptr < end; data_ptr++, i++) - if (*data_ptr != 0xFFFFFFFF) - goto found; - if ((*data_ptr | map->last_word_mask) == 0xFFFFFFFF) - return MY_BIT_NONE; - -found: - byte_ptr= (uchar*)data_ptr; - for (j=0; ; j++, byte_ptr++) - { - if (*byte_ptr != 0xFF) - { - for (k=0; ; k++) - { - if (!(*byte_ptr & (1 << k))) - return (i*32) + (j*8) + k; - } - } + return my_find_first_bit(*data_ptr) + (bitmap_bit & ~(my_bitmap_map_bits-1)); } - DBUG_ASSERT(0); - return MY_BIT_NONE; /* Impossible */ + return MY_BIT_NONE; } + + +/* Get first clear bit */ + +uint bitmap_get_first_clear(const MY_BITMAP *map) +{ + uint i; + my_bitmap_map *data_ptr= map->bitmap, *end= map->last_word_ptr; + DBUG_ASSERT_BITMAP(map); + + for (i= 0; data_ptr < end; data_ptr++, i++) + if (*data_ptr != ~(my_bitmap_map)0) + goto found; + if ((*data_ptr | map->last_bit_mask) == ~(my_bitmap_map)0) + return MY_BIT_NONE; +found: + /* find first zero bit by reverting all bits and find first bit */ + return my_find_first_bit(~*data_ptr) + i * sizeof(my_bitmap_map)*8; +} +/* + Functions to export/import bitmaps to an architecture independent format + (low_byte_first) +*/ + +#ifdef WORDS_BIGENDIAN +/* Big endian machines, like powerpc or s390x */ + +void bitmap_export(uchar *to, MY_BITMAP *map) +{ + my_bitmap_map *value; + uint length; + uchar buff[my_bitmap_map_bytes]; + + for (value= map->bitmap ; value < map->last_word_ptr ; value++) + { + int8store(to, *value); + to+= 8; + } + int8store(buff, *value); + + /* We want length & 7 to return a serie 8,2,3,4,5,6,7, 8,2,3,... */ + length= 1+ ((no_bytes_in_export_map(map) + 7) & 7); + memcpy(to, buff, length); +} + + +void bitmap_import(MY_BITMAP *map, uchar *from) +{ + my_bitmap_map *value; + uint length; + uchar buff[my_bitmap_map_bytes]; + + for (value= map->bitmap ; value < map->last_word_ptr ; value++) + { + *value= uint8korr(from); + from+= 8; + } + bzero(buff, sizeof(buff)); + + /* We want length & 7 to return a serie 8,2,3,4,5,6,7, 8,2,3,... */ + length= 1+ ((no_bytes_in_export_map(map) + 7) & 7); + memcpy(buff, from, length); + *value= uint8korr(buff) & ~map->last_bit_mask; +} + +#else + +/* Little endian machines, like intel and amd */ + +void bitmap_export(uchar *to, MY_BITMAP *map) +{ + memcpy(to, (uchar*) map->bitmap, no_bytes_in_export_map(map)); +} + +void bitmap_import(MY_BITMAP *map, uchar *from) +{ + memcpy((uchar*) map->bitmap, from, no_bytes_in_export_map(map)); + *map->last_word_ptr&= ~map->last_bit_mask; +} +#endif /* WORDS_BIGENDIAN */ diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 0343e06a2f6..449302a971e 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -172,6 +172,8 @@ static void validate_value(const char *key, const char *value, #define validate_value(key, value, filename) (void)filename #endif +#define SET_HO_ERROR_AND_CONTINUE(e) { ho_error= (e); (*argc)--; continue; } + /** Handle command line options. Sort options. @@ -241,7 +243,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, const char *UNINIT_VAR(prev_found); const struct my_option *optp; void *value; - int error, i; + int ho_error= 0, error, i; my_bool is_cmdline_arg= 1; DBUG_ENTER("handle_options"); @@ -255,7 +257,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, is_cmdline_arg= !is_file_marker(**argv); - for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++) + for (pos= *argv, pos_end=pos+ *argc; pos < pos_end ; pos++) { char **first= pos; char *cur_arg= *pos; @@ -344,7 +346,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, my_progname, special_opt_prefix[i], opt_str, special_opt_prefix[i], prev_found); - DBUG_RETURN(EXIT_AMBIGUOUS_OPTION); + SET_HO_ERROR_AND_CONTINUE(EXIT_AMBIGUOUS_OPTION) } switch (i) { case OPT_SKIP: @@ -389,7 +391,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, "%s: unknown variable '%s'", my_progname, cur_arg); if (!option_is_loose) - DBUG_RETURN(EXIT_UNKNOWN_VARIABLE); + SET_HO_ERROR_AND_CONTINUE(EXIT_UNKNOWN_VARIABLE) } else { @@ -399,7 +401,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, "%s: unknown option '--%s'", my_progname, cur_arg); if (!option_is_loose) - DBUG_RETURN(EXIT_UNKNOWN_OPTION); + SET_HO_ERROR_AND_CONTINUE(EXIT_UNKNOWN_OPTION) } if (option_is_loose) { @@ -416,7 +418,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, my_getopt_error_reporter(ERROR_LEVEL, "%s: variable prefix '%s' is not unique", my_progname, opt_str); - DBUG_RETURN(EXIT_VAR_PREFIX_NOT_UNIQUE); + SET_HO_ERROR_AND_CONTINUE(EXIT_VAR_PREFIX_NOT_UNIQUE) } else { @@ -425,7 +427,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, "%s: ambiguous option '--%s' (%s, %s)", my_progname, opt_str, prev_found, optp->name); - DBUG_RETURN(EXIT_AMBIGUOUS_OPTION); + SET_HO_ERROR_AND_CONTINUE(EXIT_AMBIGUOUS_OPTION) } } if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED) @@ -439,14 +441,14 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, (*argc)--; continue; } - DBUG_RETURN(EXIT_OPTION_DISABLED); + SET_HO_ERROR_AND_CONTINUE(EXIT_OPTION_DISABLED) } error= 0; value= optp->var_type & GET_ASK_ADDR ? (*my_getopt_get_addr)(key_name, (uint)strlen(key_name), optp, &error) : optp->value; if (error) - DBUG_RETURN(error); + SET_HO_ERROR_AND_CONTINUE(error) if (optp->arg_type == NO_ARG) { @@ -461,7 +463,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, my_getopt_error_reporter(ERROR_LEVEL, "%s: option '--%s' cannot take an argument", my_progname, optp->name); - DBUG_RETURN(EXIT_NO_ARGUMENT_ALLOWED); + SET_HO_ERROR_AND_CONTINUE(EXIT_NO_ARGUMENT_ALLOWED) } if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL) { @@ -490,7 +492,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, if (get_one_option(optp, *((my_bool*) value) ? enabled_my_option : disabled_my_option, filename)) - DBUG_RETURN(EXIT_ARGUMENT_INVALID); + SET_HO_ERROR_AND_CONTINUE(EXIT_ARGUMENT_INVALID) continue; } argument= optend; @@ -504,7 +506,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, "option '--%s' cannot take an argument", my_progname, optp->name); - DBUG_RETURN(EXIT_NO_ARGUMENT_ALLOWED); + SET_HO_ERROR_AND_CONTINUE(EXIT_NO_ARGUMENT_ALLOWED) } if (!(optp->var_type & GET_AUTO)) { @@ -514,7 +516,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, "unsupported by option '--%s'", my_progname, optp->name); if (!option_is_loose) - DBUG_RETURN(EXIT_ARGUMENT_INVALID); + SET_HO_ERROR_AND_CONTINUE(EXIT_ARGUMENT_INVALID) continue; } else @@ -533,7 +535,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, my_getopt_error_reporter(ERROR_LEVEL, "%s: option '--%s' requires an argument", my_progname, optp->name); - DBUG_RETURN(EXIT_ARGUMENT_REQUIRED); + SET_HO_ERROR_AND_CONTINUE(EXIT_ARGUMENT_REQUIRED) } argument= *pos; (*argc)--; @@ -558,14 +560,14 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, fprintf(stderr, "%s: ERROR: Option '-%c' used, but is disabled\n", my_progname, optp->id); - DBUG_RETURN(EXIT_OPTION_DISABLED); + SET_HO_ERROR_AND_CONTINUE(EXIT_OPTION_DISABLED) } if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL && optp->arg_type == NO_ARG) { *((my_bool*) optp->value)= (my_bool) 1; if (get_one_option(optp, argument, filename)) - DBUG_RETURN(EXIT_UNSPECIFIED_ERROR); + SET_HO_ERROR_AND_CONTINUE(EXIT_UNSPECIFIED_ERROR) continue; } else if (optp->arg_type == REQUIRED_ARG || @@ -585,7 +587,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, if (optp->var_type == GET_BOOL) *((my_bool*) optp->value)= (my_bool) 1; if (get_one_option(optp, argument, filename)) - DBUG_RETURN(EXIT_UNSPECIFIED_ERROR); + SET_HO_ERROR_AND_CONTINUE(EXIT_UNSPECIFIED_ERROR) continue; } /* Check if there are more arguments after this one */ @@ -595,7 +597,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, my_getopt_error_reporter(ERROR_LEVEL, "%s: option '-%c' requires an argument", my_progname, optp->id); - DBUG_RETURN(EXIT_ARGUMENT_REQUIRED); + SET_HO_ERROR_AND_CONTINUE(EXIT_ARGUMENT_REQUIRED) } argument= *++pos; (*argc)--; @@ -603,10 +605,10 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, } } if ((error= setval(optp, optp->value, argument, - set_maximum_value,filename))) - DBUG_RETURN(error); + set_maximum_value,filename))) + SET_HO_ERROR_AND_CONTINUE(error) if (get_one_option(optp, argument, filename)) - DBUG_RETURN(EXIT_UNSPECIFIED_ERROR); + SET_HO_ERROR_AND_CONTINUE(EXIT_UNSPECIFIED_ERROR) break; } } @@ -640,7 +642,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, my_getopt_error_reporter(ERROR_LEVEL, "%s: unknown option '-%c'", my_progname, *optend); - DBUG_RETURN(EXIT_UNKNOWN_OPTION); + SET_HO_ERROR_AND_CONTINUE(EXIT_UNKNOWN_OPTION) } } } @@ -651,15 +653,17 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, if ((!option_is_autoset) && ((error= setval(optp, value, argument, set_maximum_value,filename))) && !option_is_loose) - DBUG_RETURN(error); + SET_HO_ERROR_AND_CONTINUE(error) if (get_one_option(optp, argument, filename)) - DBUG_RETURN(EXIT_UNSPECIFIED_ERROR); + SET_HO_ERROR_AND_CONTINUE(EXIT_UNSPECIFIED_ERROR) (*argc)--; /* option handled (long), decrease argument count */ } else /* non-option found */ (*argv)[argvpos++]= cur_arg; } + if (ho_error) + DBUG_RETURN(ho_error); /* Destroy the first, already handled option, so that programs that look for arguments in 'argv', without checking 'argc', know when to stop. @@ -899,7 +903,7 @@ static int setval(const struct my_option *opts, void *value, char *argument, } if (err) { - res= EXIT_UNKNOWN_SUFFIX; + res= err; goto ret; }; } @@ -1036,7 +1040,7 @@ static inline ulonglong eval_num_suffix(char *suffix, int *error) case 'E': return 1ULL << 60; default: - *error= 1; + *error= EXIT_UNKNOWN_SUFFIX; return 0ULL; } } @@ -1062,15 +1066,18 @@ static longlong eval_num_suffix_ll(char *argument, if (errno == ERANGE) { my_getopt_error_reporter(ERROR_LEVEL, - "Incorrect integer value: '%s'", argument); - *error= 1; + "Integer value out of range for int64:" + " '%s' for %s", + argument, option_name); + *error= EXIT_ARGUMENT_INVALID; DBUG_RETURN(0); } num*= eval_num_suffix(endchar, error); if (*error) - fprintf(stderr, - "Unknown suffix '%c' used for variable '%s' (value '%s')\n", - *endchar, option_name, argument); + my_getopt_error_reporter(ERROR_LEVEL, + "Unknown suffix '%c' used for variable '%s' (value '%s'). " + "Legal suffix characters are: K, M, G, T, P, E", + *endchar, option_name, argument); DBUG_RETURN(num); } @@ -1093,7 +1100,7 @@ static ulonglong eval_num_suffix_ull(char *argument, my_getopt_error_reporter(ERROR_LEVEL, "Incorrect unsigned value: '%s' for %s", argument, option_name); - *error= 1; + *error= EXIT_ARGUMENT_INVALID; DBUG_RETURN(0); } *error= 0; @@ -1102,15 +1109,18 @@ static ulonglong eval_num_suffix_ull(char *argument, if (errno == ERANGE) { my_getopt_error_reporter(ERROR_LEVEL, - "Incorrect integer value: '%s' for %s", + "Integer value out of range for uint64:" + " '%s' for %s", argument, option_name); - *error= 1; + *error= EXIT_ARGUMENT_INVALID; DBUG_RETURN(0); } num*= eval_num_suffix(endchar, error); if (*error) my_getopt_error_reporter(ERROR_LEVEL, - "Unknown suffix '%c' used for variable '%s' (value '%s')", + "Unknown suffix '%c' used for variable '%s'" + " (value '%s')." + " Legal suffix characters are: K, M, G, T, P, E", *endchar, option_name, argument); DBUG_RETURN(num); } @@ -1130,6 +1140,8 @@ static ulonglong eval_num_suffix_ull(char *argument, static longlong getopt_ll(char *arg, const struct my_option *optp, int *err) { longlong num=eval_num_suffix_ll(arg, err, (char*) optp->name); + if (*err) + return(0); return getopt_ll_limit_value(num, optp, NULL); } @@ -1207,6 +1219,8 @@ longlong getopt_ll_limit_value(longlong num, const struct my_option *optp, static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err) { ulonglong num= eval_num_suffix_ull(arg, err, (char*) optp->name); + if (*err) + return(0); return getopt_ull_limit_value(num, optp, NULL); } diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 2e8decd7d06..b2436d2be27 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -220,7 +220,11 @@ void my_thread_global_end(void) fprintf(stderr, "Error in my_thread_global_end(): %d threads didn't exit\n", THR_thread_count); -#endif +#endif /* HAVE_PTHREAD_KILL */ +#ifdef SAFEMALLOC + /* We know we will have memoryleaks, suppress the leak report */ + sf_leaking_memory= 1; +#endif /* SAFEMALLOC */ all_threads_killed= 0; break; } @@ -234,9 +238,7 @@ void my_thread_global_end(void) that could use them. */ if (all_threads_killed) - { my_thread_destroy_internal_mutex(); - } my_thread_global_init_done= 0; } diff --git a/plugin/auth_ed25519/ref10/fe_mul.c b/plugin/auth_ed25519/ref10/fe_mul.c index 26ca8b3682d..8ccad3c30d8 100644 --- a/plugin/auth_ed25519/ref10/fe_mul.c +++ b/plugin/auth_ed25519/ref10/fe_mul.c @@ -1,5 +1,6 @@ #include "fe.h" #include "crypto_int64.h" +#include "crypto_uint64.h" /* h = f * g @@ -179,16 +180,16 @@ void fe_mul(fe h,const fe f,const fe g) crypto_int64 h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19; crypto_int64 h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38; crypto_int64 h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ; - crypto_int64 carry0; - crypto_int64 carry1; - crypto_int64 carry2; - crypto_int64 carry3; - crypto_int64 carry4; - crypto_int64 carry5; - crypto_int64 carry6; - crypto_int64 carry7; - crypto_int64 carry8; - crypto_int64 carry9; + crypto_uint64 carry0; + crypto_uint64 carry1; + crypto_uint64 carry2; + crypto_uint64 carry3; + crypto_uint64 carry4; + crypto_uint64 carry5; + crypto_uint64 carry6; + crypto_uint64 carry7; + crypto_uint64 carry8; + crypto_uint64 carry9; /* |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) diff --git a/plugin/auth_ed25519/ref10/fe_sq.c b/plugin/auth_ed25519/ref10/fe_sq.c index 8dd119841c6..3c718033a0a 100644 --- a/plugin/auth_ed25519/ref10/fe_sq.c +++ b/plugin/auth_ed25519/ref10/fe_sq.c @@ -1,5 +1,6 @@ #include "fe.h" #include "crypto_int64.h" +#include "crypto_uint64.h" /* h = f * f @@ -106,16 +107,16 @@ void fe_sq(fe h,const fe f) crypto_int64 h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; crypto_int64 h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; crypto_int64 h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; - crypto_int64 carry0; - crypto_int64 carry1; - crypto_int64 carry2; - crypto_int64 carry3; - crypto_int64 carry4; - crypto_int64 carry5; - crypto_int64 carry6; - crypto_int64 carry7; - crypto_int64 carry8; - crypto_int64 carry9; + crypto_uint64 carry0; + crypto_uint64 carry1; + crypto_uint64 carry2; + crypto_uint64 carry3; + crypto_uint64 carry4; + crypto_uint64 carry5; + crypto_uint64 carry6; + crypto_uint64 carry7; + crypto_uint64 carry8; + crypto_uint64 carry9; carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; diff --git a/plugin/auth_ed25519/ref10/fe_sq2.c b/plugin/auth_ed25519/ref10/fe_sq2.c index 026ed3aacf5..97c03cf4899 100644 --- a/plugin/auth_ed25519/ref10/fe_sq2.c +++ b/plugin/auth_ed25519/ref10/fe_sq2.c @@ -1,5 +1,6 @@ #include "fe.h" #include "crypto_int64.h" +#include "crypto_uint64.h" /* h = 2 * f * f @@ -106,16 +107,16 @@ void fe_sq2(fe h,const fe f) crypto_int64 h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; crypto_int64 h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; crypto_int64 h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; - crypto_int64 carry0; - crypto_int64 carry1; - crypto_int64 carry2; - crypto_int64 carry3; - crypto_int64 carry4; - crypto_int64 carry5; - crypto_int64 carry6; - crypto_int64 carry7; - crypto_int64 carry8; - crypto_int64 carry9; + crypto_uint64 carry0; + crypto_uint64 carry1; + crypto_uint64 carry2; + crypto_uint64 carry3; + crypto_uint64 carry4; + crypto_uint64 carry5; + crypto_uint64 carry6; + crypto_uint64 carry7; + crypto_uint64 carry8; + crypto_uint64 carry9; h0 += h0; h1 += h1; diff --git a/plugin/auth_ed25519/ref10/fe_tobytes.c b/plugin/auth_ed25519/ref10/fe_tobytes.c index 0a63baf9c17..a4dff2c1574 100644 --- a/plugin/auth_ed25519/ref10/fe_tobytes.c +++ b/plugin/auth_ed25519/ref10/fe_tobytes.c @@ -1,4 +1,5 @@ #include "fe.h" +#include "crypto_uint32.h" /* Preconditions: @@ -38,16 +39,16 @@ void fe_tobytes(unsigned char *s,const fe h) crypto_int32 h8 = h[8]; crypto_int32 h9 = h[9]; crypto_int32 q; - crypto_int32 carry0; - crypto_int32 carry1; - crypto_int32 carry2; - crypto_int32 carry3; - crypto_int32 carry4; - crypto_int32 carry5; - crypto_int32 carry6; - crypto_int32 carry7; - crypto_int32 carry8; - crypto_int32 carry9; + crypto_uint32 carry0; + crypto_uint32 carry1; + crypto_uint32 carry2; + crypto_uint32 carry3; + crypto_uint32 carry4; + crypto_uint32 carry5; + crypto_uint32 carry6; + crypto_uint32 carry7; + crypto_uint32 carry8; + crypto_uint32 carry9; q = (19 * h9 + (((crypto_int32) 1) << 24)) >> 25; q = (h0 + q) >> 26; @@ -87,32 +88,32 @@ void fe_tobytes(unsigned char *s,const fe h) s[0] = h0 >> 0; s[1] = h0 >> 8; s[2] = h0 >> 16; - s[3] = (h0 >> 24) | (h1 << 2); + s[3] = (h0 >> 24) | ((crypto_uint32)h1 << 2); s[4] = h1 >> 6; s[5] = h1 >> 14; - s[6] = (h1 >> 22) | (h2 << 3); + s[6] = (h1 >> 22) | ((crypto_uint32)h2 << 3); s[7] = h2 >> 5; s[8] = h2 >> 13; - s[9] = (h2 >> 21) | (h3 << 5); + s[9] = (h2 >> 21) | ((crypto_uint32)h3 << 5); s[10] = h3 >> 3; s[11] = h3 >> 11; - s[12] = (h3 >> 19) | (h4 << 6); + s[12] = (h3 >> 19) | ((crypto_uint32)h4 << 6); s[13] = h4 >> 2; s[14] = h4 >> 10; s[15] = h4 >> 18; s[16] = h5 >> 0; s[17] = h5 >> 8; s[18] = h5 >> 16; - s[19] = (h5 >> 24) | (h6 << 1); + s[19] = (h5 >> 24) | ((crypto_uint32)h6 << 1); s[20] = h6 >> 7; s[21] = h6 >> 15; - s[22] = (h6 >> 23) | (h7 << 3); + s[22] = (h6 >> 23) | ((crypto_uint32)h7 << 3); s[23] = h7 >> 5; s[24] = h7 >> 13; - s[25] = (h7 >> 21) | (h8 << 4); + s[25] = (h7 >> 21) | ((crypto_uint32)h8 << 4); s[26] = h8 >> 4; s[27] = h8 >> 12; - s[28] = (h8 >> 20) | (h9 << 6); + s[28] = (h8 >> 20) | ((crypto_uint32)h9 << 6); s[29] = h9 >> 2; s[30] = h9 >> 10; s[31] = h9 >> 18; diff --git a/plugin/auth_ed25519/ref10/ge_scalarmult_base.c b/plugin/auth_ed25519/ref10/ge_scalarmult_base.c index 421e4fa0fba..9a4ced2182f 100644 --- a/plugin/auth_ed25519/ref10/ge_scalarmult_base.c +++ b/plugin/auth_ed25519/ref10/ge_scalarmult_base.c @@ -35,7 +35,7 @@ static void select(ge_precomp *t,int pos,signed char b) { ge_precomp minust; unsigned char bnegative = negative(b); - unsigned char babs = b - (((-bnegative) & b) << 1); + unsigned char babs = b - ((unsigned char)((-bnegative) & b) << 1); ge_precomp_0(t); cmov(t,&base[pos][0],equal(babs,1)); diff --git a/plugin/auth_ed25519/ref10/sc_muladd.c b/plugin/auth_ed25519/ref10/sc_muladd.c index 6f1e9d02d60..7bf222be815 100644 --- a/plugin/auth_ed25519/ref10/sc_muladd.c +++ b/plugin/auth_ed25519/ref10/sc_muladd.c @@ -95,29 +95,29 @@ void sc_muladd(unsigned char *s,const unsigned char *a,const unsigned char *b,co crypto_int64 s21; crypto_int64 s22; crypto_int64 s23; - crypto_int64 carry0; - crypto_int64 carry1; - crypto_int64 carry2; - crypto_int64 carry3; - crypto_int64 carry4; - crypto_int64 carry5; - crypto_int64 carry6; - crypto_int64 carry7; - crypto_int64 carry8; - crypto_int64 carry9; - crypto_int64 carry10; - crypto_int64 carry11; - crypto_int64 carry12; - crypto_int64 carry13; - crypto_int64 carry14; - crypto_int64 carry15; - crypto_int64 carry16; - crypto_int64 carry17; - crypto_int64 carry18; - crypto_int64 carry19; - crypto_int64 carry20; - crypto_int64 carry21; - crypto_int64 carry22; + crypto_uint64 carry0; + crypto_uint64 carry1; + crypto_uint64 carry2; + crypto_uint64 carry3; + crypto_uint64 carry4; + crypto_uint64 carry5; + crypto_uint64 carry6; + crypto_uint64 carry7; + crypto_uint64 carry8; + crypto_uint64 carry9; + crypto_uint64 carry10; + crypto_uint64 carry11; + crypto_uint64 carry12; + crypto_uint64 carry13; + crypto_uint64 carry14; + crypto_uint64 carry15; + crypto_uint64 carry16; + crypto_uint64 carry17; + crypto_uint64 carry18; + crypto_uint64 carry19; + crypto_uint64 carry20; + crypto_uint64 carry21; + crypto_uint64 carry22; s0 = c0 + a0*b0; s1 = c1 + a0*b1 + a1*b0; diff --git a/plugin/auth_ed25519/ref10/sc_reduce.c b/plugin/auth_ed25519/ref10/sc_reduce.c index d01f5a5737e..422d94b6faf 100644 --- a/plugin/auth_ed25519/ref10/sc_reduce.c +++ b/plugin/auth_ed25519/ref10/sc_reduce.c @@ -58,23 +58,23 @@ void sc_reduce(unsigned char *s) crypto_int64 s21 = 2097151 & (load_3(s + 55) >> 1); crypto_int64 s22 = 2097151 & (load_4(s + 57) >> 6); crypto_int64 s23 = (load_4(s + 60) >> 3); - crypto_int64 carry0; - crypto_int64 carry1; - crypto_int64 carry2; - crypto_int64 carry3; - crypto_int64 carry4; - crypto_int64 carry5; - crypto_int64 carry6; - crypto_int64 carry7; - crypto_int64 carry8; - crypto_int64 carry9; - crypto_int64 carry10; - crypto_int64 carry11; - crypto_int64 carry12; - crypto_int64 carry13; - crypto_int64 carry14; - crypto_int64 carry15; - crypto_int64 carry16; + crypto_uint64 carry0; + crypto_uint64 carry1; + crypto_uint64 carry2; + crypto_uint64 carry3; + crypto_uint64 carry4; + crypto_uint64 carry5; + crypto_uint64 carry6; + crypto_uint64 carry7; + crypto_uint64 carry8; + crypto_uint64 carry9; + crypto_uint64 carry10; + crypto_uint64 carry11; + crypto_uint64 carry12; + crypto_uint64 carry13; + crypto_uint64 carry14; + crypto_uint64 carry15; + crypto_uint64 carry16; s11 += s23 * 666643; s12 += s23 * 470296; diff --git a/plugin/auth_gssapi/README.md b/plugin/auth_gssapi/README.md index ea8deaafa94..635982234c4 100644 --- a/plugin/auth_gssapi/README.md +++ b/plugin/auth_gssapi/README.md @@ -49,7 +49,7 @@ Usually nothing need to be done. MariaDB server should to run on a domain joine Creating service principal is not required here (but you can still do it using [_setspn_](https://technet.microsoft.com/en-us/library/cc731241.aspx) tool) -# Installing plugin +## Installing plugin - Start the server - On Unix, edit my the my.cnf/my.ini configuration file, set the parameter gssapi-keytab-path to point to previously @@ -72,7 +72,7 @@ configure alternative principal name with INSTALL SONAME 'auth_gssapi' ``` -#Creating users +## Creating users Now, you can create a user for GSSAPI/SSPI authentication. CREATE USER command, for Kerberos user would be like this (*long* form, see below for short one) @@ -94,7 +94,7 @@ CREATE USER usr1 IDENTIFIED WITH gssapi; If this syntax is used, realm part is *not* used for comparison thus 'usr1@EXAMPLE.COM', 'usr1@EXAMPLE.CO.UK' and 'mymachine\usr1' will all identify as 'usr1'. -#Login as GSSAPI user with command line clients +## Login as GSSAPI user with command line clients Using command line client, do @@ -102,7 +102,7 @@ Using command line client, do mysql --plugin-dir=/path/to/plugin-dir -u usr1 ``` -#Plugin variables +## Plugin variables - **gssapi-keytab-path** (Unix only) - Path to the server keytab file - **gssapi-principal-name** - name of the service principal. - **gssapi-mech-name** (Windows only) - Name of the SSPI package used by server. Can be either 'Kerberos' or 'Negotiate'. @@ -111,7 +111,7 @@ mysql --plugin-dir=/path/to/plugin-dir -u usr1 to allow non-domain environment (e.g if server does not run in domain environment). -#Implementation +## Implementation Overview of the protocol between client and server diff --git a/plugin/auth_pam/auth_pam_base.c b/plugin/auth_pam/auth_pam_base.c index 1e8f4a08def..153712df140 100644 --- a/plugin/auth_pam/auth_pam_base.c +++ b/plugin/auth_pam/auth_pam_base.c @@ -99,7 +99,7 @@ static int conv(int n, const struct pam_message **msg, freeing it is the responsibility of the caller */ if (*resp == 0) { - *resp = calloc(sizeof(struct pam_response), n); + *resp = calloc(n, sizeof(struct pam_response)); if (*resp == 0) return PAM_BUF_ERR; } diff --git a/plugin/cracklib_password_check/CMakeLists.txt b/plugin/cracklib_password_check/CMakeLists.txt index 79b3b80fbef..263495838aa 100644 --- a/plugin/cracklib_password_check/CMakeLists.txt +++ b/plugin/cracklib_password_check/CMakeLists.txt @@ -32,11 +32,12 @@ IF (HAVE_ALLOCA_H AND HAVE_CRACK_H AND HAVE_LIBCRACK AND HAVE_MEMCPY) IF(CHECKMODULE AND SEMODULE_PACKAGE) FOREACH(pol mariadb-plugin-cracklib-password-check) SET(src ${CMAKE_CURRENT_SOURCE_DIR}/policy/selinux/${pol}.te) - SET(tmp ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${pol}-pp.dir/${pol}.mod) + SET(tmp ${CMAKE_CURRENT_BINARY_DIR}/${pol}.mod) SET(out ${CMAKE_CURRENT_BINARY_DIR}/${pol}.pp) ADD_CUSTOM_COMMAND(OUTPUT ${out} COMMAND ${CHECKMODULE} -M -m ${src} -o ${tmp} COMMAND ${SEMODULE_PACKAGE} -m ${tmp} -o ${out} + COMMAND ${CMAKE_COMMAND} -E remove ${tmp} DEPENDS ${src}) ADD_CUSTOM_TARGET(${pol}-pp ALL DEPENDS ${out}) INSTALL(FILES ${out} DESTINATION ${inst_location}/policy/selinux COMPONENT cracklib-password-check) diff --git a/plugin/feedback/feedback.cc b/plugin/feedback/feedback.cc index ba4850f4cba..845e40ccf52 100644 --- a/plugin/feedback/feedback.cc +++ b/plugin/feedback/feedback.cc @@ -339,6 +339,10 @@ static int free(void *p) shutdown_plugin= true; mysql_cond_signal(&sleep_condition); mysql_mutex_unlock(&sleep_mutex); + + for (uint i= 0; i < url_count; i++) + urls[i]->abort(); + pthread_join(sender_thread, NULL); mysql_mutex_destroy(&sleep_mutex); diff --git a/plugin/feedback/feedback.h b/plugin/feedback/feedback.h index 04fe1ab6aa1..6021eb85860 100644 --- a/plugin/feedback/feedback.h +++ b/plugin/feedback/feedback.h @@ -52,6 +52,7 @@ class Url { const char *url() { return full_url.str; } size_t url_length() { return full_url.length; } + virtual void abort() = 0; virtual int send(const char* data, size_t data_length) = 0; virtual int set_proxy(const char *proxy, size_t proxy_len) { diff --git a/plugin/feedback/url_http.cc b/plugin/feedback/url_http.cc index 342c12c0057..aa1706bb0dd 100644 --- a/plugin/feedback/url_http.cc +++ b/plugin/feedback/url_http.cc @@ -37,8 +37,9 @@ static const uint FOR_WRITING= 1; class Url_http: public Url { protected: const LEX_STRING host, port, path; - bool ssl; LEX_STRING proxy_host, proxy_port; + my_socket fd; + bool ssl; bool use_proxy() { @@ -47,7 +48,8 @@ class Url_http: public Url { Url_http(LEX_STRING &url_arg, LEX_STRING &host_arg, LEX_STRING &port_arg, LEX_STRING &path_arg, bool ssl_arg) : - Url(url_arg), host(host_arg), port(port_arg), path(path_arg), ssl(ssl_arg) + Url(url_arg), host(host_arg), port(port_arg), path(path_arg), + fd(INVALID_SOCKET), ssl(ssl_arg) { proxy_host.length= 0; } @@ -60,6 +62,7 @@ class Url_http: public Url { } public: + void abort(); int send(const char* data, size_t data_length); int set_proxy(const char *proxy, size_t proxy_len) { @@ -158,13 +161,18 @@ Url* http_create(const char *url, size_t url_length) return new Url_http(full_url, host, port, path, ssl); } +void Url_http::abort() +{ + if (fd != INVALID_SOCKET) + closesocket(fd); // interrupt I/O waits +} + /* do the vio_write and check that all data were sent ok */ #define write_check(VIO, DATA, LEN) \ (vio_write((VIO), (uchar*)(DATA), (LEN)) != (LEN)) int Url_http::send(const char* data, size_t data_length) { - my_socket fd= INVALID_SOCKET; char buf[1024]; size_t len= 0; @@ -185,6 +193,7 @@ int Url_http::send(const char* data, size_t data_length) return 1; } + DBUG_ASSERT(fd == INVALID_SOCKET); for (addr= addrs; addr != NULL; addr= addr->ai_next) { fd= socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); @@ -213,6 +222,7 @@ int Url_http::send(const char* data, size_t data_length) sql_print_error("feedback plugin: vio_new failed for url '%s'", full_url.str); closesocket(fd); + fd= INVALID_SOCKET; return 1; } @@ -241,6 +251,7 @@ int Url_http::send(const char* data, size_t data_length) free_vio_ssl_acceptor_fd(ssl_fd); closesocket(fd); vio_delete(vio); + fd= INVALID_SOCKET; return 1; } } @@ -339,6 +350,7 @@ int Url_http::send(const char* data, size_t data_length) } #endif + fd= INVALID_SOCKET; return res; } diff --git a/plugin/hashicorp_key_management/CMakeLists.txt b/plugin/hashicorp_key_management/CMakeLists.txt index bd1eee844ab..809b480f6ac 100644 --- a/plugin/hashicorp_key_management/CMakeLists.txt +++ b/plugin/hashicorp_key_management/CMakeLists.txt @@ -1,10 +1,13 @@ -INCLUDE(FindCURL) +FIND_PACKAGE(CURL) IF(NOT CURL_FOUND) # Can't build plugin + MESSAGE_ONCE(WARNING "Hashicorp Key Management plugin requires curl development package") RETURN() ENDIF() -INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIR}) +SET_PACKAGE_PROPERTIES(CURL PROPERTIES TYPE REQUIRED) + +INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIRS}) set(CPACK_RPM_hashicorp-key-management_PACKAGE_SUMMARY "Hashicorp Key Management plugin for MariaDB" PARENT_SCOPE) set(CPACK_RPM_hashicorp-key-management_PACKAGE_DESCRIPTION "This encryption plugin uses Hashicorp Vault for storing encryption diff --git a/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc b/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc index bdc2f7345f1..dfeb1aca737 100644 --- a/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc +++ b/plugin/hashicorp_key_management/hashicorp_key_management_plugin.cc @@ -13,28 +13,21 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ -#include #include #include +#include #include +#include +#include +#include #include #include #include #include -#ifdef _WIN32 -#include -#define alloca _alloca -#endif #include #include #include -#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND) -#define HASHICORP_HAVE_EXCEPTIONS 1 -#else -#define HASHICORP_HAVE_EXCEPTIONS 0 -#endif - #define HASHICORP_DEBUG_LOGGING 0 #define PLUGIN_ERROR_HEADER "hashicorp: " @@ -209,15 +202,6 @@ unsigned int if (key_version == ENCRYPTION_KEY_VERSION_INVALID) { clock_t timestamp; -#if HASHICORP_HAVE_EXCEPTIONS - try - { - VER_INFO &ver_info = latest_version_cache.at(key_id); - version = ver_info.key_version; - timestamp = ver_info.timestamp; - } - catch (const std::out_of_range &e) -#else VER_MAP::const_iterator ver_iter = latest_version_cache.find(key_id); if (ver_iter != latest_version_cache.end()) { @@ -225,7 +209,6 @@ unsigned int timestamp = ver_iter->second.timestamp; } else -#endif { mtx.unlock(); return ENCRYPTION_KEY_VERSION_INVALID; @@ -246,13 +229,6 @@ unsigned int } } KEY_INFO info; -#if HASHICORP_HAVE_EXCEPTIONS - try - { - info = key_info_cache.at(KEY_ID_AND_VERSION(key_id, version)); - } - catch (const std::out_of_range &e) -#else KEY_MAP::const_iterator key_iter = key_info_cache.find(KEY_ID_AND_VERSION(key_id, version)); if (key_iter != key_info_cache.end()) @@ -260,7 +236,6 @@ unsigned int info = key_iter->second; } else -#endif { mtx.unlock(); return ENCRYPTION_KEY_VERSION_INVALID; @@ -305,20 +280,12 @@ unsigned int HCData::cache_get_version (unsigned int key_id) { unsigned int version; mtx.lock(); -#if HASHICORP_HAVE_EXCEPTIONS - try - { - version = latest_version_cache.at(key_id).key_version; - } - catch (const std::out_of_range &e) -#else VER_MAP::const_iterator ver_iter = latest_version_cache.find(key_id); if (ver_iter != latest_version_cache.end()) { version = ver_iter->second.key_version; } else -#endif { version = ENCRYPTION_KEY_VERSION_INVALID; } @@ -331,15 +298,6 @@ unsigned int HCData::cache_check_version (unsigned int key_id) unsigned int version; clock_t timestamp; mtx.lock(); -#if HASHICORP_HAVE_EXCEPTIONS - try - { - VER_INFO &ver_info = latest_version_cache.at(key_id); - version = ver_info.key_version; - timestamp = ver_info.timestamp; - } - catch (const std::out_of_range &e) -#else VER_MAP::const_iterator ver_iter = latest_version_cache.find(key_id); if (ver_iter != latest_version_cache.end()) { @@ -347,7 +305,6 @@ unsigned int HCData::cache_check_version (unsigned int key_id) timestamp = ver_iter->second.timestamp; } else -#endif { mtx.unlock(); #if HASHICORP_DEBUG_LOGGING @@ -978,29 +935,6 @@ struct st_mariadb_encryption hashicorp_key_management_plugin= { 0, 0, 0, 0, 0 }; -#ifdef _MSC_VER - -static int setenv (const char *name, const char *value, int overwrite) -{ - if (!overwrite) - { - size_t len= 0; - int rc= getenv_s(&len, NULL, 0, name); - if (rc) - { - return rc; - } - if (len) - { - errno = EINVAL; - return EINVAL; - } - } - return _putenv_s(name, value); -} - -#endif - #define MAX_URL_SIZE 32768 int HCData::init () @@ -1053,7 +987,11 @@ int HCData::init () bool not_equal= token_env != NULL && strcmp(token_env, token) != 0; if (token_env == NULL || not_equal) { - setenv("VAULT_TOKEN", token, 1); +#if defined(HAVE_SETENV) || !defined(_WIN32) + setenv("VAULT_TOKEN", token, 1); +#else + _putenv_s("VAULT_TOKEN", token); +#endif if (not_equal) { my_printf_error(ER_UNKNOWN_ERROR, PLUGIN_ERROR_HEADER diff --git a/plugin/hashicorp_key_management/mysql-test/vault/suite.pm b/plugin/hashicorp_key_management/mysql-test/vault/suite.pm index fce1737311d..bd08ff4fb18 100644 --- a/plugin/hashicorp_key_management/mysql-test/vault/suite.pm +++ b/plugin/hashicorp_key_management/mysql-test/vault/suite.pm @@ -1,9 +1,13 @@ package My::Suite::Vault; +use My::Platform; @ISA = qw(My::Suite); use strict; +return "Hashicorp Key Management plugin tests are currently not available on Windows" + if IS_WINDOWS; + return "You need to set the value of the VAULT_ADDR variable" unless $ENV{VAULT_ADDR}; diff --git a/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_cache_after_recreate.test b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_cache_after_recreate.test index 9dee7376497..925e89a3140 100644 --- a/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_cache_after_recreate.test +++ b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_cache_after_recreate.test @@ -11,7 +11,7 @@ --exec vault kv put /bug/1 data=01234567890123456789012345678901 > /dev/null --exec vault kv put /bug/4 data=01234567890123456789012345678904 > /dev/null ---let $restart_parameters=--plugin-load-add=hashicorp_key_management --hashicorp-key-management-vault-url="$VAULT_ADDR/v1/bug/" --hashicorp-key-management-token="$VAULT_TOKEN" +--let $restart_parameters=--plugin-load-add=hashicorp_key_management --hashicorp-key-management-vault-url=$VAULT_ADDR/v1/bug/ --hashicorp-key-management-token=$VAULT_TOKEN --let $restart_noprint=1 --source include/restart_mysqld.inc diff --git a/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_check_kv_version.test b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_check_kv_version.test index c108781bbd2..7d9a952f6d3 100644 --- a/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_check_kv_version.test +++ b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_check_kv_version.test @@ -20,7 +20,7 @@ --error 0,1 --remove_file $LOG_FILE ---let $vault_defaults=--plugin-load-add=hashicorp_key_management --hashicorp_key_management=force --hashicorp-key-management-check-kv-version=on --hashicorp-key-management-token="$VAULT_TOKEN" +--let $vault_defaults=--plugin-load-add=hashicorp_key_management --hashicorp_key_management=force --hashicorp-key-management-check-kv-version=on --hashicorp-key-management-token=$VAULT_TOKEN --let $defaults=--defaults-group-suffix=.1 --defaults-file=$MYSQLTEST_VARDIR/my.cnf $vault_defaults --log-error=$LOG_FILE --error 1 @@ -30,14 +30,14 @@ --remove_file $LOG_FILE ---let $restart_parameters=$vault_defaults --hashicorp-key-management-vault-url="$VAULT_ADDR/v1/good" +--let $restart_parameters=$vault_defaults --hashicorp-key-management-vault-url=$VAULT_ADDR/v1/good --let $restart_noprint=1 --source include/start_mysqld.inc CREATE TABLE t1 (a VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=1; INSERT INTO t1 VALUES ('foo'),('bar'); ---let $restart_parameters=$vault_defaults --hashicorp-key-management-vault-url="$VAULT_ADDR/v1/good//" +--let $restart_parameters=$vault_defaults --hashicorp-key-management-vault-url=$VAULT_ADDR/v1/good// --source include/restart_mysqld.inc CREATE TABLE t2 (a VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=2; diff --git a/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_key_migration.test b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_key_migration.test index 2e67c2cc639..62253cd7723 100644 --- a/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_key_migration.test +++ b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_key_migration.test @@ -24,7 +24,7 @@ SELECT * FROM t1; --exec vault secrets disable bug > /dev/null --exec vault secrets enable -path /bug -version=2 kv > /dev/null --exec vault kv put /bug/1 data=$my_key > /dev/null ---let $restart_parameters=--plugin-load-add=hashicorp_key_management --hashicorp-key-management-vault-url="$VAULT_ADDR/v1/bug/" --hashicorp-key-management-token="$VAULT_TOKEN" +--let $restart_parameters=--plugin-load-add=hashicorp_key_management --hashicorp-key-management-vault-url=$VAULT_ADDR/v1/bug/ --hashicorp-key-management-token=$VAULT_TOKEN --source include/restart_mysqld.inc CREATE TABLE t2 (a VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=1; diff --git a/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_key_rotation_age.test b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_key_rotation_age.test index c446036aaae..4eb7cdcfdef 100644 --- a/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_key_rotation_age.test +++ b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_key_rotation_age.test @@ -8,7 +8,7 @@ replace_result $VAULT_ADDR VAULT_ADDR; SHOW GLOBAL variables LIKE "hashicorp%"; --echo # Restart the server with encryption -let $default_parameters="--innodb-tablespaces-encryption --innodb_encrypt_tables=ON"; +let $default_parameters=--innodb-tablespaces-encryption --innodb_encrypt_tables=ON; let $restart_noprint=1; let $restart_parameters=$default_parameters; --source include/restart_mysqld.inc diff --git a/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_mariabackup.opt b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_mariabackup.opt new file mode 100644 index 00000000000..1df4643562e --- /dev/null +++ b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_mariabackup.opt @@ -0,0 +1 @@ +--innodb --loose-changed_page_bitmaps --innodb-sys-tables --innodb-flush-log-at-trx-commit=2 --sequence diff --git a/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_mariabackup.test b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_mariabackup.test index 6ade4e115a1..977535556cc 100644 --- a/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_mariabackup.test +++ b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_mariabackup.test @@ -8,9 +8,13 @@ CREATE TABLE t(i INT) ENGINE INNODB encrypted=yes encryption_key_id=1; INSERT INTO t VALUES(1); -echo # mariabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; +--error 0,1 +rmdir $targetdir; + +echo # mariabackup backup; + --disable_result_log exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; --enable_result_log diff --git a/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_url_prefix.test b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_url_prefix.test index 4d26affb467..ef88b61c74c 100644 --- a/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_url_prefix.test +++ b/plugin/hashicorp_key_management/mysql-test/vault/t/hashicorp_url_prefix.test @@ -16,7 +16,7 @@ --error 0,1 --remove_file $LOG_FILE ---let $vault_defaults=--plugin-load-add=hashicorp_key_management --hashicorp_key_management=force --hashicorp-key-management-check-kv-version=off --hashicorp-key-management-token="$VAULT_TOKEN" +--let $vault_defaults=--plugin-load-add=hashicorp_key_management --hashicorp_key_management=force --hashicorp-key-management-check-kv-version=off --hashicorp-key-management-token=$VAULT_TOKEN --let $defaults=--defaults-group-suffix=.1 --defaults-file=$MYSQLTEST_VARDIR/my.cnf $vault_defaults --log-error=$LOG_FILE --error 1 @@ -76,7 +76,7 @@ --remove_file $LOG_FILE ---let $restart_parameters=$vault_defaults --hashicorp-key-management-vault-url="$VAULT_ADDR/v1/bug///" +--let $restart_parameters=$vault_defaults --hashicorp-key-management-vault-url=$VAULT_ADDR/v1/bug/// --let $restart_noprint=1 --source include/start_mysqld.inc diff --git a/plugin/test_sql_service/test_sql_service.c b/plugin/test_sql_service/test_sql_service.c index 8b326c6fa46..8a9b3dab61c 100644 --- a/plugin/test_sql_service/test_sql_service.c +++ b/plugin/test_sql_service/test_sql_service.c @@ -129,7 +129,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) static int run_test(MYSQL_THD thd, struct st_mysql_sys_var *var, void *save, struct st_mysql_value *value) { - *(my_bool*) save= 0; /* Set value for sql_service_run_test */ + *(my_bool*)save= 1; // must initialize the return value return (test_passed= (do_tests() == 0)) == 0; } @@ -140,6 +140,7 @@ static int run_sql(MYSQL *mysql, void *save, struct st_mysql_value *value) int len= 0; MYSQL_RES *res; + *(my_bool*)save= 1; // must initialize the return value str= value->val_str(value, NULL, &len); if (mysql_real_query(mysql, str, len)) diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6.result b/plugin/type_inet/mysql-test/type_inet/type_inet6.result index 8322e67a413..4620f405327 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet6.result +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6.result @@ -2371,6 +2371,18 @@ Warning 1292 Incorrect inet6 value: '' Warning 1292 Incorrect inet6 value: '' DROP TABLE t1; # +# MDEV-32458 ASAN unknown-crash in Inet6::ascii_to_fbt when casting character string to inet6 +# +CREATE TABLE t1 (c CHAR(3)); +INSERT INTO t1 VALUES ('1:0'),('00:'); +SELECT * FROM t1 WHERE c>CAST('::1' AS INET6); +c +Warnings: +Warning 1292 Incorrect inet6 value: '1:0' +Warning 1292 Incorrect inet6 value: '00:' +DROP TABLE t1; +# End of 10.6 tests +# # MDEV-22256 Assertion `length == pack_length()' failed in Field_timestamp_with_dec::sort_string # SET sql_mode=''; diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6.test b/plugin/type_inet/mysql-test/type_inet/type_inet6.test index 0c56ecfe4bb..cb3d226f9b6 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet6.test +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6.test @@ -1701,6 +1701,17 @@ SELECT 1.00 + (b BETWEEN a AND '') AS f FROM t1 ORDER BY f; SELECT 1.00 + (b IN (a,'')) AS f FROM t1 ORDER BY f; DROP TABLE t1; +--echo # +--echo # MDEV-32458 ASAN unknown-crash in Inet6::ascii_to_fbt when casting character string to inet6 +--echo # + +CREATE TABLE t1 (c CHAR(3)); +INSERT INTO t1 VALUES ('1:0'),('00:'); +SELECT * FROM t1 WHERE c>CAST('::1' AS INET6); +DROP TABLE t1; + +--echo # End of 10.6 tests + --echo # --echo # MDEV-22256 Assertion `length == pack_length()' failed in Field_timestamp_with_dec::sort_string --echo # diff --git a/plugin/type_inet/sql_type_inet.cc b/plugin/type_inet/sql_type_inet.cc index f3eef3b4e2e..5907a3a9d48 100644 --- a/plugin/type_inet/sql_type_inet.cc +++ b/plugin/type_inet/sql_type_inet.cc @@ -229,7 +229,7 @@ bool Inet6::ascii_to_fbt(const char *str, size_t str_length) continue; } - if (!*p || p >= str_end) + if (p >= str_end || !*p) { DBUG_PRINT("error", ("ascii_to_ipv6(%.*s): invalid IPv6 address: " "ending at ':'.", (int) str_length, str)); diff --git a/plugin/type_inet/sql_type_inet.h b/plugin/type_inet/sql_type_inet.h index 2d7da2d07bc..d77da4a7efd 100644 --- a/plugin/type_inet/sql_type_inet.h +++ b/plugin/type_inet/sql_type_inet.h @@ -69,6 +69,12 @@ public: static Type_collection_inet tc; return &tc; } + + const Type_handler *type_handler_for_implicit_upgrade( + const Type_handler *from) const + { + return from; + } }; #include "sql_type_fixedbin.h" diff --git a/plugin/type_mysql_timestamp/plugin.cc b/plugin/type_mysql_timestamp/plugin.cc index a524c5c0124..6cbd76d8583 100644 --- a/plugin/type_mysql_timestamp/plugin.cc +++ b/plugin/type_mysql_timestamp/plugin.cc @@ -103,7 +103,19 @@ public: Field_mysql_timestampf(*name, rec, attr->unireg_check, share, attr->temporal_dec(MAX_DATETIME_WIDTH)); } - void Column_definition_implicit_upgrade(Column_definition *c) const override + const Type_handler *type_handler_for_implicit_upgrade() const override + { + /* + The derived method as of 10.11.8 does "return this;" anyway. + However, in the future this may change to return a + opt_mysql56_temporal_format dependent handler. + Here in this class we need to make sure to do "return this;" + not to depend on the derived method changes. + */ + return this; + } + void Column_definition_implicit_upgrade_to_this(Column_definition *old) + const override { /* Suppress the automatic upgrade depending on opt_mysql56_temporal_format, diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_mariadb101104.result b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_mariadb101104.result new file mode 100644 index 00000000000..b22e78519c6 --- /dev/null +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_mariadb101104.result @@ -0,0 +1,422 @@ +# +# Start of 10.11 tests +# +# +# MDEV-33442 REPAIR TABLE corrupts UUIDs +# +CREATE PROCEDURE show_table(long_version INT) +BEGIN +SHOW CREATE TABLE t1; +SELECT VERSION FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; +IF long_version>0 THEN +SELECT * FROM t1 ORDER BY b; +ELSE +SELECT * FROM t1 ORDER BY a DESC LIMIT 5; +END IF; +END; +$$ +# Upgrade a 10.11.4 table using REPAIR +CALL show_table(1); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +00001234-5566-0777-0888-99aabbccddee 0 +10101234-5566-0777-8888-99aabbccddee 1 +00201234-5566-0777-c888-99aabbccddee 2 +10301234-5566-0777-e888-99aabbccddee 3 +00401234-5566-1777-0888-99aabbccddee 4 +10501234-5566-1777-8888-99aabbccddee 5 +00601234-5566-1777-c888-99aabbccddee 6 +10701234-5566-1777-e888-99aabbccddee 7 +00801234-5566-2777-0888-99aabbccddee 8 +10901234-5566-2777-8888-99aabbccddee 9 +01001234-5566-2777-c888-99aabbccddee 10 +11101234-5566-2777-e888-99aabbccddee 11 +01201234-5566-3777-0888-99aabbccddee 12 +11301234-5566-3777-8888-99aabbccddee 13 +01401234-5566-3777-c888-99aabbccddee 14 +11501234-5566-3777-e888-99aabbccddee 15 +01601234-5566-4777-0888-99aabbccddee 16 +11701234-5566-4777-8888-99aabbccddee 17 +01801234-5566-4777-c888-99aabbccddee 18 +11901234-5566-4777-e888-99aabbccddee 19 +02001234-5566-5777-0888-99aabbccddee 20 +12101234-5566-5777-8888-99aabbccddee 21 +02201234-5566-5777-c888-99aabbccddee 22 +12301234-5566-5777-e888-99aabbccddee 23 +02401234-5566-6777-0888-99aabbccddee 24 +12501234-5566-6777-8888-99aabbccddee 25 +02601234-5566-6777-c888-99aabbccddee 26 +12701234-5566-6777-e888-99aabbccddee 27 +02801234-5566-7777-0888-99aabbccddee 28 +12901234-5566-7777-8888-99aabbccddee 29 +03001234-5566-7777-c888-99aabbccddee 30 +13101234-5566-7777-e888-99aabbccddee 31 +03201234-5566-8777-0888-99aabbccddee 32 +13301234-5566-8777-8888-99aabbccddee 33 +03401234-5566-8777-c888-99aabbccddee 34 +13501234-5566-8777-e888-99aabbccddee 35 +03601234-5566-9777-0888-99aabbccddee 36 +13701234-5566-9777-8888-99aabbccddee 37 +03801234-5566-9777-c888-99aabbccddee 38 +13901234-5566-9777-e888-99aabbccddee 39 +04001234-5566-a777-0888-99aabbccddee 40 +14101234-5566-a777-8888-99aabbccddee 41 +04201234-5566-a777-c888-99aabbccddee 42 +14301234-5566-a777-e888-99aabbccddee 43 +04401234-5566-b777-0888-99aabbccddee 44 +14501234-5566-b777-8888-99aabbccddee 45 +04601234-5566-b777-c888-99aabbccddee 46 +14701234-5566-b777-e888-99aabbccddee 47 +04801234-5566-c777-0888-99aabbccddee 48 +14901234-5566-c777-8888-99aabbccddee 49 +05001234-5566-c777-c888-99aabbccddee 50 +15101234-5566-c777-e888-99aabbccddee 51 +05201234-5566-d777-0888-99aabbccddee 52 +15301234-5566-d777-8888-99aabbccddee 53 +05401234-5566-d777-c888-99aabbccddee 54 +15501234-5566-d777-e888-99aabbccddee 55 +05601234-5566-e777-0888-99aabbccddee 56 +15701234-5566-e777-8888-99aabbccddee 57 +05801234-5566-e777-c888-99aabbccddee 58 +15901234-5566-e777-e888-99aabbccddee 59 +06001234-5566-f777-0888-99aabbccddee 60 +16101234-5566-f777-8888-99aabbccddee 61 +06201234-5566-f777-c888-99aabbccddee 62 +16301234-5566-f777-e888-99aabbccddee 63 +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check error Upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! +CALL show_table(0); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +16301234-5566-f777-e888-99aabbccddee 63 +15901234-5566-e777-e888-99aabbccddee 59 +15501234-5566-d777-e888-99aabbccddee 55 +15101234-5566-c777-e888-99aabbccddee 51 +14701234-5566-b777-e888-99aabbccddee 47 +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check error Upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! +CALL show_table(0); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +16301234-5566-f777-e888-99aabbccddee 63 +15901234-5566-e777-e888-99aabbccddee 59 +15501234-5566-d777-e888-99aabbccddee 55 +15101234-5566-c777-e888-99aabbccddee 51 +14701234-5566-b777-e888-99aabbccddee 47 +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair Warning Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 33 +test.t1 repair Warning Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 37 +test.t1 repair Warning Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 41 +test.t1 repair Warning Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 45 +test.t1 repair Warning Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 49 +test.t1 repair Warning Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 53 +test.t1 repair Warning Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 57 +test.t1 repair Warning Incorrect uuid value: '06001234-5566-f777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 61 +test.t1 repair status OK +CALL show_table(1); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +00001234-5566-0777-0888-99aabbccddee 0 +10101234-5566-0777-8888-99aabbccddee 1 +00201234-5566-0777-c888-99aabbccddee 2 +10301234-5566-0777-e888-99aabbccddee 3 +00401234-5566-1777-0888-99aabbccddee 4 +10501234-5566-1777-8888-99aabbccddee 5 +00601234-5566-1777-c888-99aabbccddee 6 +10701234-5566-1777-e888-99aabbccddee 7 +00801234-5566-2777-0888-99aabbccddee 8 +10901234-5566-2777-8888-99aabbccddee 9 +01001234-5566-2777-c888-99aabbccddee 10 +11101234-5566-2777-e888-99aabbccddee 11 +01201234-5566-3777-0888-99aabbccddee 12 +11301234-5566-3777-8888-99aabbccddee 13 +01401234-5566-3777-c888-99aabbccddee 14 +11501234-5566-3777-e888-99aabbccddee 15 +01601234-5566-4777-0888-99aabbccddee 16 +11701234-5566-4777-8888-99aabbccddee 17 +01801234-5566-4777-c888-99aabbccddee 18 +11901234-5566-4777-e888-99aabbccddee 19 +02001234-5566-5777-0888-99aabbccddee 20 +12101234-5566-5777-8888-99aabbccddee 21 +02201234-5566-5777-c888-99aabbccddee 22 +12301234-5566-5777-e888-99aabbccddee 23 +02401234-5566-6777-0888-99aabbccddee 24 +12501234-5566-6777-8888-99aabbccddee 25 +02601234-5566-6777-c888-99aabbccddee 26 +12701234-5566-6777-e888-99aabbccddee 27 +02801234-5566-7777-0888-99aabbccddee 28 +12901234-5566-7777-8888-99aabbccddee 29 +03001234-5566-7777-c888-99aabbccddee 30 +13101234-5566-7777-e888-99aabbccddee 31 +NULL 32 +13301234-5566-8777-8888-99aabbccddee 33 +03401234-5566-8777-c888-99aabbccddee 34 +13501234-5566-8777-e888-99aabbccddee 35 +NULL 36 +13701234-5566-9777-8888-99aabbccddee 37 +03801234-5566-9777-c888-99aabbccddee 38 +13901234-5566-9777-e888-99aabbccddee 39 +NULL 40 +14101234-5566-a777-8888-99aabbccddee 41 +04201234-5566-a777-c888-99aabbccddee 42 +14301234-5566-a777-e888-99aabbccddee 43 +NULL 44 +14501234-5566-b777-8888-99aabbccddee 45 +04601234-5566-b777-c888-99aabbccddee 46 +14701234-5566-b777-e888-99aabbccddee 47 +NULL 48 +14901234-5566-c777-8888-99aabbccddee 49 +05001234-5566-c777-c888-99aabbccddee 50 +15101234-5566-c777-e888-99aabbccddee 51 +NULL 52 +15301234-5566-d777-8888-99aabbccddee 53 +05401234-5566-d777-c888-99aabbccddee 54 +15501234-5566-d777-e888-99aabbccddee 55 +NULL 56 +15701234-5566-e777-8888-99aabbccddee 57 +05801234-5566-e777-c888-99aabbccddee 58 +15901234-5566-e777-e888-99aabbccddee 59 +NULL 60 +16101234-5566-f777-8888-99aabbccddee 61 +06201234-5566-f777-c888-99aabbccddee 62 +16301234-5566-f777-e888-99aabbccddee 63 +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check status OK +CALL show_table(0); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +12301234-5566-5777-e888-99aabbccddee 23 +11901234-5566-4777-e888-99aabbccddee 19 +11501234-5566-3777-e888-99aabbccddee 15 +11101234-5566-2777-e888-99aabbccddee 11 +10701234-5566-1777-e888-99aabbccddee 7 +DROP TABLE t1; +# Upgrade a 10.11.4 table using ALTER, adding a table COMMENT +CALL show_table(0); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +16301234-5566-f777-e888-99aabbccddee 63 +15901234-5566-e777-e888-99aabbccddee 59 +15501234-5566-d777-e888-99aabbccddee 55 +15101234-5566-c777-e888-99aabbccddee 51 +14701234-5566-b777-e888-99aabbccddee 47 +# ALTER..INPLACE should fail - the old column 'b UUID' needs upgrade +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, COMMENT 'test10'; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +ALTER IGNORE TABLE t1 COMMENT 'test11'; +Warnings: +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 33 +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 37 +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 41 +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 45 +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 49 +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 53 +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 57 +Warning 1292 Incorrect uuid value: '06001234-5566-f777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 61 +CALL show_table(0); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci COMMENT='test11' +VERSION +10 +a b +12301234-5566-5777-e888-99aabbccddee 23 +11901234-5566-4777-e888-99aabbccddee 19 +11501234-5566-3777-e888-99aabbccddee 15 +11101234-5566-2777-e888-99aabbccddee 11 +10701234-5566-1777-e888-99aabbccddee 7 +# Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, COMMENT 'test12'; +CALL show_table(0); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci COMMENT='test12' +VERSION +10 +a b +12301234-5566-5777-e888-99aabbccddee 23 +11901234-5566-4777-e888-99aabbccddee 19 +11501234-5566-3777-e888-99aabbccddee 15 +11101234-5566-2777-e888-99aabbccddee 11 +10701234-5566-1777-e888-99aabbccddee 7 +DROP TABLE t1; +# Upgrade a 10.11.4 table using ALTER, adding a DEFAULT for 'b INT' +CALL show_table(0); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +16301234-5566-f777-e888-99aabbccddee 63 +15901234-5566-e777-e888-99aabbccddee 59 +15501234-5566-d777-e888-99aabbccddee 55 +15101234-5566-c777-e888-99aabbccddee 51 +14701234-5566-b777-e888-99aabbccddee 47 +# ALTER..INPLACE should fail - the old column 'b UUID' needs upgrade +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, MODIFY b INT NOT NULL DEFAULT 10; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +ALTER IGNORE TABLE t1 MODIFY b INT NOT NULL DEFAULT 11; +Warnings: +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 33 +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 37 +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 41 +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 45 +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 49 +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 53 +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 57 +Warning 1292 Incorrect uuid value: '06001234-5566-f777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 61 +CALL show_table(0); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL DEFAULT 11, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +12301234-5566-5777-e888-99aabbccddee 23 +11901234-5566-4777-e888-99aabbccddee 19 +11501234-5566-3777-e888-99aabbccddee 15 +11101234-5566-2777-e888-99aabbccddee 11 +10701234-5566-1777-e888-99aabbccddee 7 +# Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, MODIFY b INT NOT NULL DEFAULT 12; +CALL show_table(0); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL DEFAULT 12, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +12301234-5566-5777-e888-99aabbccddee 23 +11901234-5566-4777-e888-99aabbccddee 19 +11501234-5566-3777-e888-99aabbccddee 15 +11101234-5566-2777-e888-99aabbccddee 11 +10701234-5566-1777-e888-99aabbccddee 7 +DROP TABLE t1; +# Upgrade a 10.11.4 table using ALTER, adding a DEFAULT for 'a UUID' +CALL show_table(0); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +16301234-5566-f777-e888-99aabbccddee 63 +15901234-5566-e777-e888-99aabbccddee 59 +15501234-5566-d777-e888-99aabbccddee 55 +15101234-5566-c777-e888-99aabbccddee 51 +14701234-5566-b777-e888-99aabbccddee 47 +# ALTER..INPLACE should fail - the old column 'b UUID' needs upgrade +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, MODIFY a UUID DEFAULT '16301234-5566-f777-e888-99aabbccdd00'; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +ALTER IGNORE TABLE t1 MODIFY a UUID DEFAULT '16301234-5566-f777-e888-99aabbccdd01'; +Warnings: +Warning 1292 Incorrect uuid value: '03201234-5566-8777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 33 +Warning 1292 Incorrect uuid value: '03601234-5566-9777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 37 +Warning 1292 Incorrect uuid value: '04001234-5566-a777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 41 +Warning 1292 Incorrect uuid value: '04401234-5566-b777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 45 +Warning 1292 Incorrect uuid value: '04801234-5566-c777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 49 +Warning 1292 Incorrect uuid value: '05201234-5566-d777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 53 +Warning 1292 Incorrect uuid value: '05601234-5566-e777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 57 +Warning 1292 Incorrect uuid value: '06001234-5566-f777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 61 +CALL show_table(0); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT '16301234-5566-f777-e888-99aabbccdd01', + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +12301234-5566-5777-e888-99aabbccddee 23 +11901234-5566-4777-e888-99aabbccddee 19 +11501234-5566-3777-e888-99aabbccddee 15 +11101234-5566-2777-e888-99aabbccddee 11 +10701234-5566-1777-e888-99aabbccddee 7 +# Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 MODIFY a UUID DEFAULT '16301234-5566-f777-e888-99aabbccdd02'; +CALL show_table(0); +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT '16301234-5566-f777-e888-99aabbccdd02', + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +VERSION +10 +a b +12301234-5566-5777-e888-99aabbccddee 23 +11901234-5566-4777-e888-99aabbccddee 19 +11501234-5566-3777-e888-99aabbccddee 15 +11101234-5566-2777-e888-99aabbccddee 11 +10701234-5566-1777-e888-99aabbccddee 7 +DROP TABLE t1; +DROP PROCEDURE show_table; +# +# End of 10.11 tests +# diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_mariadb101104.test b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_mariadb101104.test new file mode 100644 index 00000000000..6181f6efd94 --- /dev/null +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_mariadb101104.test @@ -0,0 +1,110 @@ +let $datadir= `select @@datadir`; + +--echo # +--echo # Start of 10.11 tests +--echo # + +--echo # +--echo # MDEV-33442 REPAIR TABLE corrupts UUIDs +--echo # + +DELIMITER $$; +CREATE PROCEDURE show_table(long_version INT) +BEGIN + SHOW CREATE TABLE t1; + SELECT VERSION FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; + IF long_version>0 THEN + SELECT * FROM t1 ORDER BY b; + ELSE + SELECT * FROM t1 ORDER BY a DESC LIMIT 5; + END IF; +END; +$$ +DELIMITER ;$$ + + +--echo # Upgrade a 10.11.4 table using REPAIR + +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.frm $datadir/test/t1.frm +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.MYI $datadir/test/t1.MYI +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.MYD $datadir/test/t1.MYD +CALL show_table(1); + +CHECK TABLE t1 FOR UPGRADE; +CALL show_table(0); + +CHECK TABLE t1 FOR UPGRADE; +CALL show_table(0); + +REPAIR TABLE t1; +CALL show_table(1); + +CHECK TABLE t1 FOR UPGRADE; +CALL show_table(0); + +DROP TABLE t1; + +--echo # Upgrade a 10.11.4 table using ALTER, adding a table COMMENT + +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.frm $datadir/test/t1.frm +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.MYI $datadir/test/t1.MYI +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.MYD $datadir/test/t1.MYD +CALL show_table(0); + +--echo # ALTER..INPLACE should fail - the old column 'b UUID' needs upgrade +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, COMMENT 'test10'; +ALTER IGNORE TABLE t1 COMMENT 'test11'; +CALL show_table(0); + +--echo # Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, COMMENT 'test12'; +CALL show_table(0); + +DROP TABLE t1; + + +--echo # Upgrade a 10.11.4 table using ALTER, adding a DEFAULT for 'b INT' + +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.frm $datadir/test/t1.frm +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.MYI $datadir/test/t1.MYI +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.MYD $datadir/test/t1.MYD +CALL show_table(0); + +--echo # ALTER..INPLACE should fail - the old column 'b UUID' needs upgrade +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, MODIFY b INT NOT NULL DEFAULT 10; +ALTER IGNORE TABLE t1 MODIFY b INT NOT NULL DEFAULT 11; +CALL show_table(0); + +--echo # Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, MODIFY b INT NOT NULL DEFAULT 12; +CALL show_table(0); + +DROP TABLE t1; + + +--echo # Upgrade a 10.11.4 table using ALTER, adding a DEFAULT for 'a UUID' + +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.frm $datadir/test/t1.frm +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.MYI $datadir/test/t1.MYI +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.MYD $datadir/test/t1.MYD +CALL show_table(0); + +--echo # ALTER..INPLACE should fail - the old column 'b UUID' needs upgrade +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER IGNORE TABLE t1 ALGORITHM=INPLACE, MODIFY a UUID DEFAULT '16301234-5566-f777-e888-99aabbccdd00'; +ALTER IGNORE TABLE t1 MODIFY a UUID DEFAULT '16301234-5566-f777-e888-99aabbccdd01'; +CALL show_table(0); + +--echo # Now ALTER..INPLACE should work +ALTER IGNORE TABLE t1 MODIFY a UUID DEFAULT '16301234-5566-f777-e888-99aabbccdd02'; +CALL show_table(0); + +DROP TABLE t1; + +DROP PROCEDURE show_table; + +--echo # +--echo # End of 10.11 tests +--echo # diff --git a/plugin/type_uuid/plugin.cc b/plugin/type_uuid/plugin.cc index b1113eafb84..d19e9b8f76b 100644 --- a/plugin/type_uuid/plugin.cc +++ b/plugin/type_uuid/plugin.cc @@ -99,6 +99,14 @@ const Type_handler *Type_collection_uuid::find_in_array(const Type_handler *a, return NULL; } + +const Type_handler *Type_collection_uuid::type_handler_for_implicit_upgrade( + const Type_handler *from) const +{ + return Type_handler_uuid_new::singleton(); +} + + /*************************************************************************/ class Create_func_uuid : public Create_func_arg0 diff --git a/plugin/type_uuid/sql_type_uuid.h b/plugin/type_uuid/sql_type_uuid.h index 3ca310ff0b6..9fca6878ff9 100644 --- a/plugin/type_uuid/sql_type_uuid.h +++ b/plugin/type_uuid/sql_type_uuid.h @@ -316,6 +316,9 @@ public: const override { return NULL; } + const Type_handler *type_handler_for_implicit_upgrade( + const Type_handler *from) const; + static Type_collection_uuid *singleton() { static Type_collection_uuid tc; diff --git a/plugin/versioning/versioning.cc b/plugin/versioning/versioning.cc index 38ebf76256b..a4916e2f9c1 100644 --- a/plugin/versioning/versioning.cc +++ b/plugin/versioning/versioning.cc @@ -36,8 +36,8 @@ public: static Create_func_trt s_singleton; protected: - Create_func_trt() = default; - virtual ~Create_func_trt() = default; + Create_func_trt() = default; + virtual ~Create_func_trt() = default; }; template @@ -132,8 +132,8 @@ public: static Create_func_trt_trx_sees s_singleton; protected: - Create_func_trt_trx_sees() = default; - virtual ~Create_func_trt_trx_sees() = default; + Create_func_trt_trx_sees() = default; + virtual ~Create_func_trt_trx_sees() = default; }; template diff --git a/scripts/mariadb_system_tables_fix.sql b/scripts/mariadb_system_tables_fix.sql index 9ff27359811..dfa8b08ec33 100644 --- a/scripts/mariadb_system_tables_fix.sql +++ b/scripts/mariadb_system_tables_fix.sql @@ -788,19 +788,22 @@ if @have_innodb then end if // DELIMITER ; -# MDEV-4332 longer user names +# MDEV-4332 longer user names, extended by MDEV-24312 to longer again. alter table user modify User char(128) binary not null default ''; alter table db modify User char(128) binary not null default ''; alter table tables_priv modify User char(128) binary not null default ''; alter table columns_priv modify User char(128) binary not null default ''; -alter table procs_priv modify User char(128) binary not null default ''; +alter table procs_priv modify User char(128) binary not null default '', modify Host char(255) binary DEFAULT ''; alter table proc modify definer varchar(384) collate utf8mb3_bin not null default ''; -alter table proxies_priv modify User char(128) COLLATE utf8mb3_bin not null default ''; +alter table proxies_priv modify User char(128) COLLATE utf8mb3_bin not null default '', modify Host char(255) binary DEFAULT ''; alter table proxies_priv modify Proxied_user char(128) COLLATE utf8mb3_bin not null default ''; alter table proxies_priv modify Grantor varchar(384) COLLATE utf8mb3_bin not null default ''; alter table servers modify Username char(128) not null default ''; alter table procs_priv modify Grantor varchar(384) COLLATE utf8mb3_bin not null default ''; alter table tables_priv modify Grantor varchar(384) COLLATE utf8mb3_bin not null default ''; +# MDEV-33726 longer names from MDEV-24312 extension +alter table if exists global_priv modify Host char(255) binary DEFAULT '', modify User char(128) binary not null default ''; +alter table if exists roles_mapping modify Host char(255) binary not null DEFAULT '', modify User char(128) binary not null default ''; # Activate the new, possible modified privilege tables # This should not be needed, but gives us some extra testing that the above diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index ed54fbd5fd3..1ba63b7759f 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -47,7 +47,7 @@ dirname0=`dirname $0 2>/dev/null` dirname0=`dirname $dirname0 2>/dev/null` case "$0" in - *mysqld_install_db) + *mysql_install_db) echo "$0: Deprecated program name. It will be removed in a future release, use 'mariadb-install-db' instead" 1>&2 ;; esac @@ -350,33 +350,13 @@ then pamtooldir="$builddir/plugin/auth_pam" elif test -n "$basedir" then - bindir="$basedir/bin" # only used in the help text - resolveip=`find_in_dirs resolveip @resolveip_locations@` - if test -z "$resolveip" - then - cannot_find_file resolveip @resolveip_locations@ - exit 1 - fi - mysqld=`find_in_dirs mariadbd @mysqld_locations@` - if test -z "$mysqld" - then - cannot_find_file mariadbd @mysqld_locations@ - exit 1 - fi - langdir=`find_in_dirs --dir errmsg.sys @errmsg_locations@` - if test -z "$langdir" - then - cannot_find_file errmsg.sys @errmsg_locations@ - exit 1 - fi - srcpkgdatadir=`find_in_dirs --dir fill_help_tables.sql @pkgdata_locations@` - buildpkgdatadir=$srcpkgdatadir - if test -z "$srcpkgdatadir" - then - cannot_find_file fill_help_tables.sql @pkgdata_locations@ - exit 1 - fi - plugindir=`find_in_dirs --dir auth_pam.so $basedir/lib*/plugin $basedir/lib*/mysql/plugin $basedir/lib/*/mariadb19/plugin` + bindir="$basedir/@INSTALL_BINDIR@" + resolveip="$bindir/resolveip" + mysqld="$basedir/@INSTALL_SBINDIR@/mariadbd" + langdir="$basedir/@INSTALL_MYSQLSHAREDIR@/english" + srcpkgdatadir="$basedir/@INSTALL_MYSQLSHAREDIR@" + buildpkgdatadir="$basedir/@INSTALL_MYSQLSHAREDIR@" + plugindir="$basedir/@INSTALL_PLUGINDIR@" pamtooldir=$plugindir # relative from where the script was run for a relocatable install elif test -n "$dirname0" -a -x "$rel_mysqld" -a ! "$rel_mysqld" -ef "@sbindir@/mariadbd" diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 2b540581253..dbbffee7942 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -23,6 +23,22 @@ trap 'exit 3' INT QUIT TERM # Setting the path for some utilities on CentOS export PATH="$PATH:/usr/sbin:/usr/bin:/sbin:/bin" +commandex() +{ + if [ -n "$BASH_VERSION" ]; then + command -v "$1" || : + elif [ -x "$1" ]; then + echo "$1" + else + which "$1" || : + fi +} + +with_printf=1 +if [ -z "$BASH_VERSION" ]; then + [ -z "$(commandex printf)" ] && with_printf=0 +fi + trim_string() { if [ -n "$BASH_VERSION" ]; then @@ -35,9 +51,9 @@ trim_string() y=${#y} x=$(( z-x-1 )) y=$(( y-x+1 )) - printf '%s' "${1:$x:$y}" + echo "${1:$x:$y}" else - printf '' + echo '' fi else local pattern="[[:space:]${2:-}]" @@ -59,9 +75,9 @@ trim_dir() y=$(( y-x+1 )) x="${1:$x:$y}" [ -z "$x" ] && x='.' - printf '%s' "$x" + echo "$x" else - printf '' + echo '' fi else local pattern="[:space:]${2:-}" @@ -85,9 +101,9 @@ trim_right() y=${#y} if [ $y -ne $z ]; then y=$(( y+1 )) - printf '%s' "${1:0:$y}" + echo "${1:0:$y}" else - printf '' + echo '' fi else local pattern="[[:space:]${2:-}]" @@ -95,6 +111,25 @@ trim_right() fi } +trim_left() +{ + if [ -n "$BASH_VERSION" ]; then + local pattern="[![:space:]${2:-}]" + local x="${1#*$pattern}" + local z=${#1} + x=${#x} + if [ $x -ne $z ]; then + x=$(( z-x-1 )) + echo "${1:$x:$z}" + else + echo '' + fi + else + local pattern="[[:space:]${2:-}]" + echo "$1" | sed -E "s/^$pattern+//g" + fi +} + to_minuses() { local x="$1" @@ -105,11 +140,7 @@ to_minuses() x="$t" t="${t#*_}" done - if [ -n "$BASH_VERSION" ]; then - printf '%s' "$r$x" - else - echo "$r$x" - fi + echo "$r$x" } WSREP_SST_OPT_BYPASS=0 @@ -383,9 +414,11 @@ case "$1" in # option name: if [ -n "$BASH_VERSION" ]; then option="${options:0:1}" + elif [ $with_printf -ne 0 ]; then + option=$(printf '%.1s' "$options") else - # If it's not bash, then we need to use slow - # external utilities: + # If it's not bash and without printf, + # then we need to use slow external utilities: option=$(echo "$options" | cut -c1) fi # And the subsequent characters consider option value: @@ -788,17 +821,6 @@ WSREP_SST_OPT_ADDR="$WSREP_SST_OPT_HOST:$WSREP_SST_OPT_PORT$sst_path" readonly WSREP_SST_OPT_ADDR readonly WSREP_SST_OPT_ADDR_PORT -commandex() -{ - if [ -n "$BASH_VERSION" ]; then - command -v "$1" || : - elif [ -x "$1" ]; then - echo "$1" - else - which "$1" || : - fi -} - # try to use my_print_defaults, mysql and mysqldump that come # with the sources (for MTR suite): script_binary=$(dirname "$0") @@ -929,11 +951,7 @@ parse_cnf() # Truncate spaces: [ -n "$reval" ] && reval=$(trim_string "$reval") - if [ -n "$BASH_VERSION" ]; then - printf '%s' "$reval" - else - echo "$reval" - fi + echo "$reval" } # @@ -986,11 +1004,8 @@ in_config() break fi done - if [ -n "$BASH_VERSION" ]; then - printf '%s' $found - else - echo $found - fi + + echo $found } wsrep_auth_not_set() @@ -1128,9 +1143,7 @@ wsrep_gen_secret() printf '%04x%04x%04x%04x%04x%04x%04x%04x' \ $RANDOM $RANDOM $RANDOM $RANDOM \ $RANDOM $RANDOM $RANDOM $RANDOM - elif [ -n "$(commandex cksum)" -a \ - -n "$(commandex printf)" ] - then + elif [ $with_printf -ne 0 -a -n "$(commandex cksum)" ]; then printf '%08x%08x%08x%08x' \ $(head -8 /dev/urandom | cksum | cut -d ' ' -f1) \ $(head -8 /dev/urandom | cksum | cut -d ' ' -f1) \ @@ -1569,6 +1582,139 @@ check_server_ssl_config() fi } +# Get Common Name (CN) from the certificate: +openssl_getCN() +{ + get_openssl + if [ -z "$OPENSSL_BINARY" ]; then + wsrep_log_error \ + 'openssl not found but it is required for authentication' + exit 42 + fi + + local bug=0 + local CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$1" 2>&1) || bug=1 + + if [ $bug -ne 0 ]; then + wsrep_log_info "run: \"$OPENSSL_BINARY\" x509 -noout -subject -in \"$1\"" + wsrep_log_info "output: $CN" + wsrep_log_error "******** FATAL ERROR **********************************************" + wsrep_log_error "* Unable to parse the certificate file to obtain the common name. *" + wsrep_log_error "*******************************************************************" + exit 22 + fi + + CN=$(trim_string "$CN") + + if [ -n "$CN" ]; then + # If the string begins with the "subject" prefix + # then we need to remove it: + local saved="$CN" + local remain="${CN#subject}" + if [ "$remain" != "$saved" ]; then + remain=$(trim_left "$remain") + # Now let's check for the presence of "=" character + # after the "subject": + saved="$remain" + remain="${remain#=}" + if [ "$remain" != "$saved" ]; then + remain=$(trim_left "$remain") + else + remain="" + bug=1 + fi + fi + while [ -n "$remain" ]; do + local value="" + # Let's extract the option name - all characters + # up to the first '=' or ',' character (if present): + local option="${remain%%[=,]*}" + if [ "$option" != "$remain" ]; then + option=$(trim_right "$option") + # These variables will be needed to determine + # which separator comes first: + local x="${remain#*=}" + local y="${remain#*,}" + local z=${#remain} + x=${#x}; [ $x -eq $z ] && x=0 + y=${#y}; [ $y -eq $z ] && y=0 + # The remaining string is everything that follows + # the separator character: + remain=$(trim_left "${remain#*[=,]}") + # Let's check what we are dealing with - an equal + # sign or a comma? + if [ $x -gt $y ]; then + # If the remainder begins with a double quote, + # then there is a string containing commas and + # we need to parse it: + saved="$remain" + remain="${remain#\"}" + if [ "$remain" != "$saved" ]; then + while :; do + # We need to find the closing quote: + local prefix="$remain" + remain="${remain#*\"}" + # Let's check if there is a closing quote? + if [ "$remain" = "$prefix" ]; then + bug=1 + break + fi + # Everything up to the closing quote is + # the next part of the value: + value="$value${prefix%%\"*}" + # But if the last character of the value + # is a backslash, then it is a quoted quotation + # mark and we need to add it to the value: + if [ "${value%\\}" != "$value" ]; then + value="$value\"" + else + break + fi + done + [ $bug -ne 0 ] && break + # Now we have to remove "," if it is present + # in the string after the value: + saved=$(trim_left "$remain") + remain="${saved#,}" + if [ "$remain" != "$saved" ]; then + remain=$(trim_left "$remain") + elif [ -n "$remain" ]; then + bug=1 + break + fi + else + # We are dealing with a simple unquoted string value, + # therefore we need to take everything up to the end + # of the string, or up to the next comma character: + value="${remain%%,*}" + if [ "$value" != "$remain" ]; then + remain=$(trim_left "${remain#*,}") + else + remain="" + fi + value=$(trim_right "$value") + fi + if [ "$option" = 'CN' -a -n "$value" ]; then + echo "$value" + return + fi + fi + else + remain="" + fi + done + fi + + if [ $bug -ne 0 ]; then + wsrep_log_error "******** FATAL ERROR **********************************************" + wsrep_log_error "* Unable to parse the certificate options: '$CN'" + wsrep_log_error "*******************************************************************" + exit 22 + fi + + echo '' +} + simple_cleanup() { # Since this is invoked just after exit NNN diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 9d3058ce9b4..fec659d0179 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -803,7 +803,8 @@ recv_joiner() if [ $tmt -gt 0 ]; then if [ -n "$(commandex timeout)" ]; then local koption=0 - if [ "$OS" = 'FreeBSD' ]; then + if [ "$OS" = 'FreeBSD' -o "$OS" = 'NetBSD' -o "$OS" = 'OpenBSD' -o \ + "$OS" = 'DragonFly' ]; then if timeout 2>&1 | grep -qw -F -- '-k'; then koption=1 fi @@ -1166,12 +1167,6 @@ if [ "$WSREP_SST_OPT_ROLE" = 'donor' ]; then iopts="--databases-exclude='lost+found'${iopts:+ }$iopts" - if [ ${FORCE_FTWRL:-0} -eq 1 ]; then - wsrep_log_info "Forcing FTWRL due to environment variable" \ - "FORCE_FTWRL equal to $FORCE_FTWRL" - iopts="--no-backup-locks${iopts:+ }$iopts" - fi - # if compression is enabled for backup files, then add the # appropriate options to the mariadb-backup command line: if [ "$compress" != 'none' ]; then @@ -1209,11 +1204,11 @@ if [ "$WSREP_SST_OPT_ROLE" = 'donor' ]; then else # BYPASS FOR IST wsrep_log_info "Bypassing the SST for IST" - echo "continue" # now server can resume updating data + echo 'continue' # now server can resume updating data send_magic - echo "1" > "$DATA/$IST_FILE" + echo '1' > "$DATA/$IST_FILE" if [ -n "$scomp" ]; then tcmd="$scomp | $tcmd" @@ -1324,7 +1319,7 @@ else # joiner check_round=0 while check_pid "$SST_PID" 0; do wsrep_log_info "previous SST is not completed, waiting for it to exit" - check_round=$(( check_round + 1 )) + check_round=$(( check_round+1 )) if [ $check_round -eq 10 ]; then wsrep_log_error "previous SST script still running." exit 114 # EALREADY @@ -1351,16 +1346,7 @@ else # joiner # backward-incompatible behavior: CN="" if [ -n "$tpem" ]; then - # find out my Common Name - get_openssl - if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error \ - 'openssl not found but it is required for authentication' - exit 42 - fi - CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$tpem" | \ - tr ',' '\n' | grep -F 'CN =' | cut -d '=' -f2 | sed s/^\ // | \ - sed s/\ %//) + CN=$(openssl_getCN "$tpem") fi MY_SECRET="$(wsrep_gen_secret)" # Add authentication data to address diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index aabf5bd325e..0d92a3c05b8 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -354,7 +354,7 @@ SST_PID="$DATA/wsrep_sst.pid" check_round=0 while check_pid "$SST_PID" 0; do wsrep_log_info "Previous SST is not completed, waiting for it to exit" - check_round=$(( check_round + 1 )) + check_round=$(( check_round+1 )) if [ $check_round -eq 20 ]; then wsrep_log_error "previous SST script still running." exit 114 # EALREADY @@ -370,7 +370,7 @@ check_round=0 while check_pid "$STUNNEL_PID" 1 "$STUNNEL_CONF"; do wsrep_log_info "Lingering stunnel daemon found at startup," \ "waiting for it to exit" - check_round=$(( check_round + 1 )) + check_round=$(( check_round+1 )) if [ $check_round -eq 10 ]; then wsrep_log_error "stunnel daemon still running." exit 114 # EALREADY @@ -388,7 +388,7 @@ check_round=0 while check_pid "$RSYNC_PID" 1 "$RSYNC_CONF"; do wsrep_log_info "Lingering rsync daemon found at startup," \ "waiting for it to exit" - check_round=$(( check_round + 1 )) + check_round=$(( check_round+1 )) if [ $check_round -eq 10 ]; then wsrep_log_error "rsync daemon still running." exit 114 # EALREADY @@ -481,11 +481,7 @@ EOF tar_type=2 fi if [ $tar_type -eq 2 ]; then - if [ -n "$BASH_VERSION" ]; then - printf '%s' "$binlog_files" >&2 - else - echo "$binlog_files" >&2 - fi + echo "$binlog_files" >&2 fi if [ $tar_type -ne 0 ]; then # Preparing list of the binlog file names: @@ -854,16 +850,7 @@ EOF # backward-incompatible behavior: CN="" if [ -n "$SSTCERT" ]; then - # find out my Common Name - get_openssl - if [ -z "$OPENSSL_BINARY" ]; then - wsrep_log_error \ - 'openssl not found but it is required for authentication' - exit 42 - fi - CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$SSTCERT" | \ - tr ',' '\n' | grep -F 'CN =' | cut -d '=' -f2 | sed s/^\ // | \ - sed s/\ %//) + CN=$(openssl_getCN "$SSTCERT") fi MY_SECRET="$(wsrep_gen_secret)" # Add authentication data to address diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 38fa57694a6..0195555efaf 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -58,7 +58,7 @@ ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql ${LIBFMT_INCLUDE_DIR} ${PCRE_INCLUDE_DIRS} -${ZLIB_INCLUDE_DIR} +${ZLIB_INCLUDE_DIRS} ${SSL_INCLUDE_DIRS} ${CMAKE_BINARY_DIR}/sql ${CMAKE_SOURCE_DIR}/tpool diff --git a/sql/backup.cc b/sql/backup.cc index 5ce770c3c4c..f634a11f867 100644 --- a/sql/backup.cc +++ b/sql/backup.cc @@ -39,6 +39,7 @@ #ifdef WITH_WSREP #include "wsrep_server_state.h" #include "wsrep_mysqld.h" +#include "wsrep_sst.h" #endif /* WITH_WSREP */ static const char *stage_names[]= @@ -293,29 +294,40 @@ static bool backup_block_ddl(THD *thd) #ifdef WITH_WSREP DBUG_ASSERT(thd->wsrep_desynced_backup_stage == false); - /* - if user is specifically choosing to allow BF aborting for BACKUP STAGE BLOCK_DDL lock - holder, then do not desync and pause the node from cluster replication. - e.g. mariabackup uses BACKUP STATE BLOCK_DDL; and will be abortable by this. - But, If node is processing as SST donor or WSREP_MODE_BF_MARIABACKUP mode is not set, - we desync the node for BACKUP STAGE because applier threads - bypass backup MDL locks (see MDL_lock::can_grant_lock) - */ if (WSREP_NNULL(thd)) { Wsrep_server_state &server_state= Wsrep_server_state::instance(); - if (!wsrep_check_mode(WSREP_MODE_BF_MARIABACKUP) || - server_state.state() == Wsrep_server_state::s_donor) + /* + If user is specifically choosing to allow BF aborting for + BACKUP STAGE BLOCK_DDL lock holder, then do not desync and + pause the node from cluster replication. e.g. mariabackup + uses BACKUP STATE BLOCK_DDL; and will be abortable by this. + */ + bool mariabackup= (server_state.state() == Wsrep_server_state::s_donor + && !strcmp(wsrep_sst_method, "mariabackup")); + bool allow_bf= wsrep_check_mode(WSREP_MODE_BF_MARIABACKUP); + bool pause_and_desync= true; + + if ((allow_bf) || (mariabackup)) { - if (server_state.desync_and_pause().is_undefined()) { + pause_and_desync= false; + } + + if (pause_and_desync) + { + if (server_state.desync_and_pause().is_undefined()) DBUG_RETURN(1); - } + + WSREP_INFO("Server desynched from group during BACKUP STAGE BLOCK_DDL."); DEBUG_SYNC(thd, "wsrep_backup_stage_after_desync_and_pause"); thd->wsrep_desynced_backup_stage= true; } else - WSREP_INFO("Server not desynched from group because WSREP_MODE_BF_MARIABACKUP used."); + { + WSREP_INFO("Server not desynched from group at BLOCK_DDL because %s is used.", + allow_bf ? "WSREP_MODE_BF_MARIABACKUP" : wsrep_sst_method); + } } #endif /* WITH_WSREP */ @@ -399,6 +411,28 @@ static bool backup_block_commit(THD *thd) } thd->clear_error(); +#ifdef WITH_WSREP + if (WSREP_NNULL(thd) && !thd->wsrep_desynced_backup_stage) + { + Wsrep_server_state &server_state= Wsrep_server_state::instance(); + bool mariabackup= (server_state.state() == Wsrep_server_state::s_donor + && !strcmp(wsrep_sst_method, "mariabackup")); + + /* If this node is donor and mariabackup is not used + we desync and pause provider here if it is not yet done. + */ + if (!mariabackup) + { + if (server_state.desync_and_pause().is_undefined()) + DBUG_RETURN(1); + + WSREP_INFO("Server desynched from group during BACKUP STAGE BLOCK_COMMIT."); + thd->wsrep_desynced_backup_stage= true; + DEBUG_SYNC(thd, "wsrep_backup_stage_commit_after_desync_and_pause"); + } + } +#endif /* WITH_WSREP */ + DBUG_RETURN(0); } diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc index 362463a7f22..9d95b3c70fc 100644 --- a/sql/debug_sync.cc +++ b/sql/debug_sync.cc @@ -1152,7 +1152,7 @@ static bool debug_sync_eval_action(THD *thd, char *action_str, char *action_end) st_debug_sync_action *action= NULL; const char *errmsg; char *ptr; - char *token; + char *token= nullptr; uint token_length= 0; DBUG_ENTER("debug_sync_eval_action"); DBUG_ASSERT(thd); diff --git a/sql/des_key_file.cc b/sql/des_key_file.cc index bfbe04f6015..776be8a5a2f 100644 --- a/sql/des_key_file.cc +++ b/sql/des_key_file.cc @@ -19,7 +19,7 @@ #include "log.h" // sql_print_error #include -#ifdef HAVE_OPENSSL +#ifdef HAVE_des struct st_des_keyschedule des_keyschedule[10]; uint des_default_key; @@ -103,4 +103,4 @@ error: mysql_mutex_unlock(&LOCK_des_key_file); DBUG_RETURN(result); } -#endif /* HAVE_OPENSSL */ +#endif /* HAVE_des */ diff --git a/sql/des_key_file.h b/sql/des_key_file.h index 847cd767b4b..58ed2f87b8e 100644 --- a/sql/des_key_file.h +++ b/sql/des_key_file.h @@ -16,7 +16,7 @@ #ifndef DES_KEY_FILE_INCLUDED #define DES_KEY_FILE_INCLUDED -#ifdef HAVE_OPENSSL +#ifdef HAVE_des #include #include "violite.h" /* DES_cblock, DES_key_schedule */ @@ -35,6 +35,6 @@ extern struct st_des_keyschedule des_keyschedule[10]; extern uint des_default_key; bool load_des_key_file(const char *file_name); -#endif /* HAVE_OPENSSL */ +#endif /* HAVE_des */ #endif /* DES_KEY_FILE_INCLUDED */ diff --git a/sql/field.cc b/sql/field.cc index 35be045620d..9cf95ec59fb 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1502,6 +1502,9 @@ bool Field::sp_prepare_and_store_item(THD *thd, Item **value) if (!(expr_item= thd->sp_fix_func_item_for_assignment(this, value))) goto error; + if (expr_item->check_is_evaluable_expression_or_error()) + goto error; + /* Save the value in the field. Convert the value if needed. */ expr_item->save_in_field(this, 0); @@ -5277,6 +5280,8 @@ int Field_timestamp::save_in_field(Field *to) { ulong sec_part; my_time_t ts= get_timestamp(&sec_part); + if (!ts && !sec_part) + return to->store_time_dec(Datetime::zero().get_mysql_time(), decimals()); return to->store_timestamp_dec(Timeval(ts, sec_part), decimals()); } @@ -5398,11 +5403,33 @@ int Field_timestamp::store(longlong nr, bool unsigned_val) } -int Field_timestamp::store_timestamp_dec(const timeval &ts, uint dec) +int Field_timestamp::store_timestamp_dec(const timeval &tv, uint dec) { int warn= 0; time_round_mode_t mode= Datetime::default_round_mode(get_thd()); - store_TIMESTAMP(Timestamp(ts).round(decimals(), mode, &warn)); + const Timestamp ts= Timestamp(tv).round(decimals(), mode, &warn); + store_TIMESTAMP(ts); + if (ts.tv().tv_sec == 0 && ts.tv().tv_usec == 0) + { + /* + The value {tv_sec==0, tv_usec==0} here means '1970-01-01 00:00:00 +00'. + It does not mean zero datetime! because store_timestamp_dec() knows + nothing about zero dates. It inserts only real timeval values. + Zero ts={0,0} here is possible in two scenarios: + - the passed tv was already {0,0} meaning '1970-01-01 00:00:00 +00' + - the passed tv had some microseconds but they were rounded/truncated + to zero: '1970-01-01 00:00:00.1 +00' -> '1970-01-01 00:00:00 +00'. + It does not matter whether rounding/truncation really happened. + In both cases the call for store_TIMESTAMP(ts) above re-interpreted + '1970-01-01 00:00:00 +00:00' to zero date. Return 1 no matter what + sql_mode is. Even if sql_mode allows zero dates, there is still a problem + here: '1970-01-01 00:00:00 +00' could not be stored as-is! + */ + ErrConvString str(STRING_WITH_LEN("1970-01-01 00:00:00 +00:00"), + system_charset_info); + set_datetime_warning(ER_WARN_DATA_OUT_OF_RANGE, &str, "datetime", 1); + return 1; // '1970-01-01 00:00:00 +00' was converted to a zero date + } if (warn) { /* @@ -5416,9 +5443,6 @@ int Field_timestamp::store_timestamp_dec(const timeval &ts, uint dec) */ set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); } - if (ts.tv_sec == 0 && ts.tv_usec == 0 && - get_thd()->variables.sql_mode & (ulonglong) TIME_NO_ZERO_DATE) - return zero_time_stored_return_code_with_warning(); return 0; } @@ -5789,8 +5813,10 @@ my_time_t Field_timestampf::get_timestamp(const uchar *pos, bool Field_timestampf::val_native(Native *to) { DBUG_ASSERT(marked_for_read()); + char zero[8]= "\0\0\0\0\0\0\0"; + DBUG_ASSERT(pack_length () <= sizeof(zero)); // Check if it's '0000-00-00 00:00:00' rather than a real timestamp - if (ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) + if (!memcmp(ptr, zero, pack_length())) { to->length(0); return false; @@ -11478,6 +11504,30 @@ bool Field::validate_value_in_record_with_warn(THD *thd, const uchar *record) } +/** + Find which reaction should be for IGNORE value. +*/ + +ignore_value_reaction find_ignore_reaction(THD *thd) +{ + enum_sql_command com= thd->lex->sql_command; + + // All insert-like commands + if (com == SQLCOM_INSERT || com == SQLCOM_REPLACE || + com == SQLCOM_INSERT_SELECT || com == SQLCOM_REPLACE_SELECT || + com == SQLCOM_LOAD) + { + return IGNORE_MEANS_DEFAULT; + } + // Update commands + if (com == SQLCOM_UPDATE || com == SQLCOM_UPDATE_MULTI) + { + return IGNORE_MEANS_FIELD_VALUE; + } + return IGNORE_MEANS_ERROR; +} + + bool Field::save_in_field_default_value(bool view_error_processing) { THD *thd= table->in_use; diff --git a/sql/field.h b/sql/field.h index 7f1c243a180..39e0da61e6f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -63,6 +63,15 @@ enum enum_check_fields CHECK_FIELD_ERROR_FOR_NULL, }; +enum ignore_value_reaction +{ + IGNORE_MEANS_ERROR, + IGNORE_MEANS_DEFAULT, + IGNORE_MEANS_FIELD_VALUE +}; + +ignore_value_reaction find_ignore_reaction(THD *thd); + enum enum_conv_type { @@ -5753,7 +5762,8 @@ public: { List_iterator it(list); while (Create_field *f= it++) - f->type_handler()->Column_definition_implicit_upgrade(f); + f->type_handler()->type_handler_for_implicit_upgrade()-> + Column_definition_implicit_upgrade_to_this(f); } }; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index f7b84ff3be8..177f49fb926 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -397,6 +397,7 @@ void ha_partition::init_handler_variables() m_start_key.length= 0; m_myisam= FALSE; m_innodb= FALSE; + m_myisammrg= FALSE; m_extra_cache= FALSE; m_extra_cache_size= 0; m_extra_prepare_for_update= FALSE; @@ -691,6 +692,7 @@ int ha_partition::create_partitioning_metadata(const char *path, partition_element *part; DBUG_ENTER("ha_partition::create_partitioning_metadata"); + mark_trx_read_write(); /* We need to update total number of parts since we might write the handler file as part of a partition management command @@ -1677,10 +1679,10 @@ bool ha_partition::is_crashed() const int ha_partition::prepare_new_partition(TABLE *tbl, HA_CREATE_INFO *create_info, handler *file, const char *part_name, - partition_element *p_elem, - uint disable_non_uniq_indexes) + partition_element *p_elem) { int error; + key_map keys_in_use= table->s->keys_in_use; DBUG_ENTER("prepare_new_partition"); /* @@ -1736,8 +1738,8 @@ int ha_partition::prepare_new_partition(TABLE *tbl, goto error_external_lock; DBUG_PRINT("info", ("partition %s external locked", part_name)); - if (disable_non_uniq_indexes) - file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); + if (!keys_in_use.is_prefix(table->s->keys)) + file->ha_disable_indexes(keys_in_use, true); DBUG_RETURN(0); error_external_lock: @@ -2033,13 +2035,6 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, calls */ - /* - Before creating new partitions check whether indexes are disabled - in the partitions. - */ - - uint disable_non_uniq_indexes= indexes_are_disabled(); - i= 0; part_count= 0; part_it.rewind(); @@ -2081,8 +2076,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, prepare_new_partition(table, create_info, new_file_array[part], (const char *)part_name_buff, - sub_elem, - disable_non_uniq_indexes)))) + sub_elem)))) { cleanup_new_partition(part_count); DBUG_RETURN(error); @@ -2108,8 +2102,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, prepare_new_partition(table, create_info, new_file_array[i], (const char *)part_name_buff, - part_elem, - disable_non_uniq_indexes)))) + part_elem)))) { cleanup_new_partition(part_count); DBUG_RETURN(error); @@ -3042,6 +3035,10 @@ bool ha_partition::create_handlers(MEM_ROOT *mem_root) DBUG_PRINT("info", ("InnoDB")); m_innodb= TRUE; } + else if (ha_legacy_type(hton0) == DB_TYPE_MRG_MYISAM) + { + m_myisammrg= TRUE; + } DBUG_RETURN(FALSE); } @@ -3308,10 +3305,12 @@ handlerton *ha_partition::get_def_part_engine(const char *name) goto err; if (state.st_size <= 64) goto err; - if (!(frm_image= (uchar*)my_malloc(key_memory_Partition_share, - state.st_size, MYF(MY_WME)))) + if ((ulonglong)state.st_size >= SIZE_T_MAX) /* Whole file need to fit into memory*/ goto err; - if (mysql_file_read(file, frm_image, state.st_size, MYF(MY_NABP))) + if (!(frm_image= (uchar*)my_malloc(key_memory_Partition_share, + (size_t)state.st_size, MYF(MY_WME)))) + goto err; + if (mysql_file_read(file, frm_image, (size_t)state.st_size, MYF(MY_NABP))) goto err; if (frm_image[64] != '/') @@ -8640,7 +8639,7 @@ int ha_partition::info(uint flag) file->stats.auto_increment_value); } while (*(++file_array)); - DBUG_ASSERT(auto_increment_value); + DBUG_ASSERT(!all_parts_opened || auto_increment_value); stats.auto_increment_value= auto_increment_value; if (all_parts_opened && auto_inc_is_first_in_idx) { @@ -9318,8 +9317,9 @@ int ha_partition::extra(enum ha_extra_function operation) switch (operation) { /* Category 1), used by most handlers */ case HA_EXTRA_NO_KEYREAD: - DBUG_RETURN(loop_partitions(end_keyread_cb, NULL)); + DBUG_RETURN(loop_read_partitions(end_keyread_cb, NULL)); case HA_EXTRA_KEYREAD: + DBUG_RETURN(loop_read_partitions(extra_cb, &operation)); case HA_EXTRA_FLUSH: case HA_EXTRA_PREPARE_FOR_FORCED_CLOSE: DBUG_RETURN(loop_partitions(extra_cb, &operation)); @@ -9428,9 +9428,14 @@ int ha_partition::extra(enum ha_extra_function operation) } /* Category 9) Operations only used by MERGE */ case HA_EXTRA_ADD_CHILDREN_LIST: + if (!m_myisammrg) + DBUG_RETURN(0); DBUG_RETURN(loop_partitions(extra_cb, &operation)); case HA_EXTRA_ATTACH_CHILDREN: { + if (!m_myisammrg) + DBUG_RETURN(0); + int result; uint num_locks; handler **file; @@ -9449,8 +9454,9 @@ int ha_partition::extra(enum ha_extra_function operation) break; } case HA_EXTRA_IS_ATTACHED_CHILDREN: - DBUG_RETURN(loop_partitions(extra_cb, &operation)); case HA_EXTRA_DETACH_CHILDREN: + if (!m_myisammrg) + DBUG_RETURN(0); DBUG_RETURN(loop_partitions(extra_cb, &operation)); case HA_EXTRA_MARK_AS_LOG_TABLE: /* @@ -9535,7 +9541,7 @@ int ha_partition::extra_opt(enum ha_extra_function operation, ulong arg) switch (operation) { case HA_EXTRA_KEYREAD: - DBUG_RETURN(loop_partitions(start_keyread_cb, &arg)); + DBUG_RETURN(loop_read_partitions(start_keyread_cb, &arg)); case HA_EXTRA_CACHE: prepare_extra_cache(arg); DBUG_RETURN(0); @@ -9623,14 +9629,53 @@ int ha_partition::loop_extra_alter(enum ha_extra_function operation) */ int ha_partition::loop_partitions(handler_callback callback, void *param) +{ + int result= loop_partitions_over_map(&m_part_info->lock_partitions, + callback, param); + /* Add all used partitions to be called in reset(). */ + bitmap_union(&m_partitions_to_reset, &m_part_info->lock_partitions); + return result; +} + + +/* + Call callback(part, param) on read_partitions (the ones used by the query) +*/ + +int ha_partition::loop_read_partitions(handler_callback callback, void *param) +{ + /* + There is no need to record partitions on m_partitions_to_reset as + read_partitions were opened, etc - they will be reset anyway. + */ + return loop_partitions_over_map(&m_part_info->read_partitions, callback, + param); +} + + +/** + Call callback(part, param) on specified set of partitions + + @part_map The set of partitions to call callback for + @param callback a callback to call for each partition + @param param a void*-parameter passed to callback + + @return Operation status + @retval >0 Error code + @retval 0 Success +*/ + +int ha_partition::loop_partitions_over_map(const MY_BITMAP *part_map, + handler_callback callback, + void *param) { int result= 0, tmp; uint i; - DBUG_ENTER("ha_partition::loop_partitions"); + DBUG_ENTER("ha_partition::loop_partitions_over_map"); - for (i= bitmap_get_first_set(&m_part_info->lock_partitions); + for (i= bitmap_get_first_set(part_map); i < m_tot_parts; - i= bitmap_get_next_set(&m_part_info->lock_partitions, i)) + i= bitmap_get_next_set(part_map, i)) { /* This can be called after an error in ha_open. @@ -9640,8 +9685,6 @@ int ha_partition::loop_partitions(handler_callback callback, void *param) (tmp= callback(m_file[i], param))) result= tmp; } - /* Add all used partitions to be called in reset(). */ - bitmap_union(&m_partitions_to_reset, &m_part_info->lock_partitions); DBUG_RETURN(result); } @@ -10903,18 +10946,19 @@ int ha_partition::update_next_auto_inc_val() bool ha_partition::need_info_for_auto_inc() { - handler **file= m_file; DBUG_ENTER("ha_partition::need_info_for_auto_inc"); - do + for (uint i= bitmap_get_first_set(&m_locked_partitions); + i < m_tot_parts; + i= bitmap_get_next_set(&m_locked_partitions, i)) { - if ((*file)->need_info_for_auto_inc()) + if ((m_file[i])->need_info_for_auto_inc()) { /* We have to get new auto_increment values from handler */ part_share->auto_inc_initialized= FALSE; DBUG_RETURN(TRUE); } - } while (*(++file)); + } DBUG_RETURN(FALSE); } @@ -11200,7 +11244,7 @@ int ha_partition::calculate_checksum() != 0 Error */ -int ha_partition::disable_indexes(uint mode) +int ha_partition::disable_indexes(key_map map, bool persist) { handler **file; int error= 0; @@ -11208,7 +11252,7 @@ int ha_partition::disable_indexes(uint mode) DBUG_ASSERT(bitmap_is_set_all(&(m_part_info->lock_partitions))); for (file= m_file; *file; file++) { - if (unlikely((error= (*file)->ha_disable_indexes(mode)))) + if (unlikely((error= (*file)->ha_disable_indexes(map, persist)))) break; } return error; @@ -11225,7 +11269,7 @@ int ha_partition::disable_indexes(uint mode) != 0 Error */ -int ha_partition::enable_indexes(uint mode) +int ha_partition::enable_indexes(key_map map, bool persist) { handler **file; int error= 0; @@ -11233,7 +11277,7 @@ int ha_partition::enable_indexes(uint mode) DBUG_ASSERT(bitmap_is_set_all(&(m_part_info->lock_partitions))); for (file= m_file; *file; file++) { - if (unlikely((error= (*file)->ha_enable_indexes(mode)))) + if (unlikely((error= (*file)->ha_enable_indexes(map, persist)))) break; } return error; diff --git a/sql/ha_partition.h b/sql/ha_partition.h index d450f96f4f9..51e199d3c5e 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -399,6 +399,7 @@ private: */ bool m_innodb; // Are all underlying handlers // InnoDB + bool m_myisammrg; // Are any of the handlers of type MERGE /* When calling extra(HA_EXTRA_CACHE) we do not pass this to the underlying handlers immediately. Instead we cache it and call the underlying @@ -577,8 +578,7 @@ private: void cleanup_new_partition(uint part_count); int prepare_new_partition(TABLE *table, HA_CREATE_INFO *create_info, handler *file, const char *part_name, - partition_element *p_elem, - uint disable_non_uniq_indexes); + partition_element *p_elem); /* delete_table and rename_table uses very similar logic which is packed into this routine. @@ -988,6 +988,10 @@ private: handler *file, uint *n); static const uint NO_CURRENT_PART_ID= NOT_A_PARTITION_ID; int loop_partitions(handler_callback callback, void *param); + int loop_partitions_over_map(const MY_BITMAP *map, + handler_callback callback, + void *param); + int loop_read_partitions(handler_callback callback, void *param); int loop_extra_alter(enum ha_extra_function operations); void late_extra_cache(uint partition_id); void late_extra_no_cache(uint partition_id); @@ -1578,8 +1582,8 @@ public: Enable/Disable Indexes are only supported by HEAP and MyISAM. ------------------------------------------------------------------------- */ - int disable_indexes(uint mode) override; - int enable_indexes(uint mode) override; + int disable_indexes(key_map map, bool persist) override; + int enable_indexes(key_map map, bool persist) override; int indexes_are_disabled() override; /* diff --git a/sql/handler.cc b/sql/handler.cc index fec473d97bb..18d67cb567a 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -685,13 +685,6 @@ int ha_initialize_handlerton(st_plugin_int *plugin) hton->slot= HA_SLOT_UNDEF; /* Historical Requirement */ plugin->data= hton; // shortcut for the future - /* [remove after merge] notes on merge conflict (MDEV-31400): - 10.6-10.11: 13ba00ff4933cfc1712676f323587504e453d1b5 - 11.0-11.2: 42f8be10f18163c4025710cf6a212e82bddb2f62 - The 10.11->11.0 conflict is trivial, but the reference commit also - contains different non-conflict changes needs to be applied to 11.0 - (and beyond). - */ if (plugin->plugin->init && (ret= plugin->plugin->init(hton))) goto err; @@ -1661,6 +1654,29 @@ ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list, return rw_ha_count; } +#ifdef WITH_WSREP +/** + Check if transaction contains storage engine not supporting + two-phase commit and transaction is read-write. + + @retval + true Transaction contains storage engine not supporting + two phase commit and transaction is read-write + @retval + false otherwise +*/ +static bool wsrep_have_no2pc_rw_ha(Ha_trx_info* ha_list) +{ + for (Ha_trx_info *ha_info=ha_list; ha_info; ha_info= ha_info->next()) + { + handlerton *ht= ha_info->ht(); + // Transaction is read-write and handler does not support 2pc + if (ha_info->is_trx_read_write() && ht->prepare==0) + return true; + } + return false; +} +#endif /* WITH_WSREP */ /** @retval @@ -1873,17 +1889,26 @@ int ha_commit_trans(THD *thd, bool all) */ if (run_wsrep_hooks) { - // This commit involves more than one storage engine and requires - // two phases, but some engines don't support it. - // Issue a message to the client and roll back the transaction. - if (trans->no_2pc && rw_ha_count > 1) + // This commit involves storage engines that do not support two phases. + // We allow read only transactions to such storage engines but not + // read write transactions. + if (trans->no_2pc && rw_ha_count > 1 && wsrep_have_no2pc_rw_ha(trans->ha_list)) { - my_message(ER_ERROR_DURING_COMMIT, "Transactional commit not supported " - "by involved engine(s)", MYF(0)); - error= 1; + // This commit involves more than one storage engine and requires + // two phases, but some engines don't support it. + // Issue a message to the client and roll back the transaction. + + // REPLACE|INSERT INTO ... SELECT uses TOI for MyISAM|Aria + if (WSREP(thd) && thd->wsrep_cs().mode() != wsrep::client_state::m_toi) + { + my_message(ER_ERROR_DURING_COMMIT, "Transactional commit not supported " + "by involved engine(s)", MYF(0)); + error= 1; + } } - else - error= wsrep_before_commit(thd, all); + + if (!error) + error= wsrep_before_commit(thd, all); } if (error) { @@ -2256,8 +2281,12 @@ int ha_rollback_trans(THD *thd, bool all) } #ifdef WITH_WSREP - (void) wsrep_before_rollback(thd, all); + // REPLACE|INSERT INTO ... SELECT uses TOI in consistency check + if (thd->wsrep_consistency_check != CONSISTENCY_CHECK_RUNNING) + if (thd->wsrep_cs().mode() != wsrep::client_state::m_toi) + (void) wsrep_before_rollback(thd, all); #endif /* WITH_WSREP */ + if (ha_info) { /* Close all cursors that can not survive ROLLBACK */ @@ -2294,7 +2323,11 @@ int ha_rollback_trans(THD *thd, bool all) thd->thread_id, all?"TRUE":"FALSE", wsrep_thd_query(thd), thd->get_stmt_da()->message(), is_real_trans); } - (void) wsrep_after_rollback(thd, all); + + // REPLACE|INSERT INTO ... SELECT uses TOI in consistency check + if (thd->wsrep_consistency_check != CONSISTENCY_CHECK_RUNNING) + if (thd->wsrep_cs().mode() != wsrep::client_state::m_toi) + (void) wsrep_after_rollback(thd, all); #endif /* WITH_WSREP */ if (all || !thd->in_active_multi_stmt_transaction()) @@ -3512,6 +3545,17 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode, DBUG_ASSERT(alloc_root_inited(&table->mem_root)); set_partitions_to_open(partitions_to_open); + internal_tmp_table= MY_TEST(test_if_locked & HA_OPEN_INTERNAL_TABLE); + + if (!internal_tmp_table && (test_if_locked & HA_OPEN_TMP_TABLE) && + current_thd->slave_thread) + { + /* + This is a temporary table used by replication that is not attached + to a THD. Mark it as a global temporary table. + */ + test_if_locked|= HA_OPEN_GLOBAL_TMP_TABLE; + } if (unlikely((error=open(name,mode,test_if_locked)))) { @@ -3571,7 +3615,6 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode, /* Copy current optimizer costs. Needed in case clone() is used */ reset_statistics(); } - internal_tmp_table= MY_TEST(test_if_locked & HA_OPEN_INTERNAL_TABLE); DBUG_RETURN(error); } @@ -4926,7 +4969,8 @@ int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt) KEY *keyinfo, *keyend; KEY_PART_INFO *keypart, *keypartend; - if (table->s->incompatible_version) + if (table->s->incompatible_version || + check_old_types()) return HA_ADMIN_NEEDS_ALTER; if (!table->s->mysql_version) @@ -4952,6 +4996,12 @@ int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt) } } } + + /* + True VARCHAR appeared in MySQL-5.0.3. + If the FRM is older than 5.0.3, force alter even if the check_old_type() + call above did not find data types that want upgrade. + */ if (table->s->frm_version < FRM_VER_TRUE_VARCHAR) return HA_ADMIN_NEEDS_ALTER; @@ -4965,26 +5015,15 @@ int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt) } -int handler::check_old_types() +bool handler::check_old_types() const { - Field** field; - - if (!table->s->mysql_version) + for (Field **field= table->field; (*field); field++) { - /* check for bad DECIMAL field */ - for (field= table->field; (*field); field++) - { - if ((*field)->type() == MYSQL_TYPE_NEWDECIMAL) - { - return HA_ADMIN_NEEDS_ALTER; - } - if ((*field)->type() == MYSQL_TYPE_VAR_STRING) - { - return HA_ADMIN_NEEDS_ALTER; - } - } + const Type_handler *th= (*field)->type_handler(); + if (th != th->type_handler_for_implicit_upgrade()) + return true; } - return 0; + return false; } @@ -5052,6 +5091,12 @@ uint handler::get_dup_key(int error) DBUG_RETURN(errkey); } +bool handler::has_dup_ref() const +{ + DBUG_ASSERT(lookup_errkey != (uint)-1 || errkey != (uint)-1); + return ha_table_flags() & HA_DUPLICATE_POS || lookup_errkey != (uint)-1; +} + /** Delete all files with extension from bas_ext(). @@ -5185,8 +5230,6 @@ int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt) if (table->s->mysql_version < MYSQL_VERSION_ID) { - if (unlikely((error= check_old_types()))) - return error; error= ha_check_for_upgrade(check_opt); if (unlikely(error && (error != HA_ADMIN_NEEDS_CHECK))) return error; @@ -5196,7 +5239,7 @@ int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt) if (unlikely((error= check(thd, check_opt)))) return error; /* Skip updating frm version if not main handler. */ - if (table->file != this) + if (table->file != this || opt_readonly) return error; return update_frm_version(table); } @@ -5245,7 +5288,7 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt) DBUG_ASSERT(result == HA_ADMIN_NOT_IMPLEMENTED || ha_table_flags() & HA_CAN_REPAIR); - if (result == HA_ADMIN_OK) + if (result == HA_ADMIN_OK && !opt_readonly) result= update_frm_version(table); return result; } @@ -5387,34 +5430,48 @@ handler::ha_check_and_repair(THD *thd) /** Disable indexes: public interface. + @param map has 0 for all indexes that should be disabled + @param persist indexes should stay disabled after server restart + + Currently engines don't support disabling an arbitrary subset of indexes. + + In particular, if the change is persistent: + * auto-increment index should not be disabled + * unique indexes should not be disabled + + if unique or auto-increment indexes are disabled (non-persistently), + the caller should only insert data that does not require + auto-inc generation and does not violate uniqueness + @sa handler::disable_indexes() */ int -handler::ha_disable_indexes(uint mode) +handler::ha_disable_indexes(key_map map, bool persist) { - DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE || - m_lock_type != F_UNLCK); + DBUG_ASSERT(table->s->tmp_table != NO_TMP_TABLE || m_lock_type != F_UNLCK); mark_trx_read_write(); - return disable_indexes(mode); + return disable_indexes(map, persist); } /** Enable indexes: public interface. + @param map has 1 for all indexes that should be enabled + @param persist indexes should stay enabled after server restart + @sa handler::enable_indexes() */ int -handler::ha_enable_indexes(uint mode) +handler::ha_enable_indexes(key_map map, bool persist) { - DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE || - m_lock_type != F_UNLCK); + DBUG_ASSERT(table->s->tmp_table != NO_TMP_TABLE || m_lock_type != F_UNLCK); mark_trx_read_write(); - return enable_indexes(mode); + return enable_indexes(map, persist); } @@ -5690,6 +5747,9 @@ handler::ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info_arg) { DBUG_ASSERT(m_lock_type == F_UNLCK); mark_trx_read_write(); + if ((info_arg->options & HA_LEX_CREATE_TMP_TABLE) && + current_thd->slave_thread) + info_arg->options|= HA_LEX_CREATE_GLOBAL_TMP_TABLE; int error= create(name, form, info_arg); if (!error && !(info_arg->options & (HA_LEX_CREATE_TMP_TABLE | HA_CREATE_TMP_ALTER))) @@ -5717,8 +5777,6 @@ handler::ha_create_partitioning_metadata(const char *name, DBUG_ASSERT(m_lock_type == F_UNLCK || (!old_name && strcmp(name, table_share->path.str))); - - mark_trx_read_write(); return create_partitioning_metadata(name, old_name, action_flag); } @@ -6179,7 +6237,7 @@ err: void st_ha_check_opt::init() { - flags= sql_flags= 0; + flags= sql_flags= handler_flags= 0; start_time= my_time(0); } @@ -7558,11 +7616,8 @@ exit: if (error == HA_ERR_FOUND_DUPP_KEY) { table->file->lookup_errkey= key_no; - if (ha_table_flags() & HA_DUPLICATE_POS) - { - lookup_handler->position(table->record[0]); - memcpy(table->file->dup_ref, lookup_handler->ref, ref_length); - } + lookup_handler->position(table->record[0]); + memcpy(table->file->dup_ref, lookup_handler->ref, ref_length); } restore_record(table, file->lookup_buffer); table->restore_blob_values(blob_storage); @@ -7641,7 +7696,7 @@ int handler::check_duplicate_long_entries_update(const uchar *new_rec) So also check for that too */ if((field->is_null(0) != field->is_null(reclength)) || - field->cmp_binary_offset(reclength)) + field->cmp_offset(reclength)) { if((error= check_duplicate_long_entry_key(new_rec, i))) return error; @@ -7850,7 +7905,16 @@ int handler::ha_write_row(const uchar *buf) m_lock_type == F_WRLCK); DBUG_ENTER("handler::ha_write_row"); DEBUG_SYNC_C("ha_write_row_start"); - +#ifdef WITH_WSREP + DBUG_EXECUTE_IF("wsrep_ha_write_row", + { + const char act[]= + "now " + "SIGNAL wsrep_ha_write_row_reached " + "WAIT_FOR wsrep_ha_write_row_continue"; + DBUG_ASSERT(!debug_sync_set_action(ha_thd(), STRING_WITH_LEN(act))); + }); +#endif /* WITH_WSREP */ if ((error= ha_check_overlaps(NULL, buf))) DBUG_RETURN(error); diff --git a/sql/handler.h b/sql/handler.h index 3b13166781d..0db07ed7110 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -457,12 +457,6 @@ enum chf_create_flags { #define HA_FAST_CHANGE_PARTITION (1UL << 13) #define HA_PARTITION_ONE_PHASE (1UL << 14) -/* operations for disable/enable indexes */ -#define HA_KEY_SWITCH_NONUNIQ 0 -#define HA_KEY_SWITCH_ALL 1 -#define HA_KEY_SWITCH_NONUNIQ_SAVE 2 -#define HA_KEY_SWITCH_ALL_SAVE 3 - /* Note: the following includes binlog and closing 0. TODO remove the limit, use dynarrays @@ -501,6 +495,12 @@ enum chf_create_flags { #define HA_LEX_CREATE_SEQUENCE 16U #define HA_VERSIONED_TABLE 32U #define HA_SKIP_KEY_SORT 64U +/* + A temporary table that can be used by different threads, eg. replication + threads. This flag ensure that memory is not allocated with THREAD_SPECIFIC, + as we do for other temporary tables. +*/ +#define HA_LEX_CREATE_GLOBAL_TMP_TABLE 128U #define HA_MAX_REC_LENGTH 65535 @@ -2723,6 +2723,7 @@ typedef struct st_ha_check_opt st_ha_check_opt() = default; /* Remove gcc warning */ uint flags; /* isam layer flags (e.g. for myisamchk) */ uint sql_flags; /* sql layer flags - for something myisamchk cannot do */ + uint handler_flags; /* Reserved for handler usage */ time_t start_time; /* When check/repair starts */ KEY_CACHE *key_cache; /* new key cache when changing key cache */ void init(); @@ -3463,6 +3464,7 @@ public: */ MEM_UNDEFINED(&optimizer_where_cost, sizeof(optimizer_where_cost)); MEM_UNDEFINED(&optimizer_scan_setup_cost, sizeof(optimizer_scan_setup_cost)); + active_handler_stats.active= 0; } virtual ~handler(void) { @@ -3628,8 +3630,8 @@ public: int ha_optimize(THD* thd, HA_CHECK_OPT* check_opt); int ha_analyze(THD* thd, HA_CHECK_OPT* check_opt); bool ha_check_and_repair(THD *thd); - int ha_disable_indexes(uint mode); - int ha_enable_indexes(uint mode); + int ha_disable_indexes(key_map map, bool persist); + int ha_enable_indexes(key_map map, bool persist); int ha_discard_or_import_tablespace(my_bool discard); int ha_rename_table(const char *from, const char *to); void ha_drop_table(const char *name); @@ -3653,6 +3655,7 @@ public: virtual void print_error(int error, myf errflag); virtual bool get_error_message(int error, String *buf); uint get_dup_key(int error); + bool has_dup_ref() const; /** Retrieves the names of the table and the key for which there was a duplicate entry in the case of HA_ERR_FOREIGN_DUPLICATE_KEY. @@ -4438,7 +4441,6 @@ public: } virtual void update_create_info(HA_CREATE_INFO *create_info) {} - int check_old_types(); virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt) { return HA_ADMIN_NOT_IMPLEMENTED; } virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt) @@ -5130,9 +5132,12 @@ public: } inline void ha_handler_stats_disable() { - handler_stats= 0; - active_handler_stats.active= 0; - handler_stats_updated(); + if (handler_stats) + { + handler_stats= 0; + active_handler_stats.active= 0; + handler_stats_updated(); + } } private: @@ -5146,6 +5151,7 @@ private: } } + bool check_old_types() const; void mark_trx_read_write_internal(); bool check_table_binlog_row_based_internal(); @@ -5391,8 +5397,8 @@ public: virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt) { return HA_ADMIN_NOT_IMPLEMENTED; } virtual bool check_and_repair(THD *thd) { return TRUE; } - virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; } - virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; } + virtual int disable_indexes(key_map map, bool persist) { return HA_ERR_WRONG_COMMAND; } + virtual int enable_indexes(key_map map, bool persist) { return HA_ERR_WRONG_COMMAND; } virtual int discard_or_import_tablespace(my_bool discard) { return (my_errno=HA_ERR_WRONG_COMMAND); } virtual void drop_table(const char *name); diff --git a/sql/item.cc b/sql/item.cc index 54ad511cb6b..1e3f7e8e27f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -27,6 +27,7 @@ #include "sp_rcontext.h" #include "sp_head.h" #include "sql_trigger.h" +#include "sql_parse.h" #include "sql_select.h" #include "sql_show.h" // append_identifier #include "sql_view.h" // VIEW_ANY_SQL @@ -495,7 +496,10 @@ void Item::print_parenthesised(String *str, enum_query_type query_type, bool need_parens= precedence() < parent_prec; if (need_parens) str->append('('); - print(str, query_type); + if (check_stack_overrun(current_thd, STACK_MIN_SIZE, NULL)) + str->append(STRING_WITH_LEN("")); + else + print(str, query_type); if (need_parens) str->append(')'); } @@ -4084,7 +4088,9 @@ Item_param::Item_param(THD *thd, const LEX_CSTRING *name_arg, as an actual parameter. See Item_param::set_from_item(). */ m_is_settable_routine_parameter(true), - m_clones(thd->mem_root) + m_clones(thd->mem_root), + m_associated_field(nullptr), + m_default_field(nullptr) { name= *name_arg; /* @@ -4491,10 +4497,29 @@ int Item_param::save_in_field(Field *field, bool no_conversions) case NULL_VALUE: return set_field_to_null_with_conversions(field, no_conversions); case DEFAULT_VALUE: + if (m_associated_field) + return assign_default(field); return field->save_in_field_default_value(field->table->pos_in_table_list-> top_table() != field->table->pos_in_table_list); case IGNORE_VALUE: + if (m_associated_field) + { + switch (find_ignore_reaction(field->table->in_use)) + { + case IGNORE_MEANS_DEFAULT: + DBUG_ASSERT(0); // impossible now, but fully working code if needed + return assign_default(field); + case IGNORE_MEANS_FIELD_VALUE: + m_associated_field->save_val(field); + return false; + default: + ; // fall through to error + } + DBUG_ASSERT(0); //impossible + my_error(ER_INVALID_DEFAULT_PARAM, MYF(0)); + return true; + } return field->save_in_field_ignore_value(field->table->pos_in_table_list-> top_table() != field->table->pos_in_table_list); @@ -5078,6 +5103,92 @@ bool Item_param::append_for_log(THD *thd, String *str) } +/** + Allocate a memory and create on it a copy of Field object. + + @param thd thread handler + @param field_arg an instance of Field the new Field object be based on + + @return a new created Field object on success, nullptr on error. +*/ + +static Field *make_default_field(THD *thd, Field *field_arg) +{ + Field *def_field; + + if (!(def_field= (Field*) thd->alloc(field_arg->size_of()))) + return nullptr; + + memcpy((void *)def_field, (void *)field_arg, field_arg->size_of()); + def_field->reset_fields(); + // If non-constant default value expression or a blob + if (def_field->default_value && + (def_field->default_value->flags || (def_field->flags & BLOB_FLAG))) + { + uchar *newptr= (uchar*) thd->alloc(1+def_field->pack_length()); + if (!newptr) + return nullptr; + + if (should_mark_column(thd->column_usage)) + def_field->default_value->expr->update_used_tables(); + def_field->move_field(newptr + 1, def_field->maybe_null() ? newptr : 0, 1); + } + else + def_field->move_field_offset((my_ptrdiff_t) + (def_field->table->s->default_values - + def_field->table->record[0])); + return def_field; +} + + +/** + Assign a default value of a table column to the positional parameter that + is performed on execution of a prepared statement with the clause + 'USING DEFAULT' + + @param field a field that should be assigned an actual value of positional + parameter passed via the clause 'USING DEFAULT' + + @return false on success, true on failure +*/ + +bool Item_param::assign_default(Field *field) +{ + DBUG_ASSERT(m_associated_field); + + if (m_associated_field->field->flags & NO_DEFAULT_VALUE_FLAG) + { + my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), + m_associated_field->field->field_name.str); + return true; + } + + if (!m_default_field) + { + m_default_field= make_default_field(field->table->in_use, + m_associated_field->field); + + if (!m_default_field) + return true; + } + + if (m_default_field->default_value) + { + return m_default_field->default_value->expr->save_in_field(field, 0); + } + else if (m_default_field->is_null()) + { + field->set_null(); + return false; + } + else + { + field->set_notnull(); + return field_conv(field, m_default_field); + } +} + + /**************************************************************************** Item_copy_string ****************************************************************************/ @@ -6901,6 +7012,7 @@ Item_basic_constant * Item_string::make_string_literal_concat(THD *thd, const LEX_CSTRING *str) { append(str->str, (uint32) str->length); + set_name(thd, &str_value); if (!(collation.repertoire & MY_REPERTOIRE_EXTENDED)) { // If the string has been pure ASCII so far, check the new part. @@ -9615,69 +9727,10 @@ bool Item_default_value::update_func_default_processor(void *) bool Item_default_value::fix_fields(THD *thd, Item **items) { - Item *real_arg; - Item_field *field_arg; - Field *def_field; DBUG_ASSERT(fixed() == 0); DBUG_ASSERT(arg); - /* - DEFAULT() do not need table field so should not ask handler to bring - field value (mark column for read) - */ - enum_column_usage save_column_usage= thd->column_usage; - /* - Fields which has defult value could be read, so it is better hide system - invisible columns. - */ - thd->column_usage= COLUMNS_WRITE; - if (arg->fix_fields_if_needed(thd, &arg)) - { - thd->column_usage= save_column_usage; - goto error; - } - thd->column_usage= save_column_usage; - - real_arg= arg->real_item(); - if (real_arg->type() != FIELD_ITEM) - { - my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), arg->name.str); - goto error; - } - - field_arg= (Item_field *)real_arg; - if ((field_arg->field->flags & NO_DEFAULT_VALUE_FLAG)) - { - my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), - field_arg->field->field_name.str); - goto error; - } - if (!(def_field= (Field*) thd->alloc(field_arg->field->size_of()))) - goto error; - memcpy((void *)def_field, (void *)field_arg->field, - field_arg->field->size_of()); - def_field->reset_fields(); - // If non-constant default value expression or a blob - if (def_field->default_value && - (def_field->default_value->flags || (def_field->flags & BLOB_FLAG))) - { - uchar *newptr= (uchar*) thd->alloc(1+def_field->pack_length()); - if (!newptr) - goto error; - if (should_mark_column(thd->column_usage)) - def_field->default_value->expr->update_used_tables(); - def_field->move_field(newptr+1, def_field->maybe_null() ? newptr : 0, 1); - } - else - def_field->move_field_offset((my_ptrdiff_t) - (def_field->table->s->default_values - - def_field->table->record[0])); - set_field(def_field); - return FALSE; - -error: - context->process_error(thd); - return TRUE; + return tie_field(thd); } void Item_default_value::cleanup() @@ -9866,6 +9919,79 @@ Item *Item_default_value::transform(THD *thd, Item_transformer transformer, } +bool Item_default_value:: + associate_with_target_field(THD *thd, + Item_field *field __attribute__((unused))) +{ + m_associated= true; + /* + arg set correctly in constructor (can also differ from field if + it is function with an argument) + */ + return tie_field(thd); +} + + +/** + Call fix_fields for an item representing the default value, create + an instance of Field for representing the default value and assign it + to the Item_field::field. + + @param thd thread handler + + @return false on success, true on error +*/ + +bool Item_default_value::tie_field(THD *thd) +{ + Item *real_arg; + Item_field *field_arg; + Field *def_field; + + /* + DEFAULT() do not need table field so should not ask handler to bring + field value (mark column for read) + */ + enum_column_usage save_column_usage= thd->column_usage; + /* + Fields which has defult value could be read, so it is better hide system + invisible columns. + */ + thd->column_usage= COLUMNS_WRITE; + if (arg->fix_fields_if_needed(thd, &arg)) + { + thd->column_usage= save_column_usage; + goto error; + } + thd->column_usage= save_column_usage; + + real_arg= arg->real_item(); + if (real_arg->type() != FIELD_ITEM) + { + my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), arg->name.str); + goto error; + } + + field_arg= (Item_field *)real_arg; + if ((field_arg->field->flags & NO_DEFAULT_VALUE_FLAG)) + { + my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), + field_arg->field->field_name.str); + goto error; + } + def_field= make_default_field(thd, field_arg->field); + if (!def_field) + goto error; + + set_field(def_field); + return false; + +error: + context->process_error(thd); + return true; + +} + bool Item_insert_value::eq(const Item *item, bool binary_cmp) const { return item->type() == INSERT_VALUE_ITEM && diff --git a/sql/item.h b/sql/item.h index 2d9cf135a80..d7df867028c 100644 --- a/sql/item.h +++ b/sql/item.h @@ -946,7 +946,7 @@ protected: const Tmp_field_param *param, bool is_explicit_null); - void raise_error_not_evaluable(); + virtual void raise_error_not_evaluable(); void push_note_converted_to_negative_complement(THD *thd); void push_note_converted_to_positive_complement(THD *thd); @@ -2739,6 +2739,18 @@ public: Checks if this item consists in the left part of arg IN subquery predicate */ bool pushable_equality_checker_for_subquery(uchar *arg); + + /** + This method is to set relationship between a positional parameter + represented by the '?' and an actual argument value passed to the + call of PS/SP by the USING clause. The method is overridden in classes + Item_param and Item_default_value. + */ + virtual bool associate_with_target_field(THD *, Item_field *) + { + DBUG_ASSERT(fixed()); + return false; + } }; MEM_ROOT *get_thd_memroot(THD *thd); @@ -4142,6 +4154,12 @@ public: Item_param(THD *thd, const LEX_CSTRING *name_arg, uint pos_in_query_arg, uint len_in_query_arg); + void cleanup() override + { + m_default_field= NULL; + Item::cleanup(); + } + Type type() const override { // Don't pretend to be a constant unless value for this item is set. @@ -4346,6 +4364,10 @@ public: void sync_clones(); bool register_clone(Item_param *i) { return m_clones.push_back(i); } + void raise_error_not_evaluable() override + { + invalid_default_param(); + } private: void invalid_default_param() const; bool set_value(THD *thd, sp_rcontext *ctx, Item **it) override; @@ -4356,6 +4378,17 @@ public: Item_param *get_item_param() override { return this; } void make_send_field(THD *thd, Send_field *field) override; + /** + See comments on @see Item::associate_with_target_field for method + description + */ + bool associate_with_target_field(THD *, Item_field *field) override + { + m_associated_field= field; + return false; + } + bool assign_default(Field *field); + private: Send_field *m_out_param_info; bool m_is_settable_routine_parameter; @@ -4365,6 +4398,8 @@ private: synchronize the actual value of the parameter with the values of the clones. */ Mem_root_array m_clones; + Item_field *m_associated_field; + Field *m_default_field; }; @@ -6087,6 +6122,8 @@ class Item_direct_view_ref :public Item_direct_ref if (!view->is_inner_table_of_outer_join() || !(null_ref_table= view->get_real_join_table())) null_ref_table= NO_NULL_TABLE; + if (null_ref_table && null_ref_table != NO_NULL_TABLE) + set_maybe_null(); } bool check_null_ref() @@ -6727,6 +6764,8 @@ public: class Item_default_value : public Item_field { bool vcol_assignment_ok; + bool m_associated= false; + void calculate(); public: Item *arg= nullptr; @@ -6795,6 +6834,15 @@ public: override; Field *create_tmp_field_ex(MEM_ROOT *root, TABLE *table, Tmp_field_src *src, const Tmp_field_param *param) override; + + /** + See comments on @see Item::associate_with_target_field for method + description + */ + bool associate_with_target_field(THD *thd, Item_field *field) override; + +private: + bool tie_field(THD *thd); }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index d1891818cd6..880634fca87 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1444,7 +1444,13 @@ bool Item_in_optimizer::fix_left(THD *thd) eval_not_null_tables(NULL); with_flags|= (args[0]->with_flags | (args[1]->with_flags & item_with_t::SP_VAR)); - if ((const_item_cache= args[0]->const_item())) + + /* + If left expression is a constant, cache its value. + But don't do that if that involves computing a subquery, as we are in a + prepare-phase rewrite. + */ + if ((const_item_cache= args[0]->const_item()) && !args[0]->with_subquery()) { cache->store(args[0]); cache->cache_value(); @@ -6179,8 +6185,8 @@ bool Regexp_processor_pcre::compile(String *pattern, bool send_error) if (!stringcmp(pattern, &m_prev_pattern)) return false; cleanup(); - m_prev_pattern.copy(*pattern); } + m_prev_pattern.copy(*pattern); if (!(pattern= convert_if_needed(pattern, &pattern_converter))) return true; @@ -6326,7 +6332,17 @@ bool Regexp_processor_pcre::exec(Item *item, int offset, } -void Regexp_processor_pcre::fix_owner(Item_func *owner, +/* + This method determines the owner's maybe_null flag. + Generally, the result is NULL-able. However, in case + of a constant pattern and a NOT NULL subject, the + result can also be NOT NULL. + @return true - in case if the constant regex compilation failed + (e.g. due to a wrong regex syntax in the pattern). + The compilation error message is put to the DA in this case. + false - otherwise. +*/ +bool Regexp_processor_pcre::fix_owner(Item_func *owner, Item *subject_arg, Item *pattern_arg) { @@ -6334,16 +6350,30 @@ void Regexp_processor_pcre::fix_owner(Item_func *owner, pattern_arg->const_item() && !pattern_arg->is_expensive()) { - if (compile(pattern_arg, true)) + if (compile(pattern_arg, true/* raise errors to DA, e.g. on bad syntax */)) { owner->set_maybe_null(); // Will always return NULL - return; + if (pattern_arg->null_value) + { + /* + The pattern evaluated to NULL. Regex compilation did not happen. + No errors were put to DA. Continue with maybe_null==true. + The function will return NULL per row. + */ + return false; + } + /* + A syntax error in the pattern, an error was raised to the DA. + Let's abort the query. The caller will send the error to the client. + */ + return true; } set_const(true); owner->base_flags|= subject_arg->base_flags & item_base_t::MAYBE_NULL; } else owner->set_maybe_null(); + return false; } @@ -6355,8 +6385,7 @@ Item_func_regex::fix_length_and_dec(THD *thd) return TRUE; re.init(cmp_collation.collation, 0); - re.fix_owner(this, args[0], args[1]); - return FALSE; + return re.fix_owner(this, args[0], args[1]); } @@ -6380,9 +6409,8 @@ Item_func_regexp_instr::fix_length_and_dec(THD *thd) return TRUE; re.init(cmp_collation.collation, 0); - re.fix_owner(this, args[0], args[1]); max_length= MY_INT32_NUM_DECIMAL_DIGITS; // See also Item_func_locate - return FALSE; + return re.fix_owner(this, args[0], args[1]); } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 3cd156afad9..7bcb24d0cbb 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -3061,7 +3061,7 @@ public: {} int default_regex_flags(); void init(CHARSET_INFO *data_charset, int extra_flags); - void fix_owner(Item_func *owner, Item *subject_arg, Item *pattern_arg); + bool fix_owner(Item_func *owner, Item *subject_arg, Item *pattern_arg); bool compile(String *pattern, bool send_error); bool compile(Item *item, bool send_error); bool recompile(Item *item) @@ -3530,13 +3530,11 @@ template class LI, typename T> class Item_equal_iterator { protected: Item_equal *item_equal; - Item *curr_item; + Item *curr_item= nullptr; public: Item_equal_iterator(Item_equal &item_eq) - :LI (item_eq.equal_items) + :LI (item_eq.equal_items), item_equal(&item_eq) { - curr_item= NULL; - item_equal= &item_eq; if (item_eq.with_const) { LI *list_it= this; diff --git a/sql/item_create.cc b/sql/item_create.cc index b302a42dae8..a347f49acee 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -3181,8 +3181,12 @@ Item* Create_func_aes_encrypt::create_native(THD *thd, const LEX_CSTRING *name, List *item_list) { - uint arg_count= item_list->elements; Item *a[4]; + uint arg_count= 0; + + if (item_list != NULL) + arg_count= item_list->elements; + for (uint i=0; i < MY_MIN(array_elements(a), arg_count); i++) a[i]= item_list->pop(); switch (arg_count) @@ -3205,8 +3209,12 @@ Item* Create_func_aes_decrypt::create_native(THD *thd, const LEX_CSTRING *name, List *item_list) { - uint arg_count= item_list->elements; Item *a[4]; + uint arg_count= 0; + + if (item_list != NULL) + arg_count= item_list->elements; + for (uint i=0; i < MY_MIN(array_elements(a), arg_count); i++) a[i]= item_list->pop(); switch (arg_count) diff --git a/sql/item_func.cc b/sql/item_func.cc index b6139c96848..4cd4b3b7499 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -72,6 +72,9 @@ bool check_reserved_words(const LEX_CSTRING *name) return FALSE; } +void pause_execution(THD *thd, double timeout); +static int do_pause(THD *thd, Interruptible_wait *timed_cond, + mysql_cond_t *cond, double timeout); /** Test if the sum of arguments overflows the ulonglong range. @@ -1917,6 +1920,18 @@ void Item_func_abs::fix_length_and_dec_int() set_handler(type_handler_long_or_longlong()); } +void Item_func_abs::fix_length_and_dec_sint_ge0() +{ + /* + We're converting slong_ge0 to slong/slonglong. + Add one character for the sign into max_length. + */ + max_length= args[0]->decimal_precision() + 1/*sign*/; + DBUG_ASSERT(!args[0]->unsigned_flag); + unsigned_flag= false; + set_handler(type_handler_long_or_longlong()); +} + void Item_func_abs::fix_length_and_dec_double() { @@ -2594,6 +2609,22 @@ void Item_func_round::fix_arg_int(const Type_handler *preferred, } +void Item_func_round::fix_arg_slong_ge0() +{ + DBUG_ASSERT(!args[0]->unsigned_flag); + DBUG_ASSERT(args[0]->decimals == 0); + Type_std_attributes::set(args[0]); + /* + We're converting the data type from slong_ge0 to slong/slonglong. + Add one character for the sign, + to change max_length notation from "max_length digits" to + "max_length-1 digits and the sign". + */ + max_length+= 1/*sign*/ + test_if_length_can_increase(); + set_handler(type_handler_long_or_longlong()); +} + + void Item_func_round::fix_arg_hex_hybrid() { DBUG_ASSERT(args[0]->decimals == 0); @@ -2610,12 +2641,12 @@ void Item_func_round::fix_arg_hex_hybrid() } -double my_double_round(double value, longlong dec, bool dec_unsigned, +double my_double_round(double value, longlong dec_value, bool dec_unsigned, bool truncate) { double tmp; - bool dec_negative= (dec < 0) && !dec_unsigned; - ulonglong abs_dec= dec_negative ? -dec : dec; + const Longlong_hybrid dec(dec_value, dec_unsigned); + const ulonglong abs_dec= dec.abs(); /* tmp2 is here to avoid return the value with 80 bit precision This will fix that the test round(0.1,1) = round(0.1,1) is true @@ -2630,22 +2661,24 @@ double my_double_round(double value, longlong dec, bool dec_unsigned, volatile double value_div_tmp= value / tmp; volatile double value_mul_tmp= value * tmp; - if (!dec_negative && std::isinf(tmp)) // "dec" is too large positive number + if (!dec.neg() && std::isinf(tmp)) // "dec" is a too large positive number return value; - if (dec_negative && std::isinf(tmp)) - tmp2= 0.0; - else if (!dec_negative && std::isinf(value_mul_tmp)) + if (dec.neg() && std::isinf(tmp)) // "dec" is a too small negative number + return 0.0; + + // Handle "dec" with a reasonably small absolute value + if (!dec.neg() && std::isinf(value_mul_tmp)) tmp2= value; else if (truncate) { if (value >= 0.0) - tmp2= dec < 0 ? floor(value_div_tmp) * tmp : floor(value_mul_tmp) / tmp; + tmp2= dec.neg() ? floor(value_div_tmp) * tmp : floor(value_mul_tmp) / tmp; else - tmp2= dec < 0 ? ceil(value_div_tmp) * tmp : ceil(value_mul_tmp) / tmp; + tmp2= dec.neg() ? ceil(value_div_tmp) * tmp : ceil(value_mul_tmp) / tmp; } else - tmp2=dec < 0 ? rint(value_div_tmp) * tmp : rint(value_mul_tmp) / tmp; + tmp2=dec.neg() ? rint(value_div_tmp) * tmp : rint(value_mul_tmp) / tmp; return tmp2; } @@ -2994,7 +3027,7 @@ double Item_func_min_max::val_real_native() value=tmp; } if ((null_value= args[i]->null_value)) - break; + return 0; } return value; } @@ -3015,7 +3048,7 @@ longlong Item_func_min_max::val_int_native() value=tmp; } if ((null_value= args[i]->null_value)) - break; + return 0; } return value; } @@ -3540,6 +3573,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, initid.const_item=func->const_item_cache; initid.decimals=func->decimals; initid.ptr=0; + not_original=0; for (uint i1= 0 ; i1 < arg_count ; i1++) buffers[i1].set_thread_specific(); @@ -4583,32 +4617,7 @@ longlong Item_func_sleep::val_int() if (timeout < 0.00001) return 0; - timed_cond.set_timeout((ulonglong) (timeout * 1000000000.0)); - - mysql_cond_init(key_item_func_sleep_cond, &cond, NULL); - mysql_mutex_lock(&LOCK_item_func_sleep); - - THD_STAGE_INFO(thd, stage_user_sleep); - thd->mysys_var->current_mutex= &LOCK_item_func_sleep; - thd->mysys_var->current_cond= &cond; - - error= 0; - thd_wait_begin(thd, THD_WAIT_SLEEP); - while (!thd->killed) - { - error= timed_cond.wait(&cond, &LOCK_item_func_sleep); - if (error == ETIMEDOUT || error == ETIME) - break; - error= 0; - } - thd_wait_end(thd); - mysql_mutex_unlock(&LOCK_item_func_sleep); - mysql_mutex_lock(&thd->mysys_var->mutex); - thd->mysys_var->current_mutex= 0; - thd->mysys_var->current_cond= 0; - mysql_mutex_unlock(&thd->mysys_var->mutex); - - mysql_cond_destroy(&cond); + error= do_pause(thd, &timed_cond, &cond, timeout); #ifdef ENABLED_DEBUG_SYNC DBUG_EXECUTE_IF("sleep_inject_query_done_debug_sync", { @@ -4793,7 +4802,9 @@ Item_func_set_user_var::fix_length_and_dec(THD *thd) if (args[0]->collation.derivation == DERIVATION_NUMERIC) { collation.set(DERIVATION_NUMERIC); - fix_length_and_charset(args[0]->max_char_length(), &my_charset_numeric); + uint sign_length= args[0]->type_handler() == &type_handler_slong_ge0 ? 1: 0; + fix_length_and_charset(args[0]->max_char_length() + sign_length, + &my_charset_numeric); } else { @@ -7297,3 +7308,43 @@ void fix_rownum_pointers(THD *thd, SELECT_LEX *select_lex, ha_rows *ptr) ((Item_func_rownum*) item)->store_pointer_to_row_counter(ptr); } } + +static int do_pause(THD *thd, Interruptible_wait *timed_cond, mysql_cond_t *cond, double timeout) +{ + int error= 0; + timed_cond->set_timeout((ulonglong) (timeout * 1000000000.0)); + + mysql_cond_init(key_item_func_sleep_cond, cond, NULL); + mysql_mutex_lock(&LOCK_item_func_sleep); + + THD_STAGE_INFO(thd, stage_user_sleep); + thd->mysys_var->current_mutex= &LOCK_item_func_sleep; + thd->mysys_var->current_cond= cond; + + thd_wait_begin(thd, THD_WAIT_SLEEP); + while (!thd->killed) + { + error= timed_cond->wait(cond, &LOCK_item_func_sleep); + if (error == ETIMEDOUT || error == ETIME) + break; + error= 0; + } + thd_wait_end(thd); + mysql_mutex_unlock(&LOCK_item_func_sleep); + mysql_mutex_lock(&thd->mysys_var->mutex); + thd->mysys_var->current_mutex= 0; + thd->mysys_var->current_cond= 0; + mysql_mutex_unlock(&thd->mysys_var->mutex); + + mysql_cond_destroy(cond); + + return error; +} + +void pause_execution(THD *thd, double timeout) +{ + Interruptible_wait timed_cond(thd); + mysql_cond_t cond; + + do_pause(thd, &timed_cond, &cond, timeout); +} diff --git a/sql/item_func.h b/sql/item_func.h index 79ad8fb7d05..cdcbddba273 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -91,7 +91,7 @@ public: static void wrong_param_count_error(const LEX_CSTRING &schema_name, const LEX_CSTRING &func_name); - table_map not_null_tables_cache; + table_map not_null_tables_cache= 0; enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC, GE_FUNC,GT_FUNC,FT_FUNC, @@ -1266,6 +1266,24 @@ public: }; +class Item_long_ge0_func: public Item_int_func +{ +public: + Item_long_ge0_func(THD *thd): Item_int_func(thd) { } + Item_long_ge0_func(THD *thd, Item *a): Item_int_func(thd, a) {} + Item_long_ge0_func(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {} + Item_long_ge0_func(THD *thd, Item *a, Item *b, Item *c): Item_int_func(thd, a, b, c) {} + Item_long_ge0_func(THD *thd, List &list): Item_int_func(thd, list) { } + Item_long_ge0_func(THD *thd, Item_long_ge0_func *item) :Item_int_func(thd, item) {} + const Type_handler *type_handler() const override + { + DBUG_ASSERT(!unsigned_flag); + return &type_handler_slong_ge0; + } + bool fix_length_and_dec(THD *) override { max_length= 10; return FALSE; } +}; + + class Item_func_hash: public Item_int_func { public: @@ -1410,6 +1428,13 @@ public: { fix_char_length(MAX_BIGINT_WIDTH); } + void fix_length_and_dec_sint_ge0() + { + uint32 digits= args[0]->decimal_precision(); + DBUG_ASSERT(digits > 0); + DBUG_ASSERT(digits <= MY_INT64_NUM_DECIMAL_DIGITS); + fix_char_length(digits + (unsigned_flag ? 0 : 1/*sign*/)); + } void fix_length_and_dec_generic() { uint32 char_length= MY_MIN(args[0]->max_char_length(), @@ -1826,6 +1851,7 @@ public: return name; } void fix_length_and_dec_int(); + void fix_length_and_dec_sint_ge0(); void fix_length_and_dec_double(); void fix_length_and_dec_decimal(); bool fix_length_and_dec(THD *thd) override; @@ -2155,6 +2181,7 @@ public: void fix_arg_int(const Type_handler *preferred, const Type_std_attributes *preferred_attributes, bool use_decimal_on_length_increase); + void fix_arg_slong_ge0(); void fix_arg_hex_hybrid(); void fix_arg_double(); void fix_arg_time(); @@ -4291,6 +4318,7 @@ public: { return get_item_copy(thd, this); } }; +class Interruptible_wait; Item *get_system_var(THD *thd, enum_var_type var_type, const LEX_CSTRING *name, const LEX_CSTRING *component); diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index f2f76846341..ed07ad4ab26 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -25,6 +25,32 @@ static bool get_current_value(json_engine_t *, const uchar *&, size_t &); static int check_overlaps(json_engine_t *, json_engine_t *, bool); static int json_find_overlap_with_object(json_engine_t *, json_engine_t *, bool); +#ifndef DBUG_OFF +static int dbug_json_check_min_stack_requirement() +{ + my_error(ER_STACK_OVERRUN_NEED_MORE, MYF(ME_FATAL), + my_thread_stack_size, my_thread_stack_size, STACK_MIN_SIZE); + return 1; +} +#endif + +extern void pause_execution(THD *thd, double timeout); + +/* + Allocating memory and *also* using it (reading and + writing from it) because some build instructions cause + compiler to optimize out stack_used_up. Since alloca() + here depends on stack_used_up, it doesnt get executed + correctly and causes json_debug_nonembedded to fail + ( --error ER_STACK_OVERRUN_NEED_MORE does not occur). +*/ + +#define JSON_DO_PAUSE_EXECUTION(A, B) do \ + { \ + DBUG_EXECUTE_IF("json_pause_execution", \ + { pause_execution(A, B); }); \ + } while(0) + /* Compare ASCII string against the string with the specified character set. @@ -142,11 +168,8 @@ int json_path_parts_compare( const json_path_step_t *temp_b= b; DBUG_EXECUTE_IF("json_check_min_stack_requirement", - { - long arbitrary_var; - long stack_used_up= (available_stack_size(current_thd->thread_stack, &arbitrary_var)); - ALLOCATE_MEM_ON_STACK(my_thread_stack_size-stack_used_up-STACK_MIN_SIZE); - }); + return dbug_json_check_min_stack_requirement();); + if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL)) return 1; @@ -843,7 +866,7 @@ bool Item_func_json_unquote::fix_length_and_dec(THD *thd) { collation.set(&my_charset_utf8mb3_general_ci, DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); - max_length= args[0]->max_length; + max_length= args[0]->max_char_length() * collation.collation->mbmaxlen; set_maybe_null(); return FALSE; } @@ -996,16 +1019,17 @@ bool Item_func_json_extract::fix_length_and_dec(THD *thd) } -static bool path_exact(const json_path_with_flags *paths_list, int n_paths, +static int path_exact(const json_path_with_flags *paths_list, int n_paths, const json_path_t *p, json_value_types vt, const int *array_size_counter) { + int count_path= 0; for (; n_paths > 0; n_paths--, paths_list++) { if (json_path_compare(&paths_list->p, p, vt, array_size_counter) == 0) - return TRUE; + count_path++; } - return FALSE; + return count_path; } @@ -1030,7 +1054,7 @@ String *Item_func_json_extract::read_json(String *str, json_engine_t je, sav_je; json_path_t p; const uchar *value; - int not_first_value= 0; + int not_first_value= 0, count_path= 0; uint n_arg; size_t v_len; int possible_multiple_values; @@ -1089,7 +1113,8 @@ String *Item_func_json_extract::read_json(String *str, array_size_counter + (p.last_step - p.steps))) goto error; - if (!path_exact(paths, arg_count-1, &p, je.value_type, array_size_counter)) + if (!(count_path= path_exact(paths, arg_count-1, &p, je.value_type, + array_size_counter))) continue; value= je.value_begin; @@ -1119,9 +1144,12 @@ String *Item_func_json_extract::read_json(String *str, je= sav_je; } - if ((not_first_value && str->append(", ", 2)) || - str->append((const char *) value, v_len)) - goto error; /* Out of memory. */ + for (int count= 0; count < count_path; count++) + { + if (str->append((const char *) value, v_len) || + str->append(", ", 2)) + goto error; /* Out of memory. */ + } not_first_value= 1; @@ -1142,6 +1170,11 @@ String *Item_func_json_extract::read_json(String *str, goto return_null; } + if (str->length()>2) + { + str->chop(); + str->chop(); + } if (possible_multiple_values && str->append(']')) goto error; /* Out of memory. */ @@ -1304,11 +1337,7 @@ static int check_contains(json_engine_t *js, json_engine_t *value) json_engine_t loc_js; bool set_js; DBUG_EXECUTE_IF("json_check_min_stack_requirement", - { - long arbitrary_var; - long stack_used_up= (available_stack_size(current_thd->thread_stack, &arbitrary_var)); - ALLOCATE_MEM_ON_STACK(my_thread_stack_size-stack_used_up-STACK_MIN_SIZE); - }); + return dbug_json_check_min_stack_requirement();); if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL)) return 1; @@ -1910,7 +1939,23 @@ bool Item_func_json_array::fix_length_and_dec(THD *thd) return TRUE; for (n_arg=0 ; n_arg < arg_count ; n_arg++) - char_length+= static_cast(args[n_arg]->max_char_length()) + 4; + { + ulonglong arg_length; + Item *arg= args[n_arg]; + + if (arg->result_type() == STRING_RESULT && + !Type_handler_json_common::is_json_type_handler(arg->type_handler())) + arg_length= arg->max_char_length() * 2; /*escaping possible */ + else if (arg->type_handler()->is_bool_type()) + arg_length= 5; + else + arg_length= arg->max_char_length(); + + if (arg_length < 4) + arg_length= 4; /* can be 'null' */ + + char_length+= arg_length + 4; + } fix_char_length_ulonglong(char_length); tmp_val.set_charset(collation.collation); @@ -1960,6 +2005,8 @@ err_return: bool Item_func_json_array_append::fix_length_and_dec(THD *thd) { + JSON_DO_PAUSE_EXECUTION(thd, 0.0002); + uint n_arg; ulonglong char_length; @@ -2118,6 +2165,8 @@ String *Item_func_json_array_insert::val_str(String *str) uint n_arg, n_path; THD *thd= current_thd; + JSON_DO_PAUSE_EXECUTION(thd, 0.0002); + DBUG_ASSERT(fixed()); if ((null_value= args[0]->null_value)) @@ -2307,13 +2356,8 @@ err_return: static int do_merge(String *str, json_engine_t *je1, json_engine_t *je2) { - DBUG_EXECUTE_IF("json_check_min_stack_requirement", - { - long arbitrary_var; - long stack_used_up= (available_stack_size(current_thd->thread_stack, &arbitrary_var)); - ALLOCATE_MEM_ON_STACK(my_thread_stack_size-stack_used_up-STACK_MIN_SIZE); - }); + return dbug_json_check_min_stack_requirement();); if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL)) return 1; @@ -2528,6 +2572,8 @@ String *Item_func_json_merge::val_str(String *str) THD *thd= current_thd; LINT_INIT(js2); + JSON_DO_PAUSE_EXECUTION(thd, 0.0002); + if (args[0]->null_value) goto null_return; @@ -2652,11 +2698,7 @@ static int do_merge_patch(String *str, json_engine_t *je1, json_engine_t *je2, bool *empty_result) { DBUG_EXECUTE_IF("json_check_min_stack_requirement", - { - long arbitrary_var; - long stack_used_up= (available_stack_size(current_thd->thread_stack, &arbitrary_var)); - ALLOCATE_MEM_ON_STACK(my_thread_stack_size-stack_used_up-STACK_MIN_SIZE); - }); + return dbug_json_check_min_stack_requirement();); if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL)) return 1; @@ -2841,6 +2883,8 @@ String *Item_func_json_merge_patch::val_str(String *str) bool empty_result, merge_to_null; THD *thd= current_thd; + JSON_DO_PAUSE_EXECUTION(thd, 0.0002); + /* To report errors properly if some JSON is invalid. */ je1.s.error= je2.s.error= 0; merge_to_null= args[0]->null_value; @@ -3118,6 +3162,12 @@ String *Item_func_json_type::val_str(String *str) break; } + /* ensure the json is at least valid. */ + while(json_scan_next(&je) == 0) {} + + if (je.s.error) + goto error; + str->set(type, strlen(type), &my_charset_utf8mb3_general_ci); return str; @@ -3133,14 +3183,20 @@ bool Item_func_json_insert::fix_length_and_dec(THD *thd) uint n_arg; ulonglong char_length; + JSON_DO_PAUSE_EXECUTION(thd, 0.0002); + collation.set(args[0]->collation); char_length= args[0]->max_char_length(); for (n_arg= 1; n_arg < arg_count; n_arg+= 2) { paths[n_arg/2].set_constant_flag(args[n_arg]->const_item()); - char_length+= - static_cast(args[n_arg+1]->max_char_length()) + 4; + /* + In the resulting JSON we can insert the property + name from the path, and the value itself. + */ + char_length+= args[n_arg/2]->max_char_length() + 6; + char_length+= args[n_arg/2+1]->max_char_length() + 4; } fix_char_length_ulonglong(char_length); @@ -3423,6 +3479,8 @@ String *Item_func_json_remove::val_str(String *str) DBUG_ASSERT(fixed()); + JSON_DO_PAUSE_EXECUTION(thd, 0.0002); + if (args[0]->null_value) goto null_return; @@ -3474,6 +3532,7 @@ String *Item_func_json_remove::val_str(String *str) { if (je.s.error) goto js_error; + continue; } if (json_read_value(&je)) @@ -3985,7 +4044,20 @@ bool Item_func_json_format::fix_length_and_dec(THD *thd) { decimals= 0; collation.set(args[0]->collation); - max_length= args[0]->max_length; + switch (fmt) + { + case COMPACT: + max_length= args[0]->max_length; + break; + case LOOSE: + max_length= args[0]->max_length * 2; + break; + case DETAILED: + max_length= MAX_BLOB_WIDTH; + break; + default: + DBUG_ASSERT(0); + }; set_maybe_null(); return FALSE; } @@ -4705,11 +4777,7 @@ static int json_find_overlap_with_object(json_engine_t *js, json_engine_t *value static int check_overlaps(json_engine_t *js, json_engine_t *value, bool compare_whole) { DBUG_EXECUTE_IF("json_check_min_stack_requirement", - { - long arbitrary_var; - long stack_used_up= (available_stack_size(current_thd->thread_stack, &arbitrary_var)); - ALLOCATE_MEM_ON_STACK(my_thread_stack_size-stack_used_up-STACK_MIN_SIZE); - }); + return dbug_json_check_min_stack_requirement();); if (check_stack_overrun(current_thd, STACK_MIN_SIZE , NULL)) return 1; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 2a1bfbf66b8..462a6d381a3 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -913,7 +913,7 @@ bool Item_func_des_encrypt::fix_length_and_dec(THD *thd) String *Item_func_des_encrypt::val_str(String *str) { DBUG_ASSERT(fixed()); -#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) +#if defined(HAVE_des) && !defined(EMBEDDED_LIBRARY) uint code= ER_WRONG_PARAMETERS_TO_PROCEDURE; DES_cblock ivec; struct st_des_keyblock keyblock; @@ -1002,8 +1002,8 @@ error: THD *thd= current_thd; push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_FEATURE_DISABLED, ER_THD(thd, ER_FEATURE_DISABLED), - "des_encrypt", "--with-ssl"); -#endif /* defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) */ + "des_encrypt", "openssl des cipher (HAVE_des)"); +#endif /* defined(HAVE_des) && !defined(EMBEDDED_LIBRARY) */ null_value=1; return 0; } @@ -1024,7 +1024,7 @@ bool Item_func_des_decrypt::fix_length_and_dec(THD *thd) String *Item_func_des_decrypt::val_str(String *str) { DBUG_ASSERT(fixed()); -#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) +#if defined(HAVE_des) && !defined(EMBEDDED_LIBRARY) uint code= ER_WRONG_PARAMETERS_TO_PROCEDURE; DES_cblock ivec; struct st_des_keyblock keyblock; @@ -1099,9 +1099,9 @@ wrong_key: THD *thd= current_thd; push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_FEATURE_DISABLED, ER_THD(thd, ER_FEATURE_DISABLED), - "des_decrypt", "--with-ssl"); + "des_decrypt", "openssl des cipher (HAVE_des)"); } -#endif /* defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) */ +#endif /* defined(HAVE_des) && !defined(EMBEDDED_LIBRARY) */ null_value=1; return 0; } @@ -1662,6 +1662,7 @@ String *Item_func_sformat::val_str(String *res) bool Item_func_random_bytes::fix_length_and_dec(THD *thd) { + set_maybe_null(); used_tables_cache|= RAND_TABLE_BIT; if (args[0]->can_eval_in_optimize()) { @@ -1803,15 +1804,16 @@ String *Item_func_regexp_replace::val_str_internal(String *str, LEX_CSTRING src, rpl; size_t startoffset= 0; - if ((null_value= - (!(source= args[0]->val_str(&tmp0)) || - !(replace= args[2]->val_str_null_to_empty(&tmp2, null_to_empty)) || - re.recompile(args[1])))) - return (String *) 0; - + source= args[0]->val_str(&tmp0); + if (!source) + goto err; + replace= args[2]->val_str_null_to_empty(&tmp2, null_to_empty); + if (!replace || re.recompile(args[1])) + goto err; if (!(source= re.convert_if_needed(source, &re.subject_converter)) || !(replace= re.convert_if_needed(replace, &re.replace_converter))) goto err; + null_value= false; source->get_value(&src); replace->get_value(&rpl); @@ -1857,7 +1859,7 @@ String *Item_func_regexp_replace::val_str_internal(String *str, err: null_value= true; - return (String *) 0; + return nullptr; } @@ -1993,13 +1995,21 @@ bool Item_func_insert::fix_length_and_dec(THD *thd) String *Item_str_conv::val_str(String *str) { DBUG_ASSERT(fixed()); - String *res; - size_t alloced_length, len; + String *res= args[0]->val_str(&tmp_value); - if ((null_value= (!(res= args[0]->val_str(&tmp_value)) || - str->alloc((alloced_length= res->length() * multiply))))) - return 0; + if (!res) + { + err: + null_value= true; + return nullptr; + } + size_t alloced_length= res->length() * multiply, len; + + if (str->alloc((alloced_length))) + goto err; + + null_value= false; len= converter(collation.collation, (char*) res->ptr(), res->length(), (char*) str->ptr(), alloced_length); DBUG_ASSERT(len <= alloced_length); @@ -4042,7 +4052,9 @@ bool Item_func_set_collation::fix_length_and_dec(THD *thd) return true; collation.set(cl.collation().charset_info(), DERIVATION_EXPLICIT, args[0]->collation.repertoire); - max_length= args[0]->max_length; + ulonglong max_char_length= (ulonglong) args[0]->max_char_length(); + fix_char_length_ulonglong(max_char_length * collation.collation->mbmaxlen); + return FALSE; } @@ -5126,6 +5138,11 @@ void Item_func_dyncol_create::print_arguments(String *str, { str->append(STRING_WITH_LEN(" charset ")); str->append(defs[i].cs->cs_name); + if (Charset(defs[i].cs).can_have_collate_clause()) + { + str->append(STRING_WITH_LEN(" collate ")); + str->append(defs[i].cs->coll_name); + } str->append(' '); } break; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 308bcb6e1ae..229136417b0 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -569,6 +569,9 @@ void Item_subselect::recalc_used_tables(st_select_lex *new_parent, This measure is used instead of JOIN::read_time, because it is considered to be much more reliable than the cost estimate. + Note: the logic in this function must agree with + JOIN::init_join_cache_and_keyread(). + @return true if the subquery is expensive @return false otherwise */ @@ -6771,9 +6774,10 @@ exists_complementing_null_row(MY_BITMAP *keys_to_complement) return FALSE; } - return bitmap_exists_intersection((const MY_BITMAP**) null_bitmaps, + return bitmap_exists_intersection(null_bitmaps, count_null_keys, - (uint)highest_min_row, (uint)lowest_max_row); + (uint)highest_min_row, + (uint)lowest_max_row); } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index bcaf229dd15..275451ab271 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1223,6 +1223,21 @@ bool Item_sum_hybrid::fix_length_and_dec_numeric(const Type_handler *handler) } +bool Item_sum_hybrid::fix_length_and_dec_sint_ge0() +{ + // We don't have Item_field's of "ge0" type handlers. + DBUG_ASSERT(args[0]->real_item()->type() != FIELD_ITEM); + Type_std_attributes::set(args[0]); + /* + We're converting from e.g. slong_ge0 to slonglong + and need to add one extra character for the sign. + */ + max_length++; + set_handler(&type_handler_slonglong); + return false; +} + + /** MAX(str_field) converts ENUM/SET to CHAR, and preserve all other types for Fields. @@ -4061,6 +4076,7 @@ void Item_func_group_concat::cleanup() unique_filter= NULL; } } + row_count= 0; DBUG_ASSERT(tree == 0); } /* @@ -4586,7 +4602,7 @@ void Item_func_group_concat::print(String *str, enum_query_type query_type) if (sum_func() == GROUP_CONCAT_FUNC) { str->append(STRING_WITH_LEN(" separator \'")); - str->append_for_single_quote(separator->ptr(), separator->length()); + str->append_for_single_quote_opt_convert(*separator); str->append(STRING_WITH_LEN("\'")); } diff --git a/sql/item_sum.h b/sql/item_sum.h index 7308734070d..bba93f6f4ab 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -599,6 +599,17 @@ public: bool is_window_func_sum_expr() { return window_func_sum_expr_flag; } virtual void setup_caches(THD *thd) {}; virtual void set_partition_row_count(ulonglong count) { DBUG_ASSERT(0); } + + /* + While most Item_sum descendants employ standard aggregators configured + through Item_sum::set_aggregator() call, there are exceptions like + Item_func_group_concat, which implements its own custom aggregators for + deduplication values. + This function distinguishes between the use of standard and custom + aggregators by the object + */ + virtual bool uses_non_standard_aggregator_for_distinct() const + { return false; } }; @@ -1127,6 +1138,7 @@ public: { return Type_handler_hybrid_field_type::type_handler(); } bool fix_length_and_dec_generic(); bool fix_length_and_dec_numeric(const Type_handler *h); + bool fix_length_and_dec_sint_ge0(); bool fix_length_and_dec_string(); }; @@ -2015,6 +2027,9 @@ protected: { return f->val_str(tmp, key + offset); } virtual void cut_max_length(String *result, uint old_length, uint max_length) const; + bool uses_non_standard_aggregator_for_distinct() const override + { return distinct; } + public: // Methods used by ColumnStore bool get_distinct() const { return distinct; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 2026c6edc0f..2cf63c2d284 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2974,7 +2974,7 @@ bool Item_extract::fix_length_and_dec(THD *thd) switch (int_type) { case INTERVAL_YEAR: set_date_length(4); break; // YYYY case INTERVAL_YEAR_MONTH: set_date_length(6); break; // YYYYMM - case INTERVAL_QUARTER: set_date_length(2); break; // 1..4 + case INTERVAL_QUARTER: set_date_length(1); break; // 1..4 case INTERVAL_MONTH: set_date_length(2); break; // MM case INTERVAL_WEEK: set_date_length(2); break; // 0..52 case INTERVAL_DAY: set_day_length(daylen); break; // DD @@ -3539,6 +3539,24 @@ bool Item_func_timediff::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzy if (l_time1.neg != l_time2.neg) l_sign= -l_sign; + if (l_time1.time_type == MYSQL_TIMESTAMP_TIME) + { + /* + In case of TIME-alike arguments: + TIMEDIFF('38:59:59', '839:00:00') + let's truncate extra fractional seconds that might appear if the argument + values were out of the supported TIME range. For example, args[n]->get_time() + for the string literal '839:00:00' returns TIME'838:59:59.999999'. + The fractional part must be truncated according to this->decimals, + to avoid returning more fractional seconds than it was detected + during this->fix_length_and_dec(). + Note, the thd rounding mode should not be important here, as we're removing + redundant digits from the maximum possible value: '838:59:59.999999'. + */ + my_time_trunc(&l_time1, decimals); + my_time_trunc(&l_time2, decimals); + } + if (calc_time_diff(&l_time1, &l_time2, l_sign, &l_time3, fuzzydate)) return (null_value= 1); diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index f0f2a0bc68e..084fee85ddb 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -30,23 +30,23 @@ bool get_interval_value(THD *thd, Item *args, interval_type int_type, INTERVAL *interval); -class Item_long_func_date_field: public Item_long_func +class Item_long_func_date_field: public Item_long_ge0_func { bool check_arguments() const override { return args[0]->check_type_can_return_date(func_name_cstring()); } public: Item_long_func_date_field(THD *thd, Item *a) - :Item_long_func(thd, a) { } + :Item_long_ge0_func(thd, a) { } }; -class Item_long_func_time_field: public Item_long_func +class Item_long_func_time_field: public Item_long_ge0_func { bool check_arguments() const override { return args[0]->check_type_can_return_time(func_name_cstring()); } public: Item_long_func_time_field(THD *thd, Item *a) - :Item_long_func(thd, a) { } + :Item_long_ge0_func(thd, a) { } }; @@ -186,10 +186,10 @@ public: }; -class Item_func_month :public Item_long_func +class Item_func_month :public Item_long_ge0_func { public: - Item_func_month(THD *thd, Item *a): Item_long_func(thd, a) + Item_func_month(THD *thd, Item *a): Item_long_ge0_func(thd, a) { } longlong val_int() override; LEX_CSTRING func_name_cstring() const override @@ -381,7 +381,7 @@ public: }; -class Item_func_week :public Item_long_func +class Item_func_week :public Item_long_ge0_func { bool check_arguments() const override { @@ -389,8 +389,8 @@ class Item_func_week :public Item_long_func (arg_count > 1 && args[1]->check_type_can_return_int(func_name_cstring())); } public: - Item_func_week(THD *thd, Item *a): Item_long_func(thd, a) {} - Item_func_week(THD *thd, Item *a, Item *b): Item_long_func(thd, a, b) {} + Item_func_week(THD *thd, Item *a): Item_long_ge0_func(thd, a) {} + Item_func_week(THD *thd, Item *a, Item *b): Item_long_ge0_func(thd, a, b) {} longlong val_int() override; LEX_CSTRING func_name_cstring() const override { @@ -1167,12 +1167,17 @@ class Item_extract :public Item_int_func, void set_date_length(uint32 length) { /* - Although DATE components (e.g. YEAR, YEAR_MONTH, QUARTER, MONTH, WEEK) - cannot have a sign, we should probably still add +1, - because all around the code we assume that max_length is sign inclusive. - Another options is to set unsigned_flag to "true". + DATE components (e.g. YEAR, YEAR_MONTH, QUARTER, MONTH, WEEK) + return non-negative values but historically EXTRACT for date + components always returned the signed int data type. + So do equivalent functions YEAR(), QUARTER(), MONTH(), WEEK(). + Let's set the data type to "signed int, but not negative", + so "this" produces better data types in VARCHAR and DECIMAL context + by using the fact that all of the max_length characters are spent + for digits (non of them are spent for the sign). */ - set_handler(handler_by_length(max_length= length, 10)); // QQ: see above + set_handler(&type_handler_slong_ge0); + fix_char_length(length); m_date_mode= date_mode_t(0); } void set_day_length(uint32 length) diff --git a/sql/lex.h b/sql/lex.h index fc1f06bd41d..38b0039a6cf 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -385,6 +385,7 @@ SYMBOL symbols[] = { { "MASTER_SSL_VERIFY_SERVER_CERT", SYM(MASTER_SSL_VERIFY_SERVER_CERT_SYM)}, { "MASTER_USER", SYM(MASTER_USER_SYM)}, { "MASTER_USE_GTID", SYM(MASTER_USE_GTID_SYM)}, + { "MASTER_DEMOTE_TO_REPLICA", SYM(MASTER_DEMOTE_TO_SLAVE_SYM)}, { "MASTER_DEMOTE_TO_SLAVE", SYM(MASTER_DEMOTE_TO_SLAVE_SYM)}, { "MASTER_HEARTBEAT_PERIOD", SYM(MASTER_HEARTBEAT_PERIOD_SYM)}, { "MATCH", SYM(MATCH)}, diff --git a/sql/log.cc b/sql/log.cc index 460cefea47b..259ff7c1b8b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -7279,8 +7279,8 @@ err: mysql_mutex_assert_not_owner(&LOCK_after_binlog_sync); mysql_mutex_assert_not_owner(&LOCK_commit_ordered); #ifdef HAVE_REPLICATION - if (repl_semisync_master.report_binlog_update(thd, log_file_name, - file->pos_in_file)) + if (repl_semisync_master.report_binlog_update( + thd, thd, log_file_name, file->pos_in_file)) { sql_print_error("Failed to run 'after_flush' hooks"); error= 1; @@ -8443,9 +8443,9 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry) if (entry->cache_mngr->using_xa) { - DEBUG_SYNC(entry->thd, "commit_before_prepare_ordered"); + DEBUG_SYNC(orig_entry->thd, "commit_before_prepare_ordered"); run_prepare_ordered(entry->thd, entry->all); - DEBUG_SYNC(entry->thd, "commit_after_prepare_ordered"); + DEBUG_SYNC(orig_entry->thd, "commit_after_prepare_ordered"); } if (cur) @@ -8881,9 +8881,19 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader) for (current= queue; current != NULL; current= current->next) { #ifdef HAVE_REPLICATION + /* + The thread which will await the ACK from the replica can change + depending on the wait-point. If AFTER_COMMIT, then the user thread + will perform the wait. If AFTER_SYNC, the binlog group commit leader + will perform the wait on behalf of the user thread. + */ + THD *waiter_thd= (repl_semisync_master.wait_point() == + SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT) + ? current->thd + : leader->thd; if (likely(!current->error) && unlikely(repl_semisync_master. - report_binlog_update(current->thd, + report_binlog_update(current->thd, waiter_thd, current->cache_mngr-> last_commit_pos_file, current->cache_mngr-> @@ -11636,7 +11646,7 @@ Recovery_context::Recovery_context() : prev_event_pos(0), last_gtid_standalone(false), last_gtid_valid(false), last_gtid_no2pc(false), last_gtid_engines(0), - do_truncate(repl_semisync_slave.get_slave_enabled()), + do_truncate(global_rpl_semi_sync_slave_enabled), truncate_validated(false), truncate_reset_done(false), truncate_set_in_1st(false), id_binlog(MAX_binlog_id), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF), gtid_maybe_to_truncate(NULL) diff --git a/sql/log.h b/sql/log.h index fc5209d1922..d15b8ff63aa 100644 --- a/sql/log.h +++ b/sql/log.h @@ -603,6 +603,7 @@ struct wait_for_commit; class MYSQL_BIN_LOG: public TC_LOG, private Event_log { +#ifdef HAVE_PSI_INTERFACE /** The instrumentation key to use for @ LOCK_index. */ PSI_mutex_key m_key_LOCK_index; /** The instrumentation key to use for @ COND_relay_log_updated */ @@ -613,6 +614,16 @@ class MYSQL_BIN_LOG: public TC_LOG, private Event_log PSI_file_key m_key_file_log_index, m_key_file_log_index_cache; PSI_cond_key m_key_COND_queue_busy; +#else + static constexpr PSI_mutex_key m_key_LOCK_index= 0; + static constexpr PSI_cond_key m_key_relay_log_update= 0; + static constexpr PSI_cond_key m_key_bin_log_update= 0; + static constexpr PSI_file_key m_key_file_log= 0, m_key_file_log_cache= 0; + static constexpr PSI_file_key m_key_file_log_index= 0; + static constexpr PSI_file_key m_key_file_log_index_cache= 0; + static constexpr PSI_cond_key m_key_COND_queue_busy= 0; + static constexpr PSI_mutex_key m_key_LOCK_binlog_end_pos= 0; +#endif struct group_commit_entry { diff --git a/sql/log_event.cc b/sql/log_event.cc index e60f822e751..8cf598b5159 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2421,6 +2421,11 @@ Gtid_log_event::Gtid_log_event(const uchar *buf, uint event_len, } if (flags2 & (FL_PREPARED_XA | FL_COMPLETED_XA)) { + if (event_len < static_cast(buf - buf_0) + 6) + { + seq_no= 0; + return; + } xid.formatID= uint4korr(buf); buf+= 4; @@ -2429,6 +2434,11 @@ Gtid_log_event::Gtid_log_event(const uchar *buf, uint event_len, buf+= 2; long data_length= xid.bqual_length + xid.gtrid_length; + if (event_len < static_cast(buf - buf_0) + data_length) + { + seq_no= 0; + return; + } memcpy(xid.data, buf, data_length); buf+= data_length; } @@ -2443,14 +2453,22 @@ Gtid_log_event::Gtid_log_event(const uchar *buf, uint event_len, */ if (flags_extra & FL_EXTRA_MULTI_ENGINE_E1) { - DBUG_ASSERT(static_cast(buf - buf_0) < event_len); - + if (event_len < static_cast(buf - buf_0) + 1) + { + seq_no= 0; + return; + } extra_engines= *buf++; DBUG_ASSERT(extra_engines > 0); } if (flags_extra & (FL_COMMIT_ALTER_E1 | FL_ROLLBACK_ALTER_E1)) { + if (event_len < static_cast(buf - buf_0) + 8) + { + seq_no= 0; + return; + } sa_seq_no= uint8korr(buf); buf+= 8; } @@ -3112,21 +3130,16 @@ Rows_log_event::Rows_log_event(const uchar *buf, uint event_len, /* if my_bitmap_init fails, caught in is_valid() */ if (likely(!my_bitmap_init(&m_cols, - m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, - m_width))) + m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, + m_width))) { DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); - memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8); - create_last_word_mask(&m_cols); + bitmap_import(&m_cols, ptr_after_width); + DBUG_DUMP("m_cols", (uchar*) ptr_after_width, no_bytes_in_export_map(&m_cols)); ptr_after_width+= (m_width + 7) / 8; - DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols)); } else - { - // Needed because my_bitmap_init() does not set it to null on failure - m_cols.bitmap= NULL; DBUG_VOID_RETURN; - } if (LOG_EVENT_IS_UPDATE_ROW(event_type)) { @@ -3134,15 +3147,14 @@ Rows_log_event::Rows_log_event(const uchar *buf, uint event_len, /* if my_bitmap_init fails, caught in is_valid() */ if (likely(!my_bitmap_init(&m_cols_ai, - m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL, - m_width))) + m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : + NULL, + m_width))) { DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); - memcpy(m_cols_ai.bitmap, ptr_after_width, (m_width + 7) / 8); - create_last_word_mask(&m_cols_ai); + bitmap_import(&m_cols_ai, ptr_after_width); + DBUG_DUMP("m_cols_ai", ptr_after_width, no_bytes_in_export_map(&m_cols_ai)); ptr_after_width+= (m_width + 7) / 8; - DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap, - no_bytes_in_map(&m_cols_ai)); } else { @@ -3222,8 +3234,6 @@ void Rows_log_event::uncompress_buf() Rows_log_event::~Rows_log_event() { - if (m_cols.bitmap == m_bitbuf) // no my_malloc happened - m_cols.bitmap= 0; // so no my_free in my_bitmap_free my_bitmap_free(&m_cols); // To pair with my_bitmap_init(). my_free(m_rows_buf); my_free(m_extra_row_data); @@ -3237,9 +3247,10 @@ int Rows_log_event::get_data_size() uchar *end= net_store_length(buf, m_width); DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", - return (int)(6 + no_bytes_in_map(&m_cols) + (end - buf) + - (general_type_code == UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) + - m_rows_cur - m_rows_buf);); + return (int) (6 + no_bytes_in_export_map(&m_cols) + (end - buf) + + (general_type_code == UPDATE_ROWS_EVENT ? + no_bytes_in_export_map(&m_cols_ai) : 0) + + m_rows_cur - m_rows_buf);); int data_size= 0; Log_event_type type= get_type_code(); bool is_v2_event= LOG_EVENT_IS_ROW_V2(type); @@ -3254,11 +3265,11 @@ int Rows_log_event::get_data_size() { data_size= ROWS_HEADER_LEN_V1; } - data_size+= no_bytes_in_map(&m_cols); + data_size+= no_bytes_in_export_map(&m_cols); data_size+= (uint) (end - buf); if (general_type_code == UPDATE_ROWS_EVENT) - data_size+= no_bytes_in_map(&m_cols_ai); + data_size+= no_bytes_in_export_map(&m_cols_ai); data_size+= (uint) (m_rows_cur - m_rows_buf); return data_size; @@ -3789,12 +3800,7 @@ Delete_rows_compressed_log_event::Delete_rows_compressed_log_event( Update_rows_log_event::~Update_rows_log_event() { - if (m_cols_ai.bitmap) - { - if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened - m_cols_ai.bitmap= 0; // so no my_free in my_bitmap_free - my_bitmap_free(&m_cols_ai); // To pair with my_bitmap_init(). - } + my_bitmap_free(&m_cols_ai); // To pair with my_bitmap_init(). } diff --git a/sql/log_event.h b/sql/log_event.h index 0c5683006f3..df42f0a132c 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -3394,7 +3394,16 @@ public: { return GTID_HEADER_LEN + ((flags2 & FL_GROUP_COMMIT_ID) ? 2 : 0); } - bool is_valid() const { return seq_no != 0; } + + bool is_valid() const + { + /* + seq_no is set to 0 if the structure of a serialized GTID event does not + align with that as indicated by flags and extra_flags. + */ + return seq_no != 0; + } + #ifdef MYSQL_SERVER bool write(Log_event_writer *writer); static int make_compatible_event(String *packet, bool *need_dummy_event, @@ -4781,8 +4790,8 @@ protected: ulong m_master_reclength; /* Length of record on master side */ /* Bit buffers in the same memory as the class */ - uint32 m_bitbuf[128/(sizeof(uint32)*8)]; - uint32 m_bitbuf_ai[128/(sizeof(uint32)*8)]; + my_bitmap_map m_bitbuf[128/(sizeof(my_bitmap_map)*8)]; + my_bitmap_map m_bitbuf_ai[128/(sizeof(my_bitmap_map)*8)]; uchar *m_rows_buf; /* The rows in packed format */ uchar *m_rows_cur; /* One-after the end of the data */ diff --git a/sql/log_event_client.cc b/sql/log_event_client.cc index 6b83f159896..94ae255991b 100644 --- a/sql/log_event_client.cc +++ b/sql/log_event_client.cc @@ -2996,7 +2996,7 @@ bool Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo) { char *pbeg; // beginning of the next line char *pend; // end of the next line - uint cnt= 0; // characters counter + char *qend= m_query_txt + m_query_len; if (!pinfo->short_form) { @@ -3007,28 +3007,21 @@ bool Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo) else if (my_b_printf(&pinfo->head_cache, "# Annotate_rows:\n")) goto err; - for (pbeg= m_query_txt; ; pbeg= pend) + for (pbeg= m_query_txt; pbeg < qend; pbeg= pend) { // skip all \r's and \n's at the beginning of the next line - for (;; pbeg++) - { - if (++cnt > m_query_len) - return 0; - - if (*pbeg != '\r' && *pbeg != '\n') - break; - } + for (; pbeg < qend && (*pbeg == '\r' || *pbeg == '\n'); pbeg++) + ; // find end of the next line - for (pend= pbeg + 1; - ++cnt <= m_query_len && *pend != '\r' && *pend != '\n'; - pend++) + for (pend= pbeg + 1; pend < qend && *pend != '\r' && *pend != '\n'; pend++) ; // print next line - if (my_b_write(&pinfo->head_cache, (const uchar*) "#Q> ", 4) || - my_b_write(&pinfo->head_cache, (const uchar*) pbeg, pend - pbeg) || - my_b_write(&pinfo->head_cache, (const uchar*) "\n", 1)) + if (pbeg < qend && + (my_b_write(&pinfo->head_cache, (const uchar*) "#Q> ", 4) || + my_b_write(&pinfo->head_cache, (const uchar*) pbeg, pend - pbeg) || + my_b_write(&pinfo->head_cache, (const uchar*) "\n", 1))) goto err; } diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index 169f78b5c00..f7029b39960 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -1843,7 +1843,10 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, { bool is_rb_alter= gtid_flags_extra & Gtid_log_event::FL_ROLLBACK_ALTER_E1; - thd->set_time(when, when_sec_part); +#ifdef WITH_WSREP + if (!wsrep_thd_is_applying(thd)) +#endif + thd->set_time(when, when_sec_part); thd->set_query_and_id((char*)query_arg, q_len_arg, thd->charset(), next_query_id()); thd->variables.pseudo_thread_id= thread_id; // for temp tables @@ -2944,28 +2947,43 @@ Gtid_log_event::write(Log_event_writer *writer) write_len= GTID_HEADER_LEN + 2; } - if (flags2 & (FL_PREPARED_XA | FL_COMPLETED_XA)) + if (flags2 & (FL_PREPARED_XA | FL_COMPLETED_XA) + && !DBUG_IF("negate_xid_from_gtid")) { int4store(&buf[write_len], xid.formatID); buf[write_len +4]= (uchar) xid.gtrid_length; buf[write_len +4+1]= (uchar) xid.bqual_length; write_len+= 6; long data_length= xid.bqual_length + xid.gtrid_length; - memcpy(buf+write_len, xid.data, data_length); - write_len+= data_length; + + if (!DBUG_IF("negate_xid_data_from_gtid")) + { + memcpy(buf+write_len, xid.data, data_length); + write_len+= data_length; + } } + + DBUG_EXECUTE_IF("inject_fl_extra_multi_engine_into_gtid", { + flags_extra|= FL_EXTRA_MULTI_ENGINE_E1; + }); if (flags_extra > 0) { buf[write_len]= flags_extra; write_len++; } + DBUG_EXECUTE_IF("inject_fl_extra_multi_engine_into_gtid", { + flags_extra&= ~FL_EXTRA_MULTI_ENGINE_E1; + }); + if (flags_extra & FL_EXTRA_MULTI_ENGINE_E1) { buf[write_len]= extra_engines; write_len++; } - if (flags_extra & (FL_COMMIT_ALTER_E1 | FL_ROLLBACK_ALTER_E1)) + if (flags_extra & (FL_COMMIT_ALTER_E1 | FL_ROLLBACK_ALTER_E1) + && !DBUG_IF("negate_alter_fl_from_gtid") + ) { int8store(buf + write_len, sa_seq_no); write_len+= 8; @@ -3608,6 +3626,9 @@ int Xid_apply_log_event::do_apply_event(rpl_group_info *rgi) thd->wsrep_affected_rows= 0; #endif +#ifndef DBUG_OFF + bool record_gtid_delayed_for_xa= false; +#endif if (rgi->gtid_pending) { sub_id= rgi->gtid_sub_id; @@ -3626,6 +3647,10 @@ int Xid_apply_log_event::do_apply_event(rpl_group_info *rgi) return 1; }); } +#ifndef DBUG_OFF + else + record_gtid_delayed_for_xa= true; +#endif } general_log_print(thd, COM_QUERY, get_query()); @@ -3635,6 +3660,22 @@ int Xid_apply_log_event::do_apply_event(rpl_group_info *rgi) { DBUG_ASSERT(!thd->transaction->xid_state.is_explicit_XA()); + DBUG_ASSERT(record_gtid_delayed_for_xa); + if (thd->rgi_slave->is_parallel_exec) + { + /* + With XA, since the transaction is prepared/committed without updating + the GTID pos (MDEV-32020...), we need here to clear any pending + deadlock kill. + + Otherwise if the kill happened after the prepare/commit completed, it + might end up killing the subsequent GTID position update, causing the + slave to fail with error. + */ + wait_for_pending_deadlock_kill(thd, thd->rgi_slave); + thd->reset_killed(); + } + if ((err= do_record_gtid(thd, rgi, false, &hton, true))) return err; } @@ -3741,7 +3782,8 @@ int XA_prepare_log_event::do_commit() thd->lex->xid= &xid; if (!one_phase) { - if ((res= thd->wait_for_prior_commit())) + if (thd->is_current_stmt_binlog_disabled() && + (res= thd->wait_for_prior_commit())) return res; thd->lex->sql_command= SQLCOM_XA_PREPARE; @@ -4558,20 +4600,12 @@ Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, set_flags(NO_CHECK_CONSTRAINT_CHECKS_F); /* if my_bitmap_init fails, caught in is_valid() */ if (likely(!my_bitmap_init(&m_cols, - m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, - m_width))) + m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, + m_width))) { /* Cols can be zero if this is a dummy binrows event */ if (likely(cols != NULL)) - { - memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols)); - create_last_word_mask(&m_cols); - } - } - else - { - // Needed because my_bitmap_init() does not set it to null on failure - m_cols.bitmap= 0; + bitmap_copy(&m_cols, cols); } } @@ -5002,23 +5036,23 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) which tested replicate-* rules). */ - if (m_width == table->s->fields && bitmap_is_set_all(&m_cols)) + if (m_width == table->s->fields && bitmap_is_set_all(&m_cols)) set_flags(COMPLETE_ROWS_F); Rpl_table_data rpl_data= *(RPL_TABLE_LIST*)table->pos_in_table_list; /* Set tables write and read sets. - + Read_set contains all slave columns (in case we are going to fetch - a complete record from slave) - - Write_set equals the m_cols bitmap sent from master but it can be - longer if slave has extra columns. - */ + a complete record from slave). + + Write_set equals the m_cols bitmap sent from master but it can be + longer if slave has extra columns. + */ DBUG_PRINT_BITSET("debug", "Setting table's read_set from: %s", &m_cols); - + bitmap_set_all(table->read_set); bitmap_set_all(table->write_set); table->rpl_write_set= table->write_set; @@ -5041,9 +5075,12 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) if (table->versioned()) { + bitmap_set_bit(table->read_set, table->s->vers.start_fieldno); bitmap_set_bit(table->write_set, table->s->vers.start_fieldno); + bitmap_set_bit(table->read_set, table->s->vers.end_fieldno); bitmap_set_bit(table->write_set, table->s->vers.end_fieldno); } + m_table->mark_columns_per_binlog_row_image(); if (!rpl_data.is_online_alter()) this->slave_exec_mode= (enum_slave_exec_mode)slave_exec_mode_options; @@ -5140,6 +5177,8 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) } // row processing loop while (error == 0 && (m_curr_row != m_rows_end)); + thd->inc_examined_row_count(m_row_count); + /* Restore the sql_mode after the rows event is processed. */ @@ -5281,11 +5320,13 @@ static int rows_event_stmt_cleanup(rpl_group_info *rgi, THD * thd) Xid_log_event will come next which will, if some transactional engines are involved, commit the transaction and flush the pending event to the binlog. - If there was a deadlock the transaction should have been rolled back - already. So there should be no need to rollback the transaction. + We check for thd->transaction_rollback_request because it is possible + there was a deadlock that was ignored by slave-skip-errors. Normally, the + deadlock would have been rolled back already. */ - DBUG_ASSERT(! thd->transaction_rollback_request); - error|= (int)(error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd)); + error|= (int) ((error || thd->transaction_rollback_request) + ? trans_rollback_stmt(thd) + : trans_commit_stmt(thd)); /* Now what if this is not a transactional engine? we still need to @@ -5396,30 +5437,37 @@ bool Rows_log_event::write_data_body(Log_event_writer *writer) my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf; bool res= false; uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width); + uint bitmap_size= no_bytes_in_export_map(&m_cols); + uchar *bitmap; DBUG_ASSERT(static_cast(sbuf_end - sbuf) <= sizeof(sbuf)); DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf)); res= res || write_data(writer, sbuf, (size_t) (sbuf_end - sbuf)); - DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols)); - res= res || write_data(writer, (uchar*)m_cols.bitmap, no_bytes_in_map(&m_cols)); + bitmap= (uchar*) my_alloca(bitmap_size); + bitmap_export(bitmap, &m_cols); + + DBUG_DUMP("m_cols", bitmap, bitmap_size); + res= res || write_data(writer, bitmap, bitmap_size); /* TODO[refactor write]: Remove the "down cast" here (and elsewhere). */ if (get_general_type_code() == UPDATE_ROWS_EVENT) { - DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap, - no_bytes_in_map(&m_cols_ai)); - res= res || write_data(writer, (uchar*)m_cols_ai.bitmap, - no_bytes_in_map(&m_cols_ai)); + DBUG_ASSERT(m_cols.n_bits == m_cols_ai.n_bits); + bitmap_export(bitmap, &m_cols_ai); + + DBUG_DUMP("m_cols_ai", bitmap, bitmap_size); + res= res || write_data(writer, bitmap, bitmap_size); } DBUG_DUMP("rows", m_rows_buf, data_size); res= res || write_data(writer, m_rows_buf, (size_t) data_size); + my_afree(bitmap); return res; - } + bool Rows_log_event::write_compressed(Log_event_writer *writer) { uchar *m_rows_buf_tmp= m_rows_buf; @@ -6702,7 +6750,9 @@ int Rows_log_event::write_row(rpl_group_info *rgi, const bool overwrite) TODO: Add safety measures against infinite looping. */ - if (unlikely(table->s->sequence)) + DBUG_EXECUTE_IF("write_row_inject_sleep_before_ha_write_row", + my_sleep(20000);); + if (table->s->sequence) error= update_sequence(); else while (unlikely(error= table->file->ha_write_row(table->record[0]))) { @@ -6895,6 +6945,7 @@ int Rows_log_event::update_sequence() #if defined(WITH_WSREP) ! WSREP(thd) && #endif + table->in_use->rgi_slave && !(table->in_use->rgi_slave->gtid_ev_flags2 & Gtid_log_event::FL_DDL) && !(old_master= rpl_master_has_bug(thd->rgi_slave->rli, @@ -7351,6 +7402,12 @@ bool Rows_log_event::use_pk_position() const && m_usable_key_parts == m_table->key_info->user_defined_key_parts; } +static int end_of_file_error(rpl_group_info *rgi) +{ + return rgi->speculation != rpl_group_info::SPECULATE_OPTIMISTIC + ? HA_ERR_END_OF_FILE : HA_ERR_RECORD_CHANGED; +} + /** Locate the current row in event's table. @@ -7592,6 +7649,8 @@ int Rows_log_event::find_row(rpl_group_info *rgi) while ((error= table->file->ha_index_next(table->record[0]))) { DBUG_PRINT("info",("no record matching the given row found")); + if (error == HA_ERR_END_OF_FILE) + error= end_of_file_error(rgi); table->file->print_error(error, MYF(0)); table->file->ha_index_end(); goto end; @@ -7626,6 +7685,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi) break; case HA_ERR_END_OF_FILE: + error= end_of_file_error(rgi); DBUG_PRINT("info", ("Record not found")); table->file->ha_rnd_end(); goto end; @@ -7830,10 +7890,7 @@ void Update_rows_log_event::init(MY_BITMAP const *cols) { /* Cols can be zero if this is a dummy binrows event */ if (likely(cols != NULL)) - { - memcpy(m_cols_ai.bitmap, cols->bitmap, no_bytes_in_map(cols)); - create_last_word_mask(&m_cols_ai); - } + bitmap_copy(&m_cols_ai, cols); } } diff --git a/sql/mdl.cc b/sql/mdl.cc index 32374415a2e..13a97b8e58b 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -1195,15 +1195,8 @@ MDL_wait::timed_wait(MDL_context_owner *owner, struct timespec *abs_timeout, { #ifdef WITH_WSREP # ifdef ENABLED_DEBUG_SYNC - // Allow tests to block the applier thread using the DBUG facilities - DBUG_EXECUTE_IF("sync.wsrep_before_mdl_wait", - { - const char act[]= - "now " - "wait_for signal.wsrep_before_mdl_wait"; - DBUG_ASSERT(!debug_sync_set_action((owner->get_thd()), - STRING_WITH_LEN(act))); - };); + // Allow tests to block thread before MDL-wait + DEBUG_SYNC(owner->get_thd(), "wsrep_before_mdl_wait"); # endif if (WSREP_ON && wsrep_thd_is_BF(owner->get_thd(), false)) { diff --git a/sql/multi_range_read.h b/sql/multi_range_read.h index 930ee3f238b..ecb1a08051e 100644 --- a/sql/multi_range_read.h +++ b/sql/multi_range_read.h @@ -556,10 +556,6 @@ class DsMrr_impl public: typedef void (handler::*range_check_toggle_func_t)(bool on); - DsMrr_impl() - : secondary_file(NULL), - rowid_filter(NULL) {}; - void init(handler *h_arg, TABLE *table_arg) { primary_file= h_arg; @@ -581,7 +577,7 @@ public: int dsmrr_explain_info(uint mrr_mode, char *str, size_t size); private: /* Buffer to store (key, range_id) pairs */ - Lifo_buffer *key_buffer; + Lifo_buffer *key_buffer= nullptr; /* The "owner" handler object (the one that is expected to "own" this object @@ -594,13 +590,13 @@ private: Secondary handler object. (created when needed, we need it when we need to run both index scan and rnd_pos() scan at the same time) */ - handler *secondary_file; + handler *secondary_file= nullptr; /* The rowid filter that DS-MRR has "unpushed" from the storage engine. If it's present, DS-MRR will use it. */ - Rowid_filter *rowid_filter; + Rowid_filter *rowid_filter= nullptr; uint keyno; /* index we're running the scan on */ /* TRUE <=> need range association, buffers hold {rowid, range_id} pairs */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 80a1e5a2c24..23d60146bc1 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -304,7 +304,8 @@ static TYPELIB tc_heuristic_recover_typelib= }; const char *first_keyword= "first"; -const char *my_localhost= "localhost", *delayed_user= "DELAYED"; +const char *my_localhost= "localhost", + *delayed_user= "delayed", *slave_user= ""; bool opt_large_files= sizeof(my_off_t) > 4; static my_bool opt_autocommit; ///< for --autocommit command-line option @@ -752,9 +753,6 @@ mysql_mutex_t LOCK_thread_id; server may be fairly high, we need a dedicated lock. */ mysql_mutex_t LOCK_prepared_stmt_count; -#ifdef HAVE_OPENSSL -mysql_mutex_t LOCK_des_key_file; -#endif mysql_mutex_t LOCK_backup_log, LOCK_optimizer_costs; mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; mysql_rwlock_t LOCK_ssl_refresh; @@ -897,7 +895,7 @@ static struct my_option pfs_early_options[]= PSI_file_key key_file_binlog, key_file_binlog_cache, key_file_binlog_index, key_file_binlog_index_cache, key_file_casetest, - key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file, + key_file_dbopt, key_file_ERRMSG, key_select_to_file, key_file_fileparser, key_file_frm, key_file_global_ddl_log, key_file_load, key_file_loadfile, key_file_log_event_data, key_file_log_event_info, key_file_log_ddl, @@ -909,16 +907,19 @@ PSI_file_key key_file_relaylog, key_file_relaylog_index, key_file_relaylog_cache, key_file_relaylog_index_cache; PSI_file_key key_file_binlog_state, key_file_gtid_index; +#ifdef HAVE_des +char *des_key_file; +PSI_file_key key_file_des_key_file; +PSI_mutex_key key_LOCK_des_key_file; +mysql_mutex_t LOCK_des_key_file; +#endif /* HAVE_des */ + #ifdef HAVE_PSI_INTERFACE #ifdef HAVE_MMAP PSI_mutex_key key_PAGE_lock, key_LOCK_sync, key_LOCK_active, key_LOCK_pool, key_LOCK_pending_checkpoint; #endif /* HAVE_MMAP */ -#ifdef HAVE_OPENSSL -PSI_mutex_key key_LOCK_des_key_file; -#endif /* HAVE_OPENSSL */ - PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list, key_BINLOG_LOCK_binlog_background_thread, key_LOCK_binlog_end_pos, @@ -977,9 +978,9 @@ static PSI_mutex_info all_server_mutexes[]= { &key_LOCK_pool, "TC_LOG_MMAP::LOCK_pending_checkpoint", 0}, #endif /* HAVE_MMAP */ -#ifdef HAVE_OPENSSL +#ifdef HAVE_des { &key_LOCK_des_key_file, "LOCK_des_key_file", PSI_FLAG_GLOBAL}, -#endif /* HAVE_OPENSSL */ +#endif /* HAVE_des */ { &key_BINLOG_LOCK_index, "MYSQL_BIN_LOG::LOCK_index", 0}, { &key_BINLOG_LOCK_xid_list, "MYSQL_BIN_LOG::LOCK_xid_list", 0}, @@ -1511,7 +1512,6 @@ static void openssl_dynlock_destroy(openssl_lock_t *, const char *, int); static void openssl_lock_function(int, int, const char *, int); static void openssl_lock(int, openssl_lock_t *, const char *, int); #endif /* HAVE_OPENSSL10 */ -char *des_key_file; #ifndef EMBEDDED_LIBRARY struct st_VioSSLFd *ssl_acceptor_fd; #endif @@ -1587,15 +1587,12 @@ static void kill_thread(THD *thd) /** First shutdown everything but slave threads and binlog dump connections */ -static my_bool kill_thread_phase_1(THD *thd, int *n_threads_awaiting_ack) +static my_bool kill_thread_phase_1(THD *thd, void *) { DBUG_PRINT("quit", ("Informing thread %ld that it's time to die", (ulong) thd->thread_id)); - if (thd->slave_thread || thd->is_binlog_dump_thread() || - (shutdown_wait_for_slaves && - repl_semisync_master.is_thd_awaiting_semisync_ack(thd) && - ++(*n_threads_awaiting_ack))) + if (thd->slave_thread || thd->is_binlog_dump_thread()) return 0; if (DBUG_IF("only_kill_system_threads") && !thd->system_thread) @@ -1767,31 +1764,20 @@ static void close_connections(void) This will give the threads some time to gracefully abort their statements and inform their clients that the server is about to die. */ - DBUG_EXECUTE_IF("mysqld_delay_kill_threads_phase_1", my_sleep(200000);); - int n_threads_awaiting_ack= 0; - server_threads.iterate(kill_thread_phase_1, &n_threads_awaiting_ack); + server_threads.iterate(kill_thread_phase_1); /* If we are waiting on any ACKs, delay killing the thread until either an ACK is received or the timeout is hit. - - Allow at max the number of sessions to await a timeout; however, if all - ACKs have been received in less iterations, then quit early */ if (shutdown_wait_for_slaves && repl_semisync_master.get_master_enabled()) { - int waiting_threads= repl_semisync_master.sync_get_master_wait_sessions(); - if (waiting_threads) - sql_print_information("Delaying shutdown to await semi-sync ACK"); - - while (waiting_threads-- > 0) - repl_semisync_master.await_slave_reply(); + repl_semisync_master.await_all_slave_replies( + "Delaying shutdown to await semi-sync ACK"); } - DBUG_EXECUTE_IF("delay_shutdown_phase_2_after_semisync_wait", - my_sleep(500000);); - - Events::deinit(); + if (Events::inited) + Events::stop(); slave_prepare_for_shutdown(); ack_receiver.stop(); @@ -1811,8 +1797,7 @@ static void close_connections(void) */ DBUG_PRINT("info", ("THD_count: %u", THD_count::value())); - for (int i= 0; THD_count::connection_thd_count() - n_threads_awaiting_ack - && i < 1000; i++) + for (int i= 0; THD_count::connection_thd_count() && i < 1000; i++) { if (DBUG_IF("only_kill_system_threads_no_loop")) break; @@ -1831,9 +1816,9 @@ static void close_connections(void) #endif /* All threads has now been aborted */ DBUG_PRINT("quit", ("Waiting for threads to die (count=%u)", - THD_count::connection_thd_count() - n_threads_awaiting_ack)); + THD_count::connection_thd_count())); - while (THD_count::connection_thd_count() - n_threads_awaiting_ack) + while (THD_count::connection_thd_count()) { if (DBUG_IF("only_kill_system_threads_no_loop")) break; @@ -1854,6 +1839,12 @@ static void close_connections(void) } /* End of kill phase 2 */ + /* + The signal thread can use server resources, e.g. when processing SIGHUP, + and it must end gracefully before clean_up() + */ + wait_for_signal_thread_to_end(); + DBUG_PRINT("quit",("close_connections thread")); DBUG_VOID_RETURN; } @@ -1918,6 +1909,7 @@ extern "C" void unireg_abort(int exit_code) wsrep_sst_auth_free(); #endif // WITH_WSREP + wait_for_signal_thread_to_end(); clean_up(!opt_abort && (exit_code || !opt_bootstrap)); /* purecov: inspected */ DBUG_PRINT("quit",("done with cleanup in unireg_abort")); mysqld_exit(exit_code); @@ -1928,7 +1920,6 @@ static void mysqld_exit(int exit_code) DBUG_ENTER("mysqld_exit"); rpl_deinit_gtid_waiting(); rpl_deinit_gtid_slave_state(); - wait_for_signal_thread_to_end(); #ifdef WITH_WSREP wsrep_deinit_server(); wsrep_sst_auth_free(); @@ -2012,6 +2003,9 @@ static void clean_up(bool print_message) sp_cache_end(); free_status_vars(); end_thr_timer(); +#ifndef EMBEDDED_LIBRARY + Events::deinit(); +#endif my_free_open_file_info(); if (defaults_argv) free_defaults(defaults_argv); @@ -2083,14 +2077,29 @@ static void clean_up(bool print_message) static void wait_for_signal_thread_to_end() { #ifndef _WIN32 + uint i, n_waits= DBUG_IF("force_sighup_processing_timeout") ? 5 : 100; + int err= 0; /* Wait up to 10 seconds for signal thread to die. We use this mainly to avoid getting warnings that my_thread_end has not been called */ - for (uint i= 0 ; i < 100 && signal_thread_in_use; i++) + for (i= 0 ; i < n_waits && signal_thread_in_use; i++) { kill(getpid(), MYSQL_KILL_SIGNAL); - my_sleep(100); // Give it time to die + my_sleep(100000); // Give it time to die, .1s per iteration + } + + if (err && err != ESRCH) + { + sql_print_error("Failed to send kill signal to signal handler thread, " + "pthread_kill() errno: %d", err); + } + + if (i == n_waits && signal_thread_in_use && !opt_bootstrap) + { + sql_print_warning("Signal handler thread did not exit in a timely manner. " + "Continuing to wait for it to stop.."); + pthread_join(signal_thread, NULL); } #endif } @@ -2116,7 +2125,9 @@ static void clean_up_mutexes() mysql_mutex_destroy(&LOCK_global_table_stats); mysql_mutex_destroy(&LOCK_global_index_stats); #ifdef HAVE_OPENSSL +#ifdef HAVE_des mysql_mutex_destroy(&LOCK_des_key_file); +#endif /* HAVE_des */ #if defined(HAVE_OPENSSL10) && !defined(HAVE_WOLFSSL) for (int i= 0; i < CRYPTO_num_locks(); ++i) mysql_rwlock_destroy(&openssl_stdlocks[i].lock); @@ -3126,10 +3137,8 @@ void init_signals(void) (void) sigemptyset(&set); my_sigset(SIGPIPE,SIG_IGN); sigaddset(&set,SIGPIPE); -#ifndef IGNORE_SIGHUP_SIGQUIT sigaddset(&set,SIGQUIT); sigaddset(&set,SIGHUP); -#endif sigaddset(&set,SIGTERM); /* Fix signals if blocked by parents (can happen on Mac OS X) */ @@ -3168,7 +3177,6 @@ static void start_signal_handler(void) (void) pthread_attr_init(&thr_attr); pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM); - (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); (void) my_setstacksize(&thr_attr,my_thread_stack_size); mysql_mutex_lock(&LOCK_start_thread); @@ -3187,14 +3195,14 @@ static void start_signal_handler(void) DBUG_VOID_RETURN; } -/** This threads handles all signals */ + +/** This threads handles all signals and alarms. */ /* ARGSUSED */ pthread_handler_t signal_hand(void *) { sigset_t set; int sig; my_thread_init(); // Init new thread - DBUG_ENTER("signal_hand"); signal_thread_in_use= 1; if (test_flags & TEST_SIGINT) @@ -3205,16 +3213,16 @@ pthread_handler_t signal_hand(void *) (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL); } (void) sigemptyset(&set); // Setup up SIGINT for debug -#ifndef IGNORE_SIGHUP_SIGQUIT (void) sigaddset(&set,SIGQUIT); - (void) sigaddset(&set,SIGHUP); -#endif (void) sigaddset(&set,SIGTERM); (void) sigaddset(&set,SIGTSTP); /* Save pid to this process (or thread on Linux) */ if (!opt_bootstrap) + { + (void) sigaddset(&set,SIGHUP); create_pid_file(); + } /* signal to start_signal_handler that we are ready @@ -3288,7 +3296,6 @@ pthread_handler_t signal_hand(void *) } DBUG_PRINT("quit", ("signal_handler: calling my_thread_end()")); my_thread_end(); - DBUG_LEAVE; // Must match DBUG_ENTER() signal_thread_in_use= 0; pthread_exit(0); // Safety return(0); /* purecov: deadcode */ @@ -3707,20 +3714,35 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific) thd->status_var.local_memory_used > (int64)thd->variables.max_mem_used && likely(!thd->killed) && !thd->get_stmt_da()->is_set()) { - /* Ensure we don't get called here again */ - char buf[50], *buf2; - thd->set_killed(KILL_QUERY); - my_snprintf(buf, sizeof(buf), "--max-session-mem-used=%llu", - thd->variables.max_mem_used); - if ((buf2= (char*) thd->alloc(256))) - { - my_snprintf(buf2, 256, ER_THD(thd, ER_OPTION_PREVENTS_STATEMENT), buf); - thd->set_killed(KILL_QUERY, ER_OPTION_PREVENTS_STATEMENT, buf2); - } - else - { - thd->set_killed(KILL_QUERY, ER_OPTION_PREVENTS_STATEMENT, - "--max-session-mem-used"); + /* + Ensure we don't get called here again. + + It is not safe to wait for LOCK_thd_kill here, as we could be called + from almost any context. For example while LOCK_plugin is being held; + but THD::awake() locks LOCK_thd_kill and LOCK_plugin in the opposite + order (MDEV-33443). + + So ignore the max_mem_used limit in the unlikely case we cannot obtain + LOCK_thd_kill here (the limit will be enforced on the next allocation). + */ + if (!mysql_mutex_trylock(&thd->LOCK_thd_kill)) { + char buf[50], *buf2; + thd->set_killed_no_mutex(KILL_QUERY); + my_snprintf(buf, sizeof(buf), "--max-session-mem-used=%llu", + thd->variables.max_mem_used); + if ((buf2= (char*) thd->alloc(256))) + { + my_snprintf(buf2, 256, + ER_THD(thd, ER_OPTION_PREVENTS_STATEMENT), buf); + thd->set_killed_no_mutex(KILL_QUERY, + ER_OPTION_PREVENTS_STATEMENT, buf2); + } + else + { + thd->set_killed_no_mutex(KILL_QUERY, ER_OPTION_PREVENTS_STATEMENT, + "--max-session-mem-used"); + } + mysql_mutex_unlock(&thd->LOCK_thd_kill); } } DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0 || @@ -3984,8 +4006,9 @@ static int init_common_variables() SQLCOM_END + 10); #endif - if (get_options(&remaining_argc, &remaining_argv)) - exit(1); + int opt_err; + if ((opt_err= get_options(&remaining_argc, &remaining_argv))) + exit(opt_err); if (IS_SYSVAR_AUTOSIZE(&server_version_ptr)) set_server_version(server_version, sizeof(server_version)); @@ -4410,8 +4433,10 @@ static int init_thread_environment() mysql_mutex_init(key_LOCK_temp_pool, &LOCK_temp_pool, MY_MUTEX_INIT_FAST); #ifdef HAVE_OPENSSL +#ifdef HAVE_des mysql_mutex_init(key_LOCK_des_key_file, &LOCK_des_key_file, MY_MUTEX_INIT_FAST); +#endif /* HAVE_des */ #if defined(HAVE_OPENSSL10) && !defined(HAVE_WOLFSSL) openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() * sizeof(openssl_lock_t)); @@ -4640,8 +4665,10 @@ static void init_ssl() { have_ssl= SHOW_OPTION_DISABLED; } +#ifdef HAVE_des if (des_key_file) load_des_key_file(des_key_file); +#endif /* HAVE_des */ #endif /* HAVE_OPENSSL */ #endif /* !EMBEDDED_LIBRARY */ } @@ -4901,10 +4928,13 @@ static int init_server_components() error_handler_hook= my_message_sql; proc_info_hook= set_thd_stage_info; + /* Set up hook to handle disk full */ + my_sleep_for_space= mariadb_sleep_for_space; + /* - Print source revision hash, as one of the first lines, if not the - first in error log, for troubleshooting and debugging purposes - */ + Print source revision hash, as one of the first lines, if not the + first in error log, for troubleshooting and debugging purposes + */ if (!opt_help) sql_print_information("Starting MariaDB %s source revision %s as process %lu", server_version, SOURCE_REVISION, (ulong) getpid()); @@ -4932,6 +4962,19 @@ static int init_server_components() xid_cache_init(); + /* + Do not open binlong when doing bootstrap. + This ensures that rpl_load_gtid_slave_state() will not fail with an error + as the mysql schema does not yet exists. + This also ensures that we don't get an empty binlog file if the user has + log-bin in his config files. + */ + if (opt_bootstrap) + { + opt_bin_log= opt_bin_log_used= binlog_format_used= 0; + opt_log_slave_updates= 0; + } + /* need to configure logging before initializing storage engines */ if (!opt_bin_log_used && !WSREP_ON) { @@ -5416,6 +5459,10 @@ static int init_server_components() } #endif +#ifndef EMBEDDED_LIBRARY + start_handle_manager(); +#endif + tc_log= get_tc_log_implementation(); if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file)) @@ -5427,9 +5474,6 @@ static int init_server_components() if (ha_recover(0)) unireg_abort(1); -#ifndef EMBEDDED_LIBRARY - start_handle_manager(); -#endif if (opt_bin_log) { int error; @@ -6526,12 +6570,12 @@ struct my_option my_long_options[]= &opt_debug_sync_timeout, 0, 0, GET_UINT, OPT_ARG, 0, 0, UINT_MAX, 0, 0, 0}, #endif /* defined(ENABLED_DEBUG_SYNC) */ -#ifdef HAVE_OPENSSL +#ifdef HAVE_des {"des-key-file", 0, "Load keys for des_encrypt() and des_encrypt from given file.", &des_key_file, &des_key_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, -#endif /* HAVE_OPENSSL */ +#endif /* HAVE_des */ #ifdef HAVE_STACKTRACE {"stack-trace", 0 , "Print a symbolic stack trace on failure", &opt_stack_trace, &opt_stack_trace, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -7920,7 +7964,9 @@ static int mysql_init_variables(void) libwrapName= NullS; #endif #ifdef HAVE_OPENSSL +#ifdef HAVE_des des_key_file = 0; +#endif /* HAVE_des */ #ifndef EMBEDDED_LIBRARY ssl_acceptor_fd= 0; #endif /* ! EMBEDDED_LIBRARY */ @@ -8213,7 +8259,7 @@ mysqld_get_one_option(const struct my_option *opt, const char *argument, case (int) OPT_SAFE: opt_specialflag|= SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC; SYSVAR_AUTOSIZE(delay_key_write_options, (uint) DELAY_KEY_WRITE_NONE); - SYSVAR_AUTOSIZE(myisam_recover_options, HA_RECOVER_DEFAULT); + myisam_recover_options= HA_RECOVER_DEFAULT; ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE); #ifdef HAVE_QUERY_CACHE SYSVAR_AUTOSIZE(query_cache_size, 0); @@ -9160,7 +9206,9 @@ static PSI_file_info all_server_files[]= { &key_file_io_cache, "io_cache", 0}, { &key_file_casetest, "casetest", 0}, { &key_file_dbopt, "dbopt", 0}, +#ifdef HAVE_des { &key_file_des_key_file, "des_key_file", 0}, +#endif { &key_file_ERRMSG, "ERRMSG", 0}, { &key_select_to_file, "select_to_file", 0}, { &key_file_fileparser, "file_parser", 0}, @@ -9288,6 +9336,7 @@ PSI_stage_info stage_user_lock= { 0, "User lock", 0}; PSI_stage_info stage_user_sleep= { 0, "User sleep", 0}; PSI_stage_info stage_verifying_table= { 0, "Verifying table", 0}; PSI_stage_info stage_waiting_for_delay_list= { 0, "Waiting for delay_list", 0}; +PSI_stage_info stage_waiting_for_disk_space= {0, "Waiting for someone to free space", 0}; PSI_stage_info stage_waiting_for_gtid_to_be_written_to_binary_log= { 0, "Waiting for GTID to be written to binary log", 0}; PSI_stage_info stage_waiting_for_handler_insert= { 0, "Waiting for handler insert", 0}; PSI_stage_info stage_waiting_for_handler_lock= { 0, "Waiting for handler lock", 0}; diff --git a/sql/mysqld.h b/sql/mysqld.h index 4548a247ac1..33492ad7286 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -277,7 +277,7 @@ extern time_t server_start_time, flush_status_time; extern char *opt_mysql_tmpdir, mysql_charsets_dir[]; extern size_t mysql_unpacked_real_data_home_len; extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list; -extern const char *first_keyword, *delayed_user; +extern const char *first_keyword, *delayed_user, *slave_user; extern MYSQL_PLUGIN_IMPORT const char *my_localhost; extern MYSQL_PLUGIN_IMPORT const char **errmesg; /* Error messages */ extern const char *myisam_recover_options_str; @@ -326,10 +326,6 @@ extern PSI_mutex_key key_PAGE_lock, key_LOCK_sync, key_LOCK_active, key_LOCK_pool, key_LOCK_pending_checkpoint; #endif /* HAVE_MMAP */ -#ifdef HAVE_OPENSSL -extern PSI_mutex_key key_LOCK_des_key_file; -#endif - extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list, key_BINLOG_LOCK_binlog_background_thread, key_LOCK_binlog_end_pos, @@ -409,7 +405,7 @@ extern PSI_thread_key key_thread_delayed_insert, extern PSI_file_key key_file_binlog, key_file_binlog_cache, key_file_binlog_index, key_file_binlog_index_cache, key_file_casetest, - key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file, + key_file_dbopt, key_file_ERRMSG, key_select_to_file, key_file_fileparser, key_file_frm, key_file_global_ddl_log, key_file_load, key_file_loadfile, key_file_log_event_data, key_file_log_event_info, key_file_master_info, key_file_misc, key_file_partition_ddl_log, @@ -422,6 +418,13 @@ extern PSI_socket_key key_socket_tcpip, key_socket_unix, key_socket_client_connection; extern PSI_file_key key_file_binlog_state, key_file_gtid_index; +#ifdef HAVE_des +extern char* des_key_file; +extern PSI_file_key key_file_des_key_file; +extern PSI_mutex_key key_LOCK_des_key_file; +extern mysql_mutex_t LOCK_des_key_file; +#endif + #ifdef HAVE_PSI_INTERFACE void init_server_psi_keys(); #endif /* HAVE_PSI_INTERFACE */ @@ -662,6 +665,7 @@ extern PSI_stage_info stage_user_sleep; extern PSI_stage_info stage_verifying_table; extern PSI_stage_info stage_waiting_for_ddl; extern PSI_stage_info stage_waiting_for_delay_list; +extern PSI_stage_info stage_waiting_for_disk_space; extern PSI_stage_info stage_waiting_for_flush; extern PSI_stage_info stage_waiting_for_gtid_to_be_written_to_binary_log; extern PSI_stage_info stage_waiting_for_handler_insert; @@ -778,10 +782,6 @@ extern mysql_mutex_t extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_global_system_variables; extern mysql_rwlock_t LOCK_all_status_vars; extern mysql_mutex_t LOCK_start_thread; -#ifdef HAVE_OPENSSL -extern char* des_key_file; -extern mysql_mutex_t LOCK_des_key_file; -#endif extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_server_started; extern MYSQL_PLUGIN_IMPORT mysql_cond_t COND_server_started; extern mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 7d2f884d73e..d8bfc8d312f 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -72,7 +72,13 @@ static void inline EXTRA_DEBUG_fprintf(...) {} #ifdef MYSQL_SERVER #include #include -#define MYSQL_SERVER_my_error my_error + +static void inline MYSQL_SERVER_my_error(uint error, myf flags) +{ + my_error(error, + flags | MYF(global_system_variables.log_warnings > 3 ? ME_ERROR_LOG : 0)); +} + #else static void inline MYSQL_SERVER_my_error(...) {} #endif @@ -139,6 +145,7 @@ my_bool my_net_init(NET *net, Vio *vio, void *thd, uint my_flags) net->net_skip_rest_factor= 0; net->last_errno=0; net->pkt_nr_can_be_reset= 0; + net->using_proxy_protocol= 0; net->thread_specific_malloc= MY_TEST(my_flags & MY_THREAD_SPECIFIC); net->thd= 0; net->extension= NULL; @@ -189,6 +196,7 @@ void net_end(NET *net) DBUG_ENTER("net_end"); my_free(net->buff); net->buff=0; + net->using_proxy_protocol= 0; DBUG_VOID_RETURN; } @@ -698,7 +706,19 @@ net_real_write(NET *net,const uchar *packet, size_t len) my_progname); net->error= 2; /* Close socket */ net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED : - ER_NET_ERROR_ON_WRITE); + ER_NET_ERROR_ON_WRITE); +#ifdef MYSQL_SERVER + if (global_system_variables.log_warnings > 3) + { + my_printf_error(net->last_errno, + "Could not write packet: fd: %lld state: %d " + "errno: %d vio_errno: %d length: %ld", + MYF(ME_ERROR_LOG), + (longlong) vio_fd(net->vio), (int) net->vio->state, + vio_errno(net->vio), net->last_errno, (ulong) (end-pos)); + break; + } +#endif MYSQL_SERVER_my_error(net->last_errno, MYF(0)); break; } @@ -771,6 +791,7 @@ static handle_proxy_header_result handle_proxy_header(NET *net) return RETRY; /* Change peer address in THD and ACL structures.*/ uint host_errors; + net->using_proxy_protocol= 1; return (handle_proxy_header_result)thd_set_peer_addr(thd, &(peer_info.peer_addr), NULL, peer_info.port, false, &host_errors); @@ -845,7 +866,21 @@ retry: net->error= 2; net->last_errno= (vio_was_timeout(net->vio) ? ER_NET_READ_INTERRUPTED : ER_NET_READ_ERROR); - MYSQL_SERVER_my_error(net->last_errno, MYF(0)); +#ifdef MYSQL_SERVER + if (global_system_variables.log_warnings > 3) + { + my_printf_error(net->last_errno, + "Could not read packet: fd: %lld state: %d " + "remain: %u errno: %d vio_errno: %d " + "length: %lld", + MYF(ME_ERROR_LOG), + (longlong) vio_fd(net->vio), (int) net->vio->state, + remain, vio_errno(net->vio), net->last_errno, + (longlong) length); + } + else + my_error(net->last_errno, MYF(0)); +#endif /* MYSQL_SERVER */ goto end; } remain-= (uint32) length; @@ -1022,7 +1057,10 @@ ulong my_net_read_packet(NET *net, my_bool read_from_server) { ulong reallen = 0; - return my_net_read_packet_reallen(net, read_from_server, &reallen); + ulong length; + DBUG_ENTER("my_net_read_packet"); + length= my_net_read_packet_reallen(net, read_from_server, &reallen); + DBUG_RETURN(length); } diff --git a/sql/online_alter.cc b/sql/online_alter.cc index da18b6f9466..2c5eb4dea62 100644 --- a/sql/online_alter.cc +++ b/sql/online_alter.cc @@ -154,6 +154,7 @@ int online_alter_log_row(TABLE* table, const uchar *before_record, if (!table->online_alter_cache) { table->online_alter_cache= get_cache_data(thd, table); + DBUG_ASSERT(table->online_alter_cache->cache_log.type == WRITE_CACHE); trans_register_ha(thd, false, online_alter_hton, 0); if (thd->in_multi_stmt_transaction_mode()) trans_register_ha(thd, true, online_alter_hton, 0); @@ -183,23 +184,19 @@ int online_alter_log_row(TABLE* table, const uchar *before_record, } -static void -cleanup_cache_list(ilist &list, bool ending_trans) +static void cleanup_cache_list(ilist &list) { - if (ending_trans) + auto it= list.begin(); + while (it != list.end()) { - auto it= list.begin(); - while (it != list.end()) - { - auto &cache= *it++; - cache.sink_log->release(); - cache.reset(); - cache.cleanup_sv(); - delete &cache; - } - list.clear(); - DBUG_ASSERT(list.empty()); + auto &cache= *it++; + cache.sink_log->release(); + cache.reset(); + cache.cleanup_sv(); + delete &cache; } + list.clear(); + DBUG_ASSERT(list.empty()); } @@ -239,6 +236,8 @@ int online_alter_end_trans(Online_alter_cache_list &cache_list, THD *thd, mysql_mutex_lock(binlog->get_log_lock()); error= binlog->write_cache_raw(thd, &cache.cache_log); mysql_mutex_unlock(binlog->get_log_lock()); + if (!is_ending_transaction) + cache.reset(); } } else if (!commit) // rollback @@ -257,12 +256,12 @@ int online_alter_end_trans(Online_alter_cache_list &cache_list, THD *thd, { my_error(ER_ERROR_ON_WRITE, MYF(ME_ERROR_LOG), binlog->get_name(), errno); - cleanup_cache_list(cache_list, is_ending_transaction); - DBUG_RETURN(error); + break; } } - cleanup_cache_list(cache_list, is_ending_transaction); + if (is_ending_transaction) + cleanup_cache_list(cache_list); DBUG_RETURN(error); } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 387d39e293c..5793b19f695 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3200,6 +3200,53 @@ SQL_SELECT::test_quick_select(THD *thd, ****************************************************************************/ +/* + @brief + Create a bitmap of columns for which to perform Range Analysis for EITS + condition selectivity estimates. + + @detail + Walk through the bitmap of fields used in the query, and + - pick columns for which EITS data is usable (see is_eits_usable() call) + - do not produce more than MAX_KEY columns. Range Analyzer cannot handle + more than that. If there are more than MAX_KEY eligible columns, + this function should be called multiple times to produce multiple + bitmaps. + + @param used_fields Columns used by the query + @param col_no Start from this column + @param out OUT Filled column bitmap + + @return + (uint)-1 If there are no more columns for range analysis. + Other Index of the last considered column. Pass this to next call to + this function +*/ + +uint get_columns_for_pseudo_indexes(const TABLE *table, + const MY_BITMAP *used_fields, int col_no, + MY_BITMAP *out) +{ + bitmap_clear_all(out); + int n_bits= 0; + + for (; table->field[col_no]; col_no++) + { + if (bitmap_is_set(used_fields, col_no) && + is_eits_usable(table->field[col_no])) + { + bitmap_set_bit(out, col_no); + if (++n_bits == MAX_KEY) + { + col_no++; + break; + } + } + } + return n_bits? col_no: (uint)-1; +} + + /* Build descriptors of pseudo-indexes over columns to perform range analysis @@ -3225,22 +3272,11 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param, { Field **field_ptr; TABLE *table= param->table; - uint parts= 0; - - for (field_ptr= table->field; *field_ptr; field_ptr++) - { - Field *field= *field_ptr; - if (bitmap_is_set(used_fields, field->field_index) && - is_eits_usable(field)) - parts++; - } + uint parts= bitmap_bits_set(used_fields); KEY_PART *key_part; uint keys= 0; - if (!parts) - return TRUE; - if (!(key_part= (KEY_PART *) alloc_root(param->mem_root, sizeof(KEY_PART) * parts))) return TRUE; @@ -3252,9 +3288,6 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param, Field *field= *field_ptr; if (bitmap_is_set(used_fields, field->field_index)) { - if (!is_eits_usable(field)) - continue; - uint16 store_length; uint16 max_key_part_length= (uint16) table->file->max_key_part_length(); key_part->key= keys; @@ -3656,8 +3689,6 @@ end_of_range_loop: PARAM param; MEM_ROOT alloc; SEL_TREE *tree; - double rows; - init_sql_alloc(key_memory_quick_range_select_root, &alloc, thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC)); @@ -3668,68 +3699,93 @@ end_of_range_loop: param.table= table; param.remove_false_where_parts= true; - if (create_key_parts_for_pseudo_indexes(¶m, used_fields)) - goto free_alloc; - param.prev_tables= param.read_tables= 0; param.current_table= table->map; param.using_real_indexes= FALSE; - param.real_keynr[0]= 0; + MEM_UNDEFINED(¶m.real_keynr, sizeof(param.real_keynr)); + param.alloced_sel_args= 0; param.max_key_parts= 0; - thd->no_errors=1; - - if (!(tree= cond[0]->get_mm_tree(¶m, cond))) - goto free_alloc; - + thd->no_errors=1; table->reginfo.impossible_range= 0; - if (tree->type == SEL_TREE::IMPOSSIBLE) - { - rows= 0; - table->reginfo.impossible_range= 1; - goto free_alloc; - } - else if (tree->type == SEL_TREE::ALWAYS) - { - rows= table_records; - goto free_alloc; - } - else if (tree->type == SEL_TREE::MAYBE) - { - rows= table_records; - goto free_alloc; - } - for (uint idx= 0; idx < param.keys; idx++) + uint used_fields_buff_size= bitmap_buffer_size(table->s->fields); + my_bitmap_map *used_fields_buff= (my_bitmap_map*)thd->alloc(used_fields_buff_size); + MY_BITMAP cols_for_indexes; + (void) my_bitmap_init(&cols_for_indexes, used_fields_buff, table->s->fields); + bitmap_clear_all(&cols_for_indexes); + + uint column_no= 0; // Start looping from the first column. + /* + Try getting selectivity estimates for every field that is used in the + query and has EITS statistics. We do this: + + for every usable field col + create a pseudo INDEX(col); + Run the range analyzer (get_mm_tree) for these pseudo-indexes; + Look at produced ranges and get their selectivity estimates; + + Note that the range analyzer can process at most MAX_KEY indexes. If + the table has >MAX_KEY eligible columns, we will do several range + analyzer runs. + */ + + while (1) { - SEL_ARG *key= tree->keys[idx]; - if (key) // Quick range found for key + column_no= get_columns_for_pseudo_indexes(table, used_fields, column_no, + &cols_for_indexes); + if (column_no == (uint)-1) + break; /* Couldn't create any pseudo-indexes. This means we're done */ + + if (create_key_parts_for_pseudo_indexes(¶m, &cols_for_indexes)) + goto free_alloc; + + tree= cond[0]->get_mm_tree(¶m, cond); + + if (!tree || + tree->type == SEL_TREE::ALWAYS || + tree->type == SEL_TREE::MAYBE) { - Json_writer_object selectivity_for_column(thd); - selectivity_for_column.add("column_name", key->field->field_name); - if (key->type == SEL_ARG::IMPOSSIBLE) + /* Couldn't infer anything. But there could be more fields, so continue */ + continue; + } + + if (tree->type == SEL_TREE::IMPOSSIBLE) + { + table->reginfo.impossible_range= 1; + goto free_alloc; + } + + for (uint idx= 0; idx < param.keys; idx++) + { + SEL_ARG *key= tree->keys[idx]; + if (key) { - rows= 0; - table->reginfo.impossible_range= 1; - if (unlikely(selectivity_for_column.trace_started())) - selectivity_for_column. - add("selectivity_from_histogram", rows). - add("cause", "impossible range"); - goto free_alloc; - } - else - { - enum_check_fields save_count_cuted_fields= thd->count_cuted_fields; - thd->count_cuted_fields= CHECK_FIELD_IGNORE; - rows= records_in_column_ranges(¶m, idx, key); - thd->count_cuted_fields= save_count_cuted_fields; - if (rows != DBL_MAX) + Json_writer_object selectivity_for_column(thd); + selectivity_for_column.add("column_name", key->field->field_name); + if (key->type == SEL_ARG::IMPOSSIBLE) { - key->field->cond_selectivity= rows/table_records; DBUG_ASSERT(key->field->cond_selectivity <= 1.0); - selectivity_for_column.add("selectivity_from_histogram", - key->field->cond_selectivity); + table->reginfo.impossible_range= 1; + if (unlikely(selectivity_for_column.trace_started())) + selectivity_for_column. + add("selectivity_from_histogram", 0). + add("cause", "impossible range"); + goto free_alloc; + } + else + { + enum_check_fields save_count_cuted_fields= thd->count_cuted_fields; + thd->count_cuted_fields= CHECK_FIELD_IGNORE; + double rows= records_in_column_ranges(¶m, idx, key); + thd->count_cuted_fields= save_count_cuted_fields; + if (rows != DBL_MAX) + { + key->field->cond_selectivity= rows/table_records; + selectivity_for_column.add("selectivity_from_histogram", + key->field->cond_selectivity); + } } } } @@ -6964,8 +7020,7 @@ ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param) void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src) { dst->param= src->param; - memcpy(dst->covered_fields.bitmap, src->covered_fields.bitmap, - no_bytes_in_map(&src->covered_fields)); + bitmap_copy(&dst->covered_fields, &src->covered_fields); dst->out_rows= src->out_rows; dst->is_covering= src->is_covering; dst->index_records= src->index_records; @@ -7650,7 +7705,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, (*scan)->used_fields_covered= bitmap_bits_set(&(*scan)->covered_fields); (*scan)->first_uncovered_field= - bitmap_get_first(&(*scan)->covered_fields); + bitmap_get_first_clear(&(*scan)->covered_fields); } my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark, sizeof(ROR_SCAN_INFO*), diff --git a/sql/opt_split.cc b/sql/opt_split.cc index aa6054b1244..9ae3eb47cf3 100644 --- a/sql/opt_split.cc +++ b/sql/opt_split.cc @@ -1360,6 +1360,7 @@ bool JOIN::fix_all_splittings_in_plan() { table_map prev_tables= 0; table_map all_tables= (table_map(1) << table_count) - 1; + table_map prev_sjm_lookup_tables= 0; for (uint tablenr= 0; tablenr < table_count; tablenr++) { POSITION *cur_pos= &best_positions[tablenr]; @@ -1368,7 +1369,7 @@ bool JOIN::fix_all_splittings_in_plan() { SplM_plan_info *spl_plan= cur_pos->spl_plan; table_map excluded_tables= (all_tables & ~prev_tables) | - sjm_lookup_tables; + prev_sjm_lookup_tables; ; if (spl_plan) { @@ -1386,6 +1387,8 @@ bool JOIN::fix_all_splittings_in_plan() return true; } prev_tables|= tab->table->map; + if (cur_pos->sj_strategy == SJ_OPT_MATERIALIZE) + prev_sjm_lookup_tables|= tab->table->map; } return false; } diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 333a3960360..bbfc02110a7 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -131,12 +131,13 @@ handle_queued_pos_update(THD *thd, rpl_parallel_thread::queued_event *qev) asynchronously, we need to be sure they will be completed before starting a new transaction. Otherwise the new transaction might suffer a spurious kill. */ -static void +void wait_for_pending_deadlock_kill(THD *thd, rpl_group_info *rgi) { PSI_stage_info old_stage; mysql_mutex_lock(&thd->LOCK_wakeup_ready); + thd->set_time_for_next_stage(); thd->ENTER_COND(&thd->COND_wakeup_ready, &thd->LOCK_wakeup_ready, &stage_waiting_for_deadlock_kill, &old_stage); while (rgi->killed_for_retry == rpl_group_info::RETRY_KILL_PENDING) @@ -214,6 +215,13 @@ finish_event_group(rpl_parallel_thread *rpt, uint64 sub_id, signal_error_to_sql_driver_thread(thd, rgi, err); thd->wait_for_commit_ptr= NULL; + /* + Calls to check_duplicate_gtid() must match up with + record_and_update_gtid() (or release_domain_owner() in error case). This + assertion tries to catch any missing release of the domain. + */ + DBUG_ASSERT(rgi->gtid_ignore_duplicate_state != rpl_group_info::GTID_DUPLICATE_OWNER); + mysql_mutex_lock(&entry->LOCK_parallel_entry); /* We need to mark that this event group started its commit phase, in case we @@ -399,12 +407,12 @@ do_gco_wait(rpl_group_info *rgi, group_commit_orderer *gco, if (wait_count > entry->count_committing_event_groups) { DEBUG_SYNC(thd, "rpl_parallel_start_waiting_for_prior"); + thd->set_time_for_next_stage(); thd->ENTER_COND(&gco->COND_group_commit_orderer, &entry->LOCK_parallel_entry, &stage_waiting_for_prior_transaction_to_start_commit, old_stage); *did_enter_cond= true; - thd->set_time_for_next_stage(); do { if (!rgi->worker_error && unlikely(thd->check_killed(1))) @@ -492,10 +500,10 @@ do_ftwrl_wait(rpl_group_info *rgi, */ if (unlikely(sub_id > entry->pause_sub_id)) { + thd->set_time_for_next_stage(); thd->ENTER_COND(&entry->COND_parallel_entry, &entry->LOCK_parallel_entry, &stage_waiting_for_ftwrl, old_stage); *did_enter_cond= true; - thd->set_time_for_next_stage(); do { if (entry->force_abort || rgi->worker_error) @@ -558,9 +566,9 @@ pool_mark_busy(rpl_parallel_thread_pool *pool, THD *thd) mysql_mutex_lock(&pool->LOCK_rpl_thread_pool); if (thd) { + thd->set_time_for_next_stage(); thd->ENTER_COND(&pool->COND_rpl_thread_pool, &pool->LOCK_rpl_thread_pool, &stage_waiting_for_rpl_thread_pool, &old_stage); - thd->set_time_for_next_stage(); } while (pool->busy) { @@ -700,9 +708,9 @@ rpl_pause_for_ftwrl(THD *thd) mysql_mutex_lock(&e->LOCK_parallel_entry); }); } + thd->set_time_for_next_stage(); thd->ENTER_COND(&e->COND_parallel_entry, &e->LOCK_parallel_entry, &stage_waiting_for_ftwrl_threads_to_pause, &old_stage); - thd->set_time_for_next_stage(); while (e->pause_sub_id < (uint64)ULONGLONG_MAX && e->last_committed_sub_id < e->pause_sub_id && !err) @@ -907,7 +915,13 @@ do_retry: }); #endif - rgi->cleanup_context(thd, 1); + /* + We are still applying the event group, even though we will roll it back + and retry it. So for --gtid-ignore-duplicates, keep ownership of the + domain during the retry so another master connection will not try to take + over and duplicate apply the same event group (MDEV-33475). + */ + rgi->cleanup_context(thd, 1, 1 /* keep_domain_owner */); wait_for_pending_deadlock_kill(thd, rgi); thd->reset_killed(); thd->clear_error(); @@ -2404,13 +2418,17 @@ rpl_parallel_thread_pool::copy_pool_for_pfs(Relay_log_info *rli) false Worker not allocated (choose_thread_internal not called) */ static bool handle_split_alter(rpl_parallel_entry *e, - Gtid_log_event *gtid_ev, uint32 *idx, + Gtid_log_event *gtid_ev, + //uint32 *idx, + rpl_parallel_entry::sched_bucket **ptr_cur_thr, //choose_thread_internal specific bool *did_enter_cond, rpl_group_info* rgi, PSI_stage_info *old_stage) { uint16 flags_extra= gtid_ev->flags_extra; bool thread_allocated= false; + uint32 i= 0, *idx= &i; + //Step 1 if (flags_extra & Gtid_log_event::FL_START_ALTER_E1 || //This will arrange finding threads for CA/RA as well @@ -2421,11 +2439,12 @@ static bool handle_split_alter(rpl_parallel_entry *e, j is needed for round robin scheduling, we will start with rpl_thread_idx go till rpl_thread_max and then start with 0 to rpl_thread_idx */ - int j= e->rpl_thread_idx; + auto j= static_cast(e->thread_sched_fifo->head() - e->rpl_threads); // formerly e->rpl_thread_idx; for(uint i= 0; i < e->rpl_thread_max; i++) { - if (!e->rpl_threads[j] || e->rpl_threads[j]->current_owner - != &e->rpl_threads[j] || !e->rpl_threads[j]->current_start_alter_id) + if (!e->rpl_threads[j].thr || + e->rpl_threads[j].thr->current_owner != &e->rpl_threads[j].thr || + !e->rpl_threads[j].thr->current_start_alter_id) { //This condition will hit atleast one time no matter what happens *idx= j; @@ -2436,17 +2455,26 @@ static bool handle_split_alter(rpl_parallel_entry *e, j= j % e->rpl_thread_max; } //We did not find and idx - DBUG_ASSERT(0); - return false; + DBUG_ASSERT(0); + + return false; + idx_found: - e->rpl_thread_idx= *idx; - e->choose_thread_internal(*idx, did_enter_cond, rgi, old_stage); + //e->rpl_thread_idx= *idx; + /* place the found *idx index into the head */ + *ptr_cur_thr= &e->rpl_threads[*idx]; + (*ptr_cur_thr)->unlink(); + e->thread_sched_fifo->append(*ptr_cur_thr); + *ptr_cur_thr= e->thread_sched_fifo->head(); + + e->choose_thread_internal(*ptr_cur_thr, did_enter_cond, rgi, + old_stage); thread_allocated= true; if (flags_extra & Gtid_log_event::FL_START_ALTER_E1) { - mysql_mutex_assert_owner(&e->rpl_threads[*idx]->LOCK_rpl_thread); - e->rpl_threads[e->rpl_thread_idx]->current_start_alter_id= gtid_ev->seq_no; - e->rpl_threads[e->rpl_thread_idx]->current_start_alter_domain_id= + mysql_mutex_assert_owner(&e->rpl_threads[*idx].thr->LOCK_rpl_thread); + e->rpl_threads[*idx].thr->current_start_alter_id= gtid_ev->seq_no; + e->rpl_threads[*idx].thr->current_start_alter_domain_id= gtid_ev->domain_id; /* We are locking LOCK_rpl_thread_pool becuase we are going to update @@ -2462,9 +2490,9 @@ idx_found: } else { - e->rpl_threads[*idx]->reserved_start_alter_thread= true; - e->rpl_threads[*idx]->current_start_alter_id= 0; - e->rpl_threads[*idx]->current_start_alter_domain_id= 0; + e->rpl_threads[*idx].thr->reserved_start_alter_thread= true; + e->rpl_threads[*idx].thr->current_start_alter_id= 0; + e->rpl_threads[*idx].thr->current_start_alter_domain_id= 0; } mysql_mutex_unlock(&global_rpl_thread_pool.LOCK_rpl_thread_pool); } @@ -2475,13 +2503,13 @@ idx_found: //Free the corrosponding rpt current_start_alter_id for(uint i= 0; i < e->rpl_thread_max; i++) { - if(e->rpl_threads[i] && - e->rpl_threads[i]->current_start_alter_id == gtid_ev->sa_seq_no && - e->rpl_threads[i]->current_start_alter_domain_id == gtid_ev->domain_id) + if(e->rpl_threads[i].thr && + e->rpl_threads[i].thr->current_start_alter_id == gtid_ev->sa_seq_no && + e->rpl_threads[i].thr->current_start_alter_domain_id == gtid_ev->domain_id) { mysql_mutex_lock(&global_rpl_thread_pool.LOCK_rpl_thread_pool); - e->rpl_threads[i]->current_start_alter_id= 0; - e->rpl_threads[i]->current_start_alter_domain_id= 0; + e->rpl_threads[i].thr->current_start_alter_id= 0; + e->rpl_threads[i].thr->current_start_alter_domain_id= 0; global_rpl_thread_pool.current_start_alters--; e->pending_start_alters--; DBUG_PRINT("info", ("Commit/Rollback alter id %d", i)); @@ -2496,6 +2524,79 @@ idx_found: } +/* + Check when we have done a complete round of scheduling for workers + 0, 1, ..., (rpl_thread_max-1), in this order. + This often occurs every rpl_thread_max event group, but XA XID dependency + restrictions can cause insertion of extra out-of-order worker scheduling + in-between the normal round-robin scheduling. +*/ +void +rpl_parallel_entry::check_scheduling_generation(sched_bucket *cur) +{ + uint32 idx= static_cast(cur - rpl_threads); + DBUG_ASSERT(cur >= rpl_threads); + DBUG_ASSERT(cur < rpl_threads + rpl_thread_max); + if (idx == current_generation_idx) + { + ++idx; + if (idx >= rpl_thread_max) + { + /* A new generation; all workers have been scheduled at least once. */ + idx= 0; + ++current_generation; + } + current_generation_idx= idx; + } +} + + +rpl_parallel_entry::sched_bucket * +rpl_parallel_entry::check_xa_xid_dependency(xid_t *xid) +{ + uint64 cur_gen= current_generation; + my_off_t i= 0; + while (i < maybe_active_xid.elements) + { + /* + Purge no longer active XID from the list: + + - In generation N, XID might have been scheduled for worker W. + - Events in generation (N+1) might run freely in parallel with W. + - Events in generation (N+2) will have done wait_for_prior_commit for + the event group with XID (or a later one), but the XID might still be + active for a bit longer after wakeup_prior_commit(). + - Events in generation (N+3) will have done wait_for_prior_commit() for + an event in W _after_ the XID, so are sure not to see the XID active. + + Therefore, XID can be safely scheduled to a different worker in + generation (N+3) when last prior use was in generation N (or earlier). + */ + xid_active_generation *a= + dynamic_element(&maybe_active_xid, i, xid_active_generation *); + if (a->generation + 3 <= cur_gen) + { + *a= *((xid_active_generation *)pop_dynamic(&maybe_active_xid)); + continue; + } + if (xid->eq(&a->xid)) + { + /* Update the last used generation and return the match. */ + a->generation= cur_gen; + return a->thr; + } + ++i; + } + /* try to keep allocated memory in the range of [2,10] * initial_chunk_size */ + if (maybe_active_xid.elements <= 2 * active_xid_init_alloc() && + maybe_active_xid.max_element > 10 * active_xid_init_alloc()) + freeze_size(&maybe_active_xid); + + /* No matching XID conflicts. */ + return nullptr; +} + + /* Obtain a worker thread that we can queue an event to. @@ -2528,40 +2629,70 @@ rpl_parallel_entry::choose_thread(rpl_group_info *rgi, bool *did_enter_cond, PSI_stage_info *old_stage, Gtid_log_event *gtid_ev) { - uint32 idx; + sched_bucket *cur_thr; - idx= rpl_thread_idx; if (gtid_ev) { - if (++idx >= rpl_thread_max) - idx= 0; + /* New event group; cycle the thread scheduling buckets round-robin. */ + thread_sched_fifo->push_back(thread_sched_fifo->get()); + //rpl_thread_idx will be updated handle_split_alter - if (handle_split_alter(this, gtid_ev, &idx, did_enter_cond, rgi, old_stage)) - return rpl_threads[idx]; + if (handle_split_alter(this, gtid_ev, &cur_thr, did_enter_cond, rgi, + old_stage)) + return cur_thr->thr; + if (gtid_ev->flags2 & (Gtid_log_event::FL_COMPLETED_XA | Gtid_log_event::FL_PREPARED_XA)) - { - idx= my_hash_sort(&my_charset_bin, gtid_ev->xid.key(), - gtid_ev->xid.key_length()) % rpl_thread_max; + { + if ((cur_thr= check_xa_xid_dependency(>id_ev->xid))) + { + /* + A previously scheduled event group with the same XID might still be + active in a worker, so schedule this event group in the same worker + to avoid a conflict. + */ + cur_thr->unlink(); + thread_sched_fifo->append(cur_thr); + } + else + { + /* Record this XID now active. */ + xid_active_generation *a= + (xid_active_generation *)alloc_dynamic(&maybe_active_xid); + if (!a) + return NULL; + a->thr= cur_thr= thread_sched_fifo->head(); + a->generation= current_generation; + a->xid.set(>id_ev->xid); + } } - rpl_thread_idx= idx; + else + cur_thr= thread_sched_fifo->head(); + + check_scheduling_generation(cur_thr); } - return choose_thread_internal(idx, did_enter_cond, rgi, old_stage); + else + cur_thr= thread_sched_fifo->head(); + + return choose_thread_internal(cur_thr /*idx*/, did_enter_cond, rgi, old_stage); } -rpl_parallel_thread * rpl_parallel_entry::choose_thread_internal(uint idx, - bool *did_enter_cond, rpl_group_info *rgi, - PSI_stage_info *old_stage) +rpl_parallel_thread * +rpl_parallel_entry::choose_thread_internal(sched_bucket *cur_thr, + bool *did_enter_cond, + rpl_group_info *rgi, + PSI_stage_info *old_stage) { - rpl_parallel_thread* thr= rpl_threads[idx]; Relay_log_info *rli= rgi->rli; + rpl_parallel_thread *thr= cur_thr->thr; + if (thr) { *did_enter_cond= false; mysql_mutex_lock(&thr->LOCK_rpl_thread); for (;;) { - if (thr->current_owner != &rpl_threads[idx]) + if (thr->current_owner != &cur_thr->thr) { /* The worker thread became idle, and returned to the free list and @@ -2593,16 +2724,16 @@ rpl_parallel_thread * rpl_parallel_entry::choose_thread_internal(uint idx, and this can cause THD::awake to use the wrong mutex. */ #ifdef ENABLED_DEBUG_SYNC - DBUG_EXECUTE_IF("rpl_parallel_wait_queue_max", - { - debug_sync_set_action(rli->sql_driver_thd, - STRING_WITH_LEN("now SIGNAL wait_queue_ready")); - };); + DBUG_EXECUTE_IF("rpl_parallel_wait_queue_max", { + debug_sync_set_action( + rli->sql_driver_thd, + STRING_WITH_LEN("now SIGNAL wait_queue_ready")); + };); #endif - rli->sql_driver_thd->ENTER_COND(&thr->COND_rpl_thread_queue, - &thr->LOCK_rpl_thread, - &stage_waiting_for_room_in_worker_thread, - old_stage); + rli->sql_driver_thd->set_time_for_next_stage(); + rli->sql_driver_thd->ENTER_COND( + &thr->COND_rpl_thread_queue, &thr->LOCK_rpl_thread, + &stage_waiting_for_room_in_worker_thread, old_stage); *did_enter_cond= true; } @@ -2612,11 +2743,11 @@ rpl_parallel_thread * rpl_parallel_entry::choose_thread_internal(uint idx, did_enter_cond, old_stage); my_error(ER_CONNECTION_KILLED, MYF(0)); #ifdef ENABLED_DEBUG_SYNC - DBUG_EXECUTE_IF("rpl_parallel_wait_queue_max", - { - debug_sync_set_action(rli->sql_driver_thd, - STRING_WITH_LEN("now SIGNAL wait_queue_killed")); - };); + DBUG_EXECUTE_IF("rpl_parallel_wait_queue_max", { + debug_sync_set_action( + rli->sql_driver_thd, + STRING_WITH_LEN("now SIGNAL wait_queue_killed")); + };); #endif slave_output_error_info(rgi, rli->sql_driver_thd); return NULL; @@ -2626,9 +2757,10 @@ rpl_parallel_thread * rpl_parallel_entry::choose_thread_internal(uint idx, } } } + if (!thr) - rpl_threads[idx]= thr= global_rpl_thread_pool.get_thread(&rpl_threads[idx], - this); + cur_thr->thr= thr= + global_rpl_thread_pool.get_thread(&cur_thr->thr, this); return thr; } @@ -2643,6 +2775,7 @@ free_rpl_parallel_entry(void *element) dealloc_gco(e->current_gco); e->current_gco= prev_gco; } + delete_dynamic(&e->maybe_active_xid); mysql_cond_destroy(&e->COND_parallel_entry); mysql_mutex_destroy(&e->LOCK_parallel_entry); my_free(e); @@ -2686,17 +2819,37 @@ rpl_parallel::find(uint32 domain_id, Relay_log_info *rli) ulong count= opt_slave_domain_parallel_threads; if (count == 0 || count > opt_slave_parallel_threads) count= opt_slave_parallel_threads; - rpl_parallel_thread **p; + rpl_parallel_entry::sched_bucket *p; + I_List *fifo; if (!my_multi_malloc(PSI_INSTRUMENT_ME, MYF(MY_WME|MY_ZEROFILL), &e, sizeof(*e), &p, count*sizeof(*p), + &fifo, sizeof(*fifo), NULL)) { my_error(ER_OUTOFMEMORY, MYF(0), (int)(sizeof(*e)+count*sizeof(*p))); return NULL; } + /* Initialize a FIFO of scheduled worker threads. */ + e->thread_sched_fifo = new (fifo) I_List; + /* + (We cycle the FIFO _before_ allocating next entry in + rpl_parallel_entry::choose_thread(). So initialize the FIFO with the + highest element at the front, just so that the first event group gets + scheduled on entry 0). + */ + e->thread_sched_fifo-> + push_back(::new (p+count-1) rpl_parallel_entry::sched_bucket); + for (ulong i= 0; i < count-1; ++i) + e->thread_sched_fifo-> + push_back(::new (p+i) rpl_parallel_entry::sched_bucket); e->rpl_threads= p; e->rpl_thread_max= count; + e->current_generation = 0; + e->current_generation_idx = 0; + init_dynamic_array2(PSI_INSTRUMENT_ME, &e->maybe_active_xid, + sizeof(rpl_parallel_entry::xid_active_generation), + 0, e->active_xid_init_alloc(), 0, MYF(0)); e->domain_id= domain_id; e->stop_on_error_sub_id= (uint64)ULONGLONG_MAX; e->pause_sub_id= (uint64)ULONGLONG_MAX; @@ -2766,10 +2919,10 @@ rpl_parallel::wait_for_done(THD *thd, Relay_log_info *rli) mysql_mutex_unlock(&e->LOCK_parallel_entry); for (j= 0; j < e->rpl_thread_max; ++j) { - if ((rpt= e->rpl_threads[j])) + if ((rpt= e->rpl_threads[j].thr)) { mysql_mutex_lock(&rpt->LOCK_rpl_thread); - if (rpt->current_owner == &e->rpl_threads[j]) + if (rpt->current_owner == &e->rpl_threads[j].thr) mysql_cond_signal(&rpt->COND_rpl_thread); mysql_mutex_unlock(&rpt->LOCK_rpl_thread); } @@ -2828,10 +2981,10 @@ rpl_parallel::wait_for_done(THD *thd, Relay_log_info *rli) e= (struct rpl_parallel_entry *)my_hash_element(&domain_hash, i); for (j= 0; j < e->rpl_thread_max; ++j) { - if ((rpt= e->rpl_threads[j])) + if ((rpt= e->rpl_threads[j].thr)) { mysql_mutex_lock(&rpt->LOCK_rpl_thread); - while (rpt->current_owner == &e->rpl_threads[j]) + while (rpt->current_owner == &e->rpl_threads[j].thr) mysql_cond_wait(&rpt->COND_rpl_thread_stop, &rpt->LOCK_rpl_thread); mysql_mutex_unlock(&rpt->LOCK_rpl_thread); } @@ -2889,7 +3042,7 @@ int rpl_parallel_entry::queue_master_restart(rpl_group_info *rgi, Format_description_log_event *fdev) { - uint32 idx; + sched_bucket *cur_thr; rpl_parallel_thread *thr; rpl_parallel_thread::queued_event *qev; Relay_log_info *rli= rgi->rli; @@ -2904,12 +3057,12 @@ rpl_parallel_entry::queue_master_restart(rpl_group_info *rgi, Thus there is no need for the full complexity of choose_thread(). We only need to check if we have a current worker thread, and queue for it if so. */ - idx= rpl_thread_idx; - thr= rpl_threads[idx]; + cur_thr= thread_sched_fifo->head(); + thr= cur_thr->thr; if (!thr) return 0; mysql_mutex_lock(&thr->LOCK_rpl_thread); - if (thr->current_owner != &rpl_threads[idx]) + if (thr->current_owner != &cur_thr->thr) { /* No active worker thread, so no need to queue the master restart. */ mysql_mutex_unlock(&thr->LOCK_rpl_thread); @@ -2953,6 +3106,7 @@ rpl_parallel::wait_for_workers_idle(THD *thd) e= (struct rpl_parallel_entry *)my_hash_element(&domain_hash, i); mysql_mutex_lock(&e->LOCK_parallel_entry); ++e->need_sub_id_signal; + thd->set_time_for_next_stage(); thd->ENTER_COND(&e->COND_parallel_entry, &e->LOCK_parallel_entry, &stage_waiting_for_workers_idle, &old_stage); while (e->current_sub_id > e->last_committed_sub_id) diff --git a/sql/rpl_parallel.h b/sql/rpl_parallel.h index 307d0e3bada..ef872dec66f 100644 --- a/sql/rpl_parallel.h +++ b/sql/rpl_parallel.h @@ -344,6 +344,27 @@ struct rpl_parallel_thread_pool { struct rpl_parallel_entry { + /* + A small struct to put worker threads references into a FIFO (using an + I_List) for round-robin scheduling. + */ + struct sched_bucket : public ilink { + sched_bucket() : thr(nullptr) { } + rpl_parallel_thread *thr; + }; + /* + A struct to keep track of into which "generation" an XA XID was last + scheduled. A "generation" means that we know that every worker thread + slot in the rpl_parallel_entry was scheduled at least once. When more + that two generations have passed, we can safely reuse the XID in a + different worker. + */ + struct xid_active_generation { + uint64 generation; + sched_bucket *thr; + xid_t xid; + }; + mysql_mutex_t LOCK_parallel_entry; mysql_cond_t COND_parallel_entry; uint32 domain_id; @@ -374,17 +395,36 @@ struct rpl_parallel_entry { uint64 stop_sub_id; /* - Cyclic array recording the last rpl_thread_max worker threads that we + Array recording the last rpl_thread_max worker threads that we queued event for. This is used to limit how many workers a single domain can occupy (--slave-domain-parallel-threads). + The array is structured as a FIFO using an I_List thread_sched_fifo. + Note that workers are never explicitly deleted from the array. Instead, we need to check (under LOCK_rpl_thread) that the thread still belongs to us before re-using (rpl_thread::current_owner). */ - rpl_parallel_thread **rpl_threads; + sched_bucket *rpl_threads; + I_List *thread_sched_fifo; uint32 rpl_thread_max; - uint32 rpl_thread_idx; + /* + Keep track of all XA XIDs that may still be active in a worker thread. + The elements are of type xid_active_generation. + */ + DYNAMIC_ARRAY maybe_active_xid; + /* + Keeping track of the current scheduling generation. + + A new generation means that every worker thread in the rpl_threads array + have been scheduled at least one event group. + + When we have scheduled to slot current_generation_idx= 0, 1, ..., N-1 in this + order, we know that (at least) one generation has passed. + */ + uint64 current_generation; + uint32 current_generation_idx; + /* The sub_id of the last transaction to commit within this domain_id. Must be accessed under LOCK_parallel_entry protection. @@ -440,14 +480,22 @@ struct rpl_parallel_entry { /* Relay log info of replication source for this entry. */ Relay_log_info *rli; + void check_scheduling_generation(sched_bucket *cur); + sched_bucket *check_xa_xid_dependency(xid_t *xid); rpl_parallel_thread * choose_thread(rpl_group_info *rgi, bool *did_enter_cond, PSI_stage_info *old_stage, Gtid_log_event *gtid_ev); rpl_parallel_thread * - choose_thread_internal(uint idx, bool *did_enter_cond, rpl_group_info *rgi, - PSI_stage_info *old_stage); + choose_thread_internal(sched_bucket *cur_thr, bool *did_enter_cond, + rpl_group_info *rgi, PSI_stage_info *old_stage); int queue_master_restart(rpl_group_info *rgi, Format_description_log_event *fdev); + /* + the initial size of maybe_ array corresponds to the case of + each worker receives perhaps unlikely XA-PREPARE and XA-COMMIT within + the same generation. + */ + inline uint active_xid_init_alloc() { return 3 * 2 * rpl_thread_max; } }; struct rpl_parallel { HASH domain_hash; @@ -470,6 +518,7 @@ struct rpl_parallel { extern struct rpl_parallel_thread_pool global_rpl_thread_pool; +extern void wait_for_pending_deadlock_kill(THD *thd, rpl_group_info *rgi); extern int rpl_parallel_resize_pool_if_no_slaves(void); extern int rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool); extern int rpl_parallel_inactivate_pool(rpl_parallel_thread_pool *pool); diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 9adf75228de..7f020bde162 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -44,8 +44,6 @@ rpl_slave_state *rpl_global_gtid_slave_state; /* Object used for MASTER_GTID_WAIT(). */ gtid_waiting rpl_global_gtid_waiting; -const char *const Relay_log_info::state_delaying_string = "Waiting until MASTER_DELAY seconds after master executed event"; - Relay_log_info::Relay_log_info(bool is_slave_recovery, const char* thread_name) :Slave_reporting_capability(thread_name), replicate_same_server_id(::replicate_same_server_id), @@ -2250,7 +2248,7 @@ delete_or_keep_event_post_apply(rpl_group_info *rgi, } -void rpl_group_info::cleanup_context(THD *thd, bool error) +void rpl_group_info::cleanup_context(THD *thd, bool error, bool keep_domain_owner) { DBUG_ENTER("rpl_group_info::cleanup_context"); DBUG_PRINT("enter", ("error: %d", (int) error)); @@ -2305,7 +2303,7 @@ void rpl_group_info::cleanup_context(THD *thd, bool error) Ensure we always release the domain for others to process, when using --gtid-ignore-duplicates. */ - if (gtid_ignore_duplicate_state != GTID_DUPLICATE_NULL) + if (gtid_ignore_duplicate_state != GTID_DUPLICATE_NULL && !keep_domain_owner) rpl_global_gtid_slave_state->release_domain_owner(this); } diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index 464baaced08..c3be5df4c11 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -508,11 +508,6 @@ public: m_flags&= ~flag; } - /** - Text used in THD::proc_info when the slave SQL thread is delaying. - */ - static const char *const state_delaying_string; - bool flush(); /** @@ -535,7 +530,7 @@ public: { mysql_mutex_assert_owner(&data_lock); sql_delay_end= delay_end; - thd_proc_info(sql_driver_thd, state_delaying_string); + THD_STAGE_INFO(sql_driver_thd, stage_sql_thd_waiting_until_delay); } int32 get_sql_delay() { return sql_delay; } @@ -566,6 +561,10 @@ private: Guarded by data_lock. Written by the sql thread. Read by client threads executing SHOW SLAVE STATUS. + + This is calculated as: + clock_time_for_event_on_master + clock_difference_between_master_and_slave + + SQL_DELAY. */ time_t sql_delay_end; @@ -960,7 +959,7 @@ struct rpl_group_info } void clear_tables_to_lock(); - void cleanup_context(THD *, bool); + void cleanup_context(THD *, bool, bool keep_domain_owner= false); void slave_close_thread_tables(THD *); void mark_start_commit_no_lock(); void mark_start_commit(); diff --git a/sql/semisync_master.cc b/sql/semisync_master.cc index cfe9b8c3a99..fdf2cf21cf1 100644 --- a/sql/semisync_master.cc +++ b/sql/semisync_master.cc @@ -68,6 +68,19 @@ static ulonglong timespec_to_usec(const struct timespec *ts) return (ulonglong) ts->tv_sec * TIME_MILLION + ts->tv_nsec / TIME_THOUSAND; } +int signal_waiting_transaction(THD *waiting_thd, const char *binlog_file, + my_off_t binlog_pos) +{ + /* + It is possible that the connection thd waiting for an ACK was killed. In + such circumstance, the connection thread will nullify the thd member of its + Active_tranx node. So before we try to signal, ensure the THD exists. + */ + if (waiting_thd) + mysql_cond_signal(&waiting_thd->COND_wakeup_ready); + return 0; +} + /******************************************************************************* * * class : manage all active transaction nodes @@ -75,12 +88,14 @@ static ulonglong timespec_to_usec(const struct timespec *ts) ******************************************************************************/ Active_tranx::Active_tranx(mysql_mutex_t *lock, + mysql_cond_t *cond, ulong trace_level) : Trace(trace_level), m_allocator(max_connections), m_num_entries(max_connections << 1), /* Transaction hash table size * is set to double the size * of max_connections */ - m_lock(lock) + m_lock(lock), + m_cond_empty(cond) { /* No transactions are in the list initially. */ m_trx_front = NULL; @@ -142,7 +157,8 @@ int Active_tranx::compare(const char *log_file_name1, my_off_t log_file_pos1, return 0; } -int Active_tranx::insert_tranx_node(const char *log_file_name, +int Active_tranx::insert_tranx_node(THD *thd_to_wait, + const char *log_file_name, my_off_t log_file_pos) { Tranx_node *ins_node; @@ -165,6 +181,7 @@ int Active_tranx::insert_tranx_node(const char *log_file_name, strncpy(ins_node->log_name, log_file_name, FN_REFLEN-1); ins_node->log_name[FN_REFLEN-1] = 0; /* make sure it ends properly */ ins_node->log_pos = log_file_pos; + ins_node->thd= thd_to_wait; if (!m_trx_front) { @@ -232,28 +249,22 @@ bool Active_tranx::is_tranx_end_pos(const char *log_file_name, DBUG_RETURN(entry != NULL); } -void Active_tranx::clear_active_tranx_nodes(const char *log_file_name, - my_off_t log_file_pos) +void Active_tranx::clear_active_tranx_nodes( + const char *log_file_name, my_off_t log_file_pos, + active_tranx_action pre_delete_hook) { Tranx_node *new_front; DBUG_ENTER("Active_tranx::::clear_active_tranx_nodes"); - if (log_file_name != NULL) + new_front= m_trx_front; + while (new_front) { - new_front = m_trx_front; - - while (new_front) - { - if (compare(new_front, log_file_name, log_file_pos) > 0) - break; - new_front = new_front->next; - } - } - else - { - /* If log_file_name is NULL, clear everything. */ - new_front = NULL; + if ((log_file_name != NULL) && + compare(new_front, log_file_name, log_file_pos) > 0) + break; + pre_delete_hook(new_front->thd, new_front->log_name, new_front->log_pos); + new_front = new_front->next; } if (new_front == NULL) @@ -315,9 +326,66 @@ void Active_tranx::clear_active_tranx_nodes(const char *log_file_name, m_trx_front->log_name, (ulong)m_trx_front->log_pos)); } + /* + m_cond_empty aliases Repl_semi_sync_master::COND_binlog, which holds the + condition variable to notify that we have cleared all nodes, e.g. used by + SHUTDOWN WAIT FOR ALL SLAVES. + */ + if (is_empty()) + mysql_cond_signal(m_cond_empty); + DBUG_VOID_RETURN; } +void Active_tranx::unlink_thd_as_waiter(const char *log_file_name, + my_off_t log_file_pos) +{ + DBUG_ENTER("Active_tranx::unlink_thd_as_waiter"); + mysql_mutex_assert_owner(m_lock); + + unsigned int hash_val = get_hash_value(log_file_name, log_file_pos); + Tranx_node *entry = m_trx_htb[hash_val]; + + while (entry != NULL) + { + if (compare(entry, log_file_name, log_file_pos) == 0) + break; + + entry = entry->hash_next; + } + + if (entry) + entry->thd= NULL; + + DBUG_VOID_RETURN; +} + +#ifndef DBUG_OFF +void Active_tranx::assert_thd_is_waiter(THD *thd_to_check, + const char *log_file_name, + my_off_t log_file_pos) +{ + DBUG_ENTER("Active_tranx::assert_thd_is_waiter"); + mysql_mutex_assert_owner(m_lock); + + unsigned int hash_val = get_hash_value(log_file_name, log_file_pos); + Tranx_node *entry = m_trx_htb[hash_val]; + + while (entry != NULL) + { + if (compare(entry, log_file_name, log_file_pos) == 0) + break; + + entry = entry->hash_next; + } + + DBUG_ASSERT(entry); + DBUG_ASSERT(entry->thd); + DBUG_ASSERT(entry->thd->thread_id == thd_to_check->thread_id); + + DBUG_VOID_RETURN; +} +#endif /******************************************************************************* * @@ -397,7 +465,8 @@ int Repl_semi_sync_master::enable_master() if (!get_master_enabled()) { - m_active_tranxs = new Active_tranx(&LOCK_binlog, m_trace_level); + m_active_tranxs= + new Active_tranx(&LOCK_binlog, &COND_binlog_send, m_trace_level); if (m_active_tranxs != NULL) { m_commit_file_name_inited = false; @@ -459,15 +528,6 @@ void Repl_semi_sync_master::cleanup() delete m_active_tranxs; } -int Repl_semi_sync_master::sync_get_master_wait_sessions() -{ - int wait_sessions; - lock(); - wait_sessions= rpl_semi_sync_master_wait_sessions; - unlock(); - return wait_sessions; -} - void Repl_semi_sync_master::create_timeout(struct timespec *out, struct timespec *start_arg) { @@ -500,23 +560,6 @@ void Repl_semi_sync_master::unlock() mysql_mutex_unlock(&LOCK_binlog); } -void Repl_semi_sync_master::cond_broadcast() -{ - mysql_cond_broadcast(&COND_binlog_send); -} - -int Repl_semi_sync_master::cond_timewait(struct timespec *wait_time) -{ - int wait_res; - - DBUG_ENTER("Repl_semi_sync_master::cond_timewait()"); - - wait_res= mysql_cond_timedwait(&COND_binlog_send, - &LOCK_binlog, wait_time); - - DBUG_RETURN(wait_res); -} - void Repl_semi_sync_master::add_slave() { lock(); @@ -533,7 +576,8 @@ void Repl_semi_sync_master::remove_slave() Signal transactions waiting in commit_trx() that they do not have to wait anymore. */ - cond_broadcast(); + m_active_tranxs->clear_active_tranx_nodes(NULL, 0, + signal_waiting_transaction); } unlock(); } @@ -616,7 +660,6 @@ int Repl_semi_sync_master::report_reply_binlog(uint32 server_id, my_off_t log_file_pos) { int cmp; - bool can_release_threads = false; bool need_copy_send_pos = true; DBUG_ENTER("Repl_semi_sync_master::report_reply_binlog"); @@ -668,45 +711,26 @@ int Repl_semi_sync_master::report_reply_binlog(uint32 server_id, /* Remove all active transaction nodes before this point. */ DBUG_ASSERT(m_active_tranxs != NULL); - m_active_tranxs->clear_active_tranx_nodes(log_file_name, log_file_pos); + m_active_tranxs->clear_active_tranx_nodes(log_file_name, log_file_pos, + signal_waiting_transaction); + if (m_active_tranxs->is_empty()) + m_wait_file_name_inited= false; DBUG_PRINT("semisync", ("%s: Got reply at (%s, %lu)", "Repl_semi_sync_master::report_reply_binlog", log_file_name, (ulong)log_file_pos)); } - if (rpl_semi_sync_master_wait_sessions > 0) - { - /* Let us check if some of the waiting threads doing a trx - * commit can now proceed. - */ - cmp = Active_tranx::compare(m_reply_file_name, m_reply_file_pos, - m_wait_file_name, m_wait_file_pos); - if (cmp >= 0) - { - /* Yes, at least one waiting thread can now proceed: - * let us release all waiting threads with a broadcast - */ - can_release_threads = true; - m_wait_file_name_inited = false; - } - } l_end: unlock(); - if (can_release_threads) - { - DBUG_PRINT("semisync", ("%s: signal all waiting threads.", - "Repl_semi_sync_master::report_reply_binlog")); - - cond_broadcast(); - } DBUG_RETURN(0); } -int Repl_semi_sync_master::wait_after_sync(const char *log_file, my_off_t log_pos) +int Repl_semi_sync_master::wait_after_sync(const char *log_file, + my_off_t log_pos) { if (!get_master_enabled()) return 0; @@ -762,24 +786,27 @@ int Repl_semi_sync_master::wait_after_rollback(THD *thd, bool all) /** The method runs after flush to binary log is done. */ -int Repl_semi_sync_master::report_binlog_update(THD* thd, const char *log_file, +int Repl_semi_sync_master::report_binlog_update(THD *trans_thd, + THD *waiter_thd, + const char *log_file, my_off_t log_pos) { if (get_master_enabled()) { Trans_binlog_info *log_info; - if (!(log_info= thd->semisync_info)) + if (!(log_info= trans_thd->semisync_info)) { if(!(log_info= (Trans_binlog_info*)my_malloc(PSI_INSTRUMENT_ME, sizeof(Trans_binlog_info), MYF(0)))) return 1; - thd->semisync_info= log_info; + trans_thd->semisync_info= log_info; } strcpy(log_info->log_file, log_file + dirname_length(log_file)); log_info->log_pos = log_pos; - return write_tranx_in_binlog(log_info->log_file, log_pos); + return write_tranx_in_binlog(waiter_thd, log_info->log_file, + log_pos); } return 0; @@ -825,7 +852,7 @@ void Repl_semi_sync_master::dump_end(THD* thd) ack_receiver.remove_slave(thd); } -int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, +int Repl_semi_sync_master::commit_trx(const char *trx_wait_binlog_name, my_off_t trx_wait_binlog_pos) { bool success= 0; @@ -844,7 +871,7 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, int wait_result; PSI_stage_info old_stage; THD *thd= current_thd; - bool aborted= 0; + bool aborted __attribute__((unused)) = 0; set_timespec(start_ts, 0); DEBUG_SYNC(thd, "rpl_semisync_master_commit_trx_before_lock"); @@ -852,9 +879,8 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, lock(); /* This must be called after acquired the lock */ - THD_ENTER_COND(thd, &COND_binlog_send, &LOCK_binlog, - & stage_waiting_for_semi_sync_ack_from_slave, - & old_stage); + THD_ENTER_COND(thd, &thd->COND_wakeup_ready, &LOCK_binlog, + &stage_waiting_for_semi_sync_ack_from_slave, &old_stage); /* This is the real check inside the mutex. */ if (!get_master_enabled() || !is_on()) @@ -865,7 +891,7 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, trx_wait_binlog_name, (ulong)trx_wait_binlog_pos, (int)is_on())); - while (is_on() && !thd_killed(thd)) + while (is_on() && !(aborted= thd_killed(thd))) { /* We have to check these again as things may have changed */ if (!rpl_semi_sync_master_clients && !rpl_semi_sync_master_wait_no_slave) @@ -902,7 +928,7 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, trx_wait_binlog_pos, m_wait_file_name, m_wait_file_pos); if (cmp <= 0) - { + { /* This thd has a lower position, let's update the minimum info. */ strmake_buf(m_wait_file_name, trx_wait_binlog_name); m_wait_file_pos = trx_wait_binlog_pos; @@ -934,20 +960,18 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, */ rpl_semi_sync_master_wait_sessions++; - /* We keep track of when this thread is awaiting an ack to ensure it is - * not killed while awaiting an ACK if a shutdown is issued. - */ - set_thd_awaiting_semisync_ack(thd, TRUE); - DBUG_PRINT("semisync", ("%s: wait %lu ms for binlog sent (%s, %lu)", "Repl_semi_sync_master::commit_trx", m_wait_timeout, m_wait_file_name, (ulong)m_wait_file_pos)); +#ifndef DBUG_OFF + m_active_tranxs->assert_thd_is_waiter(thd, trx_wait_binlog_name, + trx_wait_binlog_pos); +#endif create_timeout(&abstime, &start_ts); - wait_result = cond_timewait(&abstime); - - set_thd_awaiting_semisync_ack(thd, FALSE); + wait_result= mysql_cond_timedwait(&thd->COND_wakeup_ready, &LOCK_binlog, + &abstime); rpl_semi_sync_master_wait_sessions--; if (wait_result != 0) @@ -979,17 +1003,49 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, { rpl_semi_sync_master_trx_wait_num++; rpl_semi_sync_master_trx_wait_time += wait_time; + + DBUG_EXECUTE_IF("testing_cond_var_per_thd", { + /* + DBUG log warning to ensure we have either recieved our ACK; or + have timed out and are awoken in an off state. Test + rpl.rpl_semi_sync_cond_var_per_thd scans the logs to ensure this + warning is not present. + */ + bool valid_wakeup= + (!get_master_enabled() || !is_on() || thd->is_killed() || + 0 <= Active_tranx::compare( + m_reply_file_name, m_reply_file_pos, + trx_wait_binlog_name, trx_wait_binlog_pos)); + if (!valid_wakeup) + { + sql_print_warning( + "Thread awaiting semi-sync ACK was awoken before its " + "ACK. THD (%llu), Wait coord: (%s, %llu), ACK coord: (%s, " + "%llu)", + thd->thread_id, trx_wait_binlog_name, trx_wait_binlog_pos, + m_reply_file_name, m_reply_file_pos); + } + }); } } } + /* + If our THD was killed (rather than awoken from an ACK) notify the + Active_tranx cache that we are no longer waiting for the ACK, so nobody + signals our COND var invalidly. + */ + if (aborted) + m_active_tranxs->unlink_thd_as_waiter(trx_wait_binlog_name, + trx_wait_binlog_pos); + /* At this point, the binlog file and position of this transaction must have been removed from Active_tranx. m_active_tranxs may be NULL if someone disabled semi sync during - cond_timewait() + mysql_cond_timedwait */ - DBUG_ASSERT(thd_killed(thd) || !m_active_tranxs || aborted || + DBUG_ASSERT(aborted || !m_active_tranxs || m_active_tranxs->is_empty() || !m_active_tranxs->is_tranx_end_pos(trx_wait_binlog_name, trx_wait_binlog_pos)); @@ -1030,20 +1086,21 @@ void Repl_semi_sync_master::switch_off() { DBUG_ENTER("Repl_semi_sync_master::switch_off"); + /* Clear the active transaction list. */ + if (m_active_tranxs) + m_active_tranxs->clear_active_tranx_nodes(NULL, 0, + signal_waiting_transaction); + if (m_state) { m_state = false; - /* Clear the active transaction list. */ - DBUG_ASSERT(m_active_tranxs != NULL); - m_active_tranxs->clear_active_tranx_nodes(NULL, 0); rpl_semi_sync_master_off_times++; m_wait_file_name_inited = false; m_reply_file_name_inited = false; sql_print_information("Semi-sync replication switched OFF."); } - cond_broadcast(); /* wake up all waiting threads */ DBUG_VOID_RETURN; } @@ -1190,7 +1247,8 @@ int Repl_semi_sync_master::update_sync_header(THD* thd, unsigned char *packet, DBUG_RETURN(0); } -int Repl_semi_sync_master::write_tranx_in_binlog(const char* log_file_name, +int Repl_semi_sync_master::write_tranx_in_binlog(THD *thd, + const char *log_file_name, my_off_t log_file_pos) { int result = 0; @@ -1233,7 +1291,7 @@ int Repl_semi_sync_master::write_tranx_in_binlog(const char* log_file_name, if (is_on()) { DBUG_ASSERT(m_active_tranxs != NULL); - if(m_active_tranxs->insert_tranx_node(log_file_name, log_file_pos)) + if(m_active_tranxs->insert_tranx_node(thd, log_file_name, log_file_pos)) { /* if insert tranx_node failed, print a warning message @@ -1362,21 +1420,34 @@ void Repl_semi_sync_master::set_export_stats() unlock(); } -void Repl_semi_sync_master::await_slave_reply() +void Repl_semi_sync_master::await_all_slave_replies(const char *msg) { - struct timespec abstime; + struct timespec timeout; + int wait_result= 0; + bool first= true; + DBUG_ENTER("Repl_semi_sync_master::::await_all_slave_replies"); - DBUG_ENTER("Repl_semi_sync_master::::await_slave_reply"); + /* + Wait for all transactions that need ACKS to have received them; or timeout. + If it is a timeout, the connection thread should attempt to turn off + semi-sync and broadcast to all other waiting threads to move on. + + COND_binlog_send is only signalled after the Active_tranx cache has been + emptied. + */ + create_timeout(&timeout, NULL); lock(); + while (get_master_enabled() && is_on() && !m_active_tranxs->is_empty() && !wait_result) + { + if (msg && first) + { + first= false; + sql_print_information(msg); + } - /* Just return if there is nothing to wait for */ - if (!rpl_semi_sync_master_wait_sessions) - goto end; - - create_timeout(&abstime, NULL); - cond_timewait(&abstime); - -end: + wait_result= + mysql_cond_timedwait(&COND_binlog_send, &LOCK_binlog, &timeout); + } unlock(); DBUG_VOID_RETURN; } diff --git a/sql/semisync_master.h b/sql/semisync_master.h index 99f46869354..3978d21a61d 100644 --- a/sql/semisync_master.h +++ b/sql/semisync_master.h @@ -31,6 +31,7 @@ extern PSI_cond_key key_COND_binlog_send; struct Tranx_node { char log_name[FN_REFLEN]; my_off_t log_pos; + THD *thd; /* The thread awaiting an ACK */ struct Tranx_node *next; /* the next node in the sorted list */ struct Tranx_node *hash_next; /* the next node during hash collision */ }; @@ -288,6 +289,18 @@ private: } }; +/** + Function pointer type to run on the contents of an Active_tranx node. + + Return 0 for success, 1 for error. + + Note Repl_semi_sync_master::LOCK_binlog is not guaranteed to be held for + its invocation. See the context in which it is called to know. +*/ + +typedef int (*active_tranx_action)(THD *trx_thd, const char *log_file_name, + my_off_t trx_log_file_pos); + /** This class manages memory for active transaction list. @@ -308,6 +321,7 @@ private: int m_num_entries; /* maximum hash table entries */ mysql_mutex_t *m_lock; /* mutex lock */ + mysql_cond_t *m_cond_empty; /* signalled when cleared all Tranx_node */ inline void assert_lock_owner(); @@ -330,7 +344,8 @@ private: } public: - Active_tranx(mysql_mutex_t *lock, unsigned long trace_level); + Active_tranx(mysql_mutex_t *lock, mysql_cond_t *cond, + unsigned long trace_level); ~Active_tranx(); /* Insert an active transaction node with the specified position. @@ -338,15 +353,38 @@ public: * Return: * 0: success; non-zero: error */ - int insert_tranx_node(const char *log_file_name, my_off_t log_file_pos); + int insert_tranx_node(THD *thd_to_wait, const char *log_file_name, + my_off_t log_file_pos); /* Clear the active transaction nodes until(inclusive) the specified * position. * If log_file_name is NULL, everything will be cleared: the sorted * list and the hash table will be reset to empty. + * + * The pre_delete_hook parameter is a function pointer that will be invoked + * for each Active_tranx node, in order, from m_trx_front to m_trx_rear, + * e.g. to signal their wakeup condition. Repl_semi_sync_binlog::LOCK_binlog + * is held while this is invoked. */ void clear_active_tranx_nodes(const char *log_file_name, - my_off_t log_file_pos); + my_off_t log_file_pos, + active_tranx_action pre_delete_hook); + + /* Unlinks a thread from a Tranx_node, so it will not be referenced/signalled + * if it is separately killed. Note that this keeps the Tranx_node itself in + * the cache so it can still be awaited by await_all_slave_replies(), e.g. + * as is done by SHUTDOWN WAIT FOR ALL SLAVES. + */ + void unlink_thd_as_waiter(const char *log_file_name, my_off_t log_file_pos); + +#ifndef DBUG_OFF + /* Uses DBUG_ASSERT statements to ensure that the argument thd_to_check + * matches the thread of the respective Tranx_node::thd of the passed in + * log_file_name and log_file_pos. + */ + void assert_thd_is_waiter(THD *thd_to_check, const char *log_file_name, + my_off_t log_file_pos); +#endif /* Given a position, check to see whether the position is an active * transaction's ending position by probing the hash table. @@ -359,6 +397,12 @@ public: static int compare(const char *log_file_name1, my_off_t log_file_pos1, const char *log_file_name2, my_off_t log_file_pos2); + + /* Check if there are no transactions actively awaiting ACKs. Returns true + * if the internal linked list has no entries, false otherwise. + */ + bool is_empty() { return m_trx_front == NULL; } + }; /** @@ -433,8 +477,6 @@ class Repl_semi_sync_master void lock(); void unlock(); - void cond_broadcast(); - int cond_timewait(struct timespec *wait_time); /* Is semi-sync replication on? */ bool is_on() { @@ -472,8 +514,6 @@ class Repl_semi_sync_master m_wait_timeout = wait_timeout; } - int sync_get_master_wait_sessions(); - /* Calculates a timeout that is m_wait_timeout after start_arg and saves it in out. If start_arg is NULL, the timeout is m_wait_timeout after the @@ -482,10 +522,15 @@ class Repl_semi_sync_master void create_timeout(struct timespec *out, struct timespec *start_arg); /* - Blocks the calling thread until the ack_receiver either receives an ACK - or times out (from rpl_semi_sync_master_timeout) + Blocks the calling thread until the ack_receiver either receives ACKs for + all transactions awaiting ACKs, or times out (from + rpl_semi_sync_master_timeout). + + If info_msg is provided, it will be output via sql_print_information when + there are transactions awaiting ACKs; info_msg is not output if there are + no transasctions to await. */ - void await_slave_reply(); + void await_all_slave_replies(const char *msg); /*set the ACK point, after binlog sync or after transaction commit*/ void set_wait_point(unsigned long ack_point) @@ -561,9 +606,23 @@ class Repl_semi_sync_master /*Wait after the transaction is rollback*/ int wait_after_rollback(THD *thd, bool all); - /*Store the current binlog position in m_active_tranxs. This position should - * be acked by slave*/ - int report_binlog_update(THD *thd, const char *log_file,my_off_t log_pos); + /* Store the current binlog position in m_active_tranxs. This position should + * be acked by slave. + * + * Inputs: + * trans_thd Thread of the transaction which is executing the + * transaction. + * waiter_thd Thread that will wait for the ACK from the replica, + * which depends on the semi-sync wait point. If AFTER_SYNC, + * and also using binlog group commit, this will be the leader + * thread of the binlog commit. Otherwise, it is the thread that + * is executing the transaction, i.e. the same as trans_thd. + * log_file Name of the binlog file that the transaction is written into + * log_pos Offset within the binlog file that the transaction is written + * at + */ + int report_binlog_update(THD *trans_thd, THD *waiter_thd, + const char *log_file, my_off_t log_pos); int dump_start(THD* thd, const char *log_file, @@ -609,13 +668,19 @@ class Repl_semi_sync_master * semi-sync is on * * Input: (the transaction events' ending binlog position) + * THD - (IN) thread that will wait for an ACK. This can be the + * binlog leader thread when using wait_point + * AFTER_SYNC with binlog group commit. In all other + * cases, this is the user thread executing the + * transaction. * log_file_name - (IN) transaction ending position's file name * log_file_pos - (IN) transaction ending position's file offset * * Return: * 0: success; non-zero: error */ - int write_tranx_in_binlog(const char* log_file_name, my_off_t log_file_pos); + int write_tranx_in_binlog(THD *thd, const char *log_file_name, + my_off_t log_file_pos); /* Read the slave's reply so that we know how much progress the slave makes * on receive replication events. @@ -633,30 +698,6 @@ class Repl_semi_sync_master /*called before reset master*/ int before_reset_master(); - /* - Determines if the given thread is currently awaiting a semisync_ack. Note - that the thread's value is protected by this class's LOCK_binlog, so this - function (indirectly) provides safe access. - */ - my_bool is_thd_awaiting_semisync_ack(THD *thd) - { - lock(); - my_bool ret= thd->is_awaiting_semisync_ack; - unlock(); - return ret; - } - - /* - Update the thread's value for is_awaiting_semisync_ack. LOCK_binlog (from - this class) should be acquired before calling this function. - */ - void set_thd_awaiting_semisync_ack(THD *thd, - my_bool _is_awaiting_semisync_ack) - { - mysql_mutex_assert_owner(&LOCK_binlog); - thd->is_awaiting_semisync_ack= _is_awaiting_semisync_ack; - } - mysql_mutex_t LOCK_rpl_semi_sync_master_enabled; }; diff --git a/sql/semisync_master_ack_receiver.cc b/sql/semisync_master_ack_receiver.cc index a311599c54b..29fa5fd5328 100644 --- a/sql/semisync_master_ack_receiver.cc +++ b/sql/semisync_master_ack_receiver.cc @@ -149,7 +149,7 @@ bool Ack_receiver::add_slave(THD *thd) slave->thd= thd; slave->vio= *thd->net.vio; slave->vio.mysql_socket.m_psi= NULL; - slave->vio.read_timeout= 1; + slave->vio.read_timeout= 1; // 1 ms mysql_mutex_lock(&m_mutex); @@ -338,6 +338,17 @@ void Ack_receiver::run() */ net.compress= slave->thd->net.compress; + if (unlikely(listener.is_socket_hangup(slave))) + { + if (global_system_variables.log_warnings > 2) + sql_print_warning("Semisync ack receiver got hangup " + "from slave server-id %d", + slave->server_id()); + it.remove(); + m_slaves_changed= true; + continue; + } + len= my_net_read(&net); if (likely(len != packet_error)) { diff --git a/sql/semisync_master_ack_receiver.h b/sql/semisync_master_ack_receiver.h index eacb4b200c0..6b3ff3695d0 100644 --- a/sql/semisync_master_ack_receiver.h +++ b/sql/semisync_master_ack_receiver.h @@ -186,7 +186,7 @@ public: char buff[100]; /* Clear the signal message */ #ifndef _WIN32 - read(local_read_signal, buff, sizeof(buff)); + (void) !read(local_read_signal, buff, sizeof(buff)); #else recv(local_read_signal, buff, sizeof(buff), 0); #endif /* _WIN32 */ @@ -228,6 +228,11 @@ public: return m_fds[slave->m_fds_index].revents & POLLIN; } + bool is_socket_hangup(const Slave *slave) + { + return m_fds[slave->m_fds_index].revents & POLLHUP; + } + void clear_socket_info(const Slave *slave) { m_fds[slave->m_fds_index].fd= -1; @@ -296,6 +301,11 @@ public: return FD_ISSET(slave->sock_fd(), &m_fds); } + bool is_socket_hangup(const Slave *slave) + { + return 0; + } + bool has_signal_data() override { return FD_ISSET(local_read_signal, &m_fds); diff --git a/sql/semisync_slave.cc b/sql/semisync_slave.cc index 4314b116287..d10754ad374 100644 --- a/sql/semisync_slave.cc +++ b/sql/semisync_slave.cc @@ -17,6 +17,7 @@ #include #include "semisync_slave.h" +#include "debug_sync.h" Repl_semi_sync_slave repl_semisync_slave; @@ -33,7 +34,6 @@ int Repl_semi_sync_slave::init_object() m_init_done = true; /* References to the parameter works after set_options(). */ - set_slave_enabled(global_rpl_semi_sync_slave_enabled); set_trace_level(rpl_semi_sync_slave_trace_level); set_delay_master(rpl_semi_sync_slave_delay_master); set_kill_conn_timeout(rpl_semi_sync_slave_kill_conn_timeout); @@ -128,7 +128,21 @@ void Repl_semi_sync_slave::slave_start(Master_info *mi) void Repl_semi_sync_slave::slave_stop(Master_info *mi) { if (get_slave_enabled()) + { +#ifdef ENABLED_DEBUG_SYNC + /* + TODO: Remove after MDEV-28141 + */ + DBUG_EXECUTE_IF("delay_semisync_kill_connection_for_mdev_28141", { + const char act[]= "now " + "signal at_semisync_kill_connection " + "wait_for continue_semisync_kill_connection"; + DBUG_ASSERT(debug_sync_service); + DBUG_ASSERT(!debug_sync_set_action(mi->io_thd, STRING_WITH_LEN(act))); + };); +#endif kill_connection(mi->mysql); + } set_slave_enabled(0); } @@ -167,8 +181,6 @@ void Repl_semi_sync_slave::kill_connection(MYSQL *mysql) goto failed_graceful_kill; } - DBUG_EXECUTE_IF("slave_delay_killing_semisync_connection", my_sleep(400000);); - kill_buffer_length= my_snprintf(kill_buffer, 30, "KILL %lu", mysql->thread_id); if (mysql_real_query(kill_mysql, kill_buffer, (ulong)kill_buffer_length)) diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc index 17240fd4fbd..f8c6ddaa28b 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -1,4 +1,4 @@ -/* Copyright 2018-2023 Codership Oy +/* Copyright 2018-2024 Codership Oy 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 @@ -201,11 +201,11 @@ extern "C" void wsrep_handle_SR_rollback(THD *bf_thd, /* Note: do not store/reset globals before wsrep_bf_abort() call to avoid losing BF thd context. */ - mysql_mutex_lock(&victim_thd->LOCK_thd_data); if (!(bf_thd && bf_thd != victim_thd)) { DEBUG_SYNC(victim_thd, "wsrep_before_SR_rollback"); } + mysql_mutex_lock(&victim_thd->LOCK_thd_data); if (bf_thd) { wsrep_bf_abort(bf_thd, victim_thd); @@ -263,12 +263,28 @@ extern "C" my_bool wsrep_thd_order_before(const THD *left, const THD *right) return FALSE; } +/** Check if wsrep transaction is aborting state. + +Calling function should make sure that wsrep transaction state +can't change during this function. + +This function is called from +wsrep_abort_thd where we hold THD::LOCK_thd_data +wsrep_handle_mdl_conflict we hold THD::LOCK_thd_data +wsrep_assert_no_bf_bf_wait we hold lock_sys.latch +innobase_kill_query we hold THD::LOCK_thd_data (THD::awake_no_mutex) + +@param thd thread handle + +@return true if wsrep transaction is aborting +@return false if not + +*/ extern "C" my_bool wsrep_thd_is_aborting(const MYSQL_THD thd) { - mysql_mutex_assert_owner(&thd->LOCK_thd_data); - const wsrep::client_state& cs(thd->wsrep_cs()); const enum wsrep::transaction::state tx_state(cs.transaction().state()); + switch (tx_state) { case wsrep::transaction::s_must_abort: @@ -277,7 +293,7 @@ extern "C" my_bool wsrep_thd_is_aborting(const MYSQL_THD thd) case wsrep::transaction::s_aborting: return true; default: - return false; + break; } return false; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index cd93f46ede5..58fef6920f4 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -4622,24 +4622,24 @@ ER_ERROR_DURING_CHECKPOINT swe "Fick fel %M vid CHECKPOINT" ukr "Отримано помилку %M під час CHECKPOINT" ER_NEW_ABORTING_CONNECTION 08S01 - chi "终止的连接 %lld 到数据库: '%-.192s' 用户: '%-.48s' 主机: '%-.64s' (%-.64s)" - cze "Spojení %lld do databáze: '%-.192s' uživatel: '%-.48s' stroj: '%-.64s' (%-.64s) bylo přerušeno" - dan "Afbrød forbindelsen %lld til databasen '%-.192s' bruger: '%-.48s' vært: '%-.64s' (%-.64s)" - eng "Aborted connection %lld to db: '%-.192s' user: '%-.48s' host: '%-.64s' (%-.64s)" - est "Ühendus katkestatud %lld andmebaas: '%-.192s' kasutaja: '%-.48s' masin: '%-.64s' (%-.64s)" - fre "Connection %lld avortée vers la bd: '%-.192s' utilisateur: '%-.48s' hôte: '%-.64s' (%-.64s)" - ger "Abbruch der Verbindung %lld zur Datenbank '%-.192s'. Benutzer: '%-.48s', Host: '%-.64s' (%-.64s)" - geo "შეწყდა კავშირი %lld ბაზამდე: '%-.192s' მომხმარებელი: '%-.48s' ჰოსტი: '%-.64s' (%-.64s)" - ita "Interrotta la connessione %lld al db: ''%-.192s' utente: '%-.48s' host: '%-.64s' (%-.64s)" - jpn "接続 %lld が中断されました。データベース: '%-.192s' ユーザー: '%-.48s' ホスト: '%-.64s' (%-.64s)" - nla "Afgebroken verbinding %lld naar db: '%-.192s' gebruiker: '%-.48s' host: '%-.64s' (%-.64s)" - por "Conexão %lld abortada para banco de dados '%-.192s' - usuário '%-.48s' - 'host' '%-.64s' ('%-.64s')" - rus "Прервано соединение %lld к базе данных '%-.192s' пользователя '%-.48s' с хоста '%-.64s' (%-.64s)" - serbian "Prekinuta konekcija broj %lld ka bazi: '%-.192s' korisnik je bio: '%-.48s' a host: '%-.64s' (%-.64s)" - spa "Abortada conexión %lld a la base de datos: '%-.192s' usuario: '%-.48s' equipo: '%-.64s' (%-.64s)" - sw "Muunganisho ulioghairishwa %lld kwa db: mtumiaji wa '%-.192s': '%-.48s' mwenyeji: '%-.64s' (%-.64s)" - swe "Avbröt länken för tråd %lld till db '%-.192s', användare '%-.48s', host '%-.64s' (%-.64s)" - ukr "Перервано з'єднання %lld до бази данних: '%-.192s' користувач: '%-.48s' хост: '%-.64s' (%-.64s)" + chi "终止的连接 %lld 到数据库: '%-.192s' 用户: '%-.48s' 主机: '%-.64s'%-.64s (%-.64s)" + cze "Spojení %lld do databáze: '%-.192s' uživatel: '%-.48s' stroj: '%-.64s'%-.64s (%-.64s) bylo přerušeno" + dan "Afbrød forbindelsen %lld til databasen '%-.192s' bruger: '%-.48s' vært: '%-.64s'%-.64s (%-.64s)" + eng "Aborted connection %lld to db: '%-.192s' user: '%-.48s' host: '%-.64s'%-.64s (%-.64s)" + est "Ühendus katkestatud %lld andmebaas: '%-.192s' kasutaja: '%-.48s' masin: '%-.64s'%-.64s (%-.64s)" + fre "Connection %lld avortée vers la bd: '%-.192s' utilisateur: '%-.48s' hôte: '%-.64s'%-.64s (%-.64s)" + ger "Abbruch der Verbindung %lld zur Datenbank '%-.192s'. Benutzer: '%-.48s', Host: '%-.64s'%-.64s (%-.64s)" + geo "შეწყდა კავშირი %lld ბაზამდე: '%-.192s' მომხმარებელი: '%-.48s' ჰოსტი: '%-.64s'%-.64s (%-.64s)" + ita "Interrotta la connessione %lld al db: ''%-.192s' utente: '%-.48s' host: '%-.64s'%-.64s (%-.64s)" + jpn "接続 %lld が中断されました。データベース: '%-.192s' ユーザー: '%-.48s' ホスト: '%-.64s'%-.64s (%-.64s)" + nla "Afgebroken verbinding %lld naar db: '%-.192s' gebruiker: '%-.48s' host: '%-.64s'%-.64s (%-.64s)" + por "Conexão %lld abortada para banco de dados '%-.192s' - usuário '%-.48s' - 'host' '%-.64s'%-.64s ('%-.64s')" + rus "Прервано соединение %lld к базе данных '%-.192s' пользователя '%-.48s' с хоста '%-.64s'%-.64s (%-.64s)" + serbian "Prekinuta konekcija broj %lld ka bazi: '%-.192s' korisnik je bio: '%-.48s' a host: '%-.64s'%-.64s (%-.64s)" + spa "Abortada conexión %lld a la base de datos: '%-.192s' usuario: '%-.48s' equipo: '%-.64s'%-.64s (%-.64s)" + sw "Muunganisho ulioghairishwa %lld kwa db: mtumiaji wa '%-.192s': '%-.48s' mwenyeji: '%-.64s'%-.64s (%-.64s)" + swe "Avbröt länken för tråd %lld till db '%-.192s', användare '%-.48s', host '%-.64s'%-.64s (%-.64s)" + ukr "Перервано з'єднання %lld до бази данних: '%-.192s' користувач: '%-.48s' хост: '%-.64s'%-.64s (%-.64s)" ER_UNUSED_10 eng "You should never see it" geo "ეს ვერასდროს უნდა დაინახოთ" @@ -12147,7 +12147,7 @@ ER_UNKNOWN_DATA_TYPE spa "Tipo de datos desconocido: '%-.64s'" sw "Aina ya data isiyojulikana: '% -.64s'" ER_UNKNOWN_OPERATOR - eng "Operator does not exists: '%-.128s'" + eng "Operator does not exist: '%-.128s'" spa "El operador no existe: '%-.128s'" sw "Opereta haipo: '% -.128s'" ER_UNUSED_29 diff --git a/sql/slave.cc b/sql/slave.cc index a6858b428bd..48be8cd04fd 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -856,7 +856,7 @@ static void make_slave_transaction_retry_errors_printable(void) } -#define DEFAULT_SLAVE_RETRY_ERRORS 9 +static constexpr uint DEFAULT_SLAVE_RETRY_ERRORS= 10; bool init_slave_transaction_retry_errors(const char* arg) { @@ -898,9 +898,10 @@ bool init_slave_transaction_retry_errors(const char* arg) slave_transaction_retry_errors[3]= ER_NET_WRITE_INTERRUPTED; slave_transaction_retry_errors[4]= ER_LOCK_WAIT_TIMEOUT; slave_transaction_retry_errors[5]= ER_LOCK_DEADLOCK; - slave_transaction_retry_errors[6]= ER_CONNECT_TO_FOREIGN_DATA_SOURCE; - slave_transaction_retry_errors[7]= 2013; /* CR_SERVER_LOST */ - slave_transaction_retry_errors[8]= 12701; /* ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM */ + slave_transaction_retry_errors[6]= ER_CHECKREAD; + slave_transaction_retry_errors[7]= ER_CONNECT_TO_FOREIGN_DATA_SOURCE; + slave_transaction_retry_errors[8]= 2013; /* CR_SERVER_LOST */ + slave_transaction_retry_errors[9]= 12701; /* ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM */ /* Add user codes after this */ for (p= arg, i= DEFAULT_SLAVE_RETRY_ERRORS; *p; ) @@ -1325,6 +1326,8 @@ static bool io_slave_killed(Master_info* mi) DBUG_ENTER("io_slave_killed"); DBUG_ASSERT(mi->slave_running); // tracking buffer overrun + if (mi->abort_slave || mi->io_thd->killed) + DBUG_PRINT("info", ("killed")); DBUG_RETURN(mi->abort_slave || mi->io_thd->killed); } @@ -2957,9 +2960,6 @@ void show_master_info_get_fields(THD *thd, List *field_list, field_list->push_back(new (mem_root) Item_empty_string(thd, "Slave_SQL_Running", 3), mem_root); - field_list->push_back(new (mem_root) - Item_empty_string(thd, "Replicate_Rewrite_DB", 23), - mem_root); field_list->push_back(new (mem_root) Item_empty_string(thd, "Replicate_Do_DB", 20), mem_root); @@ -3108,6 +3108,21 @@ void show_master_info_get_fields(THD *thd, List *field_list, Item_return_int(thd, "Slave_Transactional_Groups", 20, MYSQL_TYPE_LONGLONG), mem_root); + field_list->push_back(new (mem_root) + Item_empty_string(thd, "Replicate_Rewrite_DB", 23), + mem_root); + + /* + Note, we must never, _ever_, add extra rows to this output of SHOW SLAVE + STATUS, except here at the end before the extra rows of SHOW ALL SLAVES + STATUS. Otherwise, we break backwards compatibility with applications or + scripts that parse the output! + + This also means that we cannot add _any_ new rows in a GA version if a + different row was already added in a later MariaDB version, as this would + make it impossible to merge the change up while preserving the order of + rows. + */ if (full) { @@ -3223,7 +3238,6 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, &my_charset_bin); protocol->store(&slave_running[mi->slave_running], &my_charset_bin); protocol->store(mi->rli.slave_running ? &msg_yes : &msg_no, &my_charset_bin); - protocol->store(rpl_filter->get_rewrite_db()); protocol->store(rpl_filter->get_do_db()); protocol->store(rpl_filter->get_ignore_db()); @@ -3370,7 +3384,7 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, // to ensure that we use the same value throughout this function. const char *slave_sql_running_state= mi->rli.sql_driver_thd ? mi->rli.sql_driver_thd->proc_info : ""; - if (slave_sql_running_state == Relay_log_info::state_delaying_string) + if (slave_sql_running_state == stage_sql_thd_waiting_until_delay.m_name) { time_t t= my_time(0), sql_delay_end= mi->rli.get_sql_delay_end(); protocol->store((uint32)(t < sql_delay_end ? sql_delay_end - t : 0)); @@ -3383,6 +3397,7 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, protocol->store(mi->total_ddl_groups); protocol->store(mi->total_non_trans_groups); protocol->store(mi->total_trans_groups); + protocol->store(rpl_filter->get_rewrite_db()); if (full) { @@ -3557,6 +3572,7 @@ static int init_slave_thread(THD* thd, Master_info *mi, } thd->security_ctx->skip_grants(); + thd->security_ctx->user=(char*) slave_user; thd->slave_thread= 1; thd->connection_name= mi->connection_name; thd->variables.sql_log_slow= !MY_TEST(thd->variables.log_slow_disabled_statements & LOG_SLOW_DISABLE_SLAVE); @@ -3940,7 +3956,7 @@ apply_event_and_update_pos_apply(Log_event* ev, THD* thd, rpl_group_info *rgi, if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && ((rli->mi->using_parallel() && rli->mi->parallel_mode <= SLAVE_PARALLEL_CONSERVATIVE) || - wsrep_ready == 0)) { + !wsrep_ready_get())) { rli->abort_slave= 1; rli->report(ERROR_LEVEL, ER_UNKNOWN_COM_ERROR, rgi->gtid_info(), "Node has dropped from cluster"); @@ -4407,6 +4423,13 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, rli->last_inuse_relaylog->dequeued_count))) && event_can_update_last_master_timestamp(ev)) { + /* + This is the first event from the master after the slave was up to date + and has been waiting for new events. + We update last_master_timestamp before executing the event to not + have Seconds_after_master == 0 while executing the event. + last_master_timestamp will be updated again when the event is commited. + */ if (rli->last_master_timestamp < ev->when) { rli->last_master_timestamp= ev->when; @@ -4443,7 +4466,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, Seconds_Behind_Master is zero. */ if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT && - rli->last_master_timestamp < ev->when) + rli->last_master_timestamp < ev->when + (time_t) ev->exec_time) rli->last_master_timestamp= ev->when + (time_t) ev->exec_time; DBUG_ASSERT(rli->last_master_timestamp >= 0); @@ -7242,9 +7265,6 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, default_client_charset_info->cs_name.str); } - /* This one is not strictly needed but we have it here for completeness */ - mysql_options(mysql, MYSQL_SET_CHARSET_DIR, charsets_dir); - /* Set MYSQL_PLUGIN_DIR in case master asks for an external authentication plugin */ if (opt_plugin_dir_ptr && *opt_plugin_dir_ptr) mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir_ptr); diff --git a/sql/sp.cc b/sql/sp.cc index ddaeeb8cb7a..3c9cd91de52 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1966,7 +1966,7 @@ Sp_handler::sp_show_create_routine(THD *thd, DBUG_EXECUTE_IF("cache_sp_in_show_create", /* Some tests need just need a way to cache SP without other side-effects.*/ - sp_cache_routine(thd, name, false, &sp); + sp_cache_routine(thd, name, &sp); sp->show_create_routine(thd, this); DBUG_RETURN(false); ); @@ -2390,7 +2390,7 @@ Sp_handler::sp_cache_routine_reentrant(THD *thd, int ret; Parser_state *oldps= thd->m_parser_state; thd->m_parser_state= NULL; - ret= sp_cache_routine(thd, name, false, sp); + ret= sp_cache_routine(thd, name, sp); thd->m_parser_state= oldps; return ret; } @@ -2797,7 +2797,6 @@ void sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx, */ int Sroutine_hash_entry::sp_cache_routine(THD *thd, - bool lookup_only, sp_head **sp) const { char qname_buff[NAME_LEN*2+1+1]; @@ -2810,7 +2809,7 @@ int Sroutine_hash_entry::sp_cache_routine(THD *thd, */ DBUG_ASSERT(mdl_request.ticket || this == thd->lex->sroutines_list.first); - return m_handler->sp_cache_routine(thd, &name, lookup_only, sp); + return m_handler->sp_cache_routine(thd, &name, sp); } @@ -2822,9 +2821,6 @@ int Sroutine_hash_entry::sp_cache_routine(THD *thd, @param[in] thd Thread context. @param[in] name Name of routine. - @param[in] lookup_only Only check that the routine is in the cache. - If it's not, don't try to load. If it is present, - but old, don't try to reload. @param[out] sp Pointer to sp_head object for routine, NULL if routine was not found. @@ -2835,7 +2831,6 @@ int Sroutine_hash_entry::sp_cache_routine(THD *thd, int Sp_handler::sp_cache_routine(THD *thd, const Database_qualified_name *name, - bool lookup_only, sp_head **sp) const { int ret= 0; @@ -2847,9 +2842,6 @@ int Sp_handler::sp_cache_routine(THD *thd, *sp= sp_cache_lookup(spc, name); - if (lookup_only) - DBUG_RETURN(SP_OK); - if (*sp) { sp_cache_flush_obsolete(spc, sp); @@ -2901,7 +2893,6 @@ int Sp_handler::sp_cache_routine(THD *thd, * name->m_db is a database name, e.g. "dbname" * name->m_name is a package-qualified name, e.g. "pkgname.spname" - @param lookup_only - don't load mysql.proc if not cached @param [OUT] sp - the result is returned here. @retval false - loaded or does not exists @retval true - error while loading mysql.proc @@ -2911,14 +2902,13 @@ int Sp_handler::sp_cache_package_routine(THD *thd, const LEX_CSTRING &pkgname_cstr, const Database_qualified_name *name, - bool lookup_only, sp_head **sp) const + sp_head **sp) const { DBUG_ENTER("sp_cache_package_routine"); DBUG_ASSERT(type() == SP_TYPE_FUNCTION || type() == SP_TYPE_PROCEDURE); sp_name pkgname(&name->m_db, &pkgname_cstr, false); sp_head *ph= NULL; int ret= sp_handler_package_body.sp_cache_routine(thd, &pkgname, - lookup_only, &ph); if (!ret) { @@ -2953,12 +2943,12 @@ Sp_handler::sp_cache_package_routine(THD *thd, int Sp_handler::sp_cache_package_routine(THD *thd, const Database_qualified_name *name, - bool lookup_only, sp_head **sp) const + sp_head **sp) const { DBUG_ENTER("Sp_handler::sp_cache_package_routine"); Prefix_name_buf pkgname(thd, name->m_name); DBUG_ASSERT(pkgname.length); - DBUG_RETURN(sp_cache_package_routine(thd, pkgname, name, lookup_only, sp)); + DBUG_RETURN(sp_cache_package_routine(thd, pkgname, name, sp)); } diff --git a/sql/sp.h b/sql/sp.h index 792321c930d..2de2d130a2e 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -103,10 +103,10 @@ protected: int sp_cache_package_routine(THD *thd, const LEX_CSTRING &pkgname_cstr, const Database_qualified_name *name, - bool lookup_only, sp_head **sp) const; + sp_head **sp) const; int sp_cache_package_routine(THD *thd, const Database_qualified_name *name, - bool lookup_only, sp_head **sp) const; + sp_head **sp) const; sp_head *sp_find_package_routine(THD *thd, const LEX_CSTRING pkgname_str, const Database_qualified_name *name, @@ -205,7 +205,7 @@ public: const Database_qualified_name *name, bool cache_only) const; virtual int sp_cache_routine(THD *thd, const Database_qualified_name *name, - bool lookup_only, sp_head **sp) const; + sp_head **sp) const; int sp_cache_routine_reentrant(THD *thd, const Database_qualified_name *nm, @@ -288,9 +288,9 @@ class Sp_handler_package_procedure: public Sp_handler_procedure { public: int sp_cache_routine(THD *thd, const Database_qualified_name *name, - bool lookup_only, sp_head **sp) const + sp_head **sp) const { - return sp_cache_package_routine(thd, name, lookup_only, sp); + return sp_cache_package_routine(thd, name, sp); } sp_head *sp_find_routine(THD *thd, const Database_qualified_name *name, @@ -339,9 +339,9 @@ class Sp_handler_package_function: public Sp_handler_function { public: int sp_cache_routine(THD *thd, const Database_qualified_name *name, - bool lookup_only, sp_head **sp) const + sp_head **sp) const { - return sp_cache_package_routine(thd, name, lookup_only, sp); + return sp_cache_package_routine(thd, name, sp); } sp_head *sp_find_routine(THD *thd, const Database_qualified_name *name, @@ -645,7 +645,7 @@ public: const Sp_handler *m_handler; - int sp_cache_routine(THD *thd, bool lookup_only, sp_head **sp) const; + int sp_cache_routine(THD *thd, sp_head **sp) const; }; diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index d005f6adb89..2a777c14d92 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -78,6 +78,8 @@ private: /* All routines in this cache */ HASH m_hashtable; +public: + void clear(); }; // class sp_cache #ifdef HAVE_PSI_INTERFACE @@ -314,6 +316,10 @@ sp_cache::cleanup() my_hash_free(&m_hashtable); } +void sp_cache::clear() +{ + my_hash_reset(&m_hashtable); +} void Sp_caches::sp_caches_clear() { @@ -322,3 +328,15 @@ void Sp_caches::sp_caches_clear() sp_cache_clear(&sp_package_spec_cache); sp_cache_clear(&sp_package_body_cache); } + +void Sp_caches::sp_caches_empty() +{ + if (sp_proc_cache) + sp_proc_cache->clear(); + if (sp_func_cache) + sp_func_cache->clear(); + if (sp_package_spec_cache) + sp_package_spec_cache->clear(); + if (sp_package_body_cache) + sp_package_body_cache->clear(); +} diff --git a/sql/sp_instr.cc b/sql/sp_instr.cc index 261c70f464a..b4302ff3d1e 100644 --- a/sql/sp_instr.cc +++ b/sql/sp_instr.cc @@ -754,6 +754,7 @@ LEX* sp_lex_instr::parse_expr(THD *thd, sp_head *sp, LEX *sp_instr_lex) cleanup_items(cursor_lex->free_list); cursor_free_list= &cursor_lex->free_list; DBUG_ASSERT(thd->lex == sp_instr_lex); + lex_start(thd); } thd->lex->sphead= sp; @@ -897,6 +898,9 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) thd->update_stats(); thd->lex->sql_command= save_sql_command; *nextp= m_ip+1; +#ifdef PROTECT_STATEMENT_MEMROOT + mark_as_qc_used(); +#endif } thd->set_query(query_backup); thd->query_name_consts= 0; diff --git a/sql/sp_instr.h b/sql/sp_instr.h index 58dcf40ef8d..cef44c457a0 100644 --- a/sql/sp_instr.h +++ b/sql/sp_instr.h @@ -112,7 +112,7 @@ public: m_ctx(ctx), m_lineno(0) #ifdef PROTECT_STATEMENT_MEMROOT - , m_has_been_run(false) + , m_has_been_run(NON_RUN) #endif {} @@ -214,21 +214,29 @@ public: #ifdef PROTECT_STATEMENT_MEMROOT bool has_been_run() const { - return m_has_been_run; + return m_has_been_run == RUN; + } + + void mark_as_qc_used() + { + m_has_been_run= QC; } void mark_as_run() { - m_has_been_run= true; + if (m_has_been_run == QC) + m_has_been_run= NON_RUN; // answer was from WC => not really executed + else + m_has_been_run= RUN; } void mark_as_not_run() { - m_has_been_run= false; + m_has_been_run= NON_RUN; } private: - bool m_has_been_run; + enum {NON_RUN, QC, RUN} m_has_been_run; #endif }; // class sp_instr : public Sql_alloc diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index cff6c31d652..6c8111a134d 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -245,7 +245,7 @@ bool Qualified_column_ident::resolve_type_ref(THD *thd, thd->temporary_tables= open_tables_state_backup.temporary_tables; if ((table_list= - lex.first_select_lex()->add_table_to_list(thd, this, NULL, 0, + lex.first_select_lex()->add_table_to_list(thd, (Table_ident*)this, NULL, 0, TL_READ_NO_INSERT, MDL_SHARED_READ)) && !check_table_access(thd, SELECT_ACL, table_list, TRUE, UINT_MAX, FALSE) && diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 5b196fbc2b3..8806462bfc3 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2949,6 +2949,7 @@ bool acl_reload(THD *thd) } acl_cache->clear(0); + mysql_mutex_record_order(&acl_cache->lock, &LOCK_status); mysql_mutex_lock(&acl_cache->lock); old_acl_hosts= acl_hosts; @@ -7632,7 +7633,7 @@ static bool can_grant_role(THD *thd, ACL_ROLE *role) { Security_context *sctx= thd->security_ctx; - if (!sctx->user) // replication + if (!sctx->is_user_defined()) // galera return true; ACL_USER *grantee= find_user_exact(sctx->priv_host, sctx->priv_user); @@ -13358,8 +13359,27 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio, *end++= 0; int2store(end, thd->client_capabilities); + + CHARSET_INFO *handshake_cs= default_charset_info; + if (handshake_cs->number > 0xFF) + { + /* + A workaround for a 2-byte collation ID: translate it into + the ID of the primary collation of this character set. + */ + CHARSET_INFO *cs= get_charset_by_csname(handshake_cs->cs_name.str, + MY_CS_PRIMARY, MYF(MY_WME)); + /* + cs should not normally be NULL, however it may be possible + with a dynamic character set incorrectly defined in Index.xml. + For safety let's fallback to latin1 in case cs is NULL. + */ + handshake_cs= cs ? cs : &my_charset_latin1; + } + /* write server characteristics: up to 16 bytes allowed */ - end[2]= (char) default_charset_info->number; + end[2]= (char) handshake_cs->number; + int2store(end+3, mpvio->auth_info.thd->server_status); int2store(end+5, thd->client_capabilities >> 16); end[7]= data_len; diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index a3b9bbd4f7e..983070a9b3d 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -863,11 +863,9 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, !(check_opt->sql_flags & TT_USEFRM)) { handler *file= table->table->file; - int check_old_types= file->check_old_types(); int check_for_upgrade= file->ha_check_for_upgrade(check_opt); - if (check_old_types == HA_ADMIN_NEEDS_ALTER || - check_for_upgrade == HA_ADMIN_NEEDS_ALTER) + if (check_for_upgrade == HA_ADMIN_NEEDS_ALTER) { /* We use extra_open_options to be able to open crashed tables */ thd->open_options|= extra_open_options; @@ -876,7 +874,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, thd->open_options&= ~extra_open_options; goto send_result; } - if (check_old_types || check_for_upgrade) + if (check_for_upgrade) { /* If repair is not implemented for the engine, run ALTER TABLE */ need_repair_or_alter= 1; @@ -905,7 +903,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, */ collect_eis= (table->table->s->table_category == TABLE_CATEGORY_USER && - !(lex->alter_info.flags & ALTER_PARTITION_ADMIN) && + !(lex->alter_info.partition_flags & ALTER_PARTITION_ADMIN) && (check_eits_collection_allowed(thd) || lex->with_persistent_for_clause)); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index e33b4728829..240ccf6f378 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -816,8 +816,10 @@ int close_thread_tables(THD *thd) { TABLE *table; int error= 0; + PSI_stage_info org_stage; DBUG_ENTER("close_thread_tables"); + thd->backup_stage(&org_stage); THD_STAGE_INFO(thd, stage_closing_tables); #ifdef EXTRA_DEBUG @@ -933,7 +935,10 @@ int close_thread_tables(THD *thd) we will exit this function a few lines below. */ if (! thd->lex->requires_prelocking()) - DBUG_RETURN(0); + { + error= 0; + goto end; + } /* We are in the top-level statement of a prelocked statement, @@ -944,7 +949,10 @@ int close_thread_tables(THD *thd) thd->locked_tables_mode= LTM_LOCK_TABLES; if (thd->locked_tables_mode == LTM_LOCK_TABLES) - DBUG_RETURN(0); + { + error= 0; + goto end; + } thd->leave_locked_tables_mode(); @@ -973,6 +981,8 @@ int close_thread_tables(THD *thd) while (thd->open_tables) (void) close_thread_table(thd, &thd->open_tables); +end: + THD_STAGE_INFO(thd, org_stage); DBUG_RETURN(error); } @@ -3802,7 +3812,7 @@ open_and_process_routine(THD *thd, Query_tables_list *prelocking_ctx, DBUG_RETURN(TRUE); /* Ensures the routine is up-to-date and cached, if exists. */ - if (rt->sp_cache_routine(thd, has_prelocking_list, &sp)) + if (rt->sp_cache_routine(thd, &sp)) DBUG_RETURN(TRUE); /* Remember the version of the routine in the parse tree. */ @@ -3843,7 +3853,7 @@ open_and_process_routine(THD *thd, Query_tables_list *prelocking_ctx, Validating routine version is unnecessary, since CALL does not affect the prepared statement prelocked list. */ - if (rt->sp_cache_routine(thd, false, &sp)) + if (rt->sp_cache_routine(thd, &sp)) DBUG_RETURN(TRUE); } } @@ -5035,6 +5045,9 @@ prepare_fk_prelocking_list(THD *thd, Query_tables_list *prelocking_ctx, Query_arena *arena, backup; TABLE *table= table_list->table; + if (!table->file->referenced_by_foreign_key()) + DBUG_RETURN(FALSE); + arena= thd->activate_stmt_arena_if_needed(&backup); table->file->get_parent_foreign_key_list(thd, &fk_list); @@ -5120,16 +5133,12 @@ bool DML_prelocking_strategy::handle_table(THD *thd, return TRUE; } - if (table->file->referenced_by_foreign_key()) - { - if (prepare_fk_prelocking_list(thd, prelocking_ctx, table_list, - need_prelocking, - table_list->trg_event_map)) - return TRUE; - } + if (prepare_fk_prelocking_list(thd, prelocking_ctx, table_list, + need_prelocking, + table_list->trg_event_map)) + return TRUE; } - else if (table_list->slave_fk_event_map && - table->file->referenced_by_foreign_key()) + else if (table_list->slave_fk_event_map) { if (prepare_fk_prelocking_list(thd, prelocking_ctx, table_list, need_prelocking, @@ -5895,13 +5904,23 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count, uint flags) } } - DEBUG_SYNC(thd, "before_lock_tables_takes_lock"); +#ifdef ENABLED_DEBUG_SYNC + if (!tables || + !(strcmp(tables->db.str, "mysql") == 0 && + strcmp(tables->table_name.str, "proc") == 0)) + DEBUG_SYNC(thd, "before_lock_tables_takes_lock"); +#endif if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start), flags))) DBUG_RETURN(TRUE); - DEBUG_SYNC(thd, "after_lock_tables_takes_lock"); +#ifdef ENABLED_DEBUG_SYNC + if (!tables || + !(strcmp(tables->db.str, "mysql") == 0 && + strcmp(tables->table_name.str, "proc") == 0)) + DEBUG_SYNC(thd, "after_lock_tables_takes_lock"); +#endif if (thd->lex->requires_prelocking() && thd->lex->sql_command != SQLCOM_LOCK_TABLES && @@ -9266,6 +9285,9 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, @param values values to fill with @param ignore_errors TRUE if we should ignore errors @param use_value forces usage of value of the items instead of result + @param check_for_computability whether to check for ability to invoke val_*() + methods (val_int () etc) against supplied + values @details fill_record() may set table->auto_increment_field_not_null and a @@ -9279,7 +9301,7 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, bool fill_record(THD *thd, TABLE *table, Field **ptr, List &values, - bool ignore_errors, bool use_value) + bool ignore_errors, bool use_value, bool check_for_computability) { List_iterator_fast v(values); List
tbl_list; @@ -9319,6 +9341,10 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List &values, /* Ensure the end of the list of values is not reached */ DBUG_ASSERT(value); + if (check_for_computability && + value->check_is_evaluable_expression_or_error()) + goto err; + const bool skip_sys_field= field->vers_sys_field() && !thd->vers_insert_history_fast(table); @@ -9395,7 +9421,7 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, Field **ptr, bool result; Table_triggers_list *triggers= table->triggers; - result= fill_record(thd, table, ptr, values, ignore_errors, FALSE); + result= fill_record(thd, table, ptr, values, ignore_errors, false, false); if (!result && triggers && *ptr) result= triggers->process_triggers(thd, event, TRG_ACTION_BEFORE, TRUE) || diff --git a/sql/sql_base.h b/sql/sql_base.h index 04e487db65d..505fd618c36 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -195,7 +195,8 @@ void unfix_fields(List &items); bool fill_record(THD * thd, TABLE *table_arg, List &fields, List &values, bool ignore_errors, bool update); bool fill_record(THD *thd, TABLE *table, Field **field, List &values, - bool ignore_errors, bool use_value); + bool ignore_errors, bool use_value, + bool check_for_evaluability); Field * find_field_in_tables(THD *thd, Item_ident *item, diff --git a/sql/sql_bootstrap.cc b/sql/sql_bootstrap.cc index b39d7a57bc0..72821384bb6 100644 --- a/sql/sql_bootstrap.cc +++ b/sql/sql_bootstrap.cc @@ -33,26 +33,35 @@ extern "C" int read_bootstrap_query(char *query, int *query_length, fgets_input_t input, fgets_fn_t fgets_fn, int preserve_delimiter, int *error) { - char line_buffer[MAX_BOOTSTRAP_LINE_SIZE]; + char *line_buffer; const char *line; size_t len; size_t query_len= 0; int fgets_error= 0; + int exit_code= 0; *error= 0; + line_buffer= (char*) malloc(MAX_BOOTSTRAP_LINE_SIZE); + *query_length= 0; for ( ; ; ) { - line= (*fgets_fn)(line_buffer, sizeof(line_buffer), input, &fgets_error); + line= (*fgets_fn)(line_buffer, MAX_BOOTSTRAP_LINE_SIZE, input, &fgets_error); if (error) *error= fgets_error; if (fgets_error != 0) - return READ_BOOTSTRAP_ERROR; + { + exit_code= READ_BOOTSTRAP_ERROR; + break; + } if (line == NULL) - return (query_len == 0) ? READ_BOOTSTRAP_EOF : READ_BOOTSTRAP_ERROR; + { + exit_code= (query_len == 0) ? READ_BOOTSTRAP_EOF : READ_BOOTSTRAP_ERROR; + break; + } len= strlen(line); @@ -98,7 +107,8 @@ extern "C" int read_bootstrap_query(char *query, int *query_length, if (!p || !p[1]) { /* Invalid DELIMITER specifier */ - return READ_BOOTSTRAP_ERROR; + exit_code= READ_BOOTSTRAP_ERROR; + break; } delimiter.assign(p+1); if (preserve_delimiter) @@ -106,7 +116,8 @@ extern "C" int read_bootstrap_query(char *query, int *query_length, memcpy(query,line,len); query[len]=0; *query_length = (int)len; - return READ_BOOTSTRAP_SUCCESS; + exit_code= READ_BOOTSTRAP_SUCCESS; + break; } continue; } @@ -125,7 +136,8 @@ extern "C" int read_bootstrap_query(char *query, int *query_length, } query[query_len]= '\0'; *query_length= (int)query_len; - return READ_BOOTSTRAP_QUERY_SIZE; + exit_code= READ_BOOTSTRAP_QUERY_SIZE; + break; } if (query_len != 0) @@ -152,8 +164,11 @@ extern "C" int read_bootstrap_query(char *query, int *query_length, } query[query_len]= 0; *query_length= (int)query_len; - return READ_BOOTSTRAP_SUCCESS; + exit_code= READ_BOOTSTRAP_SUCCESS; + break; } } + free(line_buffer); + return exit_code; } diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 8fc65a9495a..d3fbd034d1f 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2530,14 +2530,9 @@ void Query_cache::destroy() void Query_cache::disable_query_cache(THD *thd) { + lock(thd); m_cache_status= DISABLE_REQUEST; - /* - If there is no requests in progress try to free buffer. - try_lock(TRY) will exit immediately if there is lock. - unlock() should free block. - */ - if (m_requests_in_progress == 0 && !try_lock(thd, TRY)) - unlock(); + unlock(); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index aa22aa73ada..b1aab54552a 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -682,8 +682,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) #ifdef HAVE_REPLICATION , current_linfo(0), - slave_info(0), - is_awaiting_semisync_ack(0) + slave_info(0) #endif #ifdef WITH_WSREP , @@ -895,6 +894,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) prepare_derived_at_open= FALSE; create_tmp_table_for_derived= FALSE; save_prep_leaf_list= FALSE; + reset_sp_cache= false; org_charset= 0; /* Restore THR_THD */ set_current_thd(old_THR_THD); @@ -4580,7 +4580,7 @@ void Security_context::destroy() my_free((char*) host); host= NULL; } - if (user != delayed_user) + if (is_user_defined()) { my_free((char*) user); user= NULL; @@ -5402,14 +5402,6 @@ extern "C" enum enum_server_command thd_current_command(MYSQL_THD thd) return thd->get_command(); } -#ifdef HAVE_REPLICATION /* Working around MDEV-24622 */ -/** @return whether the current thread is for applying binlog in a replica */ -extern "C" int thd_is_slave(const MYSQL_THD thd) -{ - return thd && thd->slave_thread; -} -#endif /* HAVE_REPLICATION */ - /* Returns high resolution timestamp for the start of the current query. */ extern "C" unsigned long long thd_start_utime(const MYSQL_THD thd) @@ -5493,14 +5485,38 @@ thd_rpl_deadlock_check(MYSQL_THD thd, MYSQL_THD other_thd) return 0; if (!rgi->is_parallel_exec) return 0; - if (rgi->rli != other_rgi->rli) - return 0; - if (!rgi->gtid_sub_id || !other_rgi->gtid_sub_id) - return 0; - if (rgi->current_gtid.domain_id != other_rgi->current_gtid.domain_id) - return 0; - if (rgi->gtid_sub_id > other_rgi->gtid_sub_id) - return 0; + if (rgi->rli == other_rgi->rli && + rgi->current_gtid.domain_id == other_rgi->current_gtid.domain_id) + { + /* + Within the same master connection and domain, we can compare transaction + order on the GTID sub_id, and rollback the later transaction to allow the + earlier transaction to commit first. + */ + if (!rgi->gtid_sub_id || !other_rgi->gtid_sub_id || + rgi->gtid_sub_id > other_rgi->gtid_sub_id) + return 0; + } + else + { + /* + Lock conflicts between different master connections or domains should + usually not occur, but could still happen if user is running some + special setup that tolerates conflicting updates (or in case of user + error). We do not have a pre-defined ordering of transactions in this + case, but we still need to handle conflicts in _some_ way to avoid + undetected deadlocks and hangs. + + We do this by rolling back and retrying any transaction that is being + _optimistically_ applied. This can be overly conservative in some cases, + but should be fine as conflicts between different master connections / + domains are not common. And it ensures that we won't end up in a + deadlock and hang due to a transaction doing wait_for_prior_commit while + holding locks that block something in another master connection. + */ + if (other_rgi->speculation != rpl_group_info::SPECULATE_OPTIMISTIC) + return 0; + } if (rgi->finish_event_group_called || other_rgi->finish_event_group_called) { /* @@ -5808,6 +5824,40 @@ extern "C" void *thd_mdl_context(MYSQL_THD thd) return &thd->mdl_context; } +/** + Send check/repair message to the user + + @param op one of check or repair + @param msg_type one of info, warning or error + @param print_to_log <> 0 if we should also print the message to error log. +*/ + +extern "C" void +print_check_msg(THD *thd, const char *db_name, const char *table_name, const char *op, + const char *msg_type, const char *message, my_bool print_to_log) +{ + char name[NAME_LEN * 2 + 2]; + Protocol *protocol= thd->protocol; + + DBUG_ASSERT(strlen(db_name) <= NAME_LEN); + DBUG_ASSERT(strlen(table_name) <= NAME_LEN); + + size_t length= size_t(strxnmov(name, sizeof name - 1, + db_name, ".", table_name, NullS) - + name); + protocol->prepare_for_resend(); + protocol->store(name, length, system_charset_info); + protocol->store(op, strlen(op), system_charset_info); + protocol->store(msg_type, strlen(msg_type), system_charset_info); + protocol->store(message, strlen(message), system_charset_info); + if (protocol->write()) + sql_print_error("Failed on my_net_write, writing to stderr instead: %s: %s\n", + table_name, message); + else if (thd->variables.log_warnings > 2 && print_to_log) + sql_print_error("%s: table '%s' got '%s' during %s", + msg_type, table_name, message, op); +} + /**************************************************************************** Handling of statement states in functions and triggers. @@ -8291,6 +8341,34 @@ wait_for_commit::unregister_wait_for_prior_commit2() mysql_mutex_unlock(&LOCK_wait_commit); } +/* + Wait # seconds or until someone sends a signal (through kill) + + Note that this must have same prototype as my_sleep_for_space() +*/ + +C_MODE_START + +void mariadb_sleep_for_space(unsigned int seconds) +{ + THD *thd= current_thd; + PSI_stage_info old_stage; + if (!thd) + { + sleep(seconds); + return; + } + mysql_mutex_lock(&thd->LOCK_wakeup_ready); + thd->ENTER_COND(&thd->COND_wakeup_ready, &thd->LOCK_wakeup_ready, + &stage_waiting_for_disk_space, &old_stage); + if (!thd->killed) + mysql_cond_wait(&thd->COND_wakeup_ready, &thd->LOCK_wakeup_ready); + thd->EXIT_COND(&old_stage); + return; +} + +C_MODE_END + bool Discrete_intervals_list::append(ulonglong start, ulonglong val, ulonglong incr) diff --git a/sql/sql_class.h b/sql/sql_class.h index 12e3e856cca..c832cf77736 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1,5 +1,4 @@ /* - Copyright (c) 2000, 2016, Oracle and/or its affiliates. Copyright (c) 2009, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify @@ -1746,6 +1745,8 @@ public: */ bool check_access(const privilege_t want_access, bool match_any = false); bool is_priv_user(const char *user, const char *host); + bool is_user_defined() const + { return user && user != delayed_user && user != slave_user; }; }; @@ -2639,6 +2640,11 @@ public: swap_variables(sp_cache*, sp_package_body_cache, rhs.sp_package_body_cache); } void sp_caches_clear(); + /** + Clear content of sp related caches. + Don't delete cache objects itself. + */ + void sp_caches_empty(); }; @@ -3131,6 +3137,12 @@ public: bool save_prep_leaf_list; + /** + The data member reset_sp_cache is to signal that content of sp_cache + must be reset (all items be removed from it). + */ + bool reset_sp_cache; + /* container for handler's private per-connection data */ Ha_data ha_data[MAX_HA]; @@ -3191,9 +3203,14 @@ public: bool binlog_need_stmt_format(bool is_transactional) const { - return log_current_statement() && - !binlog_get_pending_rows_event(binlog_get_cache_mngr(), - use_trans_cache(this, is_transactional)); + if (!log_current_statement()) + return false; + auto *cache_mngr= binlog_get_cache_mngr(); + if (!cache_mngr) + return true; + return !binlog_get_pending_rows_event(cache_mngr, + use_trans_cache(this, + is_transactional)); } bool binlog_for_noop_dml(bool transactional_table); @@ -3642,12 +3659,12 @@ public: sent_row_count_for_statement+= count; MYSQL_SET_STATEMENT_ROWS_SENT(m_statement_psi, m_sent_row_count); } - inline void inc_examined_row_count_fast() + inline void inc_examined_row_count_fast(ha_rows count= 1) { - m_examined_row_count++; - examined_row_count_for_statement++; + m_examined_row_count+= count; + examined_row_count_for_statement+= count; } - inline void inc_examined_row_count() + inline void inc_examined_row_count(ha_rows count= 1) { inc_examined_row_count_fast(); MYSQL_SET_STATEMENT_ROWS_EXAMINED(m_statement_psi, m_examined_row_count); @@ -4936,24 +4953,24 @@ public: */ bool copy_db_to(LEX_CSTRING *to) { - if (db.str == NULL) + if (db.str) { - /* - No default database is set. In this case if it's guaranteed that - no CTE can be used in the statement then we can throw an error right - now at the parser stage. Otherwise the decision about throwing such - a message must be postponed until a post-parser stage when we are able - to resolve all CTE names as we don't need this message to be thrown - for any CTE references. - */ - if (!lex->with_cte_resolution) - my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); - return TRUE; + to->str= strmake(db.str, db.length); + to->length= db.length; + return to->str == NULL; /* True on error */ } - to->str= strmake(db.str, db.length); - to->length= db.length; - return to->str == NULL; /* True on error */ + /* + No default database is set. In this case if it's guaranteed that + no CTE can be used in the statement then we can throw an error right + now at the parser stage. Otherwise the decision about throwing such + a message must be postponed until a post-parser stage when we are able + to resolve all CTE names as we don't need this message to be thrown + for any CTE references. + */ + if (!lex->with_cte_resolution) + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); + return TRUE; } /* Get db name or "". Use for printing current db */ const char *get_db() @@ -5294,11 +5311,29 @@ public: { if (global_system_variables.log_warnings > threshold) { + char real_ip_str[64]; + real_ip_str[0]= 0; + + /* For proxied connections, add the real IP to the warning message */ + if (net.using_proxy_protocol && net.vio) + { + if(net.vio->localhost) + snprintf(real_ip_str, sizeof(real_ip_str), " real ip: 'localhost'"); + else + { + char buf[INET6_ADDRSTRLEN]; + if (!vio_getnameinfo((sockaddr *)&(net.vio->remote), buf, + sizeof(buf),NULL, 0, NI_NUMERICHOST)) + { + snprintf(real_ip_str, sizeof(real_ip_str), " real ip: '%s'",buf); + } + } + } Security_context *sctx= &main_security_ctx; sql_print_warning(ER_THD(this, ER_NEW_ABORTING_CONNECTION), thread_id, (db.str ? db.str : "unconnected"), sctx->user ? sctx->user : "unauthenticated", - sctx->host_or_ip, reason); + sctx->host_or_ip, real_ip_str, reason); } } @@ -5396,8 +5431,18 @@ public: Flag, mutex and condition for a thread to wait for a signal from another thread. - Currently used to wait for group commit to complete, can also be used for - other purposes. + Currently used to wait for group commit to complete, and COND_wakeup_ready + is used for threads to wait on semi-sync ACKs (though is protected by + Repl_semi_sync_master::LOCK_binlog). Note the following relationships + between these two use-cases when using + rpl_semi_sync_master_wait_point=AFTER_SYNC during group commit: + 1) Non-leader threads use COND_wakeup_ready to wait for the leader thread + to complete binlog commit. + 2) The leader thread uses COND_wakeup_ready to await ACKs from the + replica before signalling the non-leader threads to wake up. + + With wait_point=AFTER_COMMIT, there is no overlap as binlogging has + finished, so COND_wakeup_ready is safe to re-use. */ bool wakeup_ready; mysql_mutex_t LOCK_wakeup_ready; @@ -5527,14 +5572,6 @@ public: bool check_slave_ignored_db_with_error(const Lex_ident_db &db) const; - /* - Indicates if this thread is suspended due to awaiting an ACK from a - replica. True if suspended, false otherwise. - - Note that this variable is protected by Repl_semi_sync_master::LOCK_binlog - */ - bool is_awaiting_semisync_ack; - inline ulong wsrep_binlog_format(ulong binlog_format) const { #ifdef WITH_WSREP @@ -8354,6 +8391,10 @@ extern THD_list server_threads; void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps, uint field_count); +C_MODE_START +void mariadb_sleep_for_space(unsigned int seconds); +C_MODE_END + #ifdef WITH_WSREP extern void wsrep_to_isolation_end(THD*); #endif diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index b4decefc47f..f06a58a40e4 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1296,7 +1296,7 @@ void prepare_new_connection_state(THD* thd) thd->thread_id, thd->db.str ? thd->db.str : "unconnected", sctx->user ? sctx->user : "unauthenticated", - sctx->host_or_ip, "init_connect command failed"); + sctx->host_or_ip, "", "init_connect command failed"); thd->server_status&= ~SERVER_STATUS_CLEAR_SET; thd->protocol->end_statement(); thd->killed = KILL_CONNECTION; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 6b442da858d..1e115915642 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -266,7 +266,10 @@ int update_portion_of_time(THD *thd, TABLE *table, res= src->save_in_field(table->field[dst_fieldno], true); if (likely(!res)) + { + table->period_prepare_autoinc(); res= table->update_generated_fields(); + } if(likely(!res)) res= table->file->ha_update_row(table->record[1], table->record[0]); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index d41f725477f..848907ab6dc 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -1209,8 +1209,12 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) (derived->alias.str ? derived->alias.str : ""), derived->get_unit())); - if (unit->executed && !unit->uncacheable && !unit->describe && - !derived_is_recursive) + /* + Only fill derived tables once, unless the derived table is dependent in + which case we will delete all of its rows and refill it below. + */ + if (unit->executed && !(unit->uncacheable & UNCACHEABLE_DEPENDENT) && + !unit->describe && !derived_is_recursive) DBUG_RETURN(FALSE); /*check that table creation passed without problems. */ DBUG_ASSERT(derived->table && derived->table->is_created()); @@ -1225,7 +1229,9 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) /* Execute the query that specifies the derived table by a foreign engine */ res= derived->pushdown_derived->execute(); unit->executed= true; + if (res) DBUG_RETURN(res); + goto after_exec; } if (unit->executed && !derived_is_recursive && @@ -1267,6 +1273,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) } else { + DBUG_ASSERT(!unit->executed || (unit->uncacheable & UNCACHEABLE_DEPENDENT)); SELECT_LEX *first_select= unit->first_select(); unit->set_limit(unit->global_parameters()); if (unit->lim.is_unlimited()) @@ -1286,6 +1293,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) derived_result, unit, first_select); } + after_exec: if (!res && !derived_is_recursive) { if (derived_result->flush()) diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc index 8681e08e014..8b511b25939 100644 --- a/sql/sql_expression_cache.cc +++ b/sql/sql_expression_cache.cc @@ -272,7 +272,8 @@ my_bool Expression_cache_tmptable::put_value(Item *value) } *(items.head_ref())= value; - fill_record(table_thd, cache_table, cache_table->field, items, TRUE, TRUE); + fill_record(table_thd, cache_table, cache_table->field, items, true, true, + true); if (unlikely(table_thd->is_error())) goto err;; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index ccb5a7de1eb..fe461dfd2a5 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1449,7 +1449,7 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view, *trans_end= trans_start + num; Field_translator *trans; uint used_fields_buff_size= bitmap_buffer_size(table->s->fields); - uint32 *used_fields_buff= (uint32*)thd->alloc(used_fields_buff_size); + my_bitmap_map *used_fields_buff= (my_bitmap_map*)thd->alloc(used_fields_buff_size); MY_BITMAP used_fields; enum_column_usage saved_column_usage= thd->column_usage; List_iterator_fast it(fields); @@ -1948,14 +1948,31 @@ int write_record(THD *thd, TABLE *table, COPY_INFO *info, select_result *sink) was used. This ensures that we don't get a problem when the whole range of the key has been used. */ - if (info->handle_duplicates == DUP_REPLACE && table->next_number_field && + if (info->handle_duplicates == DUP_REPLACE && key_nr == table->s->next_number_index && insert_id_for_cur_row > 0) goto err; - if (table->file->ha_table_flags() & HA_DUPLICATE_POS) + if (table->file->has_dup_ref()) { + /* + If engine doesn't support HA_DUPLICATE_POS, the handler may init to + INDEX, but dup_ref could also be set by lookup_handled (and then, + lookup_errkey is set, f.ex. long unique duplicate). + + In such case, handler would stay uninitialized, so do it here. + */ + bool init_lookup_handler= table->file->lookup_errkey != (uint)-1 && + table->file->inited == handler::NONE; + if (init_lookup_handler && table->file->ha_rnd_init_with_error(false)) + goto err; + DBUG_ASSERT(table->file->inited == handler::RND); - if (table->file->ha_rnd_pos(table->record[1],table->file->dup_ref)) - goto err; + int rnd_pos_err= table->file->ha_rnd_pos(table->record[1], + table->file->dup_ref); + + if (init_lookup_handler) + table->file->ha_rnd_end(); + if (rnd_pos_err) + goto err; } else { @@ -2398,7 +2415,7 @@ public: passed from connection thread to the handler thread. */ MDL_request grl_protection; - Delayed_insert(SELECT_LEX *current_select) + Delayed_insert(LEX *lex) :locks_in_memory(0), thd(next_thread_id()), table(0),tables_in_use(0), stacked_inserts(0), status(0), retry(0), handler_thread_initialized(FALSE), group_count(0) @@ -2411,8 +2428,9 @@ public: strmake_buf(thd.security_ctx->priv_user, thd.security_ctx->user); thd.current_tablenr=0; thd.set_command(COM_DELAYED_INSERT); - thd.lex->current_select= current_select; - thd.lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock() + thd.lex->current_select= lex->current_select; + thd.lex->sql_command= lex->sql_command; // For innodb::store_lock() + thd.lex->duplicates= lex->duplicates; /* Prevent changes to global.lock_wait_timeout from affecting delayed insert threads as any timeouts in delayed inserts @@ -2588,7 +2606,7 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request, */ if (! (di= find_handler(thd, table_list))) { - if (!(di= new Delayed_insert(thd->lex->current_select))) + if (!(di= new Delayed_insert(thd->lex))) goto end_create; /* @@ -2889,6 +2907,8 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) copy->def_read_set.bitmap= (my_bitmap_map*) bitmap; copy->def_write_set.bitmap= ((my_bitmap_map*) (bitmap + share->column_bitmap_size)); + create_last_bit_mask(©->def_read_set); + create_last_bit_mask(©->def_write_set); bitmaps_used= 2; if (share->default_fields || share->default_expressions) { diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 1ef4b3f44b4..b80f386179f 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -1595,6 +1595,7 @@ bool JOIN_CACHE::put_record() { bool is_full; uchar *link= 0; + DBUG_ASSERT(!for_explain_only); if (prev_cache) link= prev_cache->get_curr_rec_link(); write_record_data(link, &is_full); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 22eb8834492..03509846cd7 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -4277,17 +4277,18 @@ uint8 LEX::get_effective_with_check(TABLE_LIST *view) bool LEX::copy_db_to(LEX_CSTRING *to) { - if (sphead && sphead->m_name.str) - { - DBUG_ASSERT(sphead->m_db.str && sphead->m_db.length); - /* - It is safe to assign the string by-pointer, both sphead and - its statements reside in the same memory root. - */ - *to= sphead->m_db; - return FALSE; - } - return thd->copy_db_to(to); + if (!sphead || !sphead->m_name.str) + return thd->copy_db_to(to); + + DBUG_ASSERT(sphead->m_db.str); + DBUG_ASSERT(sphead->m_db.length); + + /* + It is safe to assign the string by-pointer, both sphead and + its statements reside in the same memory root. + */ + *to= sphead->m_db; + return FALSE; } /** diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ca8bf7e940c..1740dbfa348 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1437,7 +1437,7 @@ public: bool add_ftfunc_to_list(THD *thd, Item_func_match *func); bool add_order_to_list(THD *thd, Item *item, bool asc); bool add_gorder_to_list(THD *thd, Item *item, bool asc); - TABLE_LIST* add_table_to_list(THD *thd, const Table_ident *table, + TABLE_LIST* add_table_to_list(THD *thd, Table_ident *table, const LEX_CSTRING *alias, ulong table_options, thr_lock_type flags= TL_UNLOCK, @@ -3323,7 +3323,7 @@ public: Table_type table_type; /* Used for SHOW CREATE */ List ref_list; List users_list; - List *insert_list,field_list,value_list,update_list; + List *insert_list= nullptr,field_list,value_list,update_list; List many_values; List var_list; List stmt_var_list; //SET_STATEMENT values diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 08181835dba..84b253bad75 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -107,23 +107,41 @@ public: class Wsrep_load_data_split { public: - Wsrep_load_data_split(THD *thd) + Wsrep_load_data_split(THD *thd, TABLE *table) : m_thd(thd) - , m_load_data_splitting(wsrep_load_data_splitting) + , m_load_data_splitting(false) , m_fragment_unit(thd->wsrep_trx().streaming_context().fragment_unit()) , m_fragment_size(thd->wsrep_trx().streaming_context().fragment_size()) { - if (WSREP(m_thd) && m_load_data_splitting) + /* + We support load data splitting for InnoDB only as it will use + streaming replication (SR). + */ + if (WSREP(thd) && wsrep_load_data_splitting) { - /* Override streaming settings with backward compatible values for - load data splitting */ - m_thd->wsrep_cs().streaming_params(wsrep::streaming_context::row, 10000); + handlerton *ht= table->s->db_type(); + // For partitioned tables find underlying hton + if (table->file->partition_ht()) + ht= table->file->partition_ht(); + if (ht->db_type != DB_TYPE_INNODB) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_NOT_SUPPORTED_YET, + "wsrep_load_data_splitting for other than InnoDB tables"); + } + else + { + /* Override streaming settings with backward compatible values for + load data splitting */ + m_thd->wsrep_cs().streaming_params(wsrep::streaming_context::row, 10000); + m_load_data_splitting= true; + } } } ~Wsrep_load_data_split() { - if (WSREP(m_thd) && m_load_data_splitting) + if (m_load_data_splitting) { /* Restore original settings */ m_thd->wsrep_cs().streaming_params(m_fragment_unit, m_fragment_size); @@ -348,6 +366,7 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list, bool is_concurrent; #endif const char *db= table_list->db.str; // This is never null + /* If path for file is not defined, we will use the current database. If this is not set, we will use the directory where the table to be @@ -358,9 +377,6 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list, bool transactional_table __attribute__((unused)); DBUG_ENTER("mysql_load"); -#ifdef WITH_WSREP - Wsrep_load_data_split wsrep_load_data_split(thd); -#endif /* WITH_WSREP */ /* Bug #34283 mysqlbinlog leaves tmpfile after termination if binlog contains @@ -425,6 +441,11 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list, { DBUG_RETURN(TRUE); } + +#ifdef WITH_WSREP + Wsrep_load_data_split wsrep_load_data_split(thd, table_list->table); +#endif /* WITH_WSREP */ + thd_proc_info(thd, "Executing"); /* Let us emit an error if we are loading data to table which is used diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc index 3d3728b9e00..b3d95c9ed31 100644 --- a/sql/sql_manager.cc +++ b/sql/sql_manager.cc @@ -26,7 +26,11 @@ #include "sql_manager.h" #include "sql_base.h" // flush_tables -static bool volatile manager_thread_in_use = 0; +/* + Values for manager_thread_in_use: 0 means "not started". 1 means "started + and active". 2 means "stopped". +*/ +static int volatile manager_thread_in_use = 0; static bool abort_manager = false; pthread_t manager_thread; @@ -44,7 +48,7 @@ static struct handler_cb *cb_list; // protected by LOCK_manager bool mysql_manager_submit(void (*action)(void *), void *data) { bool result= FALSE; - DBUG_ASSERT(manager_thread_in_use); + DBUG_ASSERT(manager_thread_in_use == 1); struct handler_cb **cb; mysql_mutex_lock(&LOCK_manager); cb= &cb_list; @@ -76,7 +80,9 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) pthread_detach_this_thread(); manager_thread = pthread_self(); mysql_mutex_lock(&LOCK_manager); - while (!abort_manager) + manager_thread_in_use = 1; + mysql_cond_signal(&COND_manager); + while (!abort_manager || cb_list) { /* XXX: This will need to be made more general to handle different * polling needs. */ @@ -116,7 +122,8 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) } mysql_mutex_lock(&LOCK_manager); } - manager_thread_in_use = 0; + DBUG_ASSERT(cb_list == NULL); + manager_thread_in_use = 2; mysql_mutex_unlock(&LOCK_manager); mysql_mutex_destroy(&LOCK_manager); mysql_cond_destroy(&COND_manager); @@ -135,12 +142,28 @@ void start_handle_manager() pthread_t hThread; int err; DBUG_EXECUTE_IF("delay_start_handle_manager", my_sleep(1000);); - manager_thread_in_use = 1; mysql_cond_init(key_COND_manager, &COND_manager,NULL); mysql_mutex_init(key_LOCK_manager, &LOCK_manager, NULL); if ((err= mysql_thread_create(key_thread_handle_manager, &hThread, &connection_attrib, handle_manager, 0))) + { sql_print_warning("Can't create handle_manager thread (errno: %M)", err); + DBUG_VOID_RETURN; + } + + mysql_mutex_lock(&LOCK_manager); + /* + Wait for manager thread to have started, otherwise in extreme cases the + server may start up and have initiated shutdown at the time the manager + thread even starts to run. + + Allow both values 1 and 2 for manager_thread_in_use, so that we will not + get stuck here if the manager thread somehow manages to start up and + abort again before we have time to test it here. + */ + while (!manager_thread_in_use) + mysql_cond_wait(&COND_manager, &LOCK_manager); + mysql_mutex_unlock(&LOCK_manager); } DBUG_VOID_RETURN; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2eb27c43081..38cc723ce56 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2249,6 +2249,7 @@ dispatch_command_return dispatch_command(enum enum_server_command command, THD * my_eof(thd); kill_mysql(thd); error=TRUE; + DBUG_EXECUTE_IF("simulate_slow_client_at_shutdown", my_sleep(2000000);); break; } #endif @@ -2406,6 +2407,11 @@ resume: } #endif /* WITH_WSREP */ + if (thd->reset_sp_cache) + { + thd->sp_caches_empty(); + thd->reset_sp_cache= false; + } if (do_end_of_statement) { @@ -2483,6 +2489,7 @@ resume: MYSQL_COMMAND_DONE(res); } DEBUG_SYNC(thd,"dispatch_command_end"); + DEBUG_SYNC(thd,"dispatch_command_end2"); /* Check that some variables are reset properly */ DBUG_ASSERT(thd->abort_on_warning == 0); @@ -4498,10 +4505,15 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt) if ((res= insert_precheck(thd, all_tables))) break; + #ifdef WITH_WSREP - if (WSREP(thd) && thd->wsrep_consistency_check == CONSISTENCY_CHECK_DECLARED) + bool wsrep_toi= false; + const bool wsrep= WSREP(thd); + + if (wsrep && thd->wsrep_consistency_check == CONSISTENCY_CHECK_DECLARED) { thd->wsrep_consistency_check = CONSISTENCY_CHECK_RUNNING; + wsrep_toi= true; WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL); } #endif /* WITH_WSREP */ @@ -4536,6 +4548,27 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt) if (!(res=open_and_lock_tables(thd, all_tables, TRUE, 0))) { MYSQL_INSERT_SELECT_START(thd->query()); + +#ifdef WITH_WSREP + if (wsrep && !first_table->view) + { + bool is_innodb= (first_table->table->file->ht->db_type == DB_TYPE_INNODB); + + // For consistency check inserted table needs to be InnoDB + if (!is_innodb && thd->wsrep_consistency_check != NO_CONSISTENCY_CHECK) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + HA_ERR_UNSUPPORTED, + "Galera cluster does support consistency check only" + " for InnoDB tables."); + thd->wsrep_consistency_check= NO_CONSISTENCY_CHECK; + } + + // For !InnoDB we start TOI if it is not yet started and hope for the best + if (!is_innodb && !wsrep_toi) + WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL); + } +#endif /* WITH_WSREP */ /* Only the INSERT table should be merged. Other will be handled by select. @@ -5575,7 +5608,7 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt) if (sph->sp_resolve_package_routine(thd, thd->lex->sphead, lex->spname, &sph, &pkgname)) return true; - if (sph->sp_cache_routine(thd, lex->spname, false, &sp)) + if (sph->sp_cache_routine(thd, lex->spname, &sp)) goto error; if (!sp || sp->show_routine_code(thd)) { @@ -5878,13 +5911,11 @@ finish: if (unlikely(thd->is_error()) || (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR)) { - THD_STAGE_INFO(thd, stage_rollback); trans_rollback_stmt(thd); } else { /* If commit fails, we should be able to reset the OK status. */ - THD_STAGE_INFO(thd, stage_commit); thd->get_stmt_da()->set_overwrite_status(true); trans_commit_stmt(thd); thd->get_stmt_da()->set_overwrite_status(false); @@ -5911,7 +5942,6 @@ finish: one of storage engines (e.g. due to deadlock). Rollback transaction in all storage engines including binary log. */ - THD_STAGE_INFO(thd, stage_rollback_implicit); trans_rollback_implicit(thd); thd->release_transactional_locks(); } @@ -5921,7 +5951,6 @@ finish: DBUG_ASSERT(! thd->in_sub_stmt); if (!(thd->variables.option_bits & OPTION_GTID_BEGIN)) { - THD_STAGE_INFO(thd, stage_commit_implicit); /* If commit fails, we should be able to reset the OK status. */ thd->get_stmt_da()->set_overwrite_status(true); /* Commit the normal transaction if one is active. */ @@ -7987,7 +8016,7 @@ bool add_to_list(THD *thd, SQL_I_List &list, Item *item,bool asc) */ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, - const Table_ident *table, + Table_ident *table, const LEX_CSTRING *alias, ulong table_options, thr_lock_type lock_type, @@ -7996,10 +8025,6 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, List *partition_names, LEX_STRING *option) { - TABLE_LIST *ptr; - TABLE_LIST *UNINIT_VAR(previous_table_ref); /* The table preceding the current one. */ - LEX_CSTRING alias_str; - LEX *lex= thd->lex; DBUG_ENTER("add_table_to_list"); DBUG_PRINT("enter", ("Table '%s' (%p) Select %p (%u)", (alias ? alias->str : table->table.str), @@ -8009,9 +8034,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (unlikely(!table)) DBUG_RETURN(0); // End of memory - alias_str= alias ? *alias : table->table; - DBUG_ASSERT(alias_str.str); - if (!MY_TEST(table_options & TL_OPTION_ALIAS) && + if (!(table_options & TL_OPTION_ALIAS) && unlikely(check_table_name(table->table.str, table->table.length, FALSE))) { my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str); @@ -8023,6 +8046,34 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, Lex_ident_fs(table->db).check_db_name_with_error())) DBUG_RETURN(0); + LEX_CSTRING db{0, 0}; + bool fqtn= false; + LEX *lex= thd->lex; + if (table->db.str) + { + fqtn= TRUE; + db= table->db; + } + else if (!lex->with_cte_resolution && lex->copy_db_to(&db)) + DBUG_RETURN(0); + else + fqtn= FALSE; + bool info_schema= is_infoschema_db(&db); + if (!table->sel && info_schema && + (table_options & TL_OPTION_UPDATING) && + /* Special cases which are processed by commands itself */ + lex->sql_command != SQLCOM_CHECK && + lex->sql_command != SQLCOM_CHECKSUM) + { + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->security_ctx->priv_user, + thd->security_ctx->priv_host, + INFORMATION_SCHEMA_NAME.str); + DBUG_RETURN(0); + } + + LEX_CSTRING alias_str= alias ? *alias : table->table; + DBUG_ASSERT(alias_str.str); if (!alias) /* Alias is case sensitive */ { if (unlikely(table->sel)) @@ -8035,64 +8086,15 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (unlikely(!(alias_str.str= (char*) thd->memdup(alias_str.str, alias_str.length+1)))) DBUG_RETURN(0); } - if (unlikely(!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))) - DBUG_RETURN(0); /* purecov: inspected */ - if (table->db.str) - { - ptr->is_fqtn= TRUE; - ptr->db= table->db; - } - else if (!lex->with_cte_resolution && lex->copy_db_to(&ptr->db)) - DBUG_RETURN(0); - else - ptr->is_fqtn= FALSE; - ptr->alias= alias_str; - ptr->is_alias= alias ? TRUE : FALSE; - ptr->table_name= table->table; + bool has_alias_ptr= alias != nullptr; + void *memregion= thd->calloc(sizeof(TABLE_LIST)); + TABLE_LIST *ptr= new (memregion) TABLE_LIST(thd, db, fqtn, alias_str, + has_alias_ptr, table, lock_type, + mdl_type, table_options, + info_schema, this, + index_hints_arg, option); - if (lower_case_table_names) - { - if (!(ptr->table_name= thd->make_ident_casedn(ptr->table_name)).str) - DBUG_RETURN(0); - if (ptr->db.length && ptr->db.str != any_db.str && - !(ptr->db= thd->make_ident_casedn(ptr->db)).str) - DBUG_RETURN(0); - } - - ptr->lock_type= lock_type; - ptr->mdl_type= mdl_type; - ptr->table_options= table_options; - ptr->updating= MY_TEST(table_options & TL_OPTION_UPDATING); - ptr->ignore_leaves= MY_TEST(table_options & TL_OPTION_IGNORE_LEAVES); - ptr->sequence= MY_TEST(table_options & TL_OPTION_SEQUENCE); - ptr->derived= table->sel; - if (!ptr->derived && is_infoschema_db(&ptr->db)) - { - if (ptr->updating && - /* Special cases which are processed by commands itself */ - lex->sql_command != SQLCOM_CHECK && - lex->sql_command != SQLCOM_CHECKSUM) - { - my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), - thd->security_ctx->priv_user, - thd->security_ctx->priv_host, - INFORMATION_SCHEMA_NAME.str); - DBUG_RETURN(0); - } - ST_SCHEMA_TABLE *schema_table; - schema_table= find_schema_table(thd, &ptr->table_name); - ptr->schema_table_name= ptr->table_name; - ptr->schema_table= schema_table; - } - ptr->select_lex= this; - /* - We can't cache internal temporary tables between prepares as the - table may be deleted before next execution. - */ - ptr->cacheable_table= !table->is_derived_table(); - ptr->index_hints= index_hints_arg; - ptr->option= option ? option->str : 0; /* check that used name is unique. Sequences are ignored */ if (lock_type != TL_IGNORE && !ptr->sequence) { @@ -8115,6 +8117,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, } } /* Store the table reference preceding the current one. */ + TABLE_LIST *UNINIT_VAR(previous_table_ref); /* The table preceding the current one. */ if (table_list.elements > 0 && likely(!ptr->sequence)) { /* diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 130e70d73e6..5d3c7b35321 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1080,7 +1080,7 @@ void check_range_capable_PF(TABLE *table) static bool set_up_partition_bitmaps(THD *thd, partition_info *part_info) { - uint32 *bitmap_buf; + my_bitmap_map *bitmap_buf; uint bitmap_bits= part_info->num_subparts? (part_info->num_subparts* part_info->num_parts): part_info->num_parts; @@ -1091,14 +1091,15 @@ static bool set_up_partition_bitmaps(THD *thd, partition_info *part_info) /* Allocate for both read and lock_partitions */ if (unlikely(!(bitmap_buf= - (uint32*) alloc_root(&part_info->table->mem_root, - bitmap_bytes * 2)))) + (my_bitmap_map*) alloc_root(&part_info->table->mem_root, + bitmap_bytes * 2)))) DBUG_RETURN(TRUE); my_bitmap_init(&part_info->read_partitions, bitmap_buf, bitmap_bits); /* Use the second half of the allocated buffer for lock_partitions */ - my_bitmap_init(&part_info->lock_partitions, bitmap_buf + (bitmap_bytes / 4), - bitmap_bits); + my_bitmap_init(&part_info->lock_partitions, + (my_bitmap_map*) (((char*) bitmap_buf) + bitmap_bytes), + bitmap_bits); part_info->bitmaps_are_initialized= TRUE; part_info->set_partition_bitmaps(NULL); DBUG_RETURN(FALSE); @@ -7763,7 +7764,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ERROR_INJECT("add_partition_1") || mysql_write_frm(lpt, WFRM_WRITE_SHADOW) || ERROR_INJECT("add_partition_2") || - wait_while_table_is_used(thd, table, HA_EXTRA_NOT_USED) || + wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME) || ERROR_INJECT("add_partition_3") || write_log_add_change_partition(lpt) || ERROR_INJECT("add_partition_4") || diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index fca16ffa369..7f4cf2a8c58 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -4284,7 +4284,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, if (unlikely(error)) { - sql_print_error("Parsing options for plugin '%s' failed.", + sql_print_error("Parsing options for plugin '%s' failed. Disabling plugin", tmp->name.str); goto err; } diff --git a/sql/sql_plugin_services.inl b/sql/sql_plugin_services.inl index 5b3fbea861d..2114f3560a7 100644 --- a/sql/sql_plugin_services.inl +++ b/sql/sql_plugin_services.inl @@ -18,6 +18,7 @@ #include #include #include +#include struct st_service_ref { const char *name; @@ -219,6 +220,11 @@ static struct my_print_error_service_st my_print_error_handler= my_printv_error }; +static struct print_check_msg_service_st print_check_msg_handler= +{ + print_check_msg +}; + static struct json_service_st json_handler= { json_type, @@ -339,6 +345,7 @@ static struct st_service_ref list_of_services[]= { "my_crypt_service", VERSION_my_crypt, &crypt_handler}, { "my_md5_service", VERSION_my_md5, &my_md5_handler}, { "my_print_error_service", VERSION_my_print_error, &my_print_error_handler}, + { "print_check_msg_service", VERSION_print_check_msg, &print_check_msg_handler}, { "my_sha1_service", VERSION_my_sha1, &my_sha1_handler}, { "my_sha2_service", VERSION_my_sha2, &my_sha2_handler}, { "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler }, diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 8104806af71..0c0b863edf3 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -68,6 +68,15 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, bool result=0; select_errors=0; /* Write if more errors */ int tmp_write_to_binlog= *write_to_binlog= 1; +#ifndef DBUG_OFF + /* + When invoked for handling a SIGHUP by rpl_shutdown_sighup.test, we need to + force the signal handler to wait after REFRESH_TABLES, as that will check + for a killed server, and we need to call hostname_cache_refresh after + server cleanup has happened to trigger MDEV-30260. + */ + int do_dbug_sleep= 0; +#endif DBUG_ASSERT(!thd || !thd->in_sub_stmt); @@ -102,6 +111,15 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, */ my_error(ER_UNKNOWN_ERROR, MYF(0)); } + +#ifndef DBUG_OFF + DBUG_EXECUTE_IF("hold_sighup_log_refresh", { + DBUG_ASSERT(!debug_sync_set_action( + thd, STRING_WITH_LEN("now SIGNAL in_reload_acl_and_cache " + "WAIT_FOR refresh_logs"))); + do_dbug_sleep= 1; + }); +#endif } opt_noacl= 0; @@ -354,6 +372,11 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, } my_dbopt_cleanup(); } + +#ifndef DBUG_OFF + if (do_dbug_sleep) + my_sleep(3000000); // 3s +#endif if (options & REFRESH_HOSTS) hostname_cache_refresh(); if (thd && (options & REFRESH_STATUS)) @@ -372,7 +395,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, } } #endif -#ifdef HAVE_OPENSSL +#ifdef HAVE_des if (options & REFRESH_DES_KEY_FILE) { if (des_key_file && load_des_key_file(des_key_file)) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index fb470cbcbb9..8ca252c37c6 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -223,7 +223,7 @@ static int fake_rotate_event(binlog_send_info *info, ulonglong position, char* p = info->log_file_name+dirname_length(info->log_file_name); uint ident_len = (uint) strlen(p); String *packet= info->packet; - ha_checksum crc; + ha_checksum crc= 0; /* reset transmit packet for the fake rotate event below */ if (reset_transmit_packet(info, info->flags, &ev_offset, &info->errmsg)) @@ -264,7 +264,7 @@ static int fake_gtid_list_event(binlog_send_info *info, { my_bool do_checksum; int err; - ha_checksum crc; + ha_checksum crc= 0; char buf[128]; String str(buf, sizeof(buf), system_charset_info); String* packet= info->packet; @@ -3052,12 +3052,6 @@ static int send_one_binlog_file(binlog_send_info *info, */ if (send_events(info, log, linfo, end_pos)) return 1; - DBUG_EXECUTE_IF("Notify_binlog_EOF", - { - const char act[]= "now signal eof_reached"; - DBUG_ASSERT(!debug_sync_set_action(current_thd, - STRING_WITH_LEN(act))); - };); } return 1; @@ -4130,11 +4124,7 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added) if (lex_mi->use_gtid_opt == LEX_MASTER_INFO::LEX_GTID_SLAVE_POS) mi->using_gtid= Master_info::USE_GTID_SLAVE_POS; else if (lex_mi->use_gtid_opt == LEX_MASTER_INFO::LEX_GTID_CURRENT_POS) - { mi->using_gtid= Master_info::USE_GTID_CURRENT_POS; - warn_deprecated<1010>(thd, "master_use_gtid=current_pos", - "master_demote_to_slave=1"); - } else if (lex_mi->use_gtid_opt == LEX_MASTER_INFO::LEX_GTID_NO || lex_mi->log_file_name || lex_mi->pos || lex_mi->relay_log_name || lex_mi->relay_log_pos) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6f2797b6b39..45cd5a30acb 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -324,8 +324,6 @@ static void update_tmptable_sum_func(Item_sum **func,TABLE *tmp_table); static void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end); static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab); static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr); -static bool prepare_sum_aggregators(THD *thd, Item_sum **func_ptr, - bool need_distinct); static bool init_sum_functions(Item_sum **func, Item_sum **end); static bool update_sum_func(Item_sum **func); static void select_describe(JOIN *join, bool need_tmp_table,bool need_order, @@ -852,37 +850,57 @@ void remove_redundant_subquery_clauses(st_select_lex *subq_select_lex) if (subq_select_lex->group_list.elements && !subq_select_lex->with_sum_func && !subq_select_lex->join->having) { + /* + Temporary workaround for MDEV-28621: Do not remove GROUP BY expression + if it has any subqueries in it. + */ + bool have_subquery= false; for (ORDER *ord= subq_select_lex->group_list.first; ord; ord= ord->next) { - /* - Do not remove the item if it is used in select list and then referred - from GROUP BY clause by its name or number. Example: - - select (select ... ) as SUBQ ... group by SUBQ - - Here SUBQ cannot be removed. - */ - if (!ord->in_field_list) + if ((*ord->item)->with_subquery()) { - (*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL); - /* - Remove from the JOIN::all_fields list any reference to the elements - of the eliminated GROUP BY list unless it is 'in_field_list'. - This is needed in order not to confuse JOIN::make_aggr_tables_info() - when it constructs different structure for execution phase. - */ - List_iterator li(subq_select_lex->join->all_fields); - Item *item; - while ((item= li++)) - { - if (item == *ord->item) - li.remove(); - } + have_subquery= true; + break; } } - subq_select_lex->join->group_list= NULL; - subq_select_lex->group_list.empty(); - DBUG_PRINT("info", ("GROUP BY removed")); + + if (!have_subquery) + { + for (ORDER *ord= subq_select_lex->group_list.first; ord; ord= ord->next) + { + /* + Do not remove the item if it is used in select list and then referred + from GROUP BY clause by its name or number. Example: + + select (select ... ) as SUBQ ... group by SUBQ + + Here SUBQ cannot be removed. + */ + if (!ord->in_field_list) + { + /* + Not necessary due to workaround for MDEV-28621: + (*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL); + */ + /* + Remove from the JOIN::all_fields list any reference to the elements + of the eliminated GROUP BY list unless it is 'in_field_list'. + This is needed in order not to confuse JOIN::make_aggr_tables_info() + when it constructs different structure for execution phase. + */ + List_iterator li(subq_select_lex->join->all_fields); + Item *item; + while ((item= li++)) + { + if (item == *ord->item) + li.remove(); + } + } + } + subq_select_lex->join->group_list= NULL; + subq_select_lex->group_list.empty(); + DBUG_PRINT("info", ("GROUP BY removed")); + } } /* @@ -2416,6 +2434,10 @@ JOIN::optimize_inner() select_lex->attach_to_conds, &cond_value); sel->attach_to_conds.empty(); + Json_writer_object wrapper(thd); + Json_writer_object pushd(thd, "condition_pushdown_from_having"); + pushd.add("conds", conds); + pushd.add("having", having); } } @@ -3665,7 +3687,7 @@ bool JOIN::make_aggr_tables_info() distinct in the engine, so we do this for all queries, not only GROUP BY queries. */ - if (tables_list && top_join_tab_count && !procedure) + if (tables_list && top_join_tab_count && !only_const_tables() && !procedure) { /* At the moment we only support push down for queries where @@ -4303,7 +4325,7 @@ JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List *table_fields, if (make_sum_func_list(all_fields, fields_list, true)) goto err; if (prepare_sum_aggregators(thd, sum_funcs, - !(tables_list && + !(tables_list && join_tab->is_using_agg_loose_index_scan()))) goto err; if (setup_sum_funcs(thd, sum_funcs)) @@ -11168,7 +11190,7 @@ double table_after_join_selectivity(JOIN *join, uint idx, JOIN_TAB *s, else { sel= records_out / pos->records_read; - DBUG_ASSERT(sel >= 0.0 and sel <= 1.00001); + DBUG_ASSERT(sel >= 0.0 && sel <= 1.00001); if (sel > 1.0) sel= 1.0; } @@ -14927,7 +14949,8 @@ end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) if (item->is_null()) DBUG_RETURN(NESTED_LOOP_OK); } - fill_record(thd, table, table->field, sjm->sjm_table_cols, TRUE, FALSE); + fill_record(thd, table, table->field, sjm->sjm_table_cols, true, false, + true); if (unlikely(thd->is_error())) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ if (unlikely((error= table->file->ha_write_tmp_row(table->record[0])))) @@ -18415,6 +18438,7 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels, if (!eq_item || eq_item->set_cmp_func(thd)) return 0; + eq_item->eval_not_null_tables(0); eq_item->quick_fix_field(); } current_sjm= field_sjm; @@ -18472,6 +18496,7 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels, { res->quick_fix_field(); res->update_used_tables(); + res->eval_not_null_tables(0); } return res; @@ -20141,6 +20166,12 @@ Item_cond::remove_eq_conds(THD *thd, Item::cond_result *cond_value, bool and_level= functype() == Item_func::COND_AND_FUNC; List *cond_arg_list= argument_list(); + if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL)) + { + *cond_value= Item::COND_FALSE; + return (COND*) 0; // Fatal error flag is set! + } + if (and_level) { /* @@ -22733,7 +22764,7 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table, if (open_tmp_table(&new_table)) goto err1; if (table->file->indexes_are_disabled()) - new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL); + new_table.file->ha_disable_indexes(key_map(0), false); table->file->ha_index_or_rnd_end(); if (table->file->ha_rnd_init_with_error(1)) DBUG_RETURN(1); @@ -28972,15 +29003,86 @@ static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr) } -static bool prepare_sum_aggregators(THD *thd,Item_sum **func_ptr, - bool need_distinct) +/* + @brief + Setup aggregate functions. + + @param thd Thread descriptor + @param func_ptr Array of pointers to aggregate functions + @param need_distinct FALSE means that the table access method already + guarantees that arguments of all aggregate functions + will be unique. (This is the case for Loose Scan) + TRUE - Otherwise. + @return + false Ok + true Error +*/ + +bool JOIN::prepare_sum_aggregators(THD *thd, Item_sum **func_ptr, + bool need_distinct) { Item_sum *func; DBUG_ENTER("prepare_sum_aggregators"); while ((func= *(func_ptr++))) { - if (func->set_aggregator(thd, - need_distinct && func->has_with_distinct() ? + bool need_distinct_aggregator= need_distinct && func->has_with_distinct(); + if (need_distinct_aggregator && table_count - const_tables == 1) + { + /* + We are doing setup for an aggregate with DISTINCT, like + + SELECT agg_func(DISTINCT col1, col2 ...) FROM ... + + In general case, agg_func will need to use Aggregator_distinct to + remove duplicates from its arguments. + We won't have to remove duplicates if we know the arguments are already + unique. This is true when + 1. the join operation has only one non-const table (checked above) + 2. the argument list covers a PRIMARY or a UNIQUE index. + + Example: here the values of t1.pk are unique: + + SELECT agg_func(DISTINCT t1.pk, ...) FROM t1 + + and so the whole argument of agg_func is unique. + */ + List arg_fields; + for (uint i= 0; i < func->argument_count(); i++) + { + if (func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM) + arg_fields.push_back(func->arguments()[i]); + } + + /* + If the query has a GROUP BY, then it's sufficient that a unique + key is covered by a concatenation of {argument_list, group_by_list}. + + Example: Suppose t1 has PRIMARY KEY(pk1, pk2). Then: + + SELECT agg_func(DISTINCT t1.pk1, ...) FROM t1 GROUP BY t1.pk2 + + Each GROUP BY group will have t1.pk2 fixed. Then, the values of t1.pk1 + will be unique, and no de-duplication will be needed. + */ + for (ORDER *group= group_list; group ; group= group->next) + { + if ((*group->item)->real_item()->type() == Item::FIELD_ITEM) + arg_fields.push_back(*group->item); + } + + if (list_contains_unique_index(join_tab[const_tables].table, + find_field_in_item_list, + (void *) &arg_fields)) + need_distinct_aggregator= false; + } + Json_writer_object trace_wrapper(thd); + Json_writer_object trace_aggr(thd, "prepare_sum_aggregators"); + trace_aggr.add("function", func); + trace_aggr.add("aggregator_type", + (need_distinct_aggregator || + func->uses_non_standard_aggregator_for_distinct()) ? + "distinct" : "simple"); + if (func->set_aggregator(thd, need_distinct_aggregator ? Aggregator::DISTINCT_AGGREGATOR : Aggregator::SIMPLE_AGGREGATOR)) DBUG_RETURN(TRUE); @@ -33049,7 +33151,26 @@ void JOIN::init_join_cache_and_keyread() */ table->mark_index_columns(table->file->keyread, table->read_set); } - if (tab->cache && tab->cache->init(select_options & SELECT_DESCRIBE)) + bool init_for_explain= false; + + /* + Can we use lightweight initalization mode just for EXPLAINs? We can if + we're certain that the optimizer will not execute the subquery. + The optimzier will not execute the subquery if it's too expensive. For + the exact criteria, see Item_subselect::is_expensive(). + Note that the subquery might be a UNION and we might not yet know if it + is expensive. + What we do know is that if this SELECT is too expensive, then the whole + subquery will be too expensive as well. + So, we can use lightweight initialization (init_for_explain=true) if this + SELECT examines more than @@expensive_subquery_limit rows. + */ + if ((select_options & SELECT_DESCRIBE) && + get_examined_rows() >= thd->variables.expensive_subquery_limit) + { + init_for_explain= true; + } + if (tab->cache && tab->cache->init(init_for_explain)) revise_cache_usage(tab); else tab->remove_redundant_bnl_scan_conds(); diff --git a/sql/sql_select.h b/sql/sql_select.h index f1198033c68..fd280164792 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1957,6 +1957,8 @@ private: bool add_fields_for_current_rowid(JOIN_TAB *cur, List *fields); void free_pushdown_handlers(List& join_list); void init_join_cache_and_keyread(); + bool prepare_sum_aggregators(THD *thd,Item_sum **func_ptr, + bool need_distinct); bool transform_in_predicates_into_equalities(THD *thd); bool transform_date_conds_into_sargable(); bool transform_all_conds_and_on_exprs(THD *thd, diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc index f6d7c310a2f..b1d59aac984 100644 --- a/sql/sql_sequence.cc +++ b/sql/sql_sequence.cc @@ -28,6 +28,9 @@ #include "sql_acl.h" #ifdef WITH_WSREP #include "wsrep_mysqld.h" +bool wsrep_check_sequence(THD* thd, + const sequence_definition *seq, + const bool used_engine); #endif struct Field_definition @@ -942,7 +945,8 @@ bool Sql_cmd_alter_sequence::execute(THD *thd) #ifdef WITH_WSREP if (WSREP(thd) && wsrep_thd_is_local(thd)) { - if (wsrep_check_sequence(thd, new_seq)) + const bool used_engine= lex->create_info.used_fields & HA_CREATE_USED_ENGINE; + if (wsrep_check_sequence(thd, new_seq, used_engine)) DBUG_RETURN(TRUE); if (wsrep_to_isolation_begin(thd, first_table->db.str, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 474d9611660..cc7e7a2a5da 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2831,9 +2831,10 @@ static my_bool list_callback(THD *tmp, list_callback_arg *arg) thd_info->thread_id=tmp->thread_id; thd_info->os_thread_id=tmp->os_thread_id; - thd_info->user= arg->thd->strdup(tmp_sctx->user ? tmp_sctx->user : - (tmp->system_thread ? - "system user" : "unauthenticated user")); + thd_info->user= arg->thd->strdup(tmp_sctx->user && tmp_sctx->user != slave_user ? + tmp_sctx->user : + (tmp->system_thread ? + "system user" : "unauthenticated user")); if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) && arg->thd->security_ctx->host_or_ip[0]) { @@ -3055,7 +3056,7 @@ int select_result_explain_buffer::send_data(List &items) Show_explain_request::call_in_target_thread, is this necessary anymore?) */ set_current_thd(thd); - fill_record(thd, dst_table, dst_table->field, items, TRUE, FALSE); + fill_record(thd, dst_table, dst_table->field, items, true, false, false); res= dst_table->file->ha_write_tmp_row(dst_table->record[0]); set_current_thd(cur_thd); DBUG_RETURN(MY_TEST(res)); @@ -3336,7 +3337,7 @@ static my_bool processlist_callback(THD *tmp, processlist_callback_arg *arg) /* ID */ arg->table->field[0]->store((longlong) tmp->thread_id, TRUE); /* USER */ - val= tmp_sctx->user ? tmp_sctx->user : + val= tmp_sctx->user && tmp_sctx->user != slave_user ? tmp_sctx->user : (tmp->system_thread ? "system user" : "unauthenticated user"); arg->table->field[1]->store(val, strlen(val), cs); /* HOST */ @@ -5272,6 +5273,20 @@ public: }; +static bool wildcmpcs(const LEX_CSTRING &str, const LEX_CSTRING &pat) +{ + return table_alias_charset->wildcmp(str.str, str.str + str.length, + pat.str, pat.str + pat.length, + '\\', '_', '%'); +} + +static bool strcmpcs(const LEX_CSTRING &str, const LEX_CSTRING &pat) +{ + return table_alias_charset->strnncoll(str.str, str.length, + pat.str, pat.length, 0); +} + + /** @brief Fill I_S tables whose data are retrieved from frm files and storage engine @@ -5404,15 +5419,20 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) { All_tmp_tables_list::Iterator it(*open_tables_state_backup.temporary_tables); TMP_TABLE_SHARE *share_temp; - const char *lookup_db= plan->lookup_field_vals.db_value.str; - int (*cmp)(CHARSET_INFO *, const char *, const char *)= - plan->lookup_field_vals.wild_db_value - ? wild_case_compare : system_charset_info->coll->strcasecmp; + bool (*cmp_db)(const LEX_CSTRING &, const LEX_CSTRING &)= + plan->lookup_field_vals.wild_db_value ? wildcmpcs : strcmpcs; + bool (*cmp_table)(const LEX_CSTRING &, const LEX_CSTRING &)= + plan->lookup_field_vals.wild_table_value ? wildcmpcs : strcmpcs; while ((share_temp= it++)) { - if (lookup_db) + if (plan->lookup_field_vals.db_value.str) { - if (cmp(system_charset_info, share_temp->db.str, lookup_db)) + if (cmp_db(share_temp->db, plan->lookup_field_vals.db_value)) + continue; + } + if (plan->lookup_field_vals.table_value.str) + { + if (cmp_table(share_temp->table_name, plan->lookup_field_vals.table_value)) continue; } @@ -9798,7 +9818,7 @@ ST_FIELD_INFO stat_fields_info[]= Column("PACKED", Varchar(10), NULLABLE, "Packed", OPEN_FRM_ONLY), Column("NULLABLE", Varchar(3), NOT_NULL, "Null", OPEN_FRM_ONLY), Column("INDEX_TYPE", Varchar(16), NOT_NULL, "Index_type", OPEN_FULL_TABLE), - Column("COMMENT", Varchar(16), NULLABLE, "Comment", OPEN_FRM_ONLY), + Column("COMMENT", Varchar(16), NULLABLE, "Comment", OPEN_FULL_TABLE), Column("INDEX_COMMENT", Varchar(INDEX_COMMENT_MAXLEN), NOT_NULL, "Index_comment",OPEN_FRM_ONLY), Column("IGNORED", Varchar(3), NOT_NULL, "Ignored", OPEN_FRM_ONLY), @@ -10439,6 +10459,7 @@ static_assert(array_elements(schema_tables) == SCH_ENUM_SIZE + 1, int initialize_schema_table(st_plugin_int *plugin) { ST_SCHEMA_TABLE *schema_table; + int err; DBUG_ENTER("initialize_schema_table"); if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(key_memory_ST_SCHEMA_TABLE, @@ -10455,12 +10476,15 @@ int initialize_schema_table(st_plugin_int *plugin) /* Make the name available to the init() function. */ schema_table->table_name= plugin->name.str; - if (plugin->plugin->init(schema_table)) + if ((err= plugin->plugin->init(schema_table))) { - sql_print_error("Plugin '%s' init function returned error.", - plugin->name.str); + if (err != HA_ERR_RETRY_INIT) + sql_print_error("Plugin '%s' init function returned error.", + plugin->name.str); plugin->data= NULL; my_free(schema_table); + if (err == HA_ERR_RETRY_INIT) + DBUG_RETURN(err); DBUG_RETURN(1); } diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 408a5cfe1f6..bdff67df773 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -2906,6 +2906,9 @@ int collect_statistics_for_table(THD *thd, TABLE *table) After having been updated the statistical system tables are closed. */ +/* Stack usage 20248 from clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + int update_statistics_for_table(THD *thd, TABLE *table) { TABLE_LIST tables[STATISTICS_TABLES]; @@ -2990,6 +2993,7 @@ int update_statistics_for_table(THD *thd, TABLE *table) new_trans.restore_old_transaction(); DBUG_RETURN(rc); } +PRAGMA_REENABLE_CHECK_STACK_FRAME /** @@ -3397,6 +3401,9 @@ end: The function is called when executing the statement DROP TABLE 'tab'. */ +/* Stack size 20248 with clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + int delete_statistics_for_table(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *tab) { @@ -3465,6 +3472,7 @@ int delete_statistics_for_table(THD *thd, const LEX_CSTRING *db, new_trans.restore_old_transaction(); DBUG_RETURN(rc); } +PRAGMA_REENABLE_CHECK_STACK_FRAME /** @@ -4009,6 +4017,9 @@ int rename_indexes_in_stat_table(THD *thd, TABLE *tab, The function is called when executing any statement that renames a table */ +/* Stack size 20968 with clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + int rename_table_in_stat_tables(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *tab, const LEX_CSTRING *new_db, @@ -4086,6 +4097,7 @@ int rename_table_in_stat_tables(THD *thd, const LEX_CSTRING *db, new_trans.restore_old_transaction(); DBUG_RETURN(rc); } +PRAGMA_REENABLE_CHECK_STACK_FRAME /** diff --git a/sql/sql_string.cc b/sql/sql_string.cc index c183873ddc4..79df1e0ff94 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -1144,28 +1144,45 @@ bool String::append_for_single_quote(const char *st, size_t len) int chlen; for (; st < end; st++) { - switch (*st) + char ch2= (char) (uchar) escaped_wc_for_single_quote((uchar) *st); + if (ch2) { - case '\\': APPEND(STRING_WITH_LEN("\\\\")); break; - case '\0': APPEND(STRING_WITH_LEN("\\0")); break; - case '\'': APPEND(STRING_WITH_LEN("\\'")); break; - case '\b': APPEND(STRING_WITH_LEN("\\b")); break; - case '\t': APPEND(STRING_WITH_LEN("\\t")); break; - case '\n': APPEND(STRING_WITH_LEN("\\n")); break; - case '\r': APPEND(STRING_WITH_LEN("\\r")); break; - case '\032': APPEND(STRING_WITH_LEN("\\Z")); break; - default: if ((chlen=charset()->charlen(st, end)) > 0) - { - APPEND(st, chlen); - st+= chlen-1; - } - else - APPEND(*st); + if (append('\\') || append(ch2)) + return true; + continue; } + if ((chlen= charset()->charlen(st, end)) > 0) + { + APPEND(st, chlen); + st+= chlen-1; + } + else + APPEND(*st); } return 0; } + +bool String::append_for_single_quote_using_mb_wc(const char *src, + size_t length, + CHARSET_INFO *cs) +{ + DBUG_ASSERT(&my_charset_bin != charset()); + DBUG_ASSERT(&my_charset_bin != cs); + const uchar *str= (const uchar *) src; + const uchar *end= (const uchar *) src + length; + int chlen; + my_wc_t wc; + for ( ; (chlen= cs->cset->mb_wc(cs, &wc, str, end)) > 0; str+= chlen) + { + my_wc_t wc2= escaped_wc_for_single_quote(wc); + if (wc2 ? (append_wc('\\') || append_wc(wc2)) : append_wc(wc)) + return true; + } + return false; +} + + void String::print(String *str) const { str->append_for_single_quote(Ptr, str_length); diff --git a/sql/sql_string.h b/sql/sql_string.h index 6d8d4acdad9..36cde6559be 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -1181,6 +1181,43 @@ public: print_with_conversion(to, cs); } + static my_wc_t escaped_wc_for_single_quote(my_wc_t ch) + { + switch (ch) { + case '\\': return '\\'; + case '\0': return '0'; + case '\'': return '\''; + case '\b': return 'b'; + case '\t': return 't'; + case '\n': return 'n'; + case '\r': return 'r'; + case '\032': return 'Z'; + } + return 0; + } + + // Append for single quote using mb_wc/wc_mb Unicode conversion + bool append_for_single_quote_using_mb_wc(const char *str, size_t length, + CHARSET_INFO *cs); + + // Append for single quote with optional mb_wc/wc_mb conversion + bool append_for_single_quote_opt_convert(const char *str, + size_t length, + CHARSET_INFO *cs) + { + return charset() == &my_charset_bin || cs == &my_charset_bin || + my_charset_same(charset(), cs) ? + append_for_single_quote(str, length) : + append_for_single_quote_using_mb_wc(str, length, cs); + } + + bool append_for_single_quote_opt_convert(const String &str) + { + return append_for_single_quote_opt_convert(str.ptr(), + str.length(), + str.charset()); + } + bool append_for_single_quote(const char *st, size_t len); bool append_for_single_quote(const String *s) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 55319a2242f..c46ed3c8eab 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1463,6 +1463,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, temporary_table_was_dropped= 1; } is_temporary= 1; + thd->reset_sp_cache= true; } if ((drop_temporary && if_exists) || temporary_table_was_dropped) @@ -1836,8 +1837,11 @@ report_error: } DBUG_PRINT("table", ("table: %p s: %p", table->table, table->table ? table->table->s : NULL)); + if (is_temporary_table(table)) + thd->reset_sp_cache= true; } DEBUG_SYNC(thd, "rm_table_no_locks_before_binlog"); + thd->used|= THD::THREAD_SPECIFIC_USED; error= 0; @@ -4676,6 +4680,7 @@ int create_table_impl(THD *thd, if (is_trans != NULL) *is_trans= table->file->has_transactions(); + thd->reset_sp_cache= true; thd->used|= THD::THREAD_SPECIFIC_USED; create_info->table= table; // Store pointer to table } @@ -4802,18 +4807,21 @@ int mysql_create_table_no_lock(THD *thd, #ifdef WITH_WSREP /** Additional sequence checks for Galera cluster. -@param thd thread handle -@param seq sequence definition +@param thd thread handle +@param seq sequence definition +@param used_engine create used ENGINE= @retval false success @retval true failure */ -bool wsrep_check_sequence(THD* thd, const sequence_definition *seq) +bool wsrep_check_sequence(THD* thd, + const sequence_definition *seq, + const bool used_engine) { enum legacy_db_type db_type; DBUG_ASSERT(WSREP(thd)); - if (thd->lex->create_info.used_fields & HA_CREATE_USED_ENGINE) + if (used_engine) { db_type= thd->lex->create_info.db_type->db_type; } @@ -4844,6 +4852,57 @@ bool wsrep_check_sequence(THD* thd, const sequence_definition *seq) return (false); } + +/** Additional CREATE TABLE/SEQUENCE checks for Galera cluster. + +@param thd thread handle +@param wsrep_ctas CREATE TABLE AS SELECT ? +@param used_engine CREATE TABLE ... ENGINE = ? +@param create_info Create information + +@retval false Galera cluster does support used clause +@retval true Galera cluster does not support used clause +*/ +static +bool wsrep_check_support(THD* thd, + const bool wsrep_ctas, + const bool used_engine, + const HA_CREATE_INFO* create_info) +{ + /* CREATE TABLE ... AS SELECT */ + if (wsrep_ctas && + thd->variables.wsrep_trx_fragment_size > 0) + { + my_message(ER_NOT_ALLOWED_COMMAND, + "CREATE TABLE AS SELECT is not supported with streaming replication", + MYF(0)); + return true; + } + /* CREATE TABLE .. WITH SYSTEM VERSIONING AS SELECT + is not supported in Galera cluster. + */ + if (wsrep_ctas && + create_info->versioned()) + { + my_error(ER_NOT_SUPPORTED_YET, MYF(0), + "SYSTEM VERSIONING AS SELECT in Galera cluster"); + return true; + } + /* + CREATE TABLE ... ENGINE=SEQUENCE is not supported in + Galera cluster. + CREATE SEQUENCE ... ENGINE=xxx Galera cluster supports + only InnoDB-sequences. + */ + if (((used_engine && create_info->db_type && + (create_info->db_type->db_type == DB_TYPE_SEQUENCE || + create_info->db_type->db_type >= DB_TYPE_FIRST_DYNAMIC)) || + thd->lex->sql_command == SQLCOM_CREATE_SEQUENCE) && + wsrep_check_sequence(thd, create_info->seq_create_info, used_engine)) + return true; + + return false; +} #endif /* WITH_WSREP */ /** @@ -4919,15 +4978,6 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, if (!(thd->variables.option_bits & OPTION_EXPLICIT_DEF_TIMESTAMP)) promote_first_timestamp_column(&alter_info->create_list); -#ifdef WITH_WSREP - if (thd->lex->sql_command == SQLCOM_CREATE_SEQUENCE && - WSREP(thd) && wsrep_thd_is_local_toi(thd)) - { - if (wsrep_check_sequence(thd, create_info->seq_create_info)) - DBUG_RETURN(true); - } -#endif /* WITH_WSREP */ - /* We can abort create table for any table type */ thd->abort_on_warning= thd->is_strict_mode(); @@ -5119,7 +5169,8 @@ static bool make_unique_constraint_name(THD *thd, LEX_CSTRING *name, if (!check) // Found unique name { name->length= (size_t) (real_end - buff); - name->str= strmake_root(thd->stmt_arena->mem_root, buff, name->length); + name->str= thd->strmake(buff, name->length); + return (name->str == NULL); } } @@ -6554,8 +6605,6 @@ static KEY *find_key_ci(const char *key_name, KEY *key_start, KEY *key_end) @param thd Thread @param table The original table. - @param varchar Indicates that new definition has new - VARCHAR column. @param[in/out] ha_alter_info Data structure which already contains basic information about create options, field and keys for the new version of @@ -6590,7 +6639,7 @@ static KEY *find_key_ci(const char *key_name, KEY *key_start, KEY *key_end) @retval false success */ -static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar, +static bool fill_alter_inplace_info(THD *thd, TABLE *table, Alter_inplace_info *ha_alter_info) { Field **f_ptr, *field; @@ -6640,13 +6689,6 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar, if (alter_info->flags & ALTER_CHANGE_COLUMN) ha_alter_info->handler_flags|= ALTER_COLUMN_DEFAULT; - /* - If we altering table with old VARCHAR fields we will be automatically - upgrading VARCHAR column types. - */ - if (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar) - ha_alter_info->handler_flags|= ALTER_STORED_COLUMN_TYPE; - DBUG_PRINT("info", ("handler_flags: %llu", ha_alter_info->handler_flags)); /* @@ -6688,6 +6730,30 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar, Check if type of column has changed. */ bool is_equal= field->is_equal(*new_field); + + if (is_equal) + { + const Type_handler *th= field->type_handler(); + if (th != th->type_handler_for_implicit_upgrade()) + { + /* + The field data type says it wants upgrade. + This should not be possible: + - if this is a new column definition, e.g. from statements like: + ALTER TABLE t1 ADD a INT; + ALTER TABLE t1 MODIFY a INT; + then it's coming from the parser, which returns + only up-to-date data types. + - if this is an old column definition, e.g. from: + ALTER TABLE t1 COMMENT 'new comment'; + it should have ealier called Column_definition_implicit_upgrade(), + which replaces old data types to up-to-date data types. + */ + DBUG_ASSERT(0); + is_equal= false; + } + } + if (!is_equal) { if (field->table->file->can_convert_nocopy(*field, *new_field)) @@ -7339,14 +7405,28 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled, switch (keys_onoff) { case Alter_info::ENABLE: DEBUG_SYNC(table->in_use, "alter_table_enable_indexes"); - error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); + error= table->file->ha_enable_indexes(key_map(table->s->keys), true); break; case Alter_info::LEAVE_AS_IS: if (!indexes_were_disabled) break; /* fall through */ case Alter_info::DISABLE: - error= table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); + { + key_map map= table->s->keys_in_use; + bool do_clear= false; + for (uint i=0; i < table->s->keys; i++) + { + if (!(table->s->key_info[i].flags & HA_NOSAME) && + i != table->s->next_number_index) + { + map.clear_bit(i); + do_clear= true; + } + } + if (do_clear) + error= table->file->ha_disable_indexes(map, true); + } } if (unlikely(error)) @@ -9091,7 +9171,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, case Alter_drop::CHECK_CONSTRAINT: case Alter_drop::PERIOD: my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), drop->type_name(), - alter_info->drop_list.head()->name); + drop->name); goto err; case Alter_drop::FOREIGN_KEY: // Leave the DROP FOREIGN KEY names in the alter_info->drop_list. @@ -10198,12 +10278,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, */ KEY *key_info; uint key_count; - /* - Remember if the new definition has new VARCHAR column; - create_info->varchar will be reset in create_table_impl()/ - mysql_prepare_create_table(). - */ - bool varchar= create_info->varchar, table_creation_was_logged= 0; + bool table_creation_was_logged= 0; bool binlog_as_create_select= 0, log_if_exists= 0; uint tables_opened; handlerton *new_db_type= create_info->db_type, *old_db_type; @@ -10238,6 +10313,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, TODO: this design is obsolete and will be removed. */ int table_kind= check_if_log_table(table_list, FALSE, NullS); + const bool used_engine= create_info->used_fields & HA_CREATE_USED_ENGINE; if (table_kind) { @@ -10249,7 +10325,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, } /* Disable alter of log tables to unsupported engine */ - if ((create_info->used_fields & HA_CREATE_USED_ENGINE) && + if ((used_engine) && (!create_info->db_type || /* unknown engine */ !(create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES))) { @@ -10357,14 +10433,14 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, if we can support implementing storage engine. */ if (WSREP(thd) && table && table->s->sequence && - wsrep_check_sequence(thd, thd->lex->create_info.seq_create_info)) + wsrep_check_sequence(thd, create_info->seq_create_info, used_engine)) DBUG_RETURN(TRUE); - if (WSREP(thd) && + if (WSREP(thd) && table && (thd->lex->sql_command == SQLCOM_ALTER_TABLE || thd->lex->sql_command == SQLCOM_CREATE_INDEX || thd->lex->sql_command == SQLCOM_DROP_INDEX) && - !wsrep_should_replicate_ddl(thd, table_list->table->s->db_type())) + !wsrep_should_replicate_ddl(thd, table->s->db_type())) DBUG_RETURN(true); #endif /* WITH_WSREP */ @@ -10860,12 +10936,10 @@ do_continue:; #endif #ifdef WITH_WSREP + // ALTER TABLE for sequence object, check can we support it if (table->s->sequence && WSREP(thd) && - wsrep_thd_is_local_toi(thd)) - { - if (wsrep_check_sequence(thd, create_info->seq_create_info)) + wsrep_check_sequence(thd, create_info->seq_create_info, used_engine)) DBUG_RETURN(TRUE); - } #endif /* WITH_WSREP */ /* @@ -11037,7 +11111,7 @@ do_continue:; bool use_inplace= true; /* Fill the Alter_inplace_info structure. */ - if (fill_alter_inplace_info(thd, table, varchar, &ha_alter_info)) + if (fill_alter_inplace_info(thd, table, &ha_alter_info)) goto err_new_table_cleanup; alter_ctx.tmp_storage_engine_name_partitioned= @@ -11349,6 +11423,15 @@ do_continue:; new_table->mark_columns_needed_for_insert(); mysql_bin_log.write_table_map(thd, new_table, 1); } + + /* + if ORDER BY: sorting + always: copying, building indexes. + if online: reading up the binlog (second binlog is being written) + reading up the second binlog under exclusive lock + */ + thd_progress_init(thd, MY_TEST(order) + 2 + 2 * MY_TEST(online)); + if (copy_data_between_tables(thd, table, new_table, ignore, order_num, order, &copied, &deleted, @@ -11517,6 +11600,8 @@ do_continue:; NULL); table_list->table= table= NULL; /* Safety */ + thd_progress_end(thd); + DBUG_PRINT("info", ("is_table_renamed: %d engine_changed: %d", alter_ctx.is_table_renamed(), engine_changed)); @@ -11746,6 +11831,8 @@ err_new_table_cleanup: DBUG_PRINT("error", ("err_new_table_cleanup")); thd->variables.option_bits&= ~OPTION_BIN_COMMIT_OFF; + thd_progress_end(thd); + /* No default value was provided for a DATE/DATETIME field, the current sql_mode doesn't allow the '0000-00-00' value and @@ -11875,7 +11962,7 @@ static int online_alter_read_from_binlog(THD *thd, rpl_group_info *rgi, IO_CACHE *log_file= log->flip(); - thd_progress_report(thd, 0, my_b_write_tell(log_file)); + thd_progress_report(thd, 1, MY_MAX(1, my_b_write_tell(log_file))); Has_default_error_handler hdeh; thd->push_internal_handler(&hdeh); @@ -11942,14 +12029,6 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, MYSQL_TIME query_start; DBUG_ENTER("copy_data_between_tables"); - /* - if ORDER BY: sorting - always: copying, building indexes. - if online: reading up the binlog (second binlog is being written) - reading up the second binlog under exclusive lock - */ - thd_progress_init(thd, MY_TEST(order) + 2 + 2 * MY_TEST(online)); - if (!(copy= new (thd->mem_root) Copy_field[to->s->fields])) DBUG_RETURN(-1); @@ -12115,6 +12194,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, #ifdef HAVE_REPLICATION if (online) { + DBUG_ASSERT(from->s->online_alter_binlog == NULL); from->s->online_alter_binlog= new Cache_flip_event_log(); if (!from->s->online_alter_binlog) goto err; @@ -12338,7 +12418,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, DEBUG_SYNC(thd, "alter_table_online_before_lock"); int lock_error= - thd->mdl_context.upgrade_shared_lock(from->mdl_ticket, MDL_EXCLUSIVE, + thd->mdl_context.upgrade_shared_lock(from->mdl_ticket, MDL_SHARED_NO_WRITE, (double)thd->variables.lock_wait_timeout); if (!error) error= lock_error; @@ -12348,29 +12428,21 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, thd_progress_next_stage(thd); error= online_alter_read_from_binlog(thd, &rgi, binlog, &found_count); } - if (error) - from->s->tdc->flush_unused(1); // to free the binlog + + /* + We'll do it earlier than usually in mysql_alter_table to handle the + online-related errors more comfortably. + */ + lock_error= thd->mdl_context.upgrade_shared_lock(from->mdl_ticket, + MDL_EXCLUSIVE, + (double)thd->variables.lock_wait_timeout); + if (!error) + error= lock_error; + to->pos_in_table_list= NULL; // Safety DBUG_ASSERT(thd->lex->sql_command == saved_sql_command); thd->lex->sql_command= saved_sql_command; // Just in case } - else if (online) // error was on copy stage - { - /* - We can't free the resources properly now, as we can still be in - non-exclusive state. So this s->online_alter_binlog will be used - until all transactions will release it. - Once the transaction commits, it can release online_alter_binlog - by decreasing ref_count. - - online_alter_binlog->ref_count can be reached 0 only once. - Proof: - If share exists, we'll always have ref_count >= 1. - Once it reaches destroy(), nobody can acquire it again, - therefore, only release() is possible at this moment. - */ - from->s->tdc->flush_unused(1); // to free the binlog - } #endif if (error > 0 && !from->s->tmp_table) @@ -12385,6 +12457,26 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, if (unlikely(mysql_trans_commit_alter_copy_data(thd))) error= 1; + + if (unlikely(error) && online) + { + /* + We can't free the resources properly now, as we can still be in + non-exclusive state. So this s->online_alter_binlog will be used + until all transactions will release it. + Once the transaction commits, it can release online_alter_binlog + by decreasing ref_count. + + online_alter_binlog->ref_count can be reached 0 only once. + Proof: + If share exists, we'll always have ref_count >= 1. + Once it reaches destroy(), nobody can acquire it again, + therefore, only release() is possible at this moment. + + Also, this will release the binlog. + */ + from->s->tdc->flush_unused(1); + } err: if (bulk_insert_started) @@ -12414,7 +12506,6 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, if (error < 0 && !from->s->tmp_table && to->file->extra(HA_EXTRA_PREPARE_FOR_RENAME)) error= 1; - thd_progress_end(thd); DBUG_RETURN(error > 0 ? -1 : 0); } @@ -12842,17 +12933,11 @@ bool Sql_cmd_create_table_like::execute(THD *thd) #endif #ifdef WITH_WSREP - if (wsrep_ctas) + if (WSREP(thd) && + wsrep_check_support(thd, wsrep_ctas, used_engine, &create_info)) { - if (thd->variables.wsrep_trx_fragment_size > 0) - { - my_message( - ER_NOT_ALLOWED_COMMAND, - "CREATE TABLE AS SELECT is not supported with streaming replication", - MYF(0)); - res= 1; - goto end_with_restore_list; - } + res= 1; + goto end_with_restore_list; } #endif /* WITH_WSREP */ @@ -13004,6 +13089,7 @@ bool Sql_cmd_create_table_like::execute(THD *thd) create_table->table_name, create_table->db)) goto end_with_restore_list; +#ifdef WITH_WSREP /* In STATEMENT format, we probably have to replicate also temporary tables, like mysql replication does. Also check if the requested @@ -13012,33 +13098,32 @@ bool Sql_cmd_create_table_like::execute(THD *thd) if (WSREP(thd)) { handlerton *orig_ht= create_info.db_type; + if (!check_engine(thd, create_table->db.str, create_table->table_name.str, &create_info) && (!thd->is_current_stmt_binlog_format_row() || !create_info.tmp_table())) { -#ifdef WITH_WSREP if (thd->lex->sql_command == SQLCOM_CREATE_SEQUENCE && - wsrep_check_sequence(thd, lex->create_info.seq_create_info)) + wsrep_check_sequence(thd, lex->create_info.seq_create_info, used_engine)) DBUG_RETURN(true); - WSREP_TO_ISOLATION_BEGIN_ALTER(create_table->db.str, - create_table->table_name.str, - first_table, &alter_info, NULL, - &create_info) - { - WSREP_WARN("CREATE TABLE isolation failure"); + WSREP_TO_ISOLATION_BEGIN_ALTER(create_table->db.str, create_table->table_name.str, + first_table, &alter_info, NULL, &create_info) + { + WSREP_WARN("CREATE TABLE isolation failure"); res= true; goto end_with_restore_list; - } -#endif /* WITH_WSREP */ + } } // check_engine will set db_type to NULL if e.g. TEMPORARY is // not supported by the storage engine, this case is checked // again in mysql_create_table create_info.db_type= orig_ht; } +#endif /* WITH_WSREP */ + /* Regular CREATE TABLE */ res= mysql_create_table(thd, create_table, &create_info, &alter_info); } diff --git a/sql/sql_table.h b/sql/sql_table.h index fded83531f5..a75fa58a7e0 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -216,8 +216,4 @@ extern MYSQL_PLUGIN_IMPORT const LEX_CSTRING primary_key_name; bool check_engine(THD *, const char *, const char *, HA_CREATE_INFO *); -#ifdef WITH_WSREP -bool wsrep_check_sequence(THD* thd, const class sequence_definition *seq); -#endif - #endif /* SQL_TABLE_INCLUDED */ diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 4e78dab6e4a..4322b21532e 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -41,6 +41,7 @@ Named_type_handler type_handler_bool("boolean"); Named_type_handler type_handler_stiny("tinyint"); Named_type_handler type_handler_sshort("smallint"); Named_type_handler type_handler_slong("int"); +Named_type_handler type_handler_slong_ge0("int"); Named_type_handler type_handler_sint24("mediumint"); Named_type_handler type_handler_slonglong("bigint"); Named_type_handler type_handler_utiny("tiny unsigned"); @@ -4627,6 +4628,10 @@ bool Type_handler_general_purpose_int:: bool unsigned_flag= items[0]->unsigned_flag; for (uint i= 1; i < nitems; i++) { + /* + TODO: avoid creating DECIMAL for a mix of ulong and slong_ge0. + It's too late for 10.5. Let's do it in a higher version. + */ if (unsigned_flag != items[i]->unsigned_flag) { // Convert a mixture of signed and unsigned int to decimal @@ -4636,6 +4641,21 @@ bool Type_handler_general_purpose_int:: } } func->aggregate_attributes_int(items, nitems); + for (uint i= 0; i < nitems; i++) + { + if (items[i]->type_handler() == &type_handler_slong_ge0) + { + /* + A slong_ge0 argument found. + We need to add an extra character for the sign. + TODO: rewrite aggregate_attributes_int() to find + the maximum decimal_precision() instead of the maximum max_length. + This change is too late for 10.5, so let's do it in a higher version. + */ + uint digits_and_sign= items[i]->decimal_precision() + 1; + set_if_bigger(func->max_length, digits_and_sign); + } + } handler->set_handler(func->unsigned_flag ? handler->type_handler()->type_handler_unsigned() : handler->type_handler()->type_handler_signed()); @@ -4931,6 +4951,13 @@ bool Type_handler_real_result:: /*************************************************************************/ +bool Type_handler_long_ge0:: + Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const +{ + return func->fix_length_and_dec_sint_ge0(); +} + + bool Type_handler_int_result:: Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const { @@ -6373,6 +6400,14 @@ bool Type_handler_int_result:: } +bool Type_handler_long_ge0:: + Item_func_round_fix_length_and_dec(Item_func_round *item) const +{ + item->fix_arg_slong_ge0(); + return false; +} + + bool Type_handler_year:: Item_func_round_fix_length_and_dec(Item_func_round *item) const { @@ -6594,6 +6629,14 @@ bool Type_handler_int_result:: } +bool Type_handler_long_ge0:: + Item_func_abs_fix_length_and_dec(Item_func_abs *item) const +{ + item->fix_length_and_dec_sint_ge0(); + return false; +} + + bool Type_handler_real_result:: Item_func_abs_fix_length_and_dec(Item_func_abs *item) const { @@ -6704,6 +6747,22 @@ bool Type_handler:: } +bool Type_handler_long_ge0:: + Item_func_signed_fix_length_and_dec(Item_func_signed *item) const +{ + item->fix_length_and_dec_sint_ge0(); + return false; +} + + +bool Type_handler_long_ge0:: + Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const +{ + item->fix_length_and_dec_sint_ge0(); + return false; +} + + bool Type_handler_string_result:: Item_func_signed_fix_length_and_dec(Item_func_signed *item) const { @@ -7189,6 +7248,18 @@ decimal_digits_t Type_handler_int_result::Item_decimal_precision(const Item *ite return (decimal_digits_t) MY_MIN(prec, DECIMAL_MAX_PRECISION); } +decimal_digits_t Type_handler_long_ge0::Item_decimal_precision(const Item *item) const +{ + DBUG_ASSERT(item->max_length); + DBUG_ASSERT(!item->decimals); + /* + Unlinke in Type_handler_long, Type_handler_long_ge does + not reserve one character for the sign. All max_length + characters are digits. + */ + return MY_MIN(item->max_length, DECIMAL_MAX_PRECISION); +} + decimal_digits_t Type_handler_time_common::Item_decimal_precision(const Item *item) const { return (decimal_digits_t) (7 + MY_MIN(item->decimals, TIME_SECOND_PART_DIGITS)); @@ -8288,6 +8359,26 @@ Field *Type_handler_long:: } +Field *Type_handler_long_ge0:: + make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root, + const LEX_CSTRING *name, + const Record_addr &rec, const Bit_addr &bit, + const Column_definition_attributes *attr, + uint32 flags) const +{ + /* + We're converting signed long_ge0 to signed long. + So add one character for the sign. + */ + return new (mem_root) + Field_long(rec.ptr(), (uint32) attr->length + 1/*sign*/, + rec.null_ptr(), rec.null_bit(), + attr->unireg_check, name, + f_is_zerofill(attr->pack_flag) != 0, + f_is_dec(attr->pack_flag) == 0); +} + + Field *Type_handler_longlong:: make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root, const LEX_CSTRING *name, @@ -8946,41 +9037,48 @@ bool Type_handler_string_result::union_element_finalize(Item_type_holder* item) /***************************************************************************/ -void Type_handler_var_string:: - Column_definition_implicit_upgrade(Column_definition *c) const + +const Type_handler * +Type_handler_var_string::type_handler_for_implicit_upgrade() const { - // Change old VARCHAR to new VARCHAR - c->set_handler(&type_handler_varchar); + return &type_handler_varchar; +} + + +void Type_handler:: + Column_definition_implicit_upgrade_to_this(Column_definition *old) const +{ + old->set_handler(this); } void Type_handler_time_common:: - Column_definition_implicit_upgrade(Column_definition *c) const + Column_definition_implicit_upgrade_to_this(Column_definition *old) const { if (opt_mysql56_temporal_format) - c->set_handler(&type_handler_time2); + old->set_handler(&type_handler_time2); else - c->set_handler(&type_handler_time); + old->set_handler(&type_handler_time); } void Type_handler_datetime_common:: - Column_definition_implicit_upgrade(Column_definition *c) const + Column_definition_implicit_upgrade_to_this(Column_definition *old) const { if (opt_mysql56_temporal_format) - c->set_handler(&type_handler_datetime2); + old->set_handler(&type_handler_datetime2); else - c->set_handler(&type_handler_datetime); + old->set_handler(&type_handler_datetime); } void Type_handler_timestamp_common:: - Column_definition_implicit_upgrade(Column_definition *c) const + Column_definition_implicit_upgrade_to_this(Column_definition *old) const { if (opt_mysql56_temporal_format) - c->set_handler(&type_handler_timestamp2); + old->set_handler(&type_handler_timestamp2); else - c->set_handler(&type_handler_timestamp); + old->set_handler(&type_handler_timestamp); } diff --git a/sql/sql_type.h b/sql/sql_type.h index 45e94c0dbd6..82db1bc701d 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -3867,6 +3867,16 @@ public: const Type_handler *res= type_handler_base(); return res ? res : this; } + /* + In 10.11.8 the semantics of this method has changed to the opposite. + It used to be called with the old data type handler as "this". + Now it's called with the new data type hander as "this". + To avoid problems during merges, the method name was renamed. + */ + virtual const Type_handler *type_handler_for_implicit_upgrade() const + { + return this; + } virtual const Type_handler *type_handler_for_comparison() const= 0; virtual const Type_handler *type_handler_for_native_format() const { @@ -4012,9 +4022,13 @@ public: virtual bool validate_implicit_default_value(THD *thd, const Column_definition &def) const; - // Automatic upgrade, e.g. for ALTER TABLE t1 FORCE - virtual void Column_definition_implicit_upgrade(Column_definition *c) const - { } + /* + Automatic upgrade, e.g. for REPAIR or ALTER TABLE t1 FORCE + - from the data type specified in old->type_handler() + - to the data type specified in "this" + */ + virtual void Column_definition_implicit_upgrade_to_this( + Column_definition *old) const; // Validate CHECK constraint after the parser virtual bool Column_definition_validate_check_constraint(THD *thd, Column_definition *c) @@ -5831,6 +5845,38 @@ public: }; +/* + The expression of this type reports itself as signed, + however it's known not to return negative values. + Items of this data type count only digits in Item::max_length, + without adding +1 for the sign. This allows expressions + of this type convert nicely to VARCHAR and DECIMAL. + For example, YEAR(now()) is: + - VARCHAR(4) in a string context + - DECIMAL(4,0) in a decimal context + - but INT(5) in an integer context +*/ +class Type_handler_long_ge0: public Type_handler_long +{ +public: + decimal_digits_t Item_decimal_precision(const Item *item) const override; + bool Item_func_signed_fix_length_and_dec(Item_func_signed *item) + const override; + bool Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) + const override; + bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const override; + bool Item_func_round_fix_length_and_dec(Item_func_round *) const override; + bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const override; + Field *make_table_field_from_def(TABLE_SHARE *share, + MEM_ROOT *mem_root, + const LEX_CSTRING *name, + const Record_addr &addr, + const Bit_addr &bit, + const Column_definition_attributes *attr, + uint32 flags) const override; +}; + + class Type_handler_ulong: public Type_handler_long { public: @@ -6246,7 +6292,8 @@ public: const Type_handler *type_handler_for_comparison() const override; int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) const override; - void Column_definition_implicit_upgrade(Column_definition *c) const override; + void Column_definition_implicit_upgrade_to_this( + Column_definition *old) const override; bool Column_definition_fix_attributes(Column_definition *c) const override; bool Column_definition_attributes_frm_unpack(Column_definition_attributes *attr, @@ -6570,7 +6617,8 @@ public: const Type_cast_attributes &attr) const override; bool validate_implicit_default_value(THD *thd, const Column_definition &def) const override; - void Column_definition_implicit_upgrade(Column_definition *c) const override; + void Column_definition_implicit_upgrade_to_this( + Column_definition *old) const override; bool Column_definition_fix_attributes(Column_definition *c) const override; bool Column_definition_attributes_frm_unpack(Column_definition_attributes *attr, @@ -6711,7 +6759,8 @@ public: { return true; } - void Column_definition_implicit_upgrade(Column_definition *c) const override; + void Column_definition_implicit_upgrade_to_this( + Column_definition *old) const override; bool Column_definition_attributes_frm_unpack(Column_definition_attributes *attr, TABLE_SHARE *share, @@ -7063,6 +7112,7 @@ public: { return MYSQL_TYPE_VARCHAR; } + const Type_handler *type_handler_for_implicit_upgrade() const override; const Type_handler *type_handler_for_tmp_table(const Item *item) const override { return varstring_type_handler(item); @@ -7070,7 +7120,6 @@ public: uint32 max_display_length_for_field(const Conv_source &src) const override; void show_binlog_type(const Conv_source &src, const Field &dst, String *str) const override; - void Column_definition_implicit_upgrade(Column_definition *c) const override; bool Column_definition_fix_attributes(Column_definition *c) const override; bool Column_definition_prepare_stage2(Column_definition *c, handler *file, @@ -7670,6 +7719,7 @@ extern MYSQL_PLUGIN_IMPORT Named_type_handler type_han extern MYSQL_PLUGIN_IMPORT Named_type_handler type_handler_sshort; extern MYSQL_PLUGIN_IMPORT Named_type_handler type_handler_sint24; extern MYSQL_PLUGIN_IMPORT Named_type_handler type_handler_slong; +extern MYSQL_PLUGIN_IMPORT Named_type_handler type_handler_slong_ge0; extern MYSQL_PLUGIN_IMPORT Named_type_handler type_handler_slonglong; extern Named_type_handler type_handler_utiny; diff --git a/sql/sql_type_fixedbin.h b/sql/sql_type_fixedbin.h index 698d9843e8a..6d5c72d246a 100644 --- a/sql/sql_type_fixedbin.h +++ b/sql/sql_type_fixedbin.h @@ -1125,6 +1125,11 @@ public: return FbtImpl::max_char_length(); } + const Type_handler *type_handler_for_implicit_upgrade() const override + { + return TypeCollectionImpl::singleton()-> + type_handler_for_implicit_upgrade(this); + } const Type_handler *type_handler_for_comparison() const override { return this; @@ -1943,6 +1948,12 @@ public: return NULL; } + const Type_handler *type_handler_for_implicit_upgrade( + const Type_handler *from) const + { + return from; + } + static Type_collection_fbt *singleton() { static Type_collection_fbt tc; diff --git a/sql/sql_udf.h b/sql/sql_udf.h index cb1954353fa..5bd2c6e5445 100644 --- a/sql/sql_udf.h +++ b/sql/sql_udf.h @@ -147,6 +147,20 @@ class udf_handler :public Sql_alloc *null_value= (my_bool) (is_null || error); } String *val_str(String *str,String *save_str); + + udf_handler(const udf_handler &orig) + { + u_d = orig.u_d; + buffers = orig.buffers; + f_args = orig.f_args; + initid = orig.initid; + num_buffer = orig.num_buffer; + error = orig.error; + is_null = orig.is_null; + initialized = orig.initialized; + args = orig.args; + not_original = true; + } }; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 1f3fa61dfde..eca490e83e5 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -119,12 +119,12 @@ int select_unit::send_data(List &values) if (table->no_rows_with_nulls) table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT; - fill_record(thd, table, table->field + addon_cnt, values, true, false); + fill_record(thd, table, table->field + addon_cnt, values, true, false, true); /* set up initial values for records to be written */ if (addon_cnt && step == UNION_TYPE) { DBUG_ASSERT(addon_cnt == 1); - table->field[0]->store((longlong) curr_step, 1); + table->field[0]->store((ulonglong) curr_step, 1); } if (unlikely(thd->is_error())) @@ -483,7 +483,7 @@ bool select_unit_ext::disable_index_if_needed(SELECT_LEX *curr_sl) !curr_sl->next_select()) ) { is_index_enabled= false; - if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL)) + if (table->file->ha_disable_indexes(key_map(0), false)) return false; table->no_keyread=1; return true; @@ -617,7 +617,7 @@ int select_unit_ext::send_data(List &values) if (table->no_rows_with_nulls) table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT; - fill_record(thd, table, table->field + addon_cnt, values, true, false); + fill_record(thd, table, table->field + addon_cnt, values, true, false, true); /* set up initial values for records to be written */ if ( step == UNION_TYPE ) { @@ -1001,7 +1001,7 @@ int select_union_direct::send_data(List &items) } send_records++; - fill_record(thd, table, table->field, items, true, false); + fill_record(thd, table, table->field, items, true, false, true); if (unlikely(thd->is_error())) return true; /* purecov: inspected */ @@ -1263,26 +1263,21 @@ bool st_select_lex_unit::join_union_item_types(THD *thd_arg, } -bool init_item_int(THD* thd, Item_int* &item) +static bool init_item_int(THD* thd, Item_int* &item) { if (!item) { - Query_arena *arena, backup_arena; - arena= thd->activate_stmt_arena_if_needed(&backup_arena); - item= new (thd->mem_root) Item_int(thd, 0); - if (arena) - thd->restore_active_arena(arena, &backup_arena); - if (!item) - return false; + return true; } else { item->value= 0; } - return true; + + return false; } /** @@ -1846,8 +1841,12 @@ cont: for(uint i= 0; i< hidden; i++) { - init_item_int(thd, addon_fields[i]); - types.push_front(addon_fields[i]); + if (init_item_int(thd, addon_fields[i]) || + types.push_front(addon_fields[i])) + { + types.empty(); + goto err; + } addon_fields[i]->name.str= i ? "__CNT_1" : "__CNT_2"; addon_fields[i]->name.length= 7; } @@ -2201,7 +2200,7 @@ bool st_select_lex_unit::optimize() /* re-enabling indexes for next subselect iteration */ if ((union_result->force_enable_index_if_needed() || union_distinct)) { - if(table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL)) + if(table->file->ha_enable_indexes(key_map(table->s->keys), false)) DBUG_ASSERT(0); else table->no_keyread= 0; @@ -2323,7 +2322,7 @@ bool st_select_lex_unit::exec_inner() union_result->table && union_result->table->is_created()) { union_result->table->file->ha_delete_all_rows(); - union_result->table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL); + union_result->table->file->ha_enable_indexes(key_map(table->s->keys), false); } } @@ -2391,7 +2390,7 @@ bool st_select_lex_unit::exec_inner() { // This is UNION DISTINCT, so there should be a fake_select_lex DBUG_ASSERT(fake_select_lex != NULL); - if (unlikely(table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))) + if (table->file->ha_disable_indexes(key_map(0), false)) return true; table->no_keyread=1; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index e6181b98627..589bcc9c09f 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -249,7 +249,7 @@ static void prepare_record_for_error_message(int error, TABLE *table) Field *field; uint keynr; MY_BITMAP unique_map; /* Fields in offended unique. */ - my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)]; + my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)/sizeof(my_bitmap_map)]; DBUG_ENTER("prepare_record_for_error_message"); /* @@ -1875,6 +1875,10 @@ int multi_update::prepare(List ¬_used_values, { Item *value= value_it++; uint offset= item->field->table->pos_in_table_list->shared; + + if (value->associate_with_target_field(thd, item)) + DBUG_RETURN(1); + fields_for_table[offset]->push_back(item, thd->mem_root); values_for_table[offset]->push_back(value, thd->mem_root); } @@ -2374,7 +2378,7 @@ int multi_update::send_data(List ¬_used_values) tmp_table_param[offset].func_count); fill_record(thd, tmp_table, tmp_table->field + 1 + unupdated_check_opt_tables.elements, - *values_for_table[offset], TRUE, FALSE); + *values_for_table[offset], true, false, false); /* Write row, ignoring duplicated updates to a row */ error= tmp_table->file->ha_write_tmp_row(tmp_table->record[0]); @@ -2503,8 +2507,6 @@ int multi_update::do_updates() table = cur_table->table; if (table == table_to_update) continue; // Already updated - if (table->file->pushed_rowid_filter) - table->file->disable_pushed_rowid_filter(); org_updated= updated; tmp_table= tmp_tables[cur_table->shared]; tmp_table->file->extra(HA_EXTRA_CACHE); // Change to read cache @@ -2698,9 +2700,7 @@ int multi_update::do_updates() (void) tmp_table->file->ha_rnd_end(); check_opt_it.rewind(); while (TABLE *tbl= check_opt_it++) - tbl->file->ha_rnd_end(); - if (table->file->save_pushed_rowid_filter) - table->file->enable_pushed_rowid_filter(); + tbl->file->ha_rnd_end(); } DBUG_RETURN(0); @@ -2711,8 +2711,6 @@ err: } err2: - if (table->file->save_pushed_rowid_filter) - table->file->enable_pushed_rowid_filter(); if (table->file->inited) (void) table->file->ha_rnd_end(); if (tmp_table->file->inited) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 5977e309ae4..715d83f1190 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -83,6 +83,9 @@ #pragma GCC diagnostic ignored "-Wunused-label" /* yyexhaustedlab: */ #endif +/* Stack size 28200 with clang for MYSQLparse() and ORAparse() */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + int yylex(void *yylval, void *yythd); #define yyoverflow(A,B,C,D,E,F) \ diff --git a/sql/sys_vars.inl b/sql/sys_vars.inl index 120a4e202d7..1d0722c7ae9 100644 --- a/sql/sys_vars.inl +++ b/sql/sys_vars.inl @@ -935,21 +935,10 @@ public: { option.var_type|= GET_STR; } bool do_check(THD *thd, set_var *var) { - char buff[STRING_BUFFER_USUAL_SIZE]; - String str(buff, sizeof(buff), system_charset_info), *res; - - if (!(res=var->value->val_str(&str))) - { + bool rc= Sys_var_charptr::do_string_check(thd, var, charset(thd)); + if (var->save_result.string_value.str == nullptr) var->save_result.string_value.str= const_cast(""); - var->save_result.string_value.length= 0; - } - else - { - size_t len= res->length(); - var->save_result.string_value.str= thd->strmake(res->ptr(), len); - var->save_result.string_value.length= len; - } - return false; + return rc; } bool session_update(THD *thd, set_var *var) { diff --git a/sql/table.cc b/sql/table.cc index ca4b4e40014..c42f7443767 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -54,6 +54,7 @@ #include "wsrep_schema.h" #endif #include "log_event.h" // MAX_TABLE_MAP_ID +#include "sql_class.h" /* For MySQL 5.7 virtual fields */ #define MYSQL57_GENERATED_FIELD 128 @@ -3398,6 +3399,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, goto err; // Wrong field definition reg_field->flags |= AUTO_INCREMENT_FLAG; } + else + share->next_number_index= MAX_KEY; if (share->blob_fields) { @@ -5943,6 +5946,57 @@ void TABLE::reset_item_list(List *item_list, uint skip) const } } +TABLE_LIST::TABLE_LIST(THD *thd, + LEX_CSTRING db_str, + bool fqtn, + LEX_CSTRING alias_str, + bool has_alias_ptr, + Table_ident *table_ident, + thr_lock_type lock_t, + enum_mdl_type mdl_t, + ulong table_opts, + bool info_schema, + st_select_lex *sel, + List *index_hints_ptr, + LEX_STRING *option_ptr) +{ + db= db_str; + is_fqtn= fqtn; + alias= alias_str; + is_alias= has_alias_ptr; + if (lower_case_table_names) + { + if (table_ident->table.length) + table_ident->table.length= my_casedn_str(files_charset_info, + (char*) table_ident->table.str); + if (db.length && db.str != any_db.str) + db.length= my_casedn_str(files_charset_info, (char*) db.str); + } + + table_name= table_ident->table; + lock_type= lock_t; + mdl_type= mdl_t; + table_options= table_opts; + updating= table_options & TL_OPTION_UPDATING; + ignore_leaves= table_options & TL_OPTION_IGNORE_LEAVES; + sequence= table_options & TL_OPTION_SEQUENCE; + derived= table_ident->sel; + + if (!table_ident->sel && info_schema) + { + schema_table= find_schema_table(thd, &table_name); + schema_table_name= table_name; + } + select_lex= sel; + /* + We can't cache internal temporary tables between prepares as the + table may be deleted before next exection. + */ + cacheable_table= !table_ident->is_derived_table(); + index_hints= index_hints_ptr; + option= option_ptr ? option_ptr->str : 0; +} + /* calculate md5 of query @@ -9305,10 +9359,9 @@ int TABLE::update_default_fields(bool ignore_errors) int TABLE::update_generated_fields() { int res= 0; - if (found_next_number_field) + if (next_number_field) { - next_number_field= found_next_number_field; - res= found_next_number_field->set_default(); + res= next_number_field->set_default(); if (likely(!res)) res= file->update_auto_increment(); next_number_field= NULL; @@ -9323,6 +9376,18 @@ int TABLE::update_generated_fields() return res; } +void TABLE::period_prepare_autoinc() +{ + if (!found_next_number_field) + return; + /* Don't generate a new value if the autoinc index is WITHOUT OVERLAPS */ + DBUG_ASSERT(s->next_number_index < MAX_KEY); + if (key_info[s->next_number_index].without_overlaps) + return; + + next_number_field= found_next_number_field; +} + int TABLE::period_make_insert(Item *src, Field *dst) { THD *thd= in_use; @@ -9332,7 +9397,10 @@ int TABLE::period_make_insert(Item *src, Field *dst) int res= src->save_in_field(dst, true); if (likely(!res)) + { + period_prepare_autoinc(); res= update_generated_fields(); + } if (likely(!res) && triggers) res= triggers->process_triggers(thd, TRG_EVENT_INSERT, @@ -9657,7 +9725,8 @@ bool TABLE::insert_all_rows_into_tmp_table(THD *thd, } if (file->indexes_are_disabled()) - tmp_table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL); + tmp_table->file->ha_disable_indexes(key_map(0), false); + file->ha_index_or_rnd_end(); if (unlikely(file->ha_rnd_init_with_error(1))) diff --git a/sql/table.h b/sql/table.h index 7d6eba07831..9921537b217 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1916,6 +1916,7 @@ public: #endif int update_generated_fields(); + void period_prepare_autoinc(); int period_make_insert(Item *src, Field *dst); int insert_portion_of_time(THD *thd, const vers_select_conds_t &period_conds, ha_rows *rows_inserted); @@ -2296,8 +2297,23 @@ struct TABLE_CHAIN void set_end_pos(TABLE_LIST **pos) { end_pos= pos; } }; +class Table_ident; struct TABLE_LIST { + TABLE_LIST(THD *thd, + LEX_CSTRING db_str, + bool fqtn, + LEX_CSTRING alias_str, + bool has_alias_ptr, + Table_ident *table_ident, + thr_lock_type lock_t, + enum_mdl_type mdl_t, + ulong table_opts, + bool info_schema, + st_select_lex *sel, + List *index_hints_ptr, + LEX_STRING *option_ptr); + TABLE_LIST() = default; /* Remove gcc warning */ enum prelocking_types diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc index 4a226df0e0b..cc7bd6c2fd7 100644 --- a/sql/temporary_tables.cc +++ b/sql/temporary_tables.cc @@ -1132,11 +1132,16 @@ TABLE *THD::open_temporary_table(TMP_TABLE_SHARE *share, DBUG_RETURN(NULL); /* Out of memory */ } + uint flags= ha_open_options | (open_options & HA_OPEN_FOR_CREATE); + /* + In replication, temporary tables are not confined to a single + thread/THD. + */ + if (slave_thread) + flags|= HA_OPEN_GLOBAL_TMP_TABLE; if (open_table_from_share(this, share, &alias, (uint) HA_OPEN_KEYFILE, - EXTRA_RECORD, - (ha_open_options | - (open_options & HA_OPEN_FOR_CREATE)), + EXTRA_RECORD, flags, table, false)) { my_free(table); diff --git a/sql/threadpool_generic.cc b/sql/threadpool_generic.cc index 7261eabfd82..0a653474ffa 100644 --- a/sql/threadpool_generic.cc +++ b/sql/threadpool_generic.cc @@ -107,7 +107,7 @@ struct pool_timer_t mysql_cond_t cond; volatile uint64 current_microtime; std::atomic next_timeout_check; - int tick_interval; + uint tick_interval; bool shutdown; pthread_t timer_thread_id; }; @@ -569,7 +569,7 @@ static void* timer_thread(void *param) struct timespec ts; int err; - set_timespec_nsec(ts,timer->tick_interval*1000000); + set_timespec_nsec(ts, timer->tick_interval*1000000LL); mysql_mutex_lock(&timer->mutex); err= mysql_cond_timedwait(&timer->cond, &timer->mutex, &ts); if (timer->shutdown) diff --git a/sql/threadpool_win.cc b/sql/threadpool_win.cc index ed68e31c755..65e40598135 100644 --- a/sql/threadpool_win.cc +++ b/sql/threadpool_win.cc @@ -355,10 +355,13 @@ int TP_pool_win::init() if (IS_SYSVAR_AUTOSIZE(&threadpool_max_threads)) { /* - Nr 500 comes from Microsoft documentation, - there is no API for GetThreadpoolThreadMaxThreads() + Default 500 comes from Microsoft documentation, + there is no API for GetThreadpoolThreadMaxThreads(). + + To avoid deadlocks, allow at least max_connections + safety + margin threads in the pool. */ - SYSVAR_AUTOSIZE(threadpool_max_threads,500); + SYSVAR_AUTOSIZE(threadpool_max_threads,std::max(500U,(uint)max_connections + 10)); } else { diff --git a/sql/transaction.cc b/sql/transaction.cc index 053466c0c14..1ae0928e2fd 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -255,11 +255,15 @@ bool trans_begin(THD *thd, uint flags) bool trans_commit(THD *thd) { int res; + PSI_stage_info org_stage; DBUG_ENTER("trans_commit"); if (trans_check(thd)) DBUG_RETURN(TRUE); + thd->backup_stage(&org_stage); + THD_STAGE_INFO(thd, stage_commit); + thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); @@ -288,6 +292,7 @@ bool trans_commit(THD *thd) DBUG_ASSERT(thd->m_transaction_psi == NULL); trans_track_end_trx(thd); + THD_STAGE_INFO(thd, org_stage); DBUG_RETURN(MY_TEST(res)); } @@ -320,6 +325,10 @@ bool trans_commit_implicit(THD *thd) if (thd->in_multi_stmt_transaction_mode() || (thd->variables.option_bits & OPTION_TABLE_LOCK)) { + PSI_stage_info org_stage; + thd->backup_stage(&org_stage); + THD_STAGE_INFO(thd, stage_commit_implicit); + /* Safety if one did "drop table" on locked tables */ if (!thd->locked_tables_mode) thd->variables.option_bits&= ~OPTION_TABLE_LOCK; @@ -327,6 +336,8 @@ bool trans_commit_implicit(THD *thd) ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); res= MY_TEST(ha_commit_trans(thd, TRUE)); + + THD_STAGE_INFO(thd, org_stage); } thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_BINLOG_THIS_TRX); @@ -361,11 +372,15 @@ bool trans_commit_implicit(THD *thd) bool trans_rollback(THD *thd) { int res; + PSI_stage_info org_stage; DBUG_ENTER("trans_rollback"); if (trans_check(thd)) DBUG_RETURN(TRUE); + thd->backup_stage(&org_stage); + THD_STAGE_INFO(thd, stage_rollback); + thd->server_status&= ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); @@ -384,6 +399,7 @@ bool trans_rollback(THD *thd) trans_track_end_trx(thd); + THD_STAGE_INFO(thd, org_stage); DBUG_RETURN(MY_TEST(res)); } @@ -406,8 +422,12 @@ bool trans_rollback(THD *thd) bool trans_rollback_implicit(THD *thd) { int res; + PSI_stage_info org_stage; DBUG_ENTER("trans_rollback_implict"); + thd->backup_stage(&org_stage); + THD_STAGE_INFO(thd, stage_rollback_implicit); + /* Always commit/rollback statement transaction before manipulating with the normal one. @@ -434,6 +454,7 @@ bool trans_rollback_implicit(THD *thd) trans_track_end_trx(thd); + THD_STAGE_INFO(thd, org_stage); DBUG_RETURN(MY_TEST(res)); } @@ -469,11 +490,17 @@ bool trans_commit_stmt(THD *thd) if (thd->transaction->stmt.ha_list) { + PSI_stage_info org_stage; + thd->backup_stage(&org_stage); + THD_STAGE_INFO(thd, stage_commit); + res= ha_commit_trans(thd, FALSE); if (! thd->in_active_multi_stmt_transaction()) { trans_reset_one_shot_chistics(thd); } + + THD_STAGE_INFO(thd, org_stage); } mysql_mutex_assert_not_owner(&LOCK_prepare_ordered); @@ -532,9 +559,15 @@ bool trans_rollback_stmt(THD *thd) if (thd->transaction->stmt.ha_list) { + PSI_stage_info org_stage; + thd->backup_stage(&org_stage); + THD_STAGE_INFO(thd, stage_rollback); + ha_rollback_trans(thd, FALSE); if (! thd->in_active_multi_stmt_transaction()) trans_reset_one_shot_chistics(thd); + + THD_STAGE_INFO(thd, org_stage); } #ifdef HAVE_REPLICATION diff --git a/sql/tztime.cc b/sql/tztime.cc index 1e919140660..573dde8a8c6 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -2783,6 +2783,8 @@ static const char *lock_tables= " time_zone_transition WRITE,\n" " time_zone_transition_type WRITE"; static const char *trunc_tables_const= + "SET @old_alter_alg=@@SESSION.alter_algorithm;\n" + "SET session alter_algorithm='COPY';\n" "TRUNCATE TABLE time_zone;\n" "TRUNCATE TABLE time_zone_name;\n" "TRUNCATE TABLE time_zone_transition;\n" @@ -2931,6 +2933,9 @@ main(int argc, char **argv) "concat('ALTER TABLE time_zone_transition_type ENGINE=', " "@time_zone_transition_type_engine, ', ORDER BY Time_zone_id, Transition_type_id'), 'do 0');\n"); + if (argc == 1 && !opt_leap) + printf("SET session alter_algorithm=@old_alter_alg;\n"); + free_allocated_data(); my_end(0); return 0; diff --git a/sql/unireg.cc b/sql/unireg.cc index 6cc4bc8495c..104d7e209ae 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -806,7 +806,15 @@ static bool pack_vcols(THD *thd, String *buf, List &create_fields, ? VCOL_GENERATED_STORED : VCOL_GENERATED_VIRTUAL)) return 1; if (field->has_default_expression() && !field->has_default_now_unireg_check()) - if (pack_expression(buf, field->default_value, field_nr, VCOL_DEFAULT)) + if (pack_expression(buf, field->default_value, field_nr, VCOL_DEFAULT) || + /* + field->has_default_expression() can return error (e.g. because + the method Item_param::basic_const_item invokes + invalid_default_param() + in case either DEFAULT_VALUE or IGNORE_VALUE is handled). + Take this fact into account and return error in this case. + */ + thd->is_error()) return 1; if (field->check_constraint) if (pack_expression(buf, field->check_constraint, field_nr, diff --git a/sql/unireg.h b/sql/unireg.h index f730faf665a..7a7e97c082c 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -224,7 +224,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING &table, #define FRM_FORMINFO_SIZE 288 #define FRM_MAX_SIZE (1024*1024) -static inline bool is_binary_frm_header(uchar *head) +static inline bool is_binary_frm_header(const uchar *head) { return head[0] == 254 && head[1] == 1 diff --git a/sql/winmain.cc b/sql/winmain.cc index 2ed43130fa7..ff409a6d492 100644 --- a/sql/winmain.cc +++ b/sql/winmain.cc @@ -220,6 +220,25 @@ static const char *get_svc_name(const char *arg) return arg ? arg : "MySQL"; } +/* + Disable CPU throttling for the process. + + Windows 11 heuristics misdetects server as a background process and runs it + on "efficiency" cores, in hybrid architectures such as Alder Lake (12th + generation Intel Core).This results in serious performance degradation. +*/ +void disable_cpu_throttling() +{ +#ifdef PROCESS_POWER_THROTTLING_EXECUTION_SPEED + PROCESS_POWER_THROTTLING_STATE power_throttling{}; + power_throttling.Version= PROCESS_POWER_THROTTLING_CURRENT_VERSION; + power_throttling.ControlMask= PROCESS_POWER_THROTTLING_EXECUTION_SPEED; + power_throttling.StateMask= 0; + SetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling, + &power_throttling, sizeof(power_throttling)); +#endif +} + /* Main function on Windows. Runs mysqld as normal process, or as a service. @@ -231,6 +250,7 @@ __declspec(dllexport) int mysqld_win_main(int argc, char **argv) save_argv= argv; save_argc= argc; + disable_cpu_throttling(); /* If no special arguments are given, service name is nor present run as normal program. diff --git a/sql/wsrep_applier.cc b/sql/wsrep_applier.cc index 8767f698bf2..eee9dc02319 100644 --- a/sql/wsrep_applier.cc +++ b/sql/wsrep_applier.cc @@ -177,8 +177,7 @@ int wsrep_apply_events(THD* thd, break; } - - if (!thd->variables.gtid_seq_no && wsrep_thd_is_toi(thd) && + if (!thd->variables.gtid_seq_no && wsrep_thd_is_toi(thd) && (ev->get_type_code() == QUERY_EVENT)) { uint64 seqno= wsrep_gtid_server.seqno_inc(); @@ -188,18 +187,10 @@ int wsrep_apply_events(THD* thd, thd->variables.gtid_seq_no= seqno; } } + /* Use the original server id for logging. */ thd->set_server_id(ev->server_id); - thd->set_time(); // time the query - thd->transaction->start_time.reset(thd); thd->lex->current_select= 0; - if (!ev->when) - { - my_hrtime_t hrtime= my_hrtime(); - ev->when= hrtime_to_my_time(hrtime); - ev->when_sec_part= hrtime_sec_part(hrtime); - } - thd->variables.option_bits= (thd->variables.option_bits & ~OPTION_SKIP_REPLICATION) | (ev->flags & LOG_EVENT_SKIP_REPLICATION_F ? OPTION_SKIP_REPLICATION : 0); diff --git a/sql/wsrep_client_service.h b/sql/wsrep_client_service.h index 253d2f43ac3..b74c52b038f 100644 --- a/sql/wsrep_client_service.h +++ b/sql/wsrep_client_service.h @@ -57,6 +57,10 @@ public: { return false; } + bool is_prepared_xa() + { + return false; + } bool is_xa_rollback() { return false; diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc index 96b7ff8f851..8c301267059 100644 --- a/sql/wsrep_high_priority_service.cc +++ b/sql/wsrep_high_priority_service.cc @@ -215,6 +215,7 @@ int Wsrep_high_priority_service::start_transaction( const wsrep::ws_handle& ws_handle, const wsrep::ws_meta& ws_meta) { DBUG_ENTER(" Wsrep_high_priority_service::start_transaction"); + m_thd->set_time(); DBUG_RETURN(m_thd->wsrep_cs().start_transaction(ws_handle, ws_meta) || trans_begin(m_thd)); } @@ -426,6 +427,7 @@ int Wsrep_high_priority_service::apply_toi(const wsrep::ws_meta& ws_meta, };); #endif + thd->set_time(); int ret= apply_events(thd, m_rli, data, err); wsrep_thd_set_ignored_error(thd, false); trans_commit(thd); diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index e9ce787d140..db70fbe6020 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1133,10 +1133,8 @@ void wsrep_recover() } } - -void wsrep_stop_replication(THD *thd) +static void wsrep_stop_replication_common(THD *thd) { - WSREP_INFO("Stop replication by %llu", (thd) ? thd->thread_id : 0); if (Wsrep_server_state::instance().state() != Wsrep_server_state::s_disconnected) { @@ -1149,10 +1147,10 @@ void wsrep_stop_replication(THD *thd) } } - /* my connection, should not terminate with wsrep_close_client_connection(), - make transaction to rollback - */ - if (thd && !thd->wsrep_applier) trans_rollback(thd); + /* my connection, should not terminate with + wsrep_close_client_connections(), make transaction to rollback */ + if (thd && !thd->wsrep_applier) + trans_rollback(thd); wsrep_close_client_connections(TRUE, thd); /* wait until appliers have stopped */ @@ -1161,26 +1159,16 @@ void wsrep_stop_replication(THD *thd) node_uuid= WSREP_UUID_UNDEFINED; } +void wsrep_stop_replication(THD *thd) +{ + WSREP_INFO("Stop replication by %llu", (thd) ? thd->thread_id : 0); + wsrep_stop_replication_common(thd); +} + void wsrep_shutdown_replication() { WSREP_INFO("Shutdown replication"); - if (Wsrep_server_state::instance().state() != wsrep::server_state::s_disconnected) - { - WSREP_DEBUG("Disconnect provider"); - Wsrep_server_state::instance().disconnect(); - if (Wsrep_server_state::instance().wait_until_state( - Wsrep_server_state::s_disconnected)) - { - WSREP_WARN("Wsrep interrupted while waiting for disconnected state"); - } - } - - wsrep_close_client_connections(TRUE); - - /* wait until appliers have stopped */ - wsrep_wait_appliers_close(NULL); - node_uuid= WSREP_UUID_UNDEFINED; - + wsrep_stop_replication_common(nullptr); /* Undocking the thread specific data. */ set_current_thd(nullptr); } @@ -3246,7 +3234,9 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx, } } else if (granted_thd->lex->sql_command == SQLCOM_FLUSH || - granted_thd->mdl_context.has_explicit_locks()) + /* System transactions with explicit locks are BACKUP. */ + (granted_thd->system_thread != NON_SYSTEM_THREAD && + granted_thd->mdl_context.has_explicit_locks())) { WSREP_DEBUG("BF thread waiting for FLUSH for %s", wsrep_thd_query(request_thd)); @@ -3351,14 +3341,20 @@ static my_bool have_client_connections(THD *thd, void*) { DBUG_PRINT("quit",("Informing thread %lld that it's time to die", (longlong) thd->thread_id)); - if (is_client_connection(thd) && - (thd->killed == KILL_CONNECTION || - thd->killed == KILL_CONNECTION_HARD)) + if (is_client_connection(thd)) { - (void)abort_replicated(thd); - return 1; + if (thd->killed == KILL_CONNECTION || + thd->killed == KILL_CONNECTION_HARD) + { + (void)abort_replicated(thd); + return true; + } + if (thd->get_stmt_da()->is_eof()) + { + return true; + } } - return 0; + return false; } static void wsrep_close_thread(THD *thd) @@ -3396,14 +3392,24 @@ static my_bool kill_all_threads(THD *thd, THD *caller_thd) /* We skip slave threads & scheduler on this first loop through. */ if (is_client_connection(thd) && thd != caller_thd) { + if (thd->get_stmt_da()->is_eof()) + { + return 0; + } + if (is_replaying_connection(thd)) + { thd->set_killed(KILL_CONNECTION_HARD); - else if (!abort_replicated(thd)) + return 0; + } + + if (!abort_replicated(thd)) { /* replicated transactions must be skipped */ WSREP_DEBUG("closing connection %lld", (longlong) thd->thread_id); /* instead of wsrep_close_thread() we do now soft kill by THD::awake */ thd->awake(KILL_CONNECTION_HARD); + return 0; } } return 0; @@ -3415,6 +3421,7 @@ static my_bool kill_remaining_threads(THD *thd, THD *caller_thd) if (is_client_connection(thd) && !abort_replicated(thd) && !is_replaying_connection(thd) && + !thd->get_stmt_da()->is_eof() && thd_is_connection_alive(thd) && thd != caller_thd) { @@ -3909,7 +3916,7 @@ void wsrep_ready_set(bool ready_value) mysql_mutex_lock(&LOCK_wsrep_ready); wsrep_ready= ready_value; // Signal if we have reached ready state - if (wsrep_ready) + if (ready_value) mysql_cond_signal(&COND_wsrep_ready); mysql_mutex_unlock(&LOCK_wsrep_ready); } @@ -3924,21 +3931,11 @@ void wsrep_ready_set(bool ready_value) step is performed to leave the wsrep transaction in the state as it never existed. - This should not be an inline functions as it requires a lot of stack space - because of WSREP_DBUG() usage. It's also not a function that is - frequently called. */ void wsrep_commit_empty(THD* thd, bool all) { DBUG_ENTER("wsrep_commit_empty"); - WSREP_DEBUG("wsrep_commit_empty for %llu client_state %s client_mode" - " %s trans_state %s sql %s", - thd_get_thread_id(thd), - wsrep::to_c_string(thd->wsrep_cs().state()), - wsrep::to_c_string(thd->wsrep_cs().mode()), - wsrep::to_c_string(thd->wsrep_cs().transaction().state()), - wsrep_thd_query(thd)); if (wsrep_is_real(thd, all) && wsrep_thd_is_local(thd) && @@ -3946,14 +3943,40 @@ void wsrep_commit_empty(THD* thd, bool all) !thd->internal_transaction() && thd->wsrep_trx().state() != wsrep::transaction::s_committed) { - /* Here transaction is either empty (i.e. no changes) or - it was CREATE TABLE with no row binlog format or - we have already aborted transaction e.g. because max writeset size - has been reached. */ - DBUG_ASSERT(!wsrep_has_changes(thd) || - (thd->lex->sql_command == SQLCOM_CREATE_TABLE && - !thd->is_current_stmt_binlog_format_row()) || - thd->wsrep_cs().transaction().state() == wsrep::transaction::s_aborted); +#ifndef DBUG_OFF + const bool empty= !wsrep_has_changes(thd); + const bool create= thd->lex->sql_command == SQLCOM_CREATE_TABLE && + !thd->is_current_stmt_binlog_format_row(); + const bool aborted= thd->wsrep_cs().transaction().state() == wsrep::transaction::s_aborted; + const bool ddl_replay= ((sql_command_flags[thd->lex->sql_command] & + (CF_SCHEMA_CHANGE | CF_ADMIN_COMMAND)) && + thd->wsrep_cs().transaction().state() == wsrep::transaction::s_must_replay); + /* Here transaction is either + (1) empty (i.e. no changes) or + (2) it was CREATE TABLE with no row binlog format or + (3) we have already aborted transaction e.g. because max writeset size + has been reached or + (4) it was DDL and got BF aborted and must replay. + */ + if(!(empty || create || aborted || ddl_replay)) + { + WSREP_DEBUG("wsrep_commit_empty: thread: %llu client_state: %s client_mode:" + " %s trans_state: %s error: %s empty: %d create: %d aborted:" + " %d ddl_replay: %d sql: %s", + thd_get_thread_id(thd), + wsrep::to_c_string(thd->wsrep_cs().state()), + wsrep::to_c_string(thd->wsrep_cs().mode()), + wsrep::to_c_string(thd->wsrep_cs().transaction().state()), + wsrep::to_c_string(thd->wsrep_cs().current_error()), + empty, create, aborted, ddl_replay, + wsrep_thd_query(thd)); + + DBUG_ASSERT(empty || // 1 + create || // 2 + aborted || // 3 + ddl_replay); // 4 + } +#endif /* DBUG_OFF */ bool have_error= wsrep_current_error(thd); int ret= wsrep_before_rollback(thd, all) || wsrep_after_rollback(thd, all) || @@ -3967,10 +3990,10 @@ void wsrep_commit_empty(THD* thd, bool all) DBUG_ASSERT(wsrep_current_error(thd) == wsrep::e_deadlock_error); thd->wsrep_cs().reset_error(); } + if (ret) - { - WSREP_DEBUG("wsrep_commit_empty failed: %d", wsrep_current_error(thd)); - } + WSREP_DEBUG("wsrep_commit_empty failed: %s", + wsrep::to_c_string(thd->wsrep_cs().current_error())); } DBUG_VOID_RETURN; } diff --git a/sql/wsrep_notify.cc b/sql/wsrep_notify.cc index 6cf4fc4c1a2..fd086ce4a89 100644 --- a/sql/wsrep_notify.cc +++ b/sql/wsrep_notify.cc @@ -28,7 +28,7 @@ void wsrep_notify_status(enum wsrep::server_state::state status, if (!view) { WSREP_DEBUG("wsrep_notify_status server not yet ready : wsrep_ready=%d status %d", - wsrep_ready, (int)status); + (int) wsrep_ready_get(), (int)status); return; } diff --git a/sql/wsrep_schema.cc b/sql/wsrep_schema.cc index c6e45340dd1..d9baf69999a 100644 --- a/sql/wsrep_schema.cc +++ b/sql/wsrep_schema.cc @@ -272,25 +272,17 @@ static void finish_stmt(THD* thd) { close_thread_tables(thd); } -static int open_table(THD* thd, - const LEX_CSTRING *schema_name, - const LEX_CSTRING *table_name, - enum thr_lock_type const lock_type, - TABLE** table) { - assert(table); - *table= NULL; - +static int open_table(THD *thd, const LEX_CSTRING *schema_name, + const LEX_CSTRING *table_name, + enum thr_lock_type const lock_type, + TABLE_LIST *table_list) +{ + assert(table_list); DBUG_ENTER("Wsrep_schema::open_table()"); - - TABLE_LIST tables; - uint flags= (MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK | - MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY | - MYSQL_OPEN_IGNORE_FLUSH | - MYSQL_LOCK_IGNORE_TIMEOUT); - - tables.init_one_table(schema_name, - table_name, - NULL, lock_type); + const uint flags= (MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK | + MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY | + MYSQL_OPEN_IGNORE_FLUSH | MYSQL_LOCK_IGNORE_TIMEOUT); + table_list->init_one_table(schema_name, table_name, NULL, lock_type); thd->lex->query_tables_own_last= 0; // No need to open table if the query was bf aborted, @@ -300,37 +292,39 @@ static int open_table(THD* thd, (thd->get_stmt_da()->sql_errno() == ER_QUERY_INTERRUPTED)); if (interrupted || - !open_n_lock_single_table(thd, &tables, tables.lock_type, flags)) { + !open_n_lock_single_table(thd, table_list, table_list->lock_type, flags)) + { close_thread_tables(thd); DBUG_RETURN(1); } - *table= tables.table; - (*table)->use_all_columns(); + table_list->table->use_all_columns(); DBUG_RETURN(0); } - -static int open_for_write(THD* thd, const char* table_name, TABLE** table) { +static int open_for_write(THD* thd, const char* table_name, TABLE_LIST* table_list) +{ LEX_CSTRING schema_str= { wsrep_schema_str.c_str(), wsrep_schema_str.length() }; LEX_CSTRING table_str= { table_name, strlen(table_name) }; if (Wsrep_schema_impl::open_table(thd, &schema_str, &table_str, TL_WRITE, - table)) { + table_list)) + { // No need to log an error if the query was bf aborted, // thd client will get ER_LOCK_DEADLOCK in the end. const bool interrupted= thd->killed || (thd->is_error() && (thd->get_stmt_da()->sql_errno() == ER_QUERY_INTERRUPTED)); - if (!interrupted) { + if (!interrupted) + { WSREP_ERROR("Failed to open table %s.%s for writing", schema_str.str, table_name); } return 1; } - empty_record(*table); - (*table)->use_all_columns(); - restore_record(*table, s->default_values); + empty_record(table_list->table); + table_list->table->use_all_columns(); + restore_record(table_list->table, s->default_values); return 0; } @@ -479,19 +473,21 @@ static int delete_row(TABLE* table) { return 0; } -static int open_for_read(THD* thd, const char* table_name, TABLE** table) { - +static int open_for_read(THD *thd, const char *table_name, + TABLE_LIST *table_list) +{ LEX_CSTRING schema_str= { wsrep_schema_str.c_str(), wsrep_schema_str.length() }; LEX_CSTRING table_str= { table_name, strlen(table_name) }; if (Wsrep_schema_impl::open_table(thd, &schema_str, &table_str, TL_READ, - table)) { + table_list)) + { WSREP_ERROR("Failed to open table %s.%s for reading", schema_str.str, table_name); return 1; } - empty_record(*table); - (*table)->use_all_columns(); - restore_record(*table, s->default_values); + empty_record(table_list->table); + table_list->table->use_all_columns(); + restore_record(table_list->table, s->default_values); return 0; } @@ -752,8 +748,10 @@ int Wsrep_schema::store_view(THD* thd, const Wsrep_view& view) assert(view.status() == Wsrep_view::primary); int ret= 1; int error; + TABLE_LIST cluster_table_l; TABLE* cluster_table= 0; - TABLE* members_table= 0; + TABLE_LIST members_table_l; + TABLE* members_table = 0; #ifdef WSREP_SCHEMA_MEMBERS_HISTORY TABLE* members_history_table= 0; #endif /* WSREP_SCHEMA_MEMBERS_HISTORY */ @@ -778,11 +776,13 @@ int Wsrep_schema::store_view(THD* thd, const Wsrep_view& view) Store cluster view info */ Wsrep_schema_impl::init_stmt(thd); - if (Wsrep_schema_impl::open_for_write(thd, cluster_table_str.c_str(), &cluster_table)) + if (Wsrep_schema_impl::open_for_write(thd, cluster_table_str.c_str(), &cluster_table_l)) { goto out; } + cluster_table= cluster_table_l.table; + Wsrep_schema_impl::store(cluster_table, 0, view.state_id().id()); Wsrep_schema_impl::store(cluster_table, 1, view.view_seqno().get()); Wsrep_schema_impl::store(cluster_table, 2, view.state_id().seqno().get()); @@ -802,12 +802,14 @@ int Wsrep_schema::store_view(THD* thd, const Wsrep_view& view) */ Wsrep_schema_impl::init_stmt(thd); if (Wsrep_schema_impl::open_for_write(thd, members_table_str.c_str(), - &members_table)) + &members_table_l)) { WSREP_ERROR("failed to open wsrep.members table"); goto out; } + members_table= members_table_l.table; + for (size_t i= 0; i < view.members().size(); ++i) { Wsrep_schema_impl::store(members_table, 0, view.members()[i].id()); @@ -861,8 +863,10 @@ Wsrep_view Wsrep_schema::restore_view(THD* thd, const Wsrep_id& own_id) const { int ret= 1; int error; + TABLE_LIST cluster_table_l; TABLE* cluster_table= 0; bool end_cluster_scan= false; + TABLE_LIST members_table_l; TABLE* members_table= 0; bool end_members_scan= false; @@ -888,8 +892,12 @@ Wsrep_view Wsrep_schema::restore_view(THD* thd, const Wsrep_id& own_id) const { Read cluster info from cluster table */ Wsrep_schema_impl::init_stmt(thd); - if (Wsrep_schema_impl::open_for_read(thd, cluster_table_str.c_str(), &cluster_table) || - Wsrep_schema_impl::init_for_scan(cluster_table)) { + if (Wsrep_schema_impl::open_for_read(thd, cluster_table_str.c_str(), &cluster_table_l)) { + goto out; + } + cluster_table = cluster_table_l.table; + + if (Wsrep_schema_impl::init_for_scan(cluster_table)) { goto out; } @@ -913,8 +921,14 @@ Wsrep_view Wsrep_schema::restore_view(THD* thd, const Wsrep_id& own_id) const { Read members from members table */ Wsrep_schema_impl::init_stmt(thd); - if (Wsrep_schema_impl::open_for_read(thd, members_table_str.c_str(), &members_table) || - Wsrep_schema_impl::init_for_scan(members_table)) { + if (Wsrep_schema_impl::open_for_read(thd, members_table_str.c_str(), + &members_table_l)) + { + goto out; + } + + members_table= members_table_l.table; + if (Wsrep_schema_impl::init_for_scan(members_table)) { goto out; } end_members_scan= true; @@ -1018,14 +1032,15 @@ int Wsrep_schema::append_fragment(THD* thd, Wsrep_schema_impl::sql_safe_updates sql_safe_updates(thd); Wsrep_schema_impl::init_stmt(thd); - TABLE* frag_table= 0; - if (Wsrep_schema_impl::open_for_write(thd, sr_table_str.c_str(), &frag_table)) + TABLE_LIST frag_table_l; + if (Wsrep_schema_impl::open_for_write(thd, sr_table_str.c_str(), &frag_table_l)) { trans_rollback_stmt(thd); thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(1); } + TABLE* frag_table= frag_table_l.table; Wsrep_schema_impl::store(frag_table, 0, server_id); Wsrep_schema_impl::store(frag_table, 1, transaction_id.get()); Wsrep_schema_impl::store(frag_table, 2, seqno.get()); @@ -1069,13 +1084,15 @@ int Wsrep_schema::update_fragment_meta(THD* thd, uchar *key=NULL; key_part_map key_map= 0; TABLE* frag_table= 0; + TABLE_LIST frag_table_l; Wsrep_schema_impl::init_stmt(thd); - if (Wsrep_schema_impl::open_for_write(thd, sr_table_str.c_str(), &frag_table)) + if (Wsrep_schema_impl::open_for_write(thd, sr_table_str.c_str(), &frag_table_l)) { thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(1); } + frag_table= frag_table_l.table; /* Find record with the given uuid, trx id, and seqno -1 */ Wsrep_schema_impl::store(frag_table, 0, ws_meta.server_id()); @@ -1163,7 +1180,10 @@ static int remove_fragment(THD* thd, seqno.get(), error); } - ret= error; + else + { + ret= error; + } } else if (Wsrep_schema_impl::delete_row(frag_table)) { @@ -1195,12 +1215,14 @@ int Wsrep_schema::remove_fragments(THD* thd, thd->reset_n_backup_open_tables_state(&open_tables_backup); TABLE* frag_table= 0; - if (Wsrep_schema_impl::open_for_write(thd, sr_table_str.c_str(), &frag_table)) + TABLE_LIST frag_table_l; + if (Wsrep_schema_impl::open_for_write(thd, sr_table_str.c_str(), &frag_table_l)) { ret= 1; } else { + frag_table= frag_table_l.table; for (std::vector::const_iterator i= fragments.begin(); i != fragments.end(); ++i) { @@ -1243,40 +1265,35 @@ int Wsrep_schema::remove_fragments(THD* thd, DBUG_RETURN(ret); } -int Wsrep_schema::replay_transaction(THD* orig_thd, - Relay_log_info* rli, - const wsrep::ws_meta& ws_meta, - const std::vector& fragments) +static int replay_transaction(THD* thd, + THD* orig_thd, + Relay_log_info* rli, + const wsrep::ws_meta& ws_meta, + const std::vector& fragments) { - DBUG_ENTER("Wsrep_schema::replay_transaction"); - DBUG_ASSERT(!fragments.empty()); - - THD thd(next_thread_id(), true); - thd.thread_stack= (orig_thd ? orig_thd->thread_stack : - (char*) &thd); - wsrep_assign_from_threadvars(&thd); - - Wsrep_schema_impl::wsrep_off wsrep_off(&thd); - Wsrep_schema_impl::binlog_off binlog_off(&thd); - Wsrep_schema_impl::sql_safe_updates sql_safe_updates(&thd); - Wsrep_schema_impl::thd_context_switch thd_context_switch(orig_thd, &thd); + Wsrep_schema_impl::wsrep_off wsrep_off(thd); + Wsrep_schema_impl::binlog_off binlog_off(thd); + Wsrep_schema_impl::sql_safe_updates sql_safe_updates(thd); + Wsrep_schema_impl::thd_context_switch thd_context_switch(orig_thd, thd); int ret= 1; int error; TABLE* frag_table= 0; + TABLE_LIST frag_table_l; uchar *key=NULL; key_part_map key_map= 0; for (std::vector::const_iterator i= fragments.begin(); i != fragments.end(); ++i) { - Wsrep_schema_impl::init_stmt(&thd); - if ((error= Wsrep_schema_impl::open_for_read(&thd, sr_table_str.c_str(), &frag_table))) + Wsrep_schema_impl::init_stmt(thd); + if ((error= Wsrep_schema_impl::open_for_read(thd, sr_table_str.c_str(), &frag_table_l))) { WSREP_WARN("Could not open SR table for read: %d", error); - Wsrep_schema_impl::finish_stmt(&thd); - DBUG_RETURN(1); + Wsrep_schema_impl::finish_stmt(thd); + return 1; } + frag_table= frag_table_l.table; Wsrep_schema_impl::store(frag_table, 0, ws_meta.server_id()); Wsrep_schema_impl::store(frag_table, 1, ws_meta.transaction_id().get()); @@ -1305,7 +1322,7 @@ int Wsrep_schema::replay_transaction(THD* orig_thd, frag_table->field[4]->val_str(&buf); { - Wsrep_schema_impl::thd_context_switch thd_context_switch(&thd, orig_thd); + Wsrep_schema_impl::thd_context_switch thd_context_switch(thd, orig_thd); ret= wsrep_apply_events(orig_thd, rli, buf.ptr(), buf.length()); if (ret) @@ -1316,18 +1333,20 @@ int Wsrep_schema::replay_transaction(THD* orig_thd, } Wsrep_schema_impl::end_index_scan(frag_table); - Wsrep_schema_impl::finish_stmt(&thd); + Wsrep_schema_impl::finish_stmt(thd); - Wsrep_schema_impl::init_stmt(&thd); + Wsrep_schema_impl::init_stmt(thd); - if ((error= Wsrep_schema_impl::open_for_write(&thd, + if ((error= Wsrep_schema_impl::open_for_write(thd, sr_table_str.c_str(), - &frag_table))) + &frag_table_l))) { WSREP_WARN("Could not open SR table for write: %d", error); - Wsrep_schema_impl::finish_stmt(&thd); - DBUG_RETURN(1); + Wsrep_schema_impl::finish_stmt(thd); + ret= 1; + break; } + frag_table= frag_table_l.table; error= Wsrep_schema_impl::init_for_index_scan(frag_table, key, @@ -1351,86 +1370,120 @@ int Wsrep_schema::replay_transaction(THD* orig_thd, break; } Wsrep_schema_impl::end_index_scan(frag_table); - Wsrep_schema_impl::finish_stmt(&thd); + Wsrep_schema_impl::finish_stmt(thd); my_free(key); key= NULL; } if (key) my_free(key); + + return ret; +} + +int Wsrep_schema::replay_transaction(THD* orig_thd, + Relay_log_info* rli, + const wsrep::ws_meta& ws_meta, + const std::vector& fragments) +{ + DBUG_ENTER("Wsrep_schema::replay_transaction"); + DBUG_ASSERT(!fragments.empty()); + + THD *thd= new THD(next_thread_id(), true); + if (!thd) + { + WSREP_WARN("Could not allocate memory for THD"); + DBUG_RETURN(1); + } + + thd->thread_stack= (orig_thd ? orig_thd->thread_stack : (char *) &thd); + wsrep_assign_from_threadvars(thd); + + int ret= ::replay_transaction(thd, orig_thd, rli, ws_meta, fragments); + + delete thd; DBUG_RETURN(ret); } -int Wsrep_schema::recover_sr_transactions(THD *orig_thd) +static int recover_sr_transactions(THD* storage_thd, THD* orig_thd) { - DBUG_ENTER("Wsrep_schema::recover_sr_transactions"); - THD storage_thd(next_thread_id(), true); - storage_thd.thread_stack= (orig_thd ? orig_thd->thread_stack : - (char*) &storage_thd); - wsrep_assign_from_threadvars(&storage_thd); TABLE* frag_table= 0; + TABLE_LIST frag_table_l; TABLE* cluster_table= 0; - Wsrep_storage_service storage_service(&storage_thd); - Wsrep_schema_impl::binlog_off binlog_off(&storage_thd); - Wsrep_schema_impl::wsrep_off wsrep_off(&storage_thd); - Wsrep_schema_impl::sql_safe_updates sql_safe_updates(&storage_thd); + TABLE_LIST cluster_table_l; + Wsrep_storage_service storage_service(storage_thd); + Wsrep_schema_impl::binlog_off binlog_off(storage_thd); + Wsrep_schema_impl::wsrep_off wsrep_off(storage_thd); + Wsrep_schema_impl::sql_safe_updates sql_safe_updates(storage_thd); Wsrep_schema_impl::thd_context_switch thd_context_switch(orig_thd, - &storage_thd); + storage_thd); Wsrep_server_state& server_state(Wsrep_server_state::instance()); int ret= 1; int error; wsrep::id cluster_id; - Wsrep_schema_impl::init_stmt(&storage_thd); - storage_thd.wsrep_skip_locking= FALSE; - if (Wsrep_schema_impl::open_for_read(&storage_thd, - cluster_table_str.c_str(), - &cluster_table) || - Wsrep_schema_impl::init_for_scan(cluster_table)) + Wsrep_schema_impl::init_stmt(storage_thd); + storage_thd->wsrep_skip_locking= FALSE; + if (Wsrep_schema_impl::open_for_read(storage_thd, cluster_table_str.c_str(), + &cluster_table_l)) { - Wsrep_schema_impl::finish_stmt(&storage_thd); - DBUG_RETURN(1); + Wsrep_schema_impl::finish_stmt(storage_thd); + return 1; + } + cluster_table= cluster_table_l.table; + + if (Wsrep_schema_impl::init_for_scan(cluster_table)) + { + Wsrep_schema_impl::finish_stmt(storage_thd); + return 1; } if ((error= Wsrep_schema_impl::next_record(cluster_table))) { Wsrep_schema_impl::end_scan(cluster_table); - Wsrep_schema_impl::finish_stmt(&storage_thd); - trans_commit(&storage_thd); + Wsrep_schema_impl::finish_stmt(storage_thd); + trans_commit(storage_thd); if (error == HA_ERR_END_OF_FILE) { WSREP_INFO("Cluster table is empty, not recovering transactions"); - DBUG_RETURN(0); + return 0; } else { WSREP_ERROR("Failed to read cluster table: %d", error); - DBUG_RETURN(1); + return 1; } } Wsrep_schema_impl::scan(cluster_table, 0, cluster_id); Wsrep_schema_impl::end_scan(cluster_table); - Wsrep_schema_impl::finish_stmt(&storage_thd); + Wsrep_schema_impl::finish_stmt(storage_thd); std::ostringstream os; os << cluster_id; WSREP_INFO("Recovered cluster id %s", os.str().c_str()); - storage_thd.wsrep_skip_locking= TRUE; - Wsrep_schema_impl::init_stmt(&storage_thd); + storage_thd->wsrep_skip_locking= TRUE; + Wsrep_schema_impl::init_stmt(storage_thd); /* Open the table for reading and writing so that fragments without valid seqno can be deleted. */ - if (Wsrep_schema_impl::open_for_write(&storage_thd, sr_table_str.c_str(), &frag_table) || - Wsrep_schema_impl::init_for_scan(frag_table)) + if (Wsrep_schema_impl::open_for_write(storage_thd, sr_table_str.c_str(), + &frag_table_l)) { WSREP_ERROR("Failed to open SR table for write"); goto out; } + frag_table= frag_table_l.table; + + if (Wsrep_schema_impl::init_for_scan(frag_table)) + { + WSREP_ERROR("Failed to init for index scan"); + goto out; + } while (0 == error) { @@ -1474,7 +1527,7 @@ int Wsrep_schema::recover_sr_transactions(THD *orig_thd) transaction_id))) { DBUG_ASSERT(wsrep::starts_transaction(flags)); - applier = wsrep_create_streaming_applier(&storage_thd, "recovery"); + applier = wsrep_create_streaming_applier(storage_thd, "recovery"); server_state.start_streaming_applier(server_id, transaction_id, applier); applier->start_transaction(wsrep::ws_handle(transaction_id, 0), @@ -1502,10 +1555,30 @@ int Wsrep_schema::recover_sr_transactions(THD *orig_thd) } } Wsrep_schema_impl::end_scan(frag_table); - Wsrep_schema_impl::finish_stmt(&storage_thd); - trans_commit(&storage_thd); - storage_thd.set_mysys_var(0); + Wsrep_schema_impl::finish_stmt(storage_thd); + trans_commit(storage_thd); + storage_thd->set_mysys_var(0); out: + return ret; +} + +int Wsrep_schema::recover_sr_transactions(THD *orig_thd) +{ + DBUG_ENTER("Wsrep_schema::recover_sr_transactions"); + + THD *storage_thd= new THD(next_thread_id(), true); + if (!storage_thd) + { + WSREP_WARN("Could not allocate memory for THD"); + DBUG_RETURN(1); + } + storage_thd->thread_stack= + (orig_thd ? orig_thd->thread_stack : (char *) &storage_thd); + wsrep_assign_from_threadvars(storage_thd); + + int ret= ::recover_sr_transactions(storage_thd, orig_thd); + + delete storage_thd; DBUG_RETURN(ret); } @@ -1521,13 +1594,15 @@ void Wsrep_schema::clear_allowlist() thd->thread_stack= (char*)&thd; wsrep_init_thd_for_schema(thd); TABLE* allowlist_table= 0; + TABLE_LIST allowlist_table_l; int error= 0; Wsrep_schema_impl::init_stmt(thd); if (Wsrep_schema_impl::open_for_write(thd, allowlist_table_str.c_str(), - &allowlist_table) || - Wsrep_schema_impl::init_for_scan(allowlist_table)) + &allowlist_table_l) || + (allowlist_table= allowlist_table_l.table, + Wsrep_schema_impl::init_for_scan(allowlist_table))) { WSREP_ERROR("Failed to open mysql.wsrep_allowlist table"); goto out; @@ -1567,14 +1642,16 @@ void Wsrep_schema::store_allowlist(std::vector& ip_allowlist) thd->thread_stack= (char*)&thd; wsrep_init_thd_for_schema(thd); TABLE* allowlist_table= 0; + TABLE_LIST allowlist_table_l; int error; Wsrep_schema_impl::init_stmt(thd); if (Wsrep_schema_impl::open_for_write(thd, allowlist_table_str.c_str(), - &allowlist_table)) + &allowlist_table_l)) { WSREP_ERROR("Failed to open mysql.wsrep_allowlist table"); goto out; } + allowlist_table= allowlist_table_l.table; for (size_t i= 0; i < ip_allowlist.size(); ++i) { Wsrep_schema_impl::store(allowlist_table, 0, ip_allowlist[i]); @@ -1618,6 +1695,7 @@ static void *allowlist_check_thread(void *param) int error; TABLE *allowlist_table= 0; + TABLE_LIST allowlist_table_l; bool match_found_or_empty= false; bool table_have_rows= false; char row[64]= { @@ -1629,8 +1707,9 @@ static void *allowlist_check_thread(void *param) */ Wsrep_schema_impl::init_stmt(&thd); if (Wsrep_schema_impl::open_for_read(&thd, allowlist_table_str.c_str(), - &allowlist_table) || - Wsrep_schema_impl::init_for_scan(allowlist_table)) + &allowlist_table_l) || + (allowlist_table= allowlist_table_l.table, + Wsrep_schema_impl::init_for_scan(allowlist_table))) { goto out; } diff --git a/sql/wsrep_server_service.cc b/sql/wsrep_server_service.cc index c3df6e9f73c..19fa4470687 100644 --- a/sql/wsrep_server_service.cc +++ b/sql/wsrep_server_service.cc @@ -345,7 +345,6 @@ void Wsrep_server_service::log_state_change( switch (current_state) { case Wsrep_server_state::s_synced: - wsrep_ready= TRUE; WSREP_INFO("Synchronized with group, ready for connections"); wsrep_ready_set(true); /* fall through */ diff --git a/storage/archive/CMakeLists.txt b/storage/archive/CMakeLists.txt index 5b6818fc921..5c7b6aa4aab 100644 --- a/storage/archive/CMakeLists.txt +++ b/storage/archive/CMakeLists.txt @@ -14,5 +14,5 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA SET(ARCHIVE_SOURCES azio.c ha_archive.cc ha_archive.h) -MYSQL_ADD_PLUGIN(archive ${ARCHIVE_SOURCES} STORAGE_ENGINE LINK_LIBRARIES ${ZLIB_LIBRARY}) +MYSQL_ADD_PLUGIN(archive ${ARCHIVE_SOURCES} STORAGE_ENGINE LINK_LIBRARIES ${ZLIB_LIBRARIES}) diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 2a8deb431b1..03269625040 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -269,6 +269,9 @@ ha_archive::ha_archive(handlerton *hton, TABLE_SHARE *table_arg) archive_reader_open= FALSE; } +/* Stack size 50264 with clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + static int archive_discover(handlerton *hton, THD* thd, TABLE_SHARE *share) { DBUG_ENTER("archive_discover"); @@ -310,6 +313,7 @@ ret: my_free(frm_ptr); DBUG_RETURN(my_errno); } +PRAGMA_REENABLE_CHECK_STACK_FRAME /** @brief Read version 1 meta file (5.0 compatibility routine). @@ -480,6 +484,10 @@ int ha_archive::read_data_header(azio_stream *file_to_read) See ha_example.cc for a longer description. */ + +/* Stack size 49608 with clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + Archive_share *ha_archive::get_share(const char *table_name, int *rc) { Archive_share *tmp_share; @@ -542,6 +550,7 @@ err: DBUG_RETURN(tmp_share); } +PRAGMA_REENABLE_CHECK_STACK_FRAME int Archive_share::init_archive_writer() @@ -763,6 +772,9 @@ int ha_archive::frm_compare(azio_stream *s) of creation. */ +/* Stack size 49608 with clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + int ha_archive::create(const char *name, TABLE *table_arg, HA_CREATE_INFO *create_info) { @@ -880,6 +892,7 @@ error: /* Return error number, if we got one */ DBUG_RETURN(error ? error : -1); } +PRAGMA_REENABLE_CHECK_STACK_FRAME /* This is where the actual row is written out. @@ -1544,6 +1557,10 @@ int ha_archive::repair(THD* thd, HA_CHECK_OPT* check_opt) The table can become fragmented if data was inserted, read, and then inserted again. What we do is open up the file and recompress it completely. */ + +/* Stack size 50152 with clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt) { int rc= 0; @@ -1669,6 +1686,7 @@ error: DBUG_RETURN(rc); } +PRAGMA_REENABLE_CHECK_STACK_FRAME /* Below is an example of how to setup row level locking. @@ -2010,4 +2028,3 @@ maria_declare_plugin(archive) MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ } maria_declare_plugin_end; - diff --git a/storage/columnstore/CMakeLists.txt b/storage/columnstore/CMakeLists.txt index bf4a805762e..1d6bdd4db5c 100644 --- a/storage/columnstore/CMakeLists.txt +++ b/storage/columnstore/CMakeLists.txt @@ -1,6 +1,7 @@ #set(PLUGIN_COLUMNSTORE "NO" CACHE STRING "Enable ColumnStore engine") -if("NO" STREQUAL "${PLUGIN_COLUMNSTORE}") +if("NO" STREQUAL "${PLUGIN_COLUMNSTORE}" OR + (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/columnstore/CMakeLists.txt)) return() endif() @@ -20,6 +21,10 @@ IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "12.0.0" MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-error=dangling-pointer") ENDIF() MY_CHECK_AND_SET_COMPILER_FLAG("-fno-strict-aliasing") + +# let's temporarily disable the warning, until ColumnStore is fixed +MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-error=calloc-transposed-args") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") # this does everything, gets the var from the correct scope, appends new diff --git a/storage/columnstore/columnstore b/storage/columnstore/columnstore index 15fc0328c60..a81afdaf5bb 160000 --- a/storage/columnstore/columnstore +++ b/storage/columnstore/columnstore @@ -1 +1 @@ -Subproject commit 15fc0328c603e4d61f89df6851357804c20af21e +Subproject commit a81afdaf5bb995ab50a029c201772c859d711447 diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index b8ae3a9f4f0..f64c500a011 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -405,7 +405,7 @@ MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES} STORAGE_ENGINE COMPONENT connect-engine RECOMPILE_FOR_EMBEDDED - LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY} + LINK_LIBRARIES ${ZLIB_LIBRARIES} ${XML_LIBRARY} ${ICONV_LIBRARY} ${ODBC_LIBRARY} ${MONGOC_LIBRARY} ${IPHLPAPI_LIBRARY} ${REST_LIBRARY}) IF(NOT TARGET connect) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 0d4fb857598..0d6449da7f4 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -6454,6 +6454,9 @@ char *ha_connect::GetDBfromName(const char *name) ha_create_table() in handle.cc */ +/* Stack size 25608 in clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + int ha_connect::create(const char *name, TABLE *table_arg, HA_CREATE_INFO *create_info) { @@ -6998,6 +7001,7 @@ int ha_connect::create(const char *name, TABLE *table_arg, table= st; DBUG_RETURN(rc); } // end of create +PRAGMA_REENABLE_CHECK_STACK_FRAME /** Used to check whether a file based outward table can be populated by @@ -7005,6 +7009,10 @@ int ha_connect::create(const char *name, TABLE *table_arg, - file does not exist or is void - user has file privilege */ + +/* Stack size 16664 in clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + bool ha_connect::FileExists(const char *fn, bool bf) { if (!fn || !*fn) @@ -7055,6 +7063,7 @@ bool ha_connect::FileExists(const char *fn, bool bf) return true; } // end of FileExists +PRAGMA_REENABLE_CHECK_STACK_FRAME // Called by SameString and NoFieldOptionChange bool ha_connect::CheckString(PCSZ str1, PCSZ str2) diff --git a/storage/connect/ioapi.h b/storage/connect/ioapi.h index 44430e56dd4..94b292ed78f 100644 --- a/storage/connect/ioapi.h +++ b/storage/connect/ioapi.h @@ -144,7 +144,7 @@ typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stre typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); -/* here is the "old" 32 bits structure structure */ +/* here is the "old" 32 bits structure */ typedef struct zlib_filefunc_def_s { open_file_func zopen_file; diff --git a/storage/connect/libdoc.cpp b/storage/connect/libdoc.cpp index 67f22ce29e9..ab588dd49a6 100644 --- a/storage/connect/libdoc.cpp +++ b/storage/connect/libdoc.cpp @@ -93,7 +93,6 @@ class LIBXMLDOC : public XMLDOCUMENT { xmlXPathContextPtr Ctxp; xmlXPathObjectPtr Xop; xmlXPathObjectPtr NlXop; - xmlErrorPtr Xerr; char *Buf; // Temporary bool Nofreelist; }; // end of class LIBXMLDOC @@ -327,7 +326,6 @@ LIBXMLDOC::LIBXMLDOC(char *nsl, char *nsdf, char *enc, PFBLOCK fp) Ctxp = NULL; Xop = NULL; NlXop = NULL; - Xerr = NULL; Buf = NULL; Nofreelist = false; } // end of LIBXMLDOC constructor @@ -365,8 +363,8 @@ bool LIBXMLDOC::ParseFile(PGLOBAL g, char *fn) Encoding = (char*)Docp->encoding; return false; - } else if ((Xerr = xmlGetLastError())) - xmlResetError(Xerr); + } else if (xmlGetLastError()) + xmlResetLastError(); return true; } // end of ParseFile @@ -505,9 +503,9 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn) #if 1 // This function does not crash ( if (xmlSaveFormatFileEnc((const char *)ofn, Docp, Encoding, 0) < 0) { - xmlErrorPtr err = xmlGetLastError(); + const xmlError *err = xmlGetLastError(); strcpy(g->Message, (err) ? err->message : "Error saving XML doc"); - xmlResetError(Xerr); + xmlResetLastError(); rc = -1; } // endif Save // rc = xmlDocDump(of, Docp); @@ -546,8 +544,8 @@ void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp) if (Nlist) { xmlXPathFreeNodeSet(Nlist); - if ((Xerr = xmlGetLastError())) - xmlResetError(Xerr); + if (xmlGetLastError()) + xmlResetLastError(); Nlist = NULL; } // endif Nlist @@ -555,8 +553,8 @@ void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp) if (Xop) { xmlXPathFreeObject(Xop); - if ((Xerr = xmlGetLastError())) - xmlResetError(Xerr); + if (xmlGetLastError()) + xmlResetLastError(); Xop = NULL; } // endif Xop @@ -564,8 +562,8 @@ void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp) if (NlXop) { xmlXPathFreeObject(NlXop); - if ((Xerr = xmlGetLastError())) - xmlResetError(Xerr); + if (xmlGetLastError()) + xmlResetLastError(); NlXop = NULL; } // endif NlXop @@ -573,8 +571,8 @@ void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp) if (Ctxp) { xmlXPathFreeContext(Ctxp); - if ((Xerr = xmlGetLastError())) - xmlResetError(Xerr); + if (xmlGetLastError()) + xmlResetLastError(); Ctxp = NULL; } // endif Ctxp @@ -590,6 +588,7 @@ void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp) /******************************************************************/ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp) { + const xmlError *xerr; xmlNodeSetPtr nl; if (trace(1)) @@ -649,11 +648,11 @@ xmlNodeSetPtr LIBXMLDOC::GetNodeList(PGLOBAL g, xmlNodePtr np, char *xp) } else xmlXPathFreeObject(Xop); // Caused node not found - if ((Xerr = xmlGetLastError())) { - strcpy(g->Message, Xerr->message); - xmlResetError(Xerr); + if ((xerr = xmlGetLastError())) { + strcpy(g->Message, xerr->message); + xmlResetLastError(); return NULL; - } // endif Xerr + } // endif xerr } // endif Xop @@ -1079,7 +1078,7 @@ void XML2NODE::AddText(PGLOBAL g, PCSZ txtp) /******************************************************************/ void XML2NODE::DeleteChild(PGLOBAL g, PXNODE dnp) { - xmlErrorPtr xerr; + const xmlError *xerr; if (trace(1)) htrc("DeleteChild: node=%p\n", dnp); @@ -1122,7 +1121,7 @@ err: if (trace(1)) htrc("DeleteChild: errmsg=%-.256s\n", xerr->message); - xmlResetError(xerr); + xmlResetLastError(); } // end of DeleteChild /* -------------------- class XML2NODELIST ---------------------- */ diff --git a/storage/connect/mysql-test/connect/r/drop-open-error.result b/storage/connect/mysql-test/connect/r/drop-open-error.result index a5d1e89307b..f9b9b7e87d2 100644 --- a/storage/connect/mysql-test/connect/r/drop-open-error.result +++ b/storage/connect/mysql-test/connect/r/drop-open-error.result @@ -3,7 +3,7 @@ create table tcon engine=connect table_type=mysql CONNECTION='mysql://root@local ERROR HY000: Too long value for 'SRCDEF' drop table mdev9949; Warnings: -Warning 1017 Can't find file: 'MYSQLD_DATADIR/test/mdev9949.dos' (errno: 2 "No such file or directory") +Warning 1017 Can't find file: 'DATADIR/test/mdev9949.dos' (errno: 2 "No such file or directory") drop table t1; select @@secure_file_priv 'must be NULL'; must be NULL diff --git a/storage/connect/mysql-test/connect/r/mysql.result b/storage/connect/mysql-test/connect/r/mysql.result index 1dcbca88a7b..d1c68dcc96a 100644 --- a/storage/connect/mysql-test/connect/r/mysql.result +++ b/storage/connect/mysql-test/connect/r/mysql.result @@ -229,6 +229,7 @@ a 20 30 # Start of mysqldump ------ +/*!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `t2` ( diff --git a/storage/connect/mysql-test/connect/t/drop-open-error.test b/storage/connect/mysql-test/connect/t/drop-open-error.test index 69e634e82bd..dd286c96466 100644 --- a/storage/connect/mysql-test/connect/t/drop-open-error.test +++ b/storage/connect/mysql-test/connect/t/drop-open-error.test @@ -13,8 +13,9 @@ error ER_VALUE_TOO_LONG; create table tcon engine=connect table_type=mysql CONNECTION='mysql://root@localhost/test/t1' SRCDEF='select c from t1 where c in ("foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar", "foo", "bar", "qux", "foobar")'; # copy the invalid frm (as created by the statement above before the MDEV-9949 fix) +let $MARIADB_DATADIR=`select @@datadir`; copy_file $MTR_SUITE_DIR/std_data/mdev9949.frm $datadir/test/mdev9949.frm; ---replace_result $datadir MYSQLD_DATADIR/ ./ MYSQLD_DATADIR/ +--replace_result $MARIADB_DATADIR DATADIR/ './' 'DATADIR/' drop table mdev9949; drop table t1; diff --git a/storage/connect/tabmul.cpp b/storage/connect/tabmul.cpp index d0b7b3163b6..7e2857f17a0 100644 --- a/storage/connect/tabmul.cpp +++ b/storage/connect/tabmul.cpp @@ -125,8 +125,11 @@ PTDB TDBMUL::Duplicate(PGLOBAL g) /* have a LRECL that is the sum of the lengths of all components. */ /* This is why we use a big filename array to take care of that. */ /***********************************************************************/ + +PRAGMA_DISABLE_CHECK_STACK_FRAME + bool TDBMUL::InitFileNames(PGLOBAL g) - { +{ #define PFNZ 4096 #define FNSZ (_MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT) PTDBDIR dirp; @@ -234,6 +237,7 @@ bool TDBMUL::InitFileNames(PGLOBAL g) NumFiles = n; return false; } // end of InitFileNames +PRAGMA_REENABLE_CHECK_STACK_FRAME /***********************************************************************/ /* The table column list is the sub-table column list. */ diff --git a/storage/connect/unzip.c b/storage/connect/unzip.c index 909350435a5..de69f4b62eb 100644 --- a/storage/connect/unzip.c +++ b/storage/connect/unzip.c @@ -122,7 +122,7 @@ const char unz_copyright[] = " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; -/* unz_file_info_interntal contain internal info about a file in zipfile*/ +/* unz_file_info64_internal contain internal info about a file in zipfile*/ typedef struct unz_file_info64_internal_s { ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ @@ -542,7 +542,7 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) return 0; - /* number of the disk with the start of the zip64 end of central directory */ + /* number of the disk with the start of the zip64 end of central directory */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) return 0; if (uL != 0) @@ -590,10 +590,10 @@ local unzFile unzOpenInternal (const void *path, ZPOS64_T central_pos; uLong uL; - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ + uLong number_disk; /* number of the current disk, used for + spanning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the disk with central dir, used + for spanning ZIP, unsupported, always 0*/ ZPOS64_T number_entry_CD; /* total number of entries in the central dir (same than number_entry on nospan) */ diff --git a/storage/connect/unzip.h b/storage/connect/unzip.h index 2104e391507..ef0451098b1 100644 --- a/storage/connect/unzip.h +++ b/storage/connect/unzip.h @@ -306,7 +306,7 @@ extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, Get Info about the current file if pfile_info!=NULL, the *pfile_info structure will contain somes info about the current file - if szFileName!=NULL, the filemane string will be copied in szFileName + if szFileName!=NULL, the filename string will be copied in szFileName (fileNameBufferSize is the size of the buffer) if extraField!=NULL, the extra field information will be copied in extraField (extraFieldBufferSize is the size of the buffer). diff --git a/storage/connect/zip.c b/storage/connect/zip.c index 3d3d4caddef..523ea22299d 100644 --- a/storage/connect/zip.c +++ b/storage/connect/zip.c @@ -575,7 +575,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) return 0; - /* number of the disk with the start of the zip64 end of central directory */ + /* number of the disk with the start of the zip64 end of central directory */ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) return 0; if (uL != 0) @@ -614,9 +614,9 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { ZPOS64_T central_pos; uLong uL; - uLong number_disk; /* number of the current dist, used for + uLong number_disk; /* number of the current disk, used for spanning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used + uLong number_disk_with_CD; /* number of the disk with central dir, used for spanning ZIP, unsupported, always 0*/ ZPOS64_T number_entry; ZPOS64_T number_entry_CD; /* total number of entries in @@ -814,71 +814,66 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { /************************************************************/ extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) { - zip64_internal ziinit; zip64_internal* zi; int err=ZIP_OK; - ziinit.z_filefunc.zseek32_file = NULL; - ziinit.z_filefunc.ztell32_file = NULL; - if (pzlib_filefunc64_32_def==NULL) - fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); - else - ziinit.z_filefunc = *pzlib_filefunc64_32_def; + if (!(zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)))) + return NULL; - ziinit.filestream = ZOPEN64(ziinit.z_filefunc, + zi->z_filefunc.zseek32_file = NULL; + zi->z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&zi->z_filefunc.zfile_func64); + else + zi->z_filefunc = *pzlib_filefunc64_32_def; + + zi->filestream = ZOPEN64(zi->z_filefunc, pathname, (append == APPEND_STATUS_CREATE) ? (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); - if (ziinit.filestream == NULL) - return NULL; - - if (append == APPEND_STATUS_CREATEAFTER) - ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); - - ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); - ziinit.in_opened_file_inzip = 0; - ziinit.ci.stream_initialised = 0; - ziinit.number_entry = 0; - ziinit.add_position_when_writing_offset = 0; - init_linkedlist(&(ziinit.central_dir)); - - - - zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); - if (zi==NULL) + if (zi->filestream == NULL) { - ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); + free(zi); return NULL; } + if (append == APPEND_STATUS_CREATEAFTER) + ZSEEK64(zi->z_filefunc,zi->filestream,0,SEEK_END); + + zi->begin_pos = ZTELL64(zi->z_filefunc,zi->filestream); + zi->in_opened_file_inzip = 0; + zi->ci.stream_initialised = 0; + zi->number_entry = 0; + zi->add_position_when_writing_offset = 0; + init_linkedlist(&(zi->central_dir)); + /* now we add file in a zipfile */ # ifndef NO_ADDFILEINEXISTINGZIP - ziinit.globalcomment = NULL; + zi->globalcomment = NULL; if (append == APPEND_STATUS_ADDINZIP) { // Read and Cache Central Directory Records - err = LoadCentralDirectoryRecord(&ziinit); + err = LoadCentralDirectoryRecord(zi); } if (globalcomment) { - *globalcomment = ziinit.globalcomment; + *globalcomment = zi->globalcomment; } # endif /* !NO_ADDFILEINEXISTINGZIP*/ if (err != ZIP_OK) { # ifndef NO_ADDFILEINEXISTINGZIP - free(ziinit.globalcomment); + free(zi->globalcomment); # endif /* !NO_ADDFILEINEXISTINGZIP*/ free(zi); return NULL; } else { - *zi = ziinit; return (zipFile)zi; } } @@ -1027,7 +1022,6 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c int err = ZIP_OK; # ifdef NOCRYPT - (crcForCrypting); if (password != NULL) return ZIP_PARAMERROR; # endif @@ -1043,6 +1037,17 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c return ZIP_PARAMERROR; #endif + // The filename and comment length must fit in 16 bits. + if ((filename!=NULL) && (strlen(filename)>0xffff)) + return ZIP_PARAMERROR; + if ((comment!=NULL) && (strlen(comment)>0xffff)) + return ZIP_PARAMERROR; + // The extra field length must fit in 16 bits. If the member also requires + // a Zip64 extra block, that will also need to fit within that 16-bit + // length, but that will be checked for later. + if ((size_extrafield_local>0xffff) || (size_extrafield_global>0xffff)) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; if (zi->in_opened_file_inzip == 1) @@ -1597,7 +1602,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) { - // we can not write more data to the buffer that we have room for. + // we cannot write more data to the buffer that we have room for. return ZIP_BADZIPFILE; } @@ -1861,7 +1866,7 @@ extern int ZEXPORT zipClose(zipFile file, const char* global_comment) { free_linkedlist(&(zi->central_dir)); pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; - if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) + if(pos >= 0xffffffff || zi->number_entry >= 0xFFFF) { ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); diff --git a/storage/connect/zip.h b/storage/connect/zip.h index 5fc08413241..3e230d3405f 100644 --- a/storage/connect/zip.h +++ b/storage/connect/zip.h @@ -177,9 +177,9 @@ extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, filename : the filename in zip (if NULL, '-' without quote will be used *zipfi contain supplemental information if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local - contains the extrafield data the the local header + contains the extrafield data for the local header if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global - contains the extrafield data the the local header + contains the extrafield data for the global header if comment != NULL, comment contain the comment string method contain the compression method (0 for store, Z_DEFLATED for deflate) level contain the level of compression (can be Z_DEFAULT_COMPRESSION) diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index cc7dc79e508..187d65b050e 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -499,31 +499,22 @@ int ha_heap::external_lock(THD *thd, int lock_type) SYNOPSIS disable_indexes() - mode mode of operation: - HA_KEY_SWITCH_NONUNIQ disable all non-unique keys - HA_KEY_SWITCH_ALL disable all keys - HA_KEY_SWITCH_NONUNIQ_SAVE dis. non-uni. and make persistent - HA_KEY_SWITCH_ALL_SAVE dis. all keys and make persistent DESCRIPTION - Disable indexes and clear keys to use for scanning. - - IMPLEMENTATION - HA_KEY_SWITCH_NONUNIQ is not implemented. - HA_KEY_SWITCH_NONUNIQ_SAVE is not implemented with HEAP. - HA_KEY_SWITCH_ALL_SAVE is not implemented with HEAP. + See handler::ha_disable_indexes() RETURN 0 ok HA_ERR_WRONG_COMMAND mode not implemented. */ -int ha_heap::disable_indexes(uint mode) +int ha_heap::disable_indexes(key_map map, bool persist) { int error; - if (mode == HA_KEY_SWITCH_ALL) + if (!persist) { + DBUG_ASSERT(map.is_clear_all()); if (!(error= heap_disable_indexes(file))) set_keys_for_scanning(); } @@ -541,11 +532,6 @@ int ha_heap::disable_indexes(uint mode) SYNOPSIS enable_indexes() - mode mode of operation: - HA_KEY_SWITCH_NONUNIQ enable all non-unique keys - HA_KEY_SWITCH_ALL enable all keys - HA_KEY_SWITCH_NONUNIQ_SAVE en. non-uni. and make persistent - HA_KEY_SWITCH_ALL_SAVE en. all keys and make persistent DESCRIPTION Enable indexes and set keys to use for scanning. @@ -554,10 +540,7 @@ int ha_heap::disable_indexes(uint mode) since the heap storage engine cannot repair the indexes. To be sure, call handler::delete_all_rows() before. - IMPLEMENTATION - HA_KEY_SWITCH_NONUNIQ is not implemented. - HA_KEY_SWITCH_NONUNIQ_SAVE is not implemented with HEAP. - HA_KEY_SWITCH_ALL_SAVE is not implemented with HEAP. + See also handler::ha_enable_indexes() RETURN 0 ok @@ -565,12 +548,13 @@ int ha_heap::disable_indexes(uint mode) HA_ERR_WRONG_COMMAND mode not implemented. */ -int ha_heap::enable_indexes(uint mode) +int ha_heap::enable_indexes(key_map map, bool persist) { int error; - if (mode == HA_KEY_SWITCH_ALL) + if (!persist) { + DBUG_ASSERT(map.is_prefix(table->s->keys)); if (!(error= heap_enable_indexes(file))) set_keys_for_scanning(); } diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h index eed91176136..837eae15fee 100644 --- a/storage/heap/ha_heap.h +++ b/storage/heap/ha_heap.h @@ -99,8 +99,8 @@ public: int external_lock(THD *thd, int lock_type) override; int delete_all_rows(void) override; int reset_auto_increment(ulonglong value) override; - int disable_indexes(uint mode) override; - int enable_indexes(uint mode) override; + int disable_indexes(key_map map, bool persist) override; + int enable_indexes(key_map map, bool persist) override; int indexes_are_disabled(void) override; ha_rows records_in_range(uint inx, const key_range *start_key, const key_range *end_key, page_range *pages) override; diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 7ae0454aa0c..84fb684574e 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -48,6 +48,13 @@ IF(UNIX) IF(HAVE_LIBNUMA) LINK_LIBRARIES(numa) ENDIF() + IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + IF(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch|AARCH|p(ower)?pc|x86_|amd)64") + OPTION(WITH_INNODB_PMEM "Support memory-mapped InnoDB redo log" ON) + ELSE() # Disable by default on ISA that are not covered by our CI + OPTION(WITH_INNODB_PMEM "Support memory-mapped InnoDB redo log" OFF) + ENDIF() + ENDIF() ENDIF() ENDIF() @@ -71,7 +78,7 @@ ADD_FEATURE_INFO(INNODB_ROOT_GUESS WITH_INNODB_ROOT_GUESS OPTION(WITH_INNODB_EXTRA_DEBUG "Enable extra InnoDB debug checks" OFF) IF(WITH_INNODB_EXTRA_DEBUG) - ADD_DEFINITIONS(-DUNIV_ZIP_DEBUG) + ADD_DEFINITIONS(-DUNIV_ZIP_DEBUG -DLOG_LATCH_DEBUG) ENDIF() ADD_FEATURE_INFO(INNODB_EXTRA_DEBUG WITH_INNODB_EXTRA_DEBUG "Extra InnoDB debug checks") @@ -132,7 +139,6 @@ SET(INNOBASE_SOURCES btr/btr0cur.cc btr/btr0pcur.cc btr/btr0sea.cc - buf/buf0block_hint.cc buf/buf0buddy.cc buf/buf0buf.cc buf/buf0dblwr.cc @@ -423,26 +429,16 @@ SET(INNOBASE_SOURCES ut/ut0vec.cc ut/ut0wqueue.cc) -OPTION(WITH_PMEM "Support redo log in persistent memory" OFF) -FIND_PACKAGE(PMEM) -IF(PMEM_FOUND) - INCLUDE_DIRECTORIES(${PMEM_INCLUDES}) - ADD_COMPILE_FLAGS(log/log0log.cc log/log0recv.cc - buf/buf0flu.cc mtr/mtr0mtr.cc trx/trx0trx.cc srv/srv0start.cc - COMPILE_FLAGS "-DHAVE_PMEM") - SET(PMEM_LIBRARY ${PMEM_LIBRARIES}) -ELSE() - IF(WITH_PMEM) - MESSAGE(FATAL_ERROR "WITH_PMEM=ON cannot be satisfied") - ENDIF() +IF(WITH_INNODB_PMEM) + ADD_DEFINITIONS(-DHAVE_PMEM) + SET(INNOBASE_SOURCES ${INNOBASE_SOURCES} include/cache.h sync/cache.cc) ENDIF() MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE MODULE_OUTPUT_NAME ha_innodb DEFAULT RECOMPILE_FOR_EMBEDDED LINK_LIBRARIES - ${ZLIB_LIBRARY} - ${PMEM_LIBRARY} + ${ZLIB_LIBRARIES} ${NUMA_LIBRARY} ${LIBSYSTEMD} ${LINKER_SCRIPT}) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index ef57989bf2e..45207d9d02d 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -260,6 +260,8 @@ btr_root_block_get( mtr_t* mtr, /*!< in: mtr */ dberr_t* err) /*!< out: error code */ { + ut_ad(mode != RW_NO_LATCH); + if (!index->table || !index->table->space) { *err= DB_TABLESPACE_NOT_FOUND; @@ -281,13 +283,12 @@ btr_root_block_get( if (UNIV_LIKELY(block != nullptr)) { - if (UNIV_UNLIKELY(mode == RW_NO_LATCH)); - else if (!!page_is_comp(block->page.frame) != - index->table->not_redundant() || - btr_page_get_index_id(block->page.frame) != index->id || - !fil_page_index_page_check(block->page.frame) || - index->is_spatial() != - (fil_page_get_type(block->page.frame) == FIL_PAGE_RTREE)) + if (!!page_is_comp(block->page.frame) != + index->table->not_redundant() || + btr_page_get_index_id(block->page.frame) != index->id || + !fil_page_index_page_check(block->page.frame) || + index->is_spatial() != + (fil_page_get_type(block->page.frame) == FIL_PAGE_RTREE)) { *err= DB_PAGE_CORRUPTED; block= nullptr; @@ -530,6 +531,31 @@ btr_block_reget(mtr_t *mtr, const dict_index_t &index, return btr_block_get(index, id.page_no(), RW_X_LATCH, mtr, err); } +static MY_ATTRIBUTE((nonnull, warn_unused_result)) +/** Acquire a latch on the index root page for allocating or freeing pages. +@param index index tree +@param mtr mini-transaction +@param err error code +@return root page +@retval nullptr if an error occurred */ +buf_block_t *btr_root_block_sx(dict_index_t *index, mtr_t *mtr, dberr_t *err) +{ + buf_block_t *root= + mtr->get_already_latched(page_id_t{index->table->space_id, index->page}, + MTR_MEMO_PAGE_SX_FIX); + if (!root) + { + root= btr_root_block_get(index, RW_SX_LATCH, mtr, err); + if (UNIV_UNLIKELY(!root)) + return root; + } +#ifdef BTR_CUR_HASH_ADAPT + else + ut_ad(!root->index || !root->index->freed()); +#endif + return root; +} + /**************************************************************//** Allocates a new file page to be used in an index tree. NOTE: we assume that the caller has made the reservation for free extents! @@ -552,21 +578,9 @@ btr_page_alloc( { ut_ad(level < BTR_MAX_NODE_LEVEL); - const auto savepoint= mtr->get_savepoint(); - buf_block_t *root= btr_root_block_get(index, RW_NO_LATCH, mtr, err); + buf_block_t *root= btr_root_block_sx(index, mtr, err); if (UNIV_UNLIKELY(!root)) return root; - - const bool have_latch= mtr->have_u_or_x_latch(*root); -#ifdef BTR_CUR_HASH_ADAPT - ut_ad(!have_latch || !root->index || !root->index->freed()); -#endif - mtr->rollback_to_savepoint(savepoint); - - if (!have_latch && - UNIV_UNLIKELY(!(root= btr_root_block_get(index, RW_SX_LATCH, mtr, err)))) - return root; - fseg_header_t *seg_header= root->page.frame + (level ? PAGE_HEADER + PAGE_BTR_SEG_TOP : PAGE_HEADER + PAGE_BTR_SEG_LEAF); return fseg_alloc_free_page_general(seg_header, hint_page_no, file_direction, @@ -608,24 +622,16 @@ dberr_t btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr, fil_space_t *space= index->table->space; dberr_t err; - const auto savepoint= mtr->get_savepoint(); - if (buf_block_t *root= btr_root_block_get(index, RW_NO_LATCH, mtr, &err)) + if (buf_block_t *root= btr_root_block_sx(index, mtr, &err)) { - const bool have_latch= mtr->have_u_or_x_latch(*root); -#ifdef BTR_CUR_HASH_ADAPT - ut_ad(!have_latch || !root->index || !root->index->freed()); -#endif - mtr->rollback_to_savepoint(savepoint); - if (have_latch || - (root= btr_root_block_get(index, RW_SX_LATCH, mtr, &err))) - err= fseg_free_page(&root->page.frame[blob || - page_is_leaf(block->page.frame) - ? PAGE_HEADER + PAGE_BTR_SEG_LEAF - : PAGE_HEADER + PAGE_BTR_SEG_TOP], - space, page, mtr, space_latched); + err= fseg_free_page(&root->page.frame[blob || + page_is_leaf(block->page.frame) + ? PAGE_HEADER + PAGE_BTR_SEG_LEAF + : PAGE_HEADER + PAGE_BTR_SEG_TOP], + space, page, mtr, space_latched); + if (err == DB_SUCCESS) + buf_page_free(space, page, mtr); } - if (err == DB_SUCCESS) - buf_page_free(space, page, mtr); /* The page was marked free in the allocation bitmap, but it should remain exclusively latched until mtr_t::commit() or until it @@ -1157,54 +1163,71 @@ btr_read_autoinc(dict_index_t* index) return autoinc; } +dict_index_t *dict_table_t::get_index(const dict_col_t &col) const +{ + dict_index_t *index= dict_table_get_first_index(this); + + while (index && (index->fields[0].col != &col || index->is_corrupted())) + index= dict_table_get_next_index(index); + + return index; +} + /** Read the last used AUTO_INCREMENT value from PAGE_ROOT_AUTO_INC, or fall back to MAX(auto_increment_column). -@param[in] table table containing an AUTO_INCREMENT column -@param[in] col_no index of the AUTO_INCREMENT column -@return the AUTO_INCREMENT value -@retval 0 on error or if no AUTO_INCREMENT value was used yet */ -ib_uint64_t -btr_read_autoinc_with_fallback(const dict_table_t* table, unsigned col_no) +@param table table containing an AUTO_INCREMENT column +@param col_no index of the AUTO_INCREMENT column +@param mysql_version TABLE_SHARE::mysql_version +@param max the maximum value of the AUTO_INCREMENT column +@return the AUTO_INCREMENT value +@retval 0 on error or if no AUTO_INCREMENT value was used yet */ +uint64_t btr_read_autoinc_with_fallback(const dict_table_t *table, + unsigned col_no, ulong mysql_version, + uint64_t max) { - ut_ad(table->persistent_autoinc); - ut_ad(!table->is_temporary()); + ut_ad(table->persistent_autoinc); + ut_ad(!table->is_temporary()); - dict_index_t* index = dict_table_get_first_index(table); + uint64_t autoinc= 0; + mtr_t mtr; + mtr.start(); - if (index == NULL) { - return 0; - } + if (buf_block_t *block= + buf_page_get(page_id_t(table->space_id, + dict_table_get_first_index(table)->page), + table->space->zip_size(), RW_SX_LATCH, &mtr)) + { + autoinc= page_get_autoinc(block->page.frame); - mtr_t mtr; - mtr.start(); - buf_block_t* block = buf_page_get( - page_id_t(index->table->space_id, index->page), - index->table->space->zip_size(), - RW_S_LATCH, &mtr); + if (autoinc > 0 && autoinc <= max && mysql_version >= 100210); + else if (dict_index_t *index= + table->get_index(*dict_table_get_nth_col(table, col_no))) + { + /* Read MAX(autoinc_col), in case this table had originally been + created before MariaDB 10.2.4 introduced persistent AUTO_INCREMENT + and MariaDB 10.2.10 fixed MDEV-12123, and there could be a garbage + value in the PAGE_ROOT_AUTO_INC field. */ + const uint64_t max_autoinc= row_search_max_autoinc(index); + const bool need_adjust{autoinc > max || autoinc < max_autoinc}; + ut_ad(max_autoinc <= max); - ib_uint64_t autoinc = block - ? page_get_autoinc(block->page.frame) : 0; - const bool retry = block && autoinc == 0 - && !page_is_empty(block->page.frame); - mtr.commit(); + if (UNIV_UNLIKELY(need_adjust) && !high_level_read_only && !opt_readonly) + { + sql_print_information("InnoDB: Resetting PAGE_ROOT_AUTO_INC from " + UINT64PF " to " UINT64PF + " on table %`.*s.%`s (created with version %lu)", + autoinc, max_autoinc, + int(table->name.dblen()), table->name.m_name, + table->name.basename(), mysql_version); + autoinc= max_autoinc; + index->set_modified(mtr); + page_set_autoinc(block, max_autoinc, &mtr, true); + } + } + } - if (retry) { - /* This should be an old data file where - PAGE_ROOT_AUTO_INC was initialized to 0. - Fall back to reading MAX(autoinc_col). - There should be an index on it. */ - const dict_col_t* autoinc_col - = dict_table_get_nth_col(table, col_no); - while (index && index->fields[0].col != autoinc_col) { - index = dict_table_get_next_index(index); - } - - if (index) { - autoinc = row_search_max_autoinc(index); - } - } - - return autoinc; + mtr.commit(); + return autoinc; } /** Write the next available AUTO_INCREMENT value to PAGE_ROOT_AUTO_INC. diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc index b9ea48af9f8..094d7570dc0 100644 --- a/storage/innobase/btr/btr0bulk.cc +++ b/storage/innobase/btr/btr0bulk.cc @@ -833,7 +833,7 @@ PageBulk::release() m_block->page.fix(); /* No other threads can modify this block. */ - m_modify_clock = buf_block_get_modify_clock(m_block); + m_modify_clock = m_block->modify_clock; m_mtr.commit(); } diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index fb0efe08130..799a8575a83 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -805,7 +805,7 @@ static ulint btr_node_ptr_max_size(const dict_index_t* index) /* Determine the maximum length of the index field. */ field_max_size = dict_col_get_fixed_size(col, comp); - if (field_max_size) { + if (field_max_size && field->fixed_len) { /* dict_index_add_col() should guarantee this */ ut_ad(!field->prefix_len || field->fixed_len == field->prefix_len); @@ -923,7 +923,7 @@ static inline page_cur_mode_t btr_cur_nonleaf_mode(page_cur_mode_t mode) return PAGE_CUR_LE; } -static MY_ATTRIBUTE((nonnull)) +MY_ATTRIBUTE((nonnull,warn_unused_result)) /** Acquire a latch on the previous page without violating the latching order. @param block index page @param page_id page identifier with valid space identifier @@ -934,8 +934,9 @@ static MY_ATTRIBUTE((nonnull)) @retval 0 if an error occurred @retval 1 if the page could be latched in the wrong order @retval -1 if the latch on block was temporarily released */ -int btr_latch_prev(buf_block_t *block, page_id_t page_id, ulint zip_size, - rw_lock_type_t rw_latch, mtr_t *mtr, dberr_t *err) +static int btr_latch_prev(buf_block_t *block, page_id_t page_id, + ulint zip_size, + rw_lock_type_t rw_latch, mtr_t *mtr, dberr_t *err) { ut_ad(rw_latch == RW_S_LATCH || rw_latch == RW_X_LATCH); ut_ad(page_id.space() == block->page.id().space()); @@ -943,46 +944,80 @@ int btr_latch_prev(buf_block_t *block, page_id_t page_id, ulint zip_size, const auto prev_savepoint= mtr->get_savepoint(); ut_ad(block == mtr->at_savepoint(prev_savepoint - 1)); - page_id.set_page_no(btr_page_get_prev(block->page.frame)); + const page_t *const page= block->page.frame; + page_id.set_page_no(btr_page_get_prev(page)); + /* We are holding a latch on the current page. + + We will start by buffer-fixing the left sibling. Waiting for a latch + on it while holding a latch on the current page could lead to a + deadlock, because another thread could hold that latch and wait for + a right sibling page latch (the current page). + + If there is a conflict, we will temporarily release our latch on the + current block while waiting for a latch on the left sibling. The + buffer-fixes on both blocks will prevent eviction. */ + + retry: buf_block_t *prev= buf_page_get_gen(page_id, zip_size, RW_NO_LATCH, nullptr, BUF_GET, mtr, err); if (UNIV_UNLIKELY(!prev)) return 0; int ret= 1; - if (UNIV_UNLIKELY(rw_latch == RW_S_LATCH)) + static_assert(MTR_MEMO_PAGE_S_FIX == mtr_memo_type_t(BTR_SEARCH_LEAF), ""); + static_assert(MTR_MEMO_PAGE_X_FIX == mtr_memo_type_t(BTR_MODIFY_LEAF), ""); + + if (rw_latch == RW_S_LATCH + ? prev->page.lock.s_lock_try() : prev->page.lock.x_lock_try()) { - if (UNIV_LIKELY(prev->page.lock.s_lock_try())) + mtr->lock_register(prev_savepoint, mtr_memo_type_t(rw_latch)); + if (UNIV_UNLIKELY(prev->page.id() != page_id)) { - mtr->lock_register(prev_savepoint, MTR_MEMO_PAGE_S_FIX); - goto prev_latched; + fail: + /* the page was just read and found to be corrupted */ + mtr->rollback_to_savepoint(prev_savepoint); + return 0; } - block->page.lock.s_unlock(); } else { - if (UNIV_LIKELY(prev->page.lock.x_lock_try())) + ut_ad(mtr->at_savepoint(mtr->get_savepoint() - 1)->page.id() == page_id); + mtr->release_last_page(); + if (rw_latch == RW_S_LATCH) + block->page.lock.s_unlock(); + else + block->page.lock.x_unlock(); + + prev= buf_page_get_gen(page_id, zip_size, rw_latch, prev, + BUF_GET, mtr, err); + if (rw_latch == RW_S_LATCH) + block->page.lock.s_lock(); + else + block->page.lock.x_lock(); + + const page_id_t prev_page_id= page_id; + page_id.set_page_no(btr_page_get_prev(page)); + + if (UNIV_UNLIKELY(page_id != prev_page_id)) { - mtr->lock_register(prev_savepoint, MTR_MEMO_PAGE_X_FIX); - goto prev_latched; + mtr->release_last_page(); + if (page_id.page_no() == FIL_NULL) + return -1; + goto retry; } - block->page.lock.x_unlock(); + + if (UNIV_UNLIKELY(!prev)) + goto fail; + + ret= -1; } - ret= -1; - mtr->lock_register(prev_savepoint - 1, MTR_MEMO_BUF_FIX); - mtr->rollback_to_savepoint(prev_savepoint); - prev= buf_page_get_gen(page_id, zip_size, rw_latch, prev, BUF_GET, mtr, err); - if (UNIV_UNLIKELY(!prev)) - return 0; - mtr->upgrade_buffer_fix(prev_savepoint - 1, rw_latch); - - prev_latched: - if (memcmp_aligned<2>(FIL_PAGE_TYPE + prev->page.frame, - FIL_PAGE_TYPE + block->page.frame, 2) || - memcmp_aligned<2>(PAGE_HEADER + PAGE_INDEX_ID + prev->page.frame, - PAGE_HEADER + PAGE_INDEX_ID + block->page.frame, 8) || - page_is_comp(prev->page.frame) != page_is_comp(block->page.frame)) + const page_t *const p= prev->page.frame; + if (memcmp_aligned<4>(FIL_PAGE_NEXT + p, FIL_PAGE_OFFSET + page, 4) || + memcmp_aligned<2>(FIL_PAGE_TYPE + p, FIL_PAGE_TYPE + page, 2) || + memcmp_aligned<2>(PAGE_HEADER + PAGE_INDEX_ID + p, + PAGE_HEADER + PAGE_INDEX_ID + page, 8) || + page_is_comp(p) != page_is_comp(page)) { ut_ad("corrupted" == 0); // FIXME: remove this *err= DB_CORRUPTION; @@ -5791,7 +5826,6 @@ btr_store_big_rec_extern_fields( for (ulint blob_npages = 0;; ++blob_npages) { buf_block_t* block; const ulint commit_freq = 4; - uint32_t r_extents; ut_ad(page_align(field_ref) == page_align(rec)); @@ -5826,22 +5860,14 @@ btr_store_big_rec_extern_fields( hint_prev = rec_block->page.id().page_no(); } - error = fsp_reserve_free_extents( - &r_extents, index->table->space, 1, - FSP_BLOB, &mtr, 1); - if (UNIV_UNLIKELY(error != DB_SUCCESS)) { -alloc_fail: - mtr.commit(); - goto func_exit; - } - block = btr_page_alloc(index, hint_prev + 1, FSP_NO_DIR, 0, &mtr, &mtr, &error); - index->table->space->release_free_extents(r_extents); if (!block) { - goto alloc_fail; +alloc_fail: + mtr.commit(); + goto func_exit; } const uint32_t space_id = block->page.id().space(); diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc index 0bf279ab371..61afa3c9132 100644 --- a/storage/innobase/btr/btr0pcur.cc +++ b/storage/innobase/btr/btr0pcur.cc @@ -173,10 +173,8 @@ before_first: cursor->old_n_fields, &cursor->old_rec_buf, &cursor->buf_size); - cursor->block_when_stored.store(block); - - /* Function try to check if block is S/X latch. */ - cursor->modify_clock = buf_block_get_modify_clock(block); + cursor->old_page_id = block->page.id(); + cursor->modify_clock = block->modify_clock; } /**************************************************************//** @@ -208,101 +206,80 @@ btr_pcur_copy_stored_position( } /** Optimistically latches the leaf page or pages requested. -@param[in] block guessed buffer block -@param[in,out] pcur cursor -@param[in,out] latch_mode BTR_SEARCH_LEAF, ... -@param[in,out] mtr mini-transaction -@return true if success */ +@param pcur persistent cursor +@param latch_mode BTR_SEARCH_LEAF, ... +@param mtr mini-transaction +@return true on success */ TRANSACTIONAL_TARGET -static bool btr_pcur_optimistic_latch_leaves(buf_block_t *block, - btr_pcur_t *pcur, +static bool btr_pcur_optimistic_latch_leaves(btr_pcur_t *pcur, btr_latch_mode *latch_mode, mtr_t *mtr) { - ut_ad(block->page.buf_fix_count()); - ut_ad(block->page.in_file()); - ut_ad(block->page.frame); - static_assert(BTR_SEARCH_PREV & BTR_SEARCH_LEAF, ""); static_assert(BTR_MODIFY_PREV & BTR_MODIFY_LEAF, ""); static_assert((BTR_SEARCH_PREV ^ BTR_MODIFY_PREV) == (RW_S_LATCH ^ RW_X_LATCH), ""); + buf_block_t *const block= + buf_page_optimistic_fix(pcur->btr_cur.page_cur.block, pcur->old_page_id); + + if (!block) + return false; + + if (*latch_mode == BTR_SEARCH_LEAF || *latch_mode == BTR_MODIFY_LEAF) + return buf_page_optimistic_get(block, rw_lock_type_t(*latch_mode), + pcur->modify_clock, mtr); + + ut_ad(*latch_mode == BTR_SEARCH_PREV || *latch_mode == BTR_MODIFY_PREV); const rw_lock_type_t mode= rw_lock_type_t(*latch_mode & (RW_X_LATCH | RW_S_LATCH)); - switch (*latch_mode) { - default: - ut_ad(*latch_mode == BTR_SEARCH_LEAF || *latch_mode == BTR_MODIFY_LEAF); - return buf_page_optimistic_get(mode, block, pcur->modify_clock, mtr); - case BTR_SEARCH_PREV: - case BTR_MODIFY_PREV: - page_id_t id{0}; - uint32_t left_page_no; - ulint zip_size; - buf_block_t *left_block= nullptr; - { - transactional_shared_lock_guard g{block->page.lock}; - if (block->modify_clock != pcur->modify_clock) - return false; - id= block->page.id(); - zip_size= block->zip_size(); - left_page_no= btr_page_get_prev(block->page.frame); - } + uint64_t modify_clock; + uint32_t left_page_no; + const page_t *const page= block->page.frame; + { + transactional_shared_lock_guard g{block->page.lock}; + modify_clock= block->modify_clock; + left_page_no= btr_page_get_prev(page); + } - if (left_page_no != FIL_NULL) - { - left_block= - buf_page_get_gen(page_id_t(id.space(), left_page_no), zip_size, - mode, nullptr, BUF_GET_POSSIBLY_FREED, mtr); + const auto savepoint= mtr->get_savepoint(); + mtr->memo_push(block, MTR_MEMO_BUF_FIX); - if (!left_block); - else if (btr_page_get_next(left_block->page.frame) != id.page_no()) - { -release_left_block: - mtr->release_last_page(); - return false; - } - else - buf_page_make_young_if_needed(&left_block->page); - } - - if (buf_page_optimistic_get(mode, block, pcur->modify_clock, mtr)) - { - if (btr_page_get_prev(block->page.frame) == left_page_no) - { - /* block was already buffer-fixed while entering the function and - buf_page_optimistic_get() buffer-fixes it again. */ - ut_ad(2 <= block->page.buf_fix_count()); - *latch_mode= btr_latch_mode(mode); - return true; - } - - mtr->release_last_page(); - } - - ut_ad(block->page.buf_fix_count()); - if (left_block) - goto release_left_block; + if (UNIV_UNLIKELY(modify_clock != pcur->modify_clock)) + { + fail: + mtr->rollback_to_savepoint(savepoint); return false; } -} -/** Structure acts as functor to do the latching of leaf pages. -It returns true if latching of leaf pages succeeded and false -otherwise. */ -struct optimistic_latch_leaves -{ - btr_pcur_t *const cursor; - btr_latch_mode *const latch_mode; - mtr_t *const mtr; - - bool operator()(buf_block_t *hint) const + buf_block_t *prev; + if (left_page_no != FIL_NULL) { - return hint && - btr_pcur_optimistic_latch_leaves(hint, cursor, latch_mode, mtr); + prev= buf_page_get_gen(page_id_t(pcur->old_page_id.space(), + left_page_no), block->zip_size(), + mode, nullptr, BUF_GET_POSSIBLY_FREED, mtr); + if (!prev || + page_is_comp(prev->page.frame) != page_is_comp(block->page.frame) || + memcmp_aligned<2>(block->page.frame, prev->page.frame, 2) || + memcmp_aligned<2>(block->page.frame + PAGE_HEADER + PAGE_INDEX_ID, + prev->page.frame + PAGE_HEADER + PAGE_INDEX_ID, 8)) + goto fail; } -}; + else + prev= nullptr; + + mtr->upgrade_buffer_fix(savepoint, mode); + + if (UNIV_UNLIKELY(block->modify_clock != modify_clock) || + UNIV_UNLIKELY(block->page.is_freed()) || + (prev && + memcmp_aligned<4>(FIL_PAGE_NEXT + prev->page.frame, + FIL_PAGE_OFFSET + page, 4))) + goto fail; + + return true; +} /** Restores the stored position of a persistent cursor bufferfixing the page and obtaining the specified latches. If the cursor position @@ -325,6 +302,7 @@ btr_pcur_t::SAME_UNIQ cursor position is on user rec and points on the record with the same unique field values as in the stored record, btr_pcur_t::NOT_SAME cursor position is not on user rec or points on the record with not the samebuniq field values as in the stored */ +TRANSACTIONAL_TARGET btr_pcur_t::restore_status btr_pcur_t::restore_position(btr_latch_mode restore_latch_mode, mtr_t *mtr) { @@ -355,7 +333,6 @@ btr_pcur_t::restore_position(btr_latch_mode restore_latch_mode, mtr_t *mtr) latch_mode = BTR_LATCH_MODE_WITHOUT_INTENTION(restore_latch_mode); pos_state = BTR_PCUR_IS_POSITIONED; - block_when_stored.clear(); return restore_status::NOT_SAME; } @@ -372,9 +349,8 @@ btr_pcur_t::restore_position(btr_latch_mode restore_latch_mode, mtr_t *mtr) case BTR_SEARCH_PREV: case BTR_MODIFY_PREV: /* Try optimistic restoration. */ - if (block_when_stored.run_with_hint( - optimistic_latch_leaves{this, &restore_latch_mode, - mtr})) { + if (btr_pcur_optimistic_latch_leaves(this, &restore_latch_mode, + mtr)) { pos_state = BTR_PCUR_IS_POSITIONED; latch_mode = restore_latch_mode; @@ -479,16 +455,22 @@ btr_pcur_t::restore_position(btr_latch_mode restore_latch_mode, mtr_t *mtr) since the cursor can now be on a different page! But we can retain the value of old_rec */ - block_when_stored.store(btr_pcur_get_block(this)); - modify_clock= buf_block_get_modify_clock( - block_when_stored.block()); + old_page_id = btr_cur.page_cur.block->page.id(); + modify_clock = btr_cur.page_cur.block->modify_clock; mem_heap_free(heap); return restore_status::SAME_ALL; } - if (n_matched_fields >= index->n_uniq) - ret_val= restore_status::SAME_UNIQ; + if (n_matched_fields >= index->n_uniq + /* Unique indexes can contain "NULL" keys, and if all + unique fields are NULL and not all tuple + fields match to record fields, then treat it as if + restored cursor position points to the record with + not the same unique key. */ + && !(index->n_nullable + && dtuple_contains_null(tuple, index->n_uniq))) + ret_val= restore_status::SAME_UNIQ; } mem_heap_free(heap); @@ -605,40 +587,33 @@ btr_pcur_move_backward_from_page( return true; } - buf_block_t* block = btr_pcur_get_block(cursor); + buf_block_t* block = mtr->at_savepoint(0); + ut_ad(block == btr_pcur_get_block(cursor)); + const page_t* const page = block->page.frame; + /* btr_pcur_optimistic_latch_leaves() will acquire a latch on + the preceding page if one exists; + if that fails, btr_cur_t::search_leaf() invoked by + btr_pcur_open_with_no_init() will also acquire a latch on the + succeeding page. Our caller only needs one page latch. */ + ut_ad(mtr->get_savepoint() <= 3); - if (page_has_prev(block->page.frame)) { - buf_block_t* left_block - = mtr->at_savepoint(mtr->get_savepoint() - 1); - const page_t* const left = left_block->page.frame; - if (memcmp_aligned<4>(left + FIL_PAGE_NEXT, - block->page.frame - + FIL_PAGE_OFFSET, 4)) { - /* This should be the right sibling page, or - if there is none, the current block. */ - ut_ad(left_block == block - || !memcmp_aligned<4>(left + FIL_PAGE_PREV, - block->page.frame - + FIL_PAGE_OFFSET, 4)); - /* The previous one must be the left sibling. */ - left_block - = mtr->at_savepoint(mtr->get_savepoint() - 2); - ut_ad(!memcmp_aligned<4>(left_block->page.frame - + FIL_PAGE_NEXT, - block->page.frame - + FIL_PAGE_OFFSET, 4)); - } + if (page_has_prev(page)) { + buf_block_t* const left_block = mtr->at_savepoint(1); + ut_ad(!memcmp_aligned<4>(page + FIL_PAGE_OFFSET, + left_block->page.frame + + FIL_PAGE_NEXT, 4)); if (btr_pcur_is_before_first_on_page(cursor)) { + /* Reposition on the previous page. */ page_cur_set_after_last(left_block, &cursor->btr_cur.page_cur); /* Release the right sibling. */ - } else { - /* Release the left sibling. */ + mtr->rollback_to_savepoint(0, 1); block = left_block; } - mtr->release(*block); } + mtr->rollback_to_savepoint(1); + ut_ad(block == mtr->at_savepoint(0)); cursor->latch_mode = latch_mode; cursor->old_rec = nullptr; return false; diff --git a/storage/innobase/buf/buf0block_hint.cc b/storage/innobase/buf/buf0block_hint.cc deleted file mode 100644 index 6bd01faa279..00000000000 --- a/storage/innobase/buf/buf0block_hint.cc +++ /dev/null @@ -1,59 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2020, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2020, 2021, MariaDB Corporation. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License, version 2.0, as published by the -Free Software Foundation. - -This program is also distributed with certain software (including but not -limited to OpenSSL) that is licensed under separate terms, as designated in a -particular file or component or in included license documentation. The authors -of MySQL hereby grant you an additional permission to link the program and -your derivative works with the separately licensed software that they have -included with MySQL. - -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, version 2.0, -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., -51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ - -#include "buf0block_hint.h" -namespace buf { - -TRANSACTIONAL_TARGET -void Block_hint::buffer_fix_block_if_still_valid() -{ - /* To check if m_block belongs to the current buf_pool, we must - prevent freeing memory while we check, and until we buffer-fix the - block. For this purpose it is enough to latch any of the many - latches taken by buf_pool_t::resize(). - - Similar to buf_page_optimistic_get(), we must validate - m_block->page.id() after acquiring the hash_lock, because the object - may have been freed and not actually attached to buf_pool.page_hash - at the moment. (The block could have been reused to store a - different page, and that slice of buf_pool.page_hash could be protected - by another hash_lock that we are not holding.) - - Finally, we must ensure that the block is not being freed. */ - if (m_block) - { - auto &cell= buf_pool.page_hash.cell_get(m_page_id.fold()); - transactional_shared_lock_guard g - {buf_pool.page_hash.lock_get(cell)}; - if (buf_pool.is_uncompressed(m_block) && m_page_id == m_block->page.id() && - m_block->page.frame && m_block->page.in_file()) - m_block->page.fix(); - else - clear(); - } -} -} // namespace buf diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index bd29af78092..43401e9df2c 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -76,6 +76,8 @@ struct set_numa_interleave_t if (srv_numa_interleave) { struct bitmask *numa_mems_allowed = numa_get_mems_allowed(); + MEM_MAKE_DEFINED(numa_mems_allowed, + sizeof *numa_mems_allowed); ib::info() << "Setting NUMA memory policy to" " MPOL_INTERLEAVE"; if (set_mempolicy(MPOL_INTERLEAVE, @@ -1062,6 +1064,7 @@ inline bool buf_pool_t::chunk_t::create(size_t bytes) if (srv_numa_interleave) { struct bitmask *numa_mems_allowed= numa_get_mems_allowed(); + MEM_MAKE_DEFINED(numa_mems_allowed, sizeof *numa_mems_allowed); if (mbind(mem, mem_size(), MPOL_INTERLEAVE, numa_mems_allowed->maskp, numa_mems_allowed->size, MPOL_MF_MOVE)) @@ -1591,17 +1594,14 @@ inline bool buf_pool_t::withdraw_blocks() /* reserve free_list length */ if (UT_LIST_GET_LEN(withdraw) < withdraw_target) { - buf_flush_LRU( - std::max(withdraw_target - - UT_LIST_GET_LEN(withdraw), - srv_LRU_scan_depth), - true); - mysql_mutex_unlock(&buf_pool.mutex); - buf_dblwr.flush_buffered_writes(); - mysql_mutex_lock(&buf_pool.flush_list_mutex); - buf_flush_wait_LRU_batch_end(); - mysql_mutex_unlock(&buf_pool.flush_list_mutex); - mysql_mutex_lock(&buf_pool.mutex); + try_LRU_scan = false; + mysql_mutex_unlock(&mutex); + mysql_mutex_lock(&flush_list_mutex); + page_cleaner_wakeup(true); + my_cond_wait(&done_flush_list, + &flush_list_mutex.m_mutex); + mysql_mutex_unlock(&flush_list_mutex); + mysql_mutex_lock(&mutex); } /* relocate blocks/buddies in withdrawn area */ @@ -2705,9 +2705,10 @@ got_block: if (state > buf_page_t::READ_FIX && state < buf_page_t::WRITE_FIX) { if (mode == BUF_PEEK_IF_IN_POOL) { ignore_block: + block->unfix(); +ignore_unfixed: ut_ad(mode == BUF_GET_POSSIBLY_FREED || mode == BUF_PEEK_IF_IN_POOL); - block->unfix(); if (err) { *err = DB_CORRUPTION; } @@ -2721,16 +2722,32 @@ ignore_block: in buf_page_t::read_complete() or buf_pool_t::corrupted_evict(), or after buf_zip_decompress() in this function. */ - block->page.lock.s_lock(); + if (rw_latch != RW_NO_LATCH) { + block->page.lock.s_lock(); + } else if (!block->page.lock.s_lock_try()) { + /* For RW_NO_LATCH, we should not try to acquire S or X + latch directly as we could be violating the latching + order resulting in deadlock. Instead we try latching the + page and retry in case of a failure. */ + goto wait_for_read; + } state = block->page.state(); ut_ad(state < buf_page_t::READ_FIX || state >= buf_page_t::WRITE_FIX); const page_id_t id{block->page.id()}; block->page.lock.s_unlock(); - if (UNIV_UNLIKELY(id != page_id)) { + if (UNIV_UNLIKELY(state < buf_page_t::UNFIXED)) { + if (UNIV_UNLIKELY(id == page_id)) { + /* The page read was completed, and + another thread marked the page as free + while we were waiting. */ + goto ignore_block; + } + ut_ad(id == page_id_t{~0ULL}); block->page.unfix(); + if (++retries < BUF_PAGE_READ_MAX_RETRIES) { goto loop; } @@ -2741,6 +2758,7 @@ ignore_block: return nullptr; } + ut_ad(id == page_id); } else if (mode != BUF_PEEK_IF_IN_POOL) { } else if (!mtr) { ut_ad(!block->page.oldest_modification()); @@ -2767,6 +2785,7 @@ free_unfixed_block: if (UNIV_UNLIKELY(!block->page.frame)) { if (!block->page.lock.x_lock_try()) { wait_for_unzip: +wait_for_read: /* The page is being read or written, or another thread is executing buf_zip_decompress() in buf_page_get_gen() on it. */ @@ -2879,34 +2898,25 @@ wait_for_unfix: #endif /* UNIV_DEBUG */ ut_ad(block->page.frame); + /* The state = block->page.state() may be stale at this point, + and in fact, at any point of time if we consider its + buffer-fix component. If the block is being read into the + buffer pool, it is possible that buf_page_t::read_complete() + will invoke buf_pool_t::corrupted_evict() and therefore + invalidate it (invoke buf_page_t::set_corrupt_id() and set the + state to FREED). Therefore, after acquiring the page latch we + must recheck the state. */ + switch (rw_latch) { case RW_NO_LATCH: mtr->memo_push(block, MTR_MEMO_BUF_FIX); return block; case RW_S_LATCH: block->page.lock.s_lock(); - ut_ad(!block->page.is_read_fixed()); - if (UNIV_UNLIKELY(block->page.id() != page_id)) { - block->page.lock.s_unlock(); - block->page.lock.x_lock(); -page_id_mismatch: - if (block->page.id().is_corrupted()) { - buf_pool.corrupted_evict(&block->page, - block->page.state()); - } - if (err) { - *err = DB_CORRUPTION; - } - return nullptr; - } break; case RW_SX_LATCH: block->page.lock.u_lock(); ut_ad(!block->page.is_io_fixed()); - if (UNIV_UNLIKELY(block->page.id() != page_id)) { - block->page.lock.u_x_upgrade(); - goto page_id_mismatch; - } break; default: ut_ad(rw_latch == RW_X_LATCH); @@ -2916,12 +2926,18 @@ page_id_mismatch: mtr->page_lock_upgrade(*block); return block; } - if (UNIV_UNLIKELY(block->page.id() != page_id)) { - goto page_id_mismatch; - } } mtr->memo_push(block, mtr_memo_type_t(rw_latch)); + state = block->page.state(); + + if (UNIV_UNLIKELY(state < buf_page_t::UNFIXED)) { + mtr->release_last_page(); + goto ignore_unfixed; + } + + ut_ad(state < buf_page_t::READ_FIX || state > buf_page_t::WRITE_FIX); + #ifdef BTR_CUR_HASH_ADAPT btr_search_drop_page_hash_index(block, true); #endif /* BTR_CUR_HASH_ADAPT */ @@ -2932,82 +2948,71 @@ page_id_mismatch: return block; } -/********************************************************************//** -This is the general function used to get optimistic access to a database -page. -@return TRUE if success */ TRANSACTIONAL_TARGET -bool buf_page_optimistic_get(ulint rw_latch, buf_block_t *block, - uint64_t modify_clock, mtr_t *mtr) +buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) +{ + buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(id.fold()); + transactional_shared_lock_guard g + {buf_pool.page_hash.lock_get(chain)}; + if (UNIV_UNLIKELY(!buf_pool.is_uncompressed(block) || + id != block->page.id() || !block->page.frame)) + return nullptr; + const auto state= block->page.state(); + if (UNIV_UNLIKELY(state < buf_page_t::UNFIXED || + state >= buf_page_t::READ_FIX)) + return nullptr; + block->page.fix(); + return block; +} + +buf_block_t *buf_page_optimistic_get(buf_block_t *block, + rw_lock_type_t rw_latch, + uint64_t modify_clock, mtr_t *mtr) { - ut_ad(block); - ut_ad(mtr); ut_ad(mtr->is_active()); ut_ad(rw_latch == RW_S_LATCH || rw_latch == RW_X_LATCH); + ut_ad(block->page.buf_fix_count()); - if (have_transactional_memory); - else if (UNIV_UNLIKELY(!block->page.frame)) - return false; - else + if (rw_latch == RW_S_LATCH) { - const auto state= block->page.state(); - if (UNIV_UNLIKELY(state < buf_page_t::UNFIXED || - state >= buf_page_t::READ_FIX)) - return false; - } - - bool success; - const page_id_t id{block->page.id()}; - buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(id.fold()); - bool have_u_not_x= false; - - { - transactional_shared_lock_guard g - {buf_pool.page_hash.lock_get(chain)}; - if (UNIV_UNLIKELY(id != block->page.id() || !block->page.frame)) - return false; - const auto state= block->page.state(); - if (UNIV_UNLIKELY(state < buf_page_t::UNFIXED || - state >= buf_page_t::READ_FIX)) - return false; - - if (rw_latch == RW_S_LATCH) - success= block->page.lock.s_lock_try(); - else + if (!block->page.lock.s_lock_try()) { - have_u_not_x= block->page.lock.have_u_not_x(); - success= have_u_not_x || block->page.lock.x_lock_try(); + fail: + block->page.unfix(); + return nullptr; } - } - - if (!success) - return false; - - if (have_u_not_x) - { - block->page.lock.u_x_upgrade(); - mtr->page_lock_upgrade(*block); - ut_ad(id == block->page.id()); - ut_ad(modify_clock == block->modify_clock); - } - else - { - ut_ad(rw_latch == RW_S_LATCH || !block->page.is_io_fixed()); - ut_ad(id == block->page.id()); if (modify_clock != block->modify_clock || block->page.is_freed()) { - if (rw_latch == RW_S_LATCH) - block->page.lock.s_unlock(); - else - block->page.lock.x_unlock(); - return false; + block->page.lock.s_unlock(); + goto fail; } - block->page.fix(); ut_ad(!block->page.is_read_fixed()); buf_page_make_young_if_needed(&block->page); - mtr->memo_push(block, mtr_memo_type_t(rw_latch)); + mtr->memo_push(block, MTR_MEMO_PAGE_S_FIX); + } + else if (block->page.lock.have_u_not_x()) + { + block->page.lock.u_x_upgrade(); + block->page.unfix(); + mtr->page_lock_upgrade(*block); + ut_ad(modify_clock == block->modify_clock); + } + else if (!block->page.lock.x_lock_try()) + goto fail; + else + { + ut_ad(!block->page.is_io_fixed()); + + if (modify_clock != block->modify_clock || block->page.is_freed()) + { + block->page.lock.x_unlock(); + goto fail; + } + + buf_page_make_young_if_needed(&block->page); + mtr->memo_push(block, MTR_MEMO_PAGE_X_FIX); } ut_d(if (!(++buf_dbg_counter % 5771)) buf_pool.validate()); @@ -3017,7 +3022,7 @@ bool buf_page_optimistic_get(ulint rw_latch, buf_block_t *block, ut_ad(~buf_page_t::LRU_MASK & state); ut_ad(block->page.frame); - return true; + return block; } /** Try to S-latch a page. diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index e2702adc880..ec64d8d46ff 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -53,6 +53,7 @@ void buf_dblwr_t::init() active_slot= &slots[0]; mysql_mutex_init(buf_dblwr_mutex_key, &mutex, nullptr); pthread_cond_init(&cond, nullptr); + block_size= FSP_EXTENT_SIZE; } } @@ -67,7 +68,7 @@ inline void buf_dblwr_t::init(const byte *header) block1= page_id_t(0, mach_read_from_4(header + TRX_SYS_DOUBLEWRITE_BLOCK1)); block2= page_id_t(0, mach_read_from_4(header + TRX_SYS_DOUBLEWRITE_BLOCK2)); - const uint32_t buf_size= 2 * block_size(); + const uint32_t buf_size= 2 * block_size; for (int i= 0; i < 2; i++) { slots[i].write_buf= static_cast @@ -86,7 +87,7 @@ bool buf_dblwr_t::create() return true; mtr_t mtr; - const ulint size= block_size(); + const ulint size= block_size; start_again: mtr.start(); @@ -251,7 +252,7 @@ loads the pages from double write buffer into memory. dberr_t buf_dblwr_t::init_or_load_pages(pfs_os_file_t file, const char *path) { ut_ad(this == &buf_dblwr); - const uint32_t size= block_size(); + const uint32_t size= block_size; /* We do the file i/o past the buffer pool */ byte *read_buf= static_cast(aligned_malloc(srv_page_size, @@ -488,7 +489,6 @@ void buf_dblwr_t::write_completed() mysql_mutex_lock(&mutex); ut_ad(is_created()); - ut_ad(srv_use_doublewrite_buf); ut_ad(batch_running); slot *flush_slot= active_slot == &slots[0] ? &slots[1] : &slots[0]; ut_ad(flush_slot->reserved); @@ -574,7 +574,7 @@ static void buf_dblwr_check_block(const buf_page_t *bpage) bool buf_dblwr_t::flush_buffered_writes(const ulint size) { mysql_mutex_assert_owner(&mutex); - ut_ad(size == block_size()); + ut_ad(size == block_size); for (;;) { @@ -647,7 +647,6 @@ static void *get_frame(const IORequest &request) void buf_dblwr_t::flush_buffered_writes_completed(const IORequest &request) { ut_ad(this == &buf_dblwr); - ut_ad(srv_use_doublewrite_buf); ut_ad(is_created()); ut_ad(!srv_read_only_mode); ut_ad(!request.bpage); @@ -670,8 +669,14 @@ void buf_dblwr_t::flush_buffered_writes_completed(const IORequest &request) pages_written+= flush_slot->first_free; mysql_mutex_unlock(&mutex); - /* Now flush the doublewrite buffer data to disk */ - fil_system.sys_space->flush(); + /* Make the doublewrite durable. Note: The doublewrite buffer is + always in the first file of the system tablespace. We will not + bother about fil_system.unflushed_spaces, which can result in a + redundant call during fil_flush_file_spaces() in + log_checkpoint(). Writes to the system tablespace should be rare, + except when executing DDL or using the non-default settings + innodb_file_per_table=OFF or innodb_undo_tablespaces=0. */ + os_file_flush(request.node->handle); /* The writes have been flushed to disk now and in recovery we will find them in the doublewrite buffer blocks. Next, write the data pages. */ @@ -714,17 +719,18 @@ posted, and also when we may have to wait for a page latch! Otherwise a deadlock of threads can occur. */ void buf_dblwr_t::flush_buffered_writes() { - if (!is_created() || !srv_use_doublewrite_buf) + mysql_mutex_lock(&mutex); + + if (!in_use() && active_slot->first_free == 0) { + mysql_mutex_unlock(&mutex); fil_flush_file_spaces(); return; } ut_ad(!srv_read_only_mode); - const ulint size= block_size(); - mysql_mutex_lock(&mutex); - if (!flush_buffered_writes(size)) + if (!flush_buffered_writes(block_size)) mysql_mutex_unlock(&mutex); } @@ -734,8 +740,6 @@ flush_buffered_writes() will be invoked to make space. @param size payload size in bytes */ void buf_dblwr_t::add_to_batch(const IORequest &request, size_t size) { - ut_ad(request.is_async()); - ut_ad(request.is_write()); ut_ad(request.bpage); ut_ad(request.bpage->in_file()); ut_ad(request.node); @@ -744,7 +748,7 @@ void buf_dblwr_t::add_to_batch(const IORequest &request, size_t size) ut_ad(request.node->space->referenced()); ut_ad(!srv_read_only_mode); - const ulint buf_size= 2 * block_size(); + const ulint buf_size= 2 * block_size; mysql_mutex_lock(&mutex); @@ -773,7 +777,7 @@ void buf_dblwr_t::add_to_batch(const IORequest &request, size_t size) ut_ad(active_slot->reserved == active_slot->first_free); ut_ad(active_slot->reserved < buf_size); new (active_slot->buf_block_arr + active_slot->first_free++) - element{request, size}; + element{request.doublewritten(), size}; active_slot->reserved= active_slot->first_free; if (active_slot->first_free != buf_size || diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index bd43429eb5d..a69877ba34f 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -274,30 +274,22 @@ buf_flush_relocate_on_flush_list( ut_d(buf_flush_validate_low()); } -/** Note that a block is no longer dirty, while not removing -it from buf_pool.flush_list -@param temporary whether the page belongs to the temporary tablespace -@param error whether an error may have occurred while writing */ -inline void buf_page_t::write_complete(bool temporary, bool error) +void buf_page_t::write_complete(bool persistent, bool error, uint32_t state) { - ut_ad(temporary == fsp_is_system_temporary(id().space())); - if (UNIV_UNLIKELY(error)); - else if (temporary) - { - ut_ad(oldest_modification() == 2); - oldest_modification_= 0; - } - else + ut_ad(!persistent == fsp_is_system_temporary(id().space())); + ut_ad(state >= WRITE_FIX); + + if (UNIV_LIKELY(!error)) { + ut_d(lsn_t om= oldest_modification()); + ut_ad(om >= 2); + ut_ad(persistent == (om > 2)); /* We use release memory order to guarantee that callers of oldest_modification_acquire() will observe the block as being detached from buf_pool.flush_list, after reading the value 0. */ - ut_ad(oldest_modification() > 2); - oldest_modification_.store(1, std::memory_order_release); + oldest_modification_.store(persistent, std::memory_order_release); } - const auto s= state(); - ut_ad(s >= WRITE_FIX); - zip.fix.fetch_sub((s >= WRITE_FIX_REINIT) + zip.fix.fetch_sub((state >= WRITE_FIX_REINIT) ? (WRITE_FIX_REINIT - UNFIXED) : (WRITE_FIX - UNFIXED)); lock.u_unlock(true); @@ -311,18 +303,10 @@ inline void buf_pool_t::n_flush_inc() inline void buf_pool_t::n_flush_dec() { - mysql_mutex_lock(&flush_list_mutex); + mysql_mutex_assert_owner(&flush_list_mutex); ut_ad(page_cleaner_status >= LRU_FLUSH); if ((page_cleaner_status-= LRU_FLUSH) < LRU_FLUSH) pthread_cond_broadcast(&done_flush_LRU); - mysql_mutex_unlock(&flush_list_mutex); -} - -inline void buf_pool_t::n_flush_dec_holding_mutex() -{ - mysql_mutex_assert_owner(&flush_list_mutex); - ut_ad(page_cleaner_status >= LRU_FLUSH); - page_cleaner_status-= LRU_FLUSH; } /** Complete write of a file page from buf_pool. @@ -352,28 +336,26 @@ void buf_page_write_complete(const IORequest &request, bool error) mysql_mutex_assert_not_owner(&buf_pool.mutex); mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex); - if (request.is_LRU()) + const bool persistent= bpage->oldest_modification() != 2; + + if (UNIV_UNLIKELY(!persistent) && UNIV_LIKELY(!error)) { - const bool temp= bpage->oldest_modification() == 2; - if (!temp && state < buf_page_t::WRITE_FIX_REINIT && - request.node->space->use_doublewrite()) - buf_dblwr.write_completed(); /* We must hold buf_pool.mutex while releasing the block, so that no other thread can access it before we have freed it. */ mysql_mutex_lock(&buf_pool.mutex); - bpage->write_complete(temp, error); - if (!error) - buf_LRU_free_page(bpage, true); + bpage->write_complete(persistent, error, state); + buf_LRU_free_page(bpage, true); mysql_mutex_unlock(&buf_pool.mutex); - - buf_pool.n_flush_dec(); } else { - if (state < buf_page_t::WRITE_FIX_REINIT && - request.node->space->use_doublewrite()) + bpage->write_complete(persistent, error, state); + if (request.is_doublewritten()) + { + ut_ad(state < buf_page_t::WRITE_FIX_REINIT); + ut_ad(persistent); buf_dblwr.write_completed(); - bpage->write_complete(false, error); + } } } @@ -740,17 +722,15 @@ ATTRIBUTE_COLD void buf_pool_t::release_freed_page(buf_page_t *bpage) noexcept } /** Write a flushable page to a file or free a freeable block. -@param evict whether to evict the page on write completion @param space tablespace @return whether a page write was initiated and buf_pool.mutex released */ -bool buf_page_t::flush(bool evict, fil_space_t *space) +bool buf_page_t::flush(fil_space_t *space) { mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex); ut_ad(in_file()); ut_ad(in_LRU_list); ut_ad((space->purpose == FIL_TYPE_TEMPORARY) == (space == fil_system.temp_space)); - ut_ad(evict || space != fil_system.temp_space); ut_ad(space->referenced()); const auto s= state(); @@ -797,22 +777,11 @@ bool buf_page_t::flush(bool evict, fil_space_t *space) mysql_mutex_unlock(&buf_pool.mutex); IORequest::Type type= IORequest::WRITE_ASYNC; - if (UNIV_UNLIKELY(evict)) - { - type= IORequest::WRITE_LRU; - mysql_mutex_lock(&buf_pool.flush_list_mutex); - buf_pool.n_flush_inc(); - mysql_mutex_unlock(&buf_pool.flush_list_mutex); - } /* Apart from the U-lock, this block will also be protected by is_write_fixed() and oldest_modification()>1. Thus, it cannot be relocated or removed. */ - DBUG_PRINT("ib_buf", ("%s %u page %u:%u", - evict ? "LRU" : "flush_list", - id().space(), id().page_no())); - buf_block_t *block= reinterpret_cast(this); page_t *write_frame= zip.data; @@ -864,10 +833,7 @@ bool buf_page_t::flush(bool evict, fil_space_t *space) { switch (space->chain.start->punch_hole) { case 1: - static_assert(IORequest::PUNCH_LRU - IORequest::PUNCH == - IORequest::WRITE_LRU - IORequest::WRITE_ASYNC, ""); - type= - IORequest::Type(type + (IORequest::PUNCH - IORequest::WRITE_ASYNC)); + type= IORequest::PUNCH; break; case 2: size= orig_size; @@ -894,10 +860,8 @@ bool buf_page_t::flush(bool evict, fil_space_t *space) /** Check whether a page can be flushed from the buf_pool. @param id page identifier @param fold id.fold() -@param evict true=buf_pool.LRU; false=buf_pool.flush_list @return whether the page can be flushed */ -static bool buf_flush_check_neighbor(const page_id_t id, ulint fold, - bool evict) +static bool buf_flush_check_neighbor(const page_id_t id, ulint fold) { mysql_mutex_assert_owner(&buf_pool.mutex); ut_ad(fold == id.fold()); @@ -906,26 +870,16 @@ static bool buf_flush_check_neighbor(const page_id_t id, ulint fold, const buf_page_t *bpage= buf_pool.page_hash.get(id, buf_pool.page_hash.cell_get(fold)); - if (!bpage) - return false; - - /* We avoid flushing 'non-old' blocks in an eviction flush, because the - flushed blocks are soon freed */ - if (evict && !bpage->is_old()) - return false; - - return bpage->oldest_modification() > 1 && !bpage->is_io_fixed(); + return bpage && bpage->oldest_modification() > 1 && !bpage->is_io_fixed(); } /** Check which neighbors of a page can be flushed from the buf_pool. @param space tablespace @param id page identifier of a dirty page @param contiguous whether to consider contiguous areas of pages -@param evict true=buf_pool.LRU; false=buf_pool.flush_list @return last page number that can be flushed */ static page_id_t buf_flush_check_neighbors(const fil_space_t &space, - page_id_t &id, bool contiguous, - bool evict) + page_id_t &id, bool contiguous) { ut_ad(id.page_no() < space.size + (space.physical_size() == 2048 ? 1 @@ -958,7 +912,7 @@ static page_id_t buf_flush_check_neighbors(const fil_space_t &space, for (page_id_t i= id - 1;; --i) { fold--; - if (!buf_flush_check_neighbor(i, fold, evict)) + if (!buf_flush_check_neighbor(i, fold)) { low= i + 1; break; @@ -974,7 +928,7 @@ static page_id_t buf_flush_check_neighbors(const fil_space_t &space, while (++i < high) { ++fold; - if (!buf_flush_check_neighbor(i, fold, evict)) + if (!buf_flush_check_neighbor(i, fold)) break; } @@ -1051,14 +1005,13 @@ and also write zeroes or punch the hole for the freed ranges of pages. @param page_id page identifier @param bpage buffer page @param contiguous whether to consider contiguous areas of pages -@param evict true=buf_pool.LRU; false=buf_pool.flush_list @param n_flushed number of pages flushed so far in this batch @param n_to_flush maximum number of pages we are allowed to flush @return number of pages flushed */ static ulint buf_flush_try_neighbors(fil_space_t *space, const page_id_t page_id, buf_page_t *bpage, - bool contiguous, bool evict, + bool contiguous, ulint n_flushed, ulint n_to_flush) { ut_ad(space->id == page_id.space()); @@ -1072,7 +1025,7 @@ static ulint buf_flush_try_neighbors(fil_space_t *space, ut_ad(lsn >= bpage->oldest_modification()); if (UNIV_UNLIKELY(lsn < space->get_create_lsn())) { - ut_a(!bpage->flush(evict, space)); + ut_a(!bpage->flush(space)); mysql_mutex_unlock(&buf_pool.mutex); return 0; } @@ -1082,7 +1035,7 @@ static ulint buf_flush_try_neighbors(fil_space_t *space, ulint count= 0; page_id_t id= page_id; - page_id_t high= buf_flush_check_neighbors(*space, id, contiguous, evict); + page_id_t high= buf_flush_check_neighbors(*space, id, contiguous); ut_ad(page_id >= id); ut_ad(page_id < high); @@ -1118,7 +1071,7 @@ static ulint buf_flush_try_neighbors(fil_space_t *space, bpage= nullptr; ut_ad(b->oldest_modification() > 1); flush: - if (b->flush(evict, space)) + if (b->flush(space)) { ++count; continue; @@ -1126,9 +1079,9 @@ static ulint buf_flush_try_neighbors(fil_space_t *space, } /* We avoid flushing 'non-old' blocks in an eviction flush, because the flushed blocks are soon freed */ - else if ((!evict || b->is_old()) && - b->oldest_modification() > 1 && b->lock.u_lock_try(true)) + else if (b->oldest_modification() > 1 && b->lock.u_lock_try(true)) { + /* For the buf_pool.watch[] sentinels, oldest_modification() == 0 */ if (b->oldest_modification() < 2) b->lock.u_unlock(true); else @@ -1250,10 +1203,8 @@ static void buf_flush_discard_page(buf_page_t *bpage) /** Flush dirty blocks from the end buf_pool.LRU, and move clean blocks to buf_pool.free. @param max maximum number of blocks to flush -@param evict whether dirty pages are to be evicted after flushing them @param n counts of flushed and evicted pages */ -static void buf_flush_LRU_list_batch(ulint max, bool evict, - flush_counters_t *n) +static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n) { ulint scanned= 0; ulint free_limit= srv_LRU_scan_depth; @@ -1301,8 +1252,12 @@ static void buf_flush_LRU_list_batch(ulint max, bool evict, if (state < buf_page_t::READ_FIX && bpage->lock.u_lock_try(true)) { ut_ad(!bpage->is_io_fixed()); - bool do_evict= evict; switch (bpage->oldest_modification()) { + case 2: + /* LRU flushing will always evict pages of the temporary tablespace, + in buf_page_write_complete(). */ + ++n->evicted; + break; case 1: mysql_mutex_lock(&buf_pool.flush_list_mutex); if (ut_d(lsn_t lsn=) bpage->oldest_modification()) @@ -1315,12 +1270,8 @@ static void buf_flush_LRU_list_batch(ulint max, bool evict, case 0: bpage->lock.u_unlock(true); goto evict; - case 2: - /* LRU flushing will always evict pages of the temporary tablespace. */ - do_evict= true; } - /* Block is ready for flush. Dispatch an IO request. - If do_evict, the page may be evicted by buf_page_write_complete(). */ + /* Block is ready for flush. Dispatch an IO request. */ const page_id_t page_id(bpage->id()); const uint32_t space_id= page_id.space(); if (!space || space->id != space_id) @@ -1355,6 +1306,7 @@ static void buf_flush_LRU_list_batch(ulint max, bool evict, no_space: mysql_mutex_lock(&buf_pool.flush_list_mutex); buf_flush_discard_page(bpage); + ++n->evicted; continue; } @@ -1367,8 +1319,8 @@ static void buf_flush_LRU_list_batch(ulint max, bool evict, if (neighbors && space->is_rotational()) n->flushed+= buf_flush_try_neighbors(space, page_id, bpage, neighbors == 1, - do_evict, n->flushed, max); - else if (bpage->flush(do_evict, space)) + n->flushed, max); + else if (bpage->flush(space)) ++n->flushed; else continue; @@ -1386,24 +1338,25 @@ static void buf_flush_LRU_list_batch(ulint max, bool evict, space->release(); if (scanned) + { MONITOR_INC_VALUE_CUMULATIVE(MONITOR_LRU_BATCH_SCANNED, MONITOR_LRU_BATCH_SCANNED_NUM_CALL, MONITOR_LRU_BATCH_SCANNED_PER_CALL, scanned); + } } /** Flush and move pages from LRU or unzip_LRU list to the free list. Whether LRU or unzip_LRU is used depends on the state of the system. @param max maximum number of blocks to flush -@param evict whether dirty pages are to be evicted after flushing them @param n counts of flushed and evicted pages */ -static void buf_do_LRU_batch(ulint max, bool evict, flush_counters_t *n) +static void buf_do_LRU_batch(ulint max, flush_counters_t *n) { if (buf_LRU_evict_from_unzip_LRU()) buf_free_from_unzip_LRU_list_batch(); n->evicted= 0; n->flushed= 0; - buf_flush_LRU_list_batch(max, evict, n); + buf_flush_LRU_list_batch(max, n); mysql_mutex_assert_owner(&buf_pool.mutex); buf_lru_freed_page_count+= n->evicted; @@ -1515,8 +1468,8 @@ static ulint buf_do_flush_list_batch(ulint max_n, lsn_t lsn) { if (neighbors && space->is_rotational()) count+= buf_flush_try_neighbors(space, page_id, bpage, - neighbors == 1, false, count, max_n); - else if (bpage->flush(false, space)) + neighbors == 1, count, max_n); + else if (bpage->flush(space)) ++count; else continue; @@ -1535,10 +1488,13 @@ static ulint buf_do_flush_list_batch(ulint max_n, lsn_t lsn) space->release(); if (scanned) + { MONITOR_INC_VALUE_CUMULATIVE(MONITOR_FLUSH_BATCH_SCANNED, MONITOR_FLUSH_BATCH_SCANNED_NUM_CALL, MONITOR_FLUSH_BATCH_SCANNED_PER_CALL, scanned); + } + return count; } @@ -1682,7 +1638,7 @@ bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed) goto was_freed; } mysql_mutex_unlock(&buf_pool.flush_list_mutex); - if (bpage->flush(false, space)) + if (bpage->flush(space)) { ++n_flush; if (!--max_n_flush) @@ -1740,27 +1696,22 @@ and move clean blocks to buf_pool.free. The caller must invoke buf_dblwr.flush_buffered_writes() after releasing buf_pool.mutex. @param max_n wished maximum mumber of blocks flushed -@param evict whether to evict pages after flushing -@return evict ? number of processed pages : number of pages written */ -ulint buf_flush_LRU(ulint max_n, bool evict) +@return number of pages written */ +static ulint buf_flush_LRU(ulint max_n) { mysql_mutex_assert_owner(&buf_pool.mutex); flush_counters_t n; - buf_do_LRU_batch(max_n, evict, &n); + buf_do_LRU_batch(max_n, &n); ulint pages= n.flushed; if (n.evicted) { - if (evict) - pages+= n.evicted; buf_pool.try_LRU_scan= true; pthread_cond_broadcast(&buf_pool.done_free); } - else if (!pages && !buf_pool.try_LRU_scan && - !buf_pool.LRU_warned.test_and_set(std::memory_order_acquire)) - { + else if (!pages && !buf_pool.try_LRU_scan) /* For example, with the minimum innodb_buffer_pool_size=5M and the default innodb_page_size=16k there are only a little over 316 pages in the buffer pool. The buffer pool can easily be exhausted @@ -1774,18 +1725,13 @@ ulint buf_flush_LRU(ulint max_n, bool evict) (3) This thread is the only one that could make progress, but we fail to do so because all the pages that we scanned are buffer-fixed or latched by some thread. */ - sql_print_warning("InnoDB: Could not free any blocks in the buffer pool!" - " %zu blocks are in use and %zu free." - " Consider increasing innodb_buffer_pool_size.", - UT_LIST_GET_LEN(buf_pool.LRU), - UT_LIST_GET_LEN(buf_pool.free)); - } + buf_pool.LRU_warn(); return pages; } #ifdef HAVE_PMEM -# include +# include "cache.h" #endif /** Write checkpoint information to the log header and release mutex. @@ -1899,8 +1845,7 @@ inline void log_t::write_checkpoint(lsn_t end_lsn) noexcept ut_ad(!log.is_opened()); bool success; log.m_file= - os_file_create_func(get_log_file_path().c_str(), - OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT, + os_file_create_func(get_log_file_path().c_str(), OS_FILE_OPEN, OS_FILE_NORMAL, OS_LOG_FILE, false, &success); ut_a(success); ut_a(log.is_opened()); @@ -1915,7 +1860,7 @@ inline void log_t::write_checkpoint(lsn_t end_lsn) noexcept { my_munmap(buf, file_size); buf= resize_buf; - buf_free= START_OFFSET + (get_lsn() - resizing); + set_buf_free(START_OFFSET + (get_lsn() - resizing)); } else #endif @@ -1957,9 +1902,7 @@ inline void log_t::write_checkpoint(lsn_t end_lsn) noexcept static bool log_checkpoint_low(lsn_t oldest_lsn, lsn_t end_lsn) { ut_ad(!srv_read_only_mode); -#ifndef SUX_LOCK_GENERIC - ut_ad(log_sys.latch.is_write_locked()); -#endif + ut_ad(log_sys.latch_have_wr()); ut_ad(oldest_lsn <= end_lsn); ut_ad(end_lsn == log_sys.get_lsn()); @@ -2314,7 +2257,7 @@ func_exit: sum_pages += last_pages_in; - const ulint time_elapsed = std::max(curr_time - prev_time, 1); + const ulint time_elapsed = std::max(ulint(curr_time - prev_time), 1); /* We update our variables every innodb_flushing_avg_loops iterations to smooth out transition in workload. */ @@ -2528,26 +2471,16 @@ static void buf_flush_page_cleaner() { buf_pool.page_cleaner_set_idle(false); buf_pool.n_flush_inc(); - /* Remove clean blocks from buf_pool.flush_list before the LRU scan. */ - for (buf_page_t *p= UT_LIST_GET_FIRST(buf_pool.flush_list); p; ) - { - const lsn_t lsn{p->oldest_modification()}; - ut_ad(lsn > 2 || lsn == 1); - buf_page_t *n= UT_LIST_GET_NEXT(list, p); - if (lsn <= 1) - buf_pool.delete_from_flush_list(p); - p= n; - } mysql_mutex_unlock(&buf_pool.flush_list_mutex); n= srv_max_io_capacity; mysql_mutex_lock(&buf_pool.mutex); LRU_flush: - n= buf_flush_LRU(n, false); + n= buf_flush_LRU(n); mysql_mutex_unlock(&buf_pool.mutex); last_pages+= n; check_oldest_and_set_idle: mysql_mutex_lock(&buf_pool.flush_list_mutex); - buf_pool.n_flush_dec_holding_mutex(); + buf_pool.n_flush_dec(); oldest_lsn= buf_pool.get_oldest_modification(0); if (!oldest_lsn) goto fully_unemployed; @@ -2680,6 +2613,16 @@ static void buf_flush_page_cleaner() #endif } +ATTRIBUTE_COLD void buf_pool_t::LRU_warn() +{ + mysql_mutex_assert_owner(&mutex); + if (!LRU_warned.test_and_set(std::memory_order_acquire)) + sql_print_warning("InnoDB: Could not free any blocks in the buffer pool!" + " %zu blocks are in use and %zu free." + " Consider increasing innodb_buffer_pool_size.", + UT_LIST_GET_LEN(LRU), UT_LIST_GET_LEN(free)); +} + /** Initialize page_cleaner. */ ATTRIBUTE_COLD void buf_flush_page_cleaner_init() { diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index 8301d10b75f..41e3b4e7feb 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -386,148 +386,82 @@ we put it to free list to be used. @retval nullptr if get==have_no_mutex_soft and memory was not available */ buf_block_t* buf_LRU_get_free_block(buf_LRU_get get) { - ulint n_iterations = 0; - ulint flush_failures = 0; - MONITOR_INC(MONITOR_LRU_GET_FREE_SEARCH); - if (UNIV_UNLIKELY(get == have_mutex)) { - mysql_mutex_assert_owner(&buf_pool.mutex); - goto got_mutex; - } - DBUG_EXECUTE_IF("recv_ran_out_of_buffer", - if (recv_recovery_is_on() - && recv_sys.apply_log_recs) { - mysql_mutex_lock(&buf_pool.mutex); - goto flush_lru; - }); -get_mutex: - mysql_mutex_lock(&buf_pool.mutex); -got_mutex: - buf_LRU_check_size_of_non_data_objects(); - buf_block_t* block; + bool waited= false; + MONITOR_INC(MONITOR_LRU_GET_FREE_SEARCH); + if (UNIV_LIKELY(get != have_mutex)) + mysql_mutex_lock(&buf_pool.mutex); - IF_DBUG(static bool buf_lru_free_blocks_error_printed,); - DBUG_EXECUTE_IF("ib_lru_force_no_free_page", - if (!buf_lru_free_blocks_error_printed) { - n_iterations = 21; - block = nullptr; - goto not_found;}); + buf_LRU_check_size_of_non_data_objects(); + + buf_block_t *block; retry: - /* If there is a block in the free list, take it */ - if ((block = buf_LRU_get_free_only()) != nullptr) { + /* If there is a block in the free list, take it */ + block= buf_LRU_get_free_only(); + if (block) + { got_block: - const ulint LRU_size = UT_LIST_GET_LEN(buf_pool.LRU); - const ulint available = UT_LIST_GET_LEN(buf_pool.free); - const ulint scan_depth = srv_LRU_scan_depth / 2; - ut_ad(LRU_size <= BUF_LRU_MIN_LEN || available >= scan_depth - || buf_pool.need_LRU_eviction()); + const ulint LRU_size= UT_LIST_GET_LEN(buf_pool.LRU); + const ulint available= UT_LIST_GET_LEN(buf_pool.free); + const ulint scan_depth= srv_LRU_scan_depth / 2; + ut_ad(LRU_size <= BUF_LRU_MIN_LEN || + available >= scan_depth || buf_pool.need_LRU_eviction()); - if (UNIV_LIKELY(get != have_mutex)) { - mysql_mutex_unlock(&buf_pool.mutex); - } + if (UNIV_UNLIKELY(available < scan_depth) && LRU_size > BUF_LRU_MIN_LEN) + { + mysql_mutex_lock(&buf_pool.flush_list_mutex); + if (!buf_pool.page_cleaner_active()) + buf_pool.page_cleaner_wakeup(true); + mysql_mutex_unlock(&buf_pool.flush_list_mutex); + } - if (UNIV_UNLIKELY(available < scan_depth) - && LRU_size > BUF_LRU_MIN_LEN) { - mysql_mutex_lock(&buf_pool.flush_list_mutex); - if (!buf_pool.page_cleaner_active()) { - buf_pool.page_cleaner_wakeup(true); - } - mysql_mutex_unlock(&buf_pool.flush_list_mutex); - } + if (UNIV_LIKELY(get != have_mutex)) + mysql_mutex_unlock(&buf_pool.mutex); - block->page.zip.clear(); - return block; - } + block->page.zip.clear(); + return block; + } - MONITOR_INC( MONITOR_LRU_GET_FREE_LOOPS ); - if (n_iterations || buf_pool.try_LRU_scan) { - /* If no block was in the free list, search from the - end of the LRU list and try to free a block there. - If we are doing for the first time we'll scan only - tail of the LRU list otherwise we scan the whole LRU - list. */ - if (buf_LRU_scan_and_free_block(n_iterations - ? ULINT_UNDEFINED : 100)) { - goto retry; - } + MONITOR_INC(MONITOR_LRU_GET_FREE_LOOPS); + if (waited || buf_pool.try_LRU_scan) + { + /* If no block was in the free list, search from the end of the + LRU list and try to free a block there. If we are doing for the + first time we'll scan only tail of the LRU list otherwise we scan + the whole LRU list. */ + if (buf_LRU_scan_and_free_block(waited ? ULINT_UNDEFINED : 100)) + goto retry; - /* Tell other threads that there is no point - in scanning the LRU list. */ - buf_pool.try_LRU_scan = false; - } + /* Tell other threads that there is no point in scanning the LRU + list. */ + buf_pool.try_LRU_scan= false; + } - if (get == have_no_mutex_soft) { - mysql_mutex_unlock(&buf_pool.mutex); - return nullptr; - } + if (get == have_no_mutex_soft) + { + mysql_mutex_unlock(&buf_pool.mutex); + return nullptr; + } - for (;;) { - if ((block = buf_LRU_get_free_only()) != nullptr) { - goto got_block; - } - const bool wake = buf_pool.need_LRU_eviction(); - mysql_mutex_unlock(&buf_pool.mutex); - mysql_mutex_lock(&buf_pool.flush_list_mutex); - const auto n_flush = buf_pool.n_flush(); - if (wake && !buf_pool.page_cleaner_active()) { - buf_pool.page_cleaner_wakeup(true); - } - mysql_mutex_unlock(&buf_pool.flush_list_mutex); - mysql_mutex_lock(&buf_pool.mutex); - if (!n_flush) { - goto not_found; - } - if (!buf_pool.try_LRU_scan) { - my_cond_wait(&buf_pool.done_free, - &buf_pool.mutex.m_mutex); - } - } + waited= true; -not_found: - if (n_iterations > 1) { - MONITOR_INC( MONITOR_LRU_GET_FREE_WAITS ); - } + while (!(block= buf_LRU_get_free_only())) + { + buf_pool.stat.LRU_waits++; - if (n_iterations == 21 - && srv_buf_pool_old_size == srv_buf_pool_size - && buf_pool.LRU_warned.test_and_set(std::memory_order_acquire)) { - IF_DBUG(buf_lru_free_blocks_error_printed = true,); - mysql_mutex_unlock(&buf_pool.mutex); - ib::warn() << "Difficult to find free blocks in the buffer pool" - " (" << n_iterations << " search iterations)! " - << flush_failures << " failed attempts to" - " flush a page!" - " Consider increasing innodb_buffer_pool_size." - " Pending flushes (fsync): " - << fil_n_pending_tablespace_flushes - << ". " << os_n_file_reads << " OS file reads, " - << os_n_file_writes << " OS file writes, " - << os_n_fsyncs - << " OS fsyncs."; - mysql_mutex_lock(&buf_pool.mutex); - } + timespec abstime; + set_timespec(abstime, 1); - /* No free block was found: try to flush the LRU list. - The freed blocks will be up for grabs for all threads. + mysql_mutex_lock(&buf_pool.flush_list_mutex); + if (!buf_pool.page_cleaner_active()) + buf_pool.page_cleaner_wakeup(true); + mysql_mutex_unlock(&buf_pool.flush_list_mutex); + if (my_cond_timedwait(&buf_pool.done_free, &buf_pool.mutex.m_mutex, + &abstime)) + buf_pool.LRU_warn(); + } - TODO: A more elegant way would have been to return one freed - up block to the caller here but the code that deals with - removing the block from buf_pool.page_hash and buf_pool.LRU is fairly - involved (particularly in case of ROW_FORMAT=COMPRESSED pages). We - can do that in a separate patch sometime in future. */ -#ifndef DBUG_OFF -flush_lru: -#endif - if (!buf_flush_LRU(innodb_lru_flush_size, true)) { - MONITOR_INC(MONITOR_LRU_SINGLE_FLUSH_FAILURE_COUNT); - ++flush_failures; - } - - n_iterations++; - buf_pool.stat.LRU_waits++; - mysql_mutex_unlock(&buf_pool.mutex); - buf_dblwr.flush_buffered_writes(); - goto get_mutex; + goto got_block; } /** Move the LRU_old pointer so that the length of the old blocks list diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index c93fc9f814a..e33f86e9b55 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -657,47 +657,22 @@ dict_table_t::parse_name<>(char(&)[NAME_LEN + 1], char(&)[NAME_LEN + 1], /** Acquire MDL shared for the table name. @tparam trylock whether to use non-blocking operation @param[in,out] table table object -@param[in,out] thd background thread -@param[out] mdl mdl ticket +@param[in,out] mdl_context MDL context +@param[out] mdl MDL ticket @param[in] table_op operation to perform when opening @return table object after locking MDL shared @retval nullptr if the table is not readable, or if trylock && MDL blocked */ template +__attribute__((nonnull, warn_unused_result)) dict_table_t* dict_acquire_mdl_shared(dict_table_t *table, - THD *thd, - MDL_ticket **mdl, + MDL_context *mdl_context, MDL_ticket **mdl, dict_table_op_t table_op) { - if (!table || !mdl) - return table; - - MDL_context *mdl_context= static_cast(thd_mdl_context(thd)); - size_t db_len; - dict_table_t *not_found= nullptr; - - if (trylock) - { - dict_sys.freeze(SRW_LOCK_CALL); - db_len= dict_get_db_name_len(table->name.m_name); - dict_sys.unfreeze(); - } - else - { - ut_ad(dict_sys.frozen_not_locked()); - db_len= dict_get_db_name_len(table->name.m_name); - } - - if (db_len == 0) - return table; /* InnoDB system tables are not covered by MDL */ - - if (!mdl_context) - return nullptr; - table_id_t table_id= table->id; char db_buf[NAME_LEN + 1], db_buf1[NAME_LEN + 1]; char tbl_buf[NAME_LEN + 1], tbl_buf1[NAME_LEN + 1]; - size_t tbl_len; + size_t db_len, tbl_len; bool unaccessible= false; if (!table->parse_name(db_buf, tbl_buf, &db_len, &tbl_len)) @@ -768,7 +743,6 @@ retry: if (!table || !table->is_accessible()) { - table= nullptr; return_without_mdl: if (trylock) dict_sys.unfreeze(); @@ -777,7 +751,7 @@ return_without_mdl: mdl_context->release_lock(*mdl); *mdl= nullptr; } - return not_found; + return nullptr; } size_t db1_len, tbl1_len; @@ -814,6 +788,50 @@ return_without_mdl: goto retry; } +template dict_table_t* dict_acquire_mdl_shared +(dict_table_t*,MDL_context*,MDL_ticket**,dict_table_op_t); + +/** Acquire MDL shared for the table name. +@tparam trylock whether to use non-blocking operation +@param[in,out] table table object +@param[in,out] thd background thread +@param[out] mdl mdl ticket +@param[in] table_op operation to perform when opening +@return table object after locking MDL shared +@retval nullptr if the table is not readable, or if trylock && MDL blocked */ +template +dict_table_t* +dict_acquire_mdl_shared(dict_table_t *table, + THD *thd, + MDL_ticket **mdl, + dict_table_op_t table_op) +{ + if (!table || !mdl) + return table; + + MDL_context *mdl_context= static_cast(thd_mdl_context(thd)); + size_t db_len; + + if (trylock) + { + dict_sys.freeze(SRW_LOCK_CALL); + db_len= dict_get_db_name_len(table->name.m_name); + dict_sys.unfreeze(); + } + else + { + ut_ad(dict_sys.frozen_not_locked()); + db_len= dict_get_db_name_len(table->name.m_name); + } + + if (db_len == 0) + return table; /* InnoDB system tables are not covered by MDL */ + + return mdl_context + ? dict_acquire_mdl_shared(table, mdl_context, mdl, table_op) + : nullptr; +} + template dict_table_t* dict_acquire_mdl_shared (dict_table_t*,THD*,MDL_ticket**,dict_table_op_t); template dict_table_t* dict_acquire_mdl_shared @@ -960,9 +978,6 @@ void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line)) { latch.wr_lock(SRW_LOCK_ARGS(file, line)); latch_ex_wait_start.store(0, std::memory_order_relaxed); - ut_ad(!latch_readers); - ut_ad(!latch_ex); - ut_d(latch_ex= pthread_self()); return; } @@ -978,35 +993,36 @@ void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line)) ib::warn() << "A long wait (" << waited << " seconds) was observed for dict_sys.latch"; latch.wr_lock(SRW_LOCK_ARGS(file, line)); - ut_ad(!latch_readers); - ut_ad(!latch_ex); - ut_d(latch_ex= pthread_self()); } #ifdef UNIV_PFS_RWLOCK ATTRIBUTE_NOINLINE void dict_sys_t::unlock() { - ut_ad(latch_ex == pthread_self()); - ut_ad(!latch_readers); - ut_d(latch_ex= 0); latch.wr_unlock(); } ATTRIBUTE_NOINLINE void dict_sys_t::freeze(const char *file, unsigned line) { latch.rd_lock(file, line); - ut_ad(!latch_ex); - ut_d(latch_readers++); } ATTRIBUTE_NOINLINE void dict_sys_t::unfreeze() { - ut_ad(!latch_ex); - ut_ad(latch_readers--); latch.rd_unlock(); } #endif /* UNIV_PFS_RWLOCK */ +/** Report an error about failing to open a table. +@param name table name */ +static void dict_table_open_failed(const table_name_t &name) +{ + my_printf_error(ER_TABLE_CORRUPT, + "Table %`.*s.%`s is corrupted." + " Please drop the table and recreate.", + MYF(ME_ERROR_LOG), + int(name.dblen()), name.m_name, name.basename()); +} + /**********************************************************************//** Returns a table object and increments its open handle count. NOTE! This is a high-level function to be used mainly from outside the @@ -1039,18 +1055,20 @@ dict_table_open_on_name( if (!(ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY) && !table->is_readable() && table->corrupted) { - ulint algo = table->space->get_compression_algo(); - if (algo <= PAGE_ALGORITHM_LAST && !fil_comp_algo_loaded(algo)) { - my_printf_error(ER_PROVIDER_NOT_LOADED, - "Table %s is compressed with %s, which is not currently loaded. " - "Please load the %s provider plugin to open the table", - MYF(ME_ERROR_LOG), table->name, - page_compression_algorithms[algo], page_compression_algorithms[algo]); - } else { - my_printf_error(ER_TABLE_CORRUPT, - "Table %s is corrupted. Please drop the table and recreate.", - MYF(ME_ERROR_LOG), table->name); - } + ulint algo= table->space->get_compression_algo(); + if (algo <= PAGE_ALGORITHM_LAST && !fil_comp_algo_loaded(algo)) + my_printf_error(ER_PROVIDER_NOT_LOADED, + "Table %`.*s.%`s is compressed with %s," + " which is not currently loaded. " + "Please load the %s provider plugin" + " to open the table", + MYF(ME_ERROR_LOG), + int(table->name.dblen()), table->name.m_name, + table->name.basename(), + page_compression_algorithms[algo], + page_compression_algorithms[algo]); + else + dict_table_open_failed(table->name); dict_sys.unfreeze(); DBUG_RETURN(nullptr); } @@ -1070,8 +1088,7 @@ dict_table_open_on_name( if (!(ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY) && !table->is_readable() && table->corrupted) { - ib::error() << "Table " << table->name - << " is corrupted. Please drop the table and recreate."; + dict_table_open_failed(table->name); if (!dict_locked) dict_sys.unlock(); DBUG_RETURN(nullptr); @@ -1992,7 +2009,6 @@ dict_index_add_to_cache( new_index->n_fields = new_index->n_def; new_index->trx_id = index->trx_id; new_index->set_committed(index->is_committed()); - new_index->nulls_equal = index->nulls_equal; n_ord = new_index->n_uniq; /* Flag the ordering columns and also set column max_prefix */ diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 97f8ba319d3..ca0e68859e9 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -3803,6 +3803,10 @@ release_and_exit: goto release_and_exit; } +#ifdef ENABLED_DEBUG_SYNC + DEBUG_SYNC(thd, "dict_stats_mdl_acquired"); +#endif /* ENABLED_DEBUG_SYNC */ + trx = trx_create(); trx_start_internal_read_only(trx); diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 83435867b04..0d67e1a9f6c 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -2290,7 +2290,7 @@ void fil_space_crypt_close_tablespace(const fil_space_t *space) << space->chain.start->name << " (" << space->id << ") active threads " << crypt_data->rotate_state.active_threads - << "flushing=" + << " flushing=" << crypt_data->rotate_state.flushing << "."; last = now; } diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 0ce54df6574..b16a4c54f5c 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -342,7 +342,7 @@ static bool fil_node_open_file_low(fil_node_t *node) ut_ad(node->space->is_closing()); mysql_mutex_assert_owner(&fil_system.mutex); static_assert(((UNIV_ZIP_SIZE_MIN >> 1) << 3) == 4096, "compatibility"); -#if defined _WIN32 || defined HAVE_FCNTL_DIRECT +#if defined _WIN32 || defined O_DIRECT ulint type; switch (FSP_FLAGS_GET_ZIP_SSIZE(node->space->flags)) { case 1: @@ -361,8 +361,7 @@ static bool fil_node_open_file_low(fil_node_t *node) bool success; node->handle= os_file_create(innodb_data_file_key, node->name, node->is_raw_disk - ? OS_FILE_OPEN_RAW | OS_FILE_ON_ERROR_NO_EXIT - : OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT, + ? OS_FILE_OPEN_RAW : OS_FILE_OPEN, OS_FILE_AIO, type, srv_read_only_mode, &success); @@ -945,9 +944,7 @@ bool fil_space_free(uint32_t id, bool x_latched) log_sys.latch.wr_unlock(); } else { -#ifndef SUX_LOCK_GENERIC - ut_ad(log_sys.latch.is_write_locked()); -#endif + ut_ad(log_sys.latch_have_wr()); if (space->max_lsn) { ut_d(space->max_lsn = 0); fil_system.named_spaces.remove(*space); @@ -1249,9 +1246,6 @@ void fil_system_t::create(ulint hash_size) ut_ad(!is_initialised()); ut_ad(!(srv_page_size % FSP_EXTENT_SIZE)); ut_ad(srv_page_size); - ut_ad(!spaces.array); - - m_initialised = true; compile_time_assert(!(UNIV_PAGE_SIZE_MAX % FSP_EXTENT_SIZE_MAX)); compile_time_assert(!(UNIV_PAGE_SIZE_MIN % FSP_EXTENT_SIZE_MIN)); @@ -1262,6 +1256,8 @@ void fil_system_t::create(ulint hash_size) spaces.create(hash_size); + need_unflushed_spaces = !write_through && buf_dblwr.need_fsync(); + fil_space_crypt_init(); #ifdef __linux__ ssd.clear(); @@ -1335,13 +1331,12 @@ void fil_system_t::close() if (is_initialised()) { - m_initialised= false; spaces.free(); mysql_mutex_destroy(&mutex); fil_space_crypt_cleanup(); } - ut_ad(!spaces.array); + ut_ad(!is_initialised()); #ifdef __linux__ ssd.clear(); @@ -1410,10 +1405,12 @@ ATTRIBUTE_COLD void fil_space_t::reopen_all() ulint type= OS_DATA_FILE; +#if defined _WIN32 || defined O_DIRECT switch (FSP_FLAGS_GET_ZIP_SSIZE(space.flags)) { case 1: case 2: type= OS_DATA_FILE_NO_O_DIRECT; } +#endif for (ulint count= 10000; count--;) { @@ -1480,6 +1477,7 @@ void fil_system_t::set_write_through(bool write_through) { this->write_through= write_through; fil_space_t::reopen_all(); + need_unflushed_spaces = !write_through && buf_dblwr.need_fsync(); } mysql_mutex_unlock(&mutex); @@ -1819,30 +1817,27 @@ pfs_os_file_t fil_delete_tablespace(uint32_t id) /*******************************************************************//** Allocates and builds a file name from a path, a table or tablespace name and a suffix. The string must be freed by caller with ut_free(). -@param[in] path NULL or the directory path or the full path and filename. +@param[in] path nullptr or the directory path or the full path and filename @param[in] name {} if path is full, or Table/Tablespace name -@param[in] ext the file extension to use -@param[in] trim_name true if the last name on the path should be trimmed. +@param[in] extension the file extension to use +@param[in] trim_name true if the last name on the path should be trimmed @return own: file name */ -char* fil_make_filepath(const char *path, const fil_space_t::name_type &name, - ib_extention ext, bool trim_name) +char* fil_make_filepath_low(const char *path, + const fil_space_t::name_type &name, + ib_extention extension, bool trim_name) { /* The path may contain the basename of the file, if so we do not need the name. If the path is NULL, we can use the default path, but there needs to be a name. */ ut_ad(path || name.data()); - /* If we are going to strip a name off the path, there better be a - path and a new name to put back on. */ - ut_ad(!trim_name || (path && name.data())); - if (path == NULL) { path = fil_path_to_mysql_datadir; } ulint len = 0; /* current length */ ulint path_len = strlen(path); - const char* suffix = dot_ext[ext]; + const char* suffix = dot_ext[extension]; ulint suffix_len = strlen(suffix); ulint full_len = path_len + 1 + name.size() + suffix_len + 1; @@ -1925,8 +1920,16 @@ char* fil_make_filepath(const char *path, const fil_space_t::name_type &name, char *fil_make_filepath(const char* path, const table_name_t name, ib_extention suffix, bool strip_name) { - return fil_make_filepath(path, {name.m_name, strlen(name.m_name)}, - suffix, strip_name); + return fil_make_filepath_low(path, {name.m_name, strlen(name.m_name)}, + suffix, strip_name); +} + +/** Wrapper function over fil_make_filepath_low() to build directory name. +@param path the directory path or the full path and filename +@return own: directory name */ +static inline char *fil_make_dirpath(const char *path) +{ + return fil_make_filepath_low(path, fil_space_t::name_type{}, NO_EXT, true); } dberr_t fil_space_t::rename(const char *path, bool log, bool replace) @@ -1967,14 +1970,32 @@ dberr_t fil_space_t::rename(const char *path, bool log, bool replace) return DB_TABLESPACE_NOT_FOUND; } - exists= false; - if (replace); - else if (!os_file_status(path, &exists, &ftype) || exists) + if (!replace) { - sql_print_error("InnoDB: Cannot rename '%s' to '%s'" - " because the target file exists.", - old_path, path); - return DB_TABLESPACE_EXISTS; + char *schema_path= fil_make_dirpath(path); + if (!schema_path) + return DB_ERROR; + + exists= false; + bool schema_fail= os_file_status(schema_path, &exists, &ftype) && !exists; + ut_free(schema_path); + + if (schema_fail) + { + sql_print_error("InnoDB: Cannot rename '%s' to '%s'" + " because the target schema directory doesn't exist.", + old_path, path); + return DB_ERROR; + } + + exists= false; + if (!os_file_status(path, &exists, &ftype) || exists) + { + sql_print_error("InnoDB: Cannot rename '%s' to '%s'" + " because the target file exists.", + old_path, path); + return DB_TABLESPACE_EXISTS; + } } mtr_t mtr; @@ -2034,7 +2055,7 @@ fil_ibd_create( static_assert(((UNIV_ZIP_SIZE_MIN >> 1) << 3) == 4096, "compatibility"); -#if defined _WIN32 || defined HAVE_FCNTL_DIRECT +#if defined _WIN32 || defined O_DIRECT ulint type; switch (FSP_FLAGS_GET_ZIP_SSIZE(flags)) { case 1: @@ -2050,7 +2071,7 @@ fil_ibd_create( file = os_file_create( innodb_data_file_key, path, - OS_FILE_CREATE | OS_FILE_ON_ERROR_NO_EXIT, + OS_FILE_CREATE, OS_FILE_AIO, type, srv_read_only_mode, &success); if (!success) { @@ -2826,19 +2847,18 @@ static void fil_invalid_page_access_msg(const char *name, } /** Update the data structures on write completion */ -inline void fil_node_t::complete_write() +void fil_space_t::complete_write() { mysql_mutex_assert_not_owner(&fil_system.mutex); - if (space->purpose != FIL_TYPE_TEMPORARY && - (!fil_system.is_write_through() && !my_disable_sync) && - space->set_needs_flush()) + if (purpose != FIL_TYPE_TEMPORARY && + fil_system.use_unflushed_spaces() && set_needs_flush()) { mysql_mutex_lock(&fil_system.mutex); - if (!space->is_in_unflushed_spaces) + if (!is_in_unflushed_spaces) { - space->is_in_unflushed_spaces= true; - fil_system.unflushed_spaces.push_front(*space); + is_in_unflushed_spaces= true; + fil_system.unflushed_spaces.push_front(*this); } mysql_mutex_unlock(&fil_system.mutex); } @@ -2938,7 +2958,7 @@ io_error: if (!type.is_async()) { if (type.is_write()) { release_sync_write: - node->complete_write(); + complete_write(); release: release(); goto func_exit; @@ -2958,21 +2978,28 @@ void IORequest::write_complete(int io_error) const { ut_ad(fil_validate_skip()); ut_ad(node); + fil_space_t *space= node->space; ut_ad(is_write()); - node->complete_write(); if (!bpage) { ut_ad(!srv_read_only_mode); if (type == IORequest::DBLWR_BATCH) + { buf_dblwr.flush_buffered_writes_completed(*this); + /* Above, we already invoked os_file_flush() on the + doublewrite buffer if needed. */ + goto func_exit; + } else ut_ad(type == IORequest::WRITE_ASYNC); } else buf_page_write_complete(*this, io_error); - node->space->release(); + space->complete_write(); + func_exit: + space->release(); } void IORequest::read_complete(int io_error) const @@ -3153,9 +3180,7 @@ void fil_names_dirty( fil_space_t* space) { -#ifndef SUX_LOCK_GENERIC - ut_ad(log_sys.latch.is_write_locked()); -#endif + ut_ad(log_sys.latch_have_wr()); ut_ad(recv_recovery_is_on()); ut_ad(log_sys.get_lsn() != 0); ut_ad(space->max_lsn == 0); @@ -3169,9 +3194,7 @@ fil_names_dirty( tablespace was modified for the first time since fil_names_clear(). */ ATTRIBUTE_NOINLINE ATTRIBUTE_COLD void mtr_t::name_write() { -#ifndef SUX_LOCK_GENERIC - ut_ad(log_sys.latch.is_write_locked()); -#endif + ut_ad(log_sys.latch_have_wr()); ut_d(fil_space_validate_for_mtr_commit(m_user_space)); ut_ad(!m_user_space->max_lsn); m_user_space->max_lsn= log_sys.get_lsn(); @@ -3195,9 +3218,7 @@ ATTRIBUTE_COLD lsn_t fil_names_clear(lsn_t lsn) { mtr_t mtr; -#ifndef SUX_LOCK_GENERIC - ut_ad(log_sys.latch.is_write_locked()); -#endif + ut_ad(log_sys.latch_have_wr()); ut_ad(lsn); ut_ad(log_sys.is_latest()); diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index 1c20efcdca2..62f90f53a54 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -502,9 +502,10 @@ err_exit: return DB_SUCCESS; } - sql_print_error("InnoDB: %s in datafile: %s, Space ID: " - UINT32PF ", " "Flags: " UINT32PF, - error_txt, m_filepath, m_space_id, m_flags); + sql_print_information( + "InnoDB: %s in datafile: %s, Space ID: " UINT32PF + ", " "Flags: " UINT32PF, + error_txt, m_filepath, m_space_id, m_flags); m_is_valid = false; return DB_CORRUPTION; } diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index 787bda53895..1793ff44a2c 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -258,6 +258,7 @@ inline void xdes_init(const buf_block_t &block, xdes_t *descr, mtr_t *mtr) } /** Mark a page used in an extent descriptor. +@param[in] space tablespace @param[in,out] seg_inode segment inode @param[in,out] iblock segment inode page @param[in] page page number @@ -267,8 +268,9 @@ inline void xdes_init(const buf_block_t &block, xdes_t *descr, mtr_t *mtr) @return error code */ static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t -fseg_mark_page_used(fseg_inode_t *seg_inode, buf_block_t *iblock, - ulint page, xdes_t *descr, buf_block_t *xdes, mtr_t *mtr) +fseg_mark_page_used(const fil_space_t *space, + fseg_inode_t *seg_inode, buf_block_t *iblock, + uint32_t page, xdes_t *descr, buf_block_t *xdes, mtr_t *mtr) { ut_ad(fil_page_get_type(iblock->page.frame) == FIL_PAGE_INODE); ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); @@ -277,15 +279,16 @@ fseg_mark_page_used(fseg_inode_t *seg_inode, buf_block_t *iblock, const uint16_t xoffset= uint16_t(descr - xdes->page.frame + XDES_FLST_NODE); const uint16_t ioffset= uint16_t(seg_inode - iblock->page.frame); + const uint32_t limit= space->free_limit; if (!xdes_get_n_used(descr)) { /* We move the extent from the free list to the NOT_FULL list */ if (dberr_t err= flst_remove(iblock, uint16_t(FSEG_FREE + ioffset), - xdes, xoffset, mtr)) + xdes, xoffset, limit, mtr)) return err; if (dberr_t err= flst_add_last(iblock, uint16_t(FSEG_NOT_FULL + ioffset), - xdes, xoffset, mtr)) + xdes, xoffset, limit, mtr)) return err; } @@ -302,10 +305,10 @@ fseg_mark_page_used(fseg_inode_t *seg_inode, buf_block_t *iblock, { /* We move the extent from the NOT_FULL list to the FULL list */ if (dberr_t err= flst_remove(iblock, uint16_t(FSEG_NOT_FULL + ioffset), - xdes, xoffset, mtr)) + xdes, xoffset, limit, mtr)) return err; if (dberr_t err= flst_add_last(iblock, uint16_t(FSEG_FULL + ioffset), - xdes, xoffset, mtr)) + xdes, xoffset, limit, mtr)) return err; mtr->write<4>(*iblock, seg_inode + FSEG_NOT_FULL_N_USED, not_full_n_used - FSP_EXTENT_SIZE); @@ -890,7 +893,7 @@ fsp_fill_free_list( xdes_set_free(*xdes, descr, 1, mtr); xdes_set_state(*xdes, descr, XDES_FREE_FRAG, mtr); if (dberr_t err= flst_add_last(header, FSP_HEADER_OFFSET + FSP_FREE_FRAG, - xdes, xoffset, mtr)) + xdes, xoffset, space->free_limit, mtr)) return err; byte *n_used= FSP_HEADER_OFFSET + FSP_FRAG_N_USED + header->page.frame; mtr->write<4>(*header, n_used, 2U + mach_read_from_4(n_used)); @@ -899,7 +902,7 @@ fsp_fill_free_list( { if (dberr_t err= flst_add_last(header, FSP_HEADER_OFFSET + FSP_FREE, - xdes, xoffset, mtr)) + xdes, xoffset, space->free_limit, mtr)) return err; count++; } @@ -950,7 +953,11 @@ corrupted: first = flst_get_first(FSP_HEADER_OFFSET + FSP_FREE + header->page.frame); - if (first.page == FIL_NULL) { + if (first.page >= space->free_limit) { + if (first.page != FIL_NULL) { + goto flst_corrupted; + } + *err = fsp_fill_free_list(false, space, header, mtr); if (UNIV_UNLIKELY(*err != DB_SUCCESS)) { goto corrupted; @@ -961,6 +968,17 @@ corrupted: if (first.page == FIL_NULL) { return nullptr; /* No free extents left */ } + if (first.page >= space->free_limit) { + goto flst_corrupted; + } + } + + if (first.boffset < FSP_HEADER_OFFSET + FSP_HEADER_SIZE + || first.boffset >= space->physical_size() + - (XDES_SIZE + FIL_PAGE_DATA_END)) { + flst_corrupted: + *err = DB_CORRUPTION; + goto corrupted; } descr = xdes_lst_get_descriptor(*space, first, mtr, @@ -973,7 +991,7 @@ corrupted: *err = flst_remove(header, FSP_HEADER_OFFSET + FSP_FREE, desc_block, static_cast(descr - desc_block->page.frame + XDES_FLST_NODE), - mtr); + space->free_limit, mtr); if (UNIV_UNLIKELY(*err != DB_SUCCESS)) { return nullptr; } @@ -990,11 +1008,12 @@ MY_ATTRIBUTE((nonnull, warn_unused_result)) @param[in,out] xdes extent descriptor page @param[in,out] descr extent descriptor @param[in] bit slot to allocate in the extent +@param[in] space tablespace @param[in,out] mtr mini-transaction @return error code */ static dberr_t fsp_alloc_from_free_frag(buf_block_t *header, buf_block_t *xdes, xdes_t *descr, - ulint bit, mtr_t *mtr) + uint32_t bit, fil_space_t *space, mtr_t *mtr) { if (UNIV_UNLIKELY(xdes_get_state(descr) != XDES_FREE_FRAG || !xdes_is_free(descr, bit))) @@ -1007,14 +1026,15 @@ fsp_alloc_from_free_frag(buf_block_t *header, buf_block_t *xdes, xdes_t *descr, if (xdes_is_full(descr)) { + const uint32_t limit= space->free_limit; /* The fragment is full: move it to another list */ const uint16_t xoffset= static_cast(descr - xdes->page.frame + XDES_FLST_NODE); if (dberr_t err= flst_remove(header, FSP_HEADER_OFFSET + FSP_FREE_FRAG, - xdes, xoffset, mtr)) + xdes, xoffset, limit, mtr)) return err; if (dberr_t err= flst_add_last(header, FSP_HEADER_OFFSET + FSP_FULL_FRAG, - xdes, xoffset, mtr)) + xdes, xoffset, limit, mtr)) return err; xdes_set_state(*xdes, descr, XDES_FULL_FRAG, mtr); n_used-= FSP_EXTENT_SIZE; @@ -1076,8 +1096,11 @@ buf_block_t *fsp_alloc_free_page(fil_space_t *space, uint32_t hint, /* Else take the first extent in free_frag list */ fil_addr_t first = flst_get_first(FSP_HEADER_OFFSET + FSP_FREE_FRAG + block->page.frame); - if (first.page == FIL_NULL) + if (first.page >= space->free_limit) { + if (first.page != FIL_NULL) + goto flst_corrupted; + /* There are no partially full fragments: allocate a free extent and add it to the FREE_FRAG list. NOTE that the allocation may have as a side-effect that an extent containing a descriptor @@ -1088,13 +1111,23 @@ buf_block_t *fsp_alloc_free_page(fil_space_t *space, uint32_t hint, return nullptr; *err= flst_add_last(block, FSP_HEADER_OFFSET + FSP_FREE_FRAG, xdes, static_cast(descr - xdes->page.frame + - XDES_FLST_NODE), mtr); + XDES_FLST_NODE), + space->free_limit, mtr); if (UNIV_UNLIKELY(*err != DB_SUCCESS)) return nullptr; xdes_set_state(*xdes, descr, XDES_FREE_FRAG, mtr); } else { + if (first.boffset < FSP_HEADER_OFFSET + FSP_HEADER_SIZE || + first.boffset >= space->physical_size() - + (XDES_SIZE + FIL_PAGE_DATA_END)) + { + flst_corrupted: + *err= DB_CORRUPTION; + goto err_exit; + } + descr= xdes_lst_get_descriptor(*space, first, mtr, &xdes, err); if (!descr) return nullptr; @@ -1141,7 +1174,7 @@ buf_block_t *fsp_alloc_free_page(fil_space_t *space, uint32_t hint, } } - *err= fsp_alloc_from_free_frag(block, xdes, descr, free, mtr); + *err= fsp_alloc_from_free_frag(block, xdes, descr, free, space, mtr); if (UNIV_UNLIKELY(*err != DB_SUCCESS)) goto corrupted; return fsp_page_create(space, page_no, init_mtr); @@ -1180,7 +1213,8 @@ static dberr_t fsp_free_extent(fil_space_t* space, uint32_t offset, space->free_len++; return flst_add_last(block, FSP_HEADER_OFFSET + FSP_FREE, xdes, static_cast(descr - xdes->page.frame + - XDES_FLST_NODE), mtr); + XDES_FLST_NODE), + space->free_limit, mtr); } MY_ATTRIBUTE((nonnull)) @@ -1234,16 +1268,17 @@ static dberr_t fsp_free_page(fil_space_t *space, uint32_t offset, mtr_t *mtr) const uint16_t xoffset= static_cast(descr - xdes->page.frame + XDES_FLST_NODE); + const uint32_t limit = space->free_limit; if (state == XDES_FULL_FRAG) { /* The fragment was full: move it to another list */ err = flst_remove(header, FSP_HEADER_OFFSET + FSP_FULL_FRAG, - xdes, xoffset, mtr); + xdes, xoffset, limit, mtr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { return err; } err = flst_add_last(header, FSP_HEADER_OFFSET + FSP_FREE_FRAG, - xdes, xoffset, mtr); + xdes, xoffset, limit, mtr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { return err; } @@ -1265,7 +1300,7 @@ static dberr_t fsp_free_page(fil_space_t *space, uint32_t offset, mtr_t *mtr) if (!xdes_get_n_used(descr)) { /* The extent has become free: move it to another list */ err = flst_remove(header, FSP_HEADER_OFFSET + FSP_FREE_FRAG, - xdes, xoffset, mtr); + xdes, xoffset, limit, mtr); if (err == DB_SUCCESS) { err = fsp_free_extent(space, offset, mtr); } @@ -1359,7 +1394,7 @@ static dberr_t fsp_alloc_seg_inode_page(fil_space_t *space, #endif return flst_add_last(header, FSP_HEADER_OFFSET + FSP_SEG_INODES_FREE, - block, FSEG_INODE_PAGE_NODE, mtr); + block, FSEG_INODE_PAGE_NODE, space->free_limit, mtr); } MY_ATTRIBUTE((nonnull, warn_unused_result)) @@ -1415,12 +1450,13 @@ fsp_alloc_seg_inode(fil_space_t *space, buf_block_t *header, { /* There are no other unused headers left on the page: move it to another list */ + const uint32_t limit= space->free_limit; *err= flst_remove(header, FSP_HEADER_OFFSET + FSP_SEG_INODES_FREE, - block, FSEG_INODE_PAGE_NODE, mtr); + block, FSEG_INODE_PAGE_NODE, limit, mtr); if (UNIV_UNLIKELY(*err != DB_SUCCESS)) return nullptr; *err= flst_add_last(header, FSP_HEADER_OFFSET + FSP_SEG_INODES_FULL, - block, FSEG_INODE_PAGE_NODE, mtr); + block, FSEG_INODE_PAGE_NODE, limit, mtr); if (UNIV_UNLIKELY(*err != DB_SUCCESS)) return nullptr; } @@ -1453,16 +1489,17 @@ static void fsp_free_seg_inode(fil_space_t *space, fseg_inode_t *inode, } const ulint physical_size= space->physical_size(); + const uint32_t limit= space->free_limit; if (ULINT_UNDEFINED == fsp_seg_inode_page_find_free(iblock->page.frame, 0, physical_size)) { /* Move the page to another list */ if (flst_remove(header, FSP_HEADER_OFFSET + FSP_SEG_INODES_FULL, - iblock, FSEG_INODE_PAGE_NODE, mtr) != DB_SUCCESS) + iblock, FSEG_INODE_PAGE_NODE, limit, mtr) != DB_SUCCESS) return; if (flst_add_last(header, FSP_HEADER_OFFSET + FSP_SEG_INODES_FREE, - iblock, FSEG_INODE_PAGE_NODE, mtr) != DB_SUCCESS) + iblock, FSEG_INODE_PAGE_NODE, limit, mtr) != DB_SUCCESS) return; } @@ -1474,7 +1511,7 @@ static void fsp_free_seg_inode(fil_space_t *space, fseg_inode_t *inode, /* There are no other used headers left on the page: free it */ if (flst_remove(header, FSP_HEADER_OFFSET + FSP_SEG_INODES_FREE, - iblock, FSEG_INODE_PAGE_NODE, mtr) == DB_SUCCESS) + iblock, FSEG_INODE_PAGE_NODE, limit, mtr) == DB_SUCCESS) fsp_free_page(space, iblock->page.id().page_no(), mtr); } @@ -1846,7 +1883,8 @@ static dberr_t fseg_fill_free_list(const fseg_inode_t *inode, static_cast(inode - iblock->page.frame + FSEG_FREE), xdes, static_cast(descr - xdes->page.frame + - XDES_FLST_NODE), mtr)) + XDES_FLST_NODE), + space->free_limit, mtr)) return err; xdes_set_state(*xdes, descr, XDES_FSEG, mtr); mtr->memcpy(*xdes, descr + XDES_ID, inode + FSEG_ID, 8); @@ -1881,11 +1919,25 @@ fseg_alloc_free_extent( ut_ad(!memcmp(FSEG_MAGIC_N_BYTES, FSEG_MAGIC_N + inode, 4)); ut_d(space->modify_check(*mtr)); + if (UNIV_UNLIKELY(page_offset(inode) < FSEG_ARR_OFFSET)) + { + corrupted: + *err= DB_CORRUPTION; + space->set_corrupted(); + return nullptr; + } + if (flst_get_len(inode + FSEG_FREE)) { + const fil_addr_t first= flst_get_first(inode + FSEG_FREE); + if (first.page >= space->free_limit || + first.boffset < FSP_HEADER_OFFSET + FSP_HEADER_SIZE || + first.boffset >= space->physical_size() - + (XDES_SIZE + FIL_PAGE_DATA_END)) + goto corrupted; + /* Segment free list is not empty, allocate from it */ - return xdes_lst_get_descriptor(*space, flst_get_first(inode + FSEG_FREE), - mtr, xdes, err); + return xdes_lst_get_descriptor(*space, first, mtr, xdes, err); } xdes_t* descr= fsp_alloc_free_extent(space, 0, xdes, mtr, err); @@ -1897,7 +1949,8 @@ fseg_alloc_free_extent( static_cast(inode - iblock->page.frame + FSEG_FREE), *xdes, static_cast(descr - (*xdes)->page.frame + - XDES_FLST_NODE), mtr); + XDES_FLST_NODE), + space->free_limit, mtr); if (UNIV_LIKELY(*err != DB_SUCCESS)) return nullptr; /* Try to fill the segment free list */ @@ -1983,29 +2036,42 @@ fseg_alloc_free_page_low( } } - /* In the big if-else below we look for ret_page and ret_descr */ - /*-------------------------------------------------------------*/ - if ((xdes_get_state(descr) == XDES_FSEG) - && mach_read_from_8(descr + XDES_ID) == seg_id - && xdes_is_free(descr, hint % FSP_EXTENT_SIZE)) { + const uint32_t extent_size = FSP_EXTENT_SIZE; + ret_descr = descr; + /* Try to get the page from extent which belongs to segment */ + if (xdes_get_state(descr) == XDES_FSEG + && mach_read_from_8(descr + XDES_ID) == seg_id) { + /* Get the page from the segment extent */ + if (xdes_is_free(descr, hint % extent_size)) { take_hinted_page: - /* 1. We can take the hinted page - =================================*/ - ret_descr = descr; - ret_page = hint; - /* Skip the check for extending the tablespace. If the - page hint were not within the size of the tablespace, - we would have got (descr == NULL) above and reset the hint. */ - goto got_hinted_page; - /*-----------------------------------------------------------*/ - } else if (xdes_get_state(descr) == XDES_FREE - && reserved - used < reserved / FSEG_FILLFACTOR - && used >= FSEG_FRAG_LIMIT) { + ret_page = hint; + goto got_hinted_page; + } else if (!xdes_is_full(descr)) { + /* Take the page from the same extent as the + hinted page (and the extent already belongs to + the segment) */ + ret_page = xdes_find_free(descr, hint % extent_size); + if (ret_page == FIL_NULL) { + ut_ad(!has_done_reservation); + return nullptr; + } + ret_page += xdes_get_offset(ret_descr); + goto alloc_done; + } + } - /* 2. We allocate the free extent from space and can take - ========================================================= - the hinted page - ===============*/ + /** If the number of unused but reserved pages in a segment is + esser than minimum value of 1/8 of reserved pages or + 4 * FSP_EXTENT_SIZE and there are at least half of extent size + used pages, then we allow a new empty extent to be added to + the segment in fseg_alloc_free_page_general(). Otherwise, we use + unused pages of the segment. */ + if (used < extent_size / 2 || + reserved - used >= reserved / 8 || + reserved - used >= extent_size * 4) { + } else if (xdes_get_state(descr) == XDES_FREE) { + /* Allocate the free extent from space and can + take the hinted page */ ret_descr = fsp_alloc_free_extent(space, hint, &xdes, mtr, err); @@ -2025,61 +2091,42 @@ take_hinted_page: + FSEG_FREE), xdes, static_cast(ret_descr - xdes->page.frame - + XDES_FLST_NODE), mtr); + + XDES_FLST_NODE), + space->free_limit, mtr); if (UNIV_UNLIKELY(*err != DB_SUCCESS)) { return nullptr; } /* Try to fill the segment free list */ *err = fseg_fill_free_list(seg_inode, iblock, space, - hint + FSP_EXTENT_SIZE, mtr); + hint + extent_size, mtr); if (UNIV_UNLIKELY(*err != DB_SUCCESS)) { return nullptr; } goto take_hinted_page; - /*-----------------------------------------------------------*/ - } else if ((direction != FSP_NO_DIR) - && ((reserved - used) < reserved / FSEG_FILLFACTOR) - && (used >= FSEG_FRAG_LIMIT) - && (ret_descr = fseg_alloc_free_extent(seg_inode, iblock, - &xdes, space, - mtr, err))) { - /* 3. We take any free extent (which was already assigned above - =============================================================== - in the if-condition to ret_descr) and take the lowest or - ======================================================== - highest page in it, depending on the direction - ==============================================*/ + } else if (direction != FSP_NO_DIR) { + + ret_descr = fseg_alloc_free_extent(seg_inode, iblock, + &xdes, space, mtr, err); + + if (!ret_descr) { + ut_ad(*err != DB_SUCCESS); + return nullptr; + } + /* Take any free extent (which was already assigned + above in the if-condition to ret_descr) and take the + lowest or highest page in it, depending on the direction */ ret_page = xdes_get_offset(ret_descr); if (direction == FSP_DOWN) { - ret_page += FSP_EXTENT_SIZE - 1; + ret_page += extent_size - 1; } - ut_ad(!has_done_reservation || ret_page != FIL_NULL); - /*-----------------------------------------------------------*/ - } else if (UNIV_UNLIKELY(*err != DB_SUCCESS)) { - return nullptr; - } else if ((xdes_get_state(descr) == XDES_FSEG) - && mach_read_from_8(descr + XDES_ID) == seg_id - && (!xdes_is_full(descr))) { + goto alloc_done; + } - /* 4. We can take the page from the same extent as the - ====================================================== - hinted page (and the extent already belongs to the - ================================================== - segment) - ========*/ - ret_descr = descr; - ret_page = xdes_find_free(ret_descr, hint % FSP_EXTENT_SIZE); - if (ret_page == FIL_NULL) { - ut_ad(!has_done_reservation); - } else { - ret_page += xdes_get_offset(ret_descr); - } - /*-----------------------------------------------------------*/ - } else if (reserved - used > 0) { - /* 5. We take any unused page from the segment - ==============================================*/ + /* Try to take individual page from the segment or tablespace */ + if (reserved - used > 0) { + /* Take any unused page from the segment */ fil_addr_t first; if (flst_get_len(seg_inode + FSEG_NOT_FULL) > 0) { @@ -2088,7 +2135,15 @@ take_hinted_page: first = flst_get_first(seg_inode + FSEG_FREE); } else { ut_ad(!has_done_reservation); - return(NULL); + return nullptr; + } + + if (first.page >= space->free_limit + || first.boffset < FSP_HEADER_OFFSET + FSP_HEADER_SIZE + || first.boffset >= space->physical_size() + - (XDES_SIZE + FIL_PAGE_DATA_END)) { + *err= DB_CORRUPTION; + return nullptr; } ret_descr = xdes_lst_get_descriptor(*space, first, mtr, &xdes); @@ -2102,10 +2157,9 @@ take_hinted_page: } else { ret_page += xdes_get_offset(ret_descr); } - /*-----------------------------------------------------------*/ - } else if (used < FSEG_FRAG_LIMIT) { - /* 6. We allocate an individual page from the space - ===================================================*/ + + } else if (used < extent_size / 2) { + /* Allocate an individual page from the space */ buf_block_t* block = fsp_alloc_free_page( space, hint, mtr, init_mtr, err); @@ -2128,13 +2182,11 @@ take_hinted_page: /* fsp_alloc_free_page() invoked fsp_init_file_page() already. */ return(block); - /*-----------------------------------------------------------*/ } else { - /* 7. We allocate a new extent and take its first page - ======================================================*/ + /* In worst case, try to allocate a new extent + and take its first page */ ret_descr = fseg_alloc_free_extent(seg_inode, iblock, &xdes, space, mtr, err); - if (!ret_descr) { ut_ad(!has_done_reservation || *err); return nullptr; @@ -2147,14 +2199,13 @@ take_hinted_page: /* Page could not be allocated */ ut_ad(!has_done_reservation); - return(NULL); + return nullptr; } - +alloc_done: if (space->size <= ret_page && !is_predefined_tablespace(space->id)) { /* It must be that we are extending a single-table tablespace whose size is still < 64 pages */ - - if (ret_page >= FSP_EXTENT_SIZE) { + if (ret_page >= extent_size) { sql_print_error("InnoDB: Trying to extend '%s'" " by single page(s) though the" " space size " UINT32PF "." @@ -2162,33 +2213,34 @@ take_hinted_page: space->chain.start->name, space->size, ret_page); ut_ad(!has_done_reservation); - return(NULL); + return nullptr; } if (!fsp_try_extend_data_file_with_pages( space, ret_page, header, mtr)) { /* No disk space left */ ut_ad(!has_done_reservation); - return(NULL); + return nullptr; } } -got_hinted_page: - /* ret_descr == NULL if the block was allocated from free_frag - (XDES_FREE_FRAG) */ + /* Skip the check for extending the tablespace. + If the page hint were not within the size of the tablespace, + descr set to nullptr above and reset the hint and the block + was allocated from free_frag (XDES_FREE_FRAG) */ if (ret_descr != NULL) { +got_hinted_page: /* At this point we know the extent and the page offset. The extent is still in the appropriate list (FSEG_NOT_FULL or FSEG_FREE), and the page is not yet marked as used. */ - ut_d(buf_block_t* xxdes); ut_ad(xdes_get_descriptor(space, ret_page, mtr, err, &xxdes) == ret_descr); ut_ad(xdes == xxdes); - ut_ad(xdes_is_free(ret_descr, ret_page % FSP_EXTENT_SIZE)); + ut_ad(xdes_is_free(ret_descr, ret_page % extent_size)); - *err = fseg_mark_page_used(seg_inode, iblock, ret_page, - ret_descr, xdes, mtr); + *err = fseg_mark_page_used(space, seg_inode, iblock, ret_page, + ret_descr, xdes, mtr); if (UNIV_UNLIKELY(*err != DB_SUCCESS)) { return nullptr; } @@ -2529,18 +2581,19 @@ corrupted: const uint16_t xoffset= uint16_t(descr - xdes->page.frame + XDES_FLST_NODE); const uint16_t ioffset= uint16_t(seg_inode - iblock->page.frame); + const uint32_t limit = space->free_limit; if (xdes_is_full(descr)) { /* The fragment is full: move it to another list */ err = flst_remove(iblock, static_cast(FSEG_FULL + ioffset), - xdes, xoffset, mtr); + xdes, xoffset, limit, mtr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { return err; } err = flst_add_last(iblock, static_cast(FSEG_NOT_FULL + ioffset), - xdes, xoffset, mtr); + xdes, xoffset, limit, mtr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { return err; } @@ -2558,7 +2611,7 @@ corrupted: if (!xdes_get_n_used(descr)) { err = flst_remove(iblock, static_cast(FSEG_NOT_FULL + ioffset), - xdes, xoffset, mtr); + xdes, xoffset, limit, mtr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { return err; } @@ -2703,11 +2756,12 @@ fseg_free_extent( #endif /* BTR_CUR_HASH_ADAPT */ uint16_t lst; + uint32_t limit = space->free_limit; if (xdes_is_full(descr)) { lst = static_cast(FSEG_FULL + ioffset); remove: - err = flst_remove(iblock, lst, xdes, xoffset, mtr); + err = flst_remove(iblock, lst, xdes, xoffset, limit, mtr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { return err; } @@ -2717,7 +2771,7 @@ remove: } else { err = flst_remove( iblock, static_cast(FSEG_NOT_FULL + ioffset), - xdes, xoffset, mtr); + xdes, xoffset, limit, mtr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) { return err; } @@ -2967,7 +3021,10 @@ fseg_get_first_extent( return nullptr; } - if (first.page == FIL_NULL) + if (first.page >= space->free_limit || + first.boffset < FSP_HEADER_OFFSET + FSP_HEADER_SIZE || + first.boffset >= space->physical_size() - + (XDES_SIZE + FIL_PAGE_DATA_END)) goto corrupted; return xdes_lst_get_descriptor(*space, first, mtr, nullptr, err); @@ -3553,12 +3610,12 @@ func_exit: if (fixed_size > last_used_extent) last_used_extent= fixed_size; - my_bool old_dblwr_buf= srv_use_doublewrite_buf; + bool old_dblwr_buf= buf_dblwr.in_use(); /* Flush all pages in buffer pool, so that it doesn't have to use doublewrite buffer and disable dblwr and there should be enough space in redo log */ log_make_checkpoint(); - srv_use_doublewrite_buf= false; + fil_system.set_use_doublewrite(false); buf_block_t *header= nullptr; ut_ad(!fsp_tablespace_validate(space)); @@ -3645,7 +3702,7 @@ mtr_max: mtr.commit_shrink(*space, last_used_extent); sql_print_information("InnoDB: System tablespace truncated successfully"); - srv_use_doublewrite_buf= old_dblwr_buf; + fil_system.set_use_doublewrite(old_dblwr_buf); } inline void fil_space_t::clear_freed_ranges(uint32_t threshold) diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 0775d939002..4d9a1d3a33f 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -2187,6 +2187,22 @@ fts_trx_row_get_new_state( return(result); } +/** Compare two doubly indirected pointers */ +static int fts_ptr2_cmp(const void *p1, const void *p2) +{ + const void *a= **static_cast(p1); + const void *b= **static_cast(p2); + return b > a ? -1 : a > b; +} + +/** Compare a singly indirected pointer to a doubly indirected one */ +static int fts_ptr1_ptr2_cmp(const void *p1, const void *p2) +{ + const void *a= *static_cast(p1); + const void *b= **static_cast(p2); + return b > a ? -1 : a > b; +} + /******************************************************************//** Create a savepoint instance. @return savepoint instance */ @@ -2209,8 +2225,8 @@ fts_savepoint_create( savepoint->name = mem_heap_strdup(heap, name); } - savepoint->tables = rbt_create( - sizeof(fts_trx_table_t*), fts_trx_table_cmp); + static_assert(!offsetof(fts_trx_table_t, table), "ABI"); + savepoint->tables = rbt_create(sizeof(fts_trx_table_t*), fts_ptr2_cmp); return(savepoint); } @@ -2258,6 +2274,19 @@ fts_trx_create( return(ftt); } +/** Compare two doc_id */ +static inline int doc_id_cmp(doc_id_t a, doc_id_t b) +{ + return b > a ? -1 : a > b; +} + +/** Compare two DOC_ID. */ +int fts_doc_id_cmp(const void *p1, const void *p2) +{ + return doc_id_cmp(*static_cast(p1), + *static_cast(p2)); +} + /******************************************************************//** Create an FTS trx table. @return FTS trx table */ @@ -2276,7 +2305,8 @@ fts_trx_table_create( ftt->table = table; ftt->fts_trx = fts_trx; - ftt->rows = rbt_create(sizeof(fts_trx_row_t), fts_trx_row_doc_id_cmp); + static_assert(!offsetof(fts_trx_row_t, doc_id), "ABI"); + ftt->rows = rbt_create(sizeof(fts_trx_row_t), fts_doc_id_cmp); return(ftt); } @@ -2300,7 +2330,8 @@ fts_trx_table_clone( ftt->table = ftt_src->table; ftt->fts_trx = ftt_src->fts_trx; - ftt->rows = rbt_create(sizeof(fts_trx_row_t), fts_trx_row_doc_id_cmp); + static_assert(!offsetof(fts_trx_row_t, doc_id), "ABI"); + ftt->rows = rbt_create(sizeof(fts_trx_row_t), fts_doc_id_cmp); /* Copy the rb tree values to the new savepoint. */ rbt_merge_uniq(ftt->rows, ftt_src->rows); @@ -2325,13 +2356,9 @@ fts_trx_init( { fts_trx_table_t* ftt; ib_rbt_bound_t parent; - ib_rbt_t* tables; - fts_savepoint_t* savepoint; - - savepoint = static_cast(ib_vector_last(savepoints)); - - tables = savepoint->tables; - rbt_search_cmp(tables, &parent, &table->id, fts_trx_table_id_cmp, NULL); + ib_rbt_t* tables = static_cast( + ib_vector_last(savepoints))->tables; + rbt_search_cmp(tables, &parent, &table, fts_ptr1_ptr2_cmp, nullptr); if (parent.result == 0) { fts_trx_table_t** fttp; @@ -3860,6 +3887,13 @@ fts_write_node( return(error); } +/** Sort an array of doc_id */ +void fts_doc_ids_sort(ib_vector_t *doc_ids) +{ + doc_id_t *const data= reinterpret_cast(doc_ids->data); + std::sort(data, data + doc_ids->used); +} + /*********************************************************************//** Add rows to the DELETED_CACHE table. @return DB_SUCCESS if all went well else error code*/ @@ -3881,7 +3915,7 @@ fts_sync_add_deleted_cache( ut_a(ib_vector_size(doc_ids) > 0); - ib_vector_sort(doc_ids, fts_doc_id_cmp); + fts_doc_ids_sort(doc_ids); info = pars_info_create(); @@ -5575,8 +5609,8 @@ fts_savepoint_rollback_last_stmt( l_ftt = rbt_value(fts_trx_table_t*, node); rbt_search_cmp( - s_tables, &parent, &(*l_ftt)->table->id, - fts_trx_table_id_cmp, NULL); + s_tables, &parent, &(*l_ftt)->table, + fts_ptr1_ptr2_cmp, nullptr); if (parent.result == 0) { fts_trx_table_t** s_ftt; diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index fe31767d901..30889e5903c 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -1016,7 +1016,7 @@ fts_table_fetch_doc_ids( que_graph_free(graph); if (error == DB_SUCCESS) { - ib_vector_sort(doc_ids->doc_ids, fts_doc_id_cmp); + fts_doc_ids_sort(doc_ids->doc_ids); } if (alloc_bk_trx) { diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc index 9c92a1171cf..b8f220768a0 100644 --- a/storage/innobase/fts/fts0que.cc +++ b/storage/innobase/fts/fts0que.cc @@ -385,22 +385,6 @@ fts_query_terms_in_document( ulint* total); /*!< out: total words in document */ #endif -/******************************************************************** -Compare two fts_doc_freq_t doc_ids. -@return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */ -UNIV_INLINE -int -fts_freq_doc_id_cmp( -/*================*/ - const void* p1, /*!< in: id1 */ - const void* p2) /*!< in: id2 */ -{ - const fts_doc_freq_t* fq1 = (const fts_doc_freq_t*) p1; - const fts_doc_freq_t* fq2 = (const fts_doc_freq_t*) p2; - - return((int) (fq1->doc_id - fq2->doc_id)); -} - #if 0 /*******************************************************************//** Print the table used for calculating LCS. */ @@ -506,14 +490,11 @@ fts_query_compare_rank( if (r2->rank < r1->rank) { return(-1); } else if (r2->rank == r1->rank) { - if (r1->doc_id < r2->doc_id) { - return(1); - } else if (r1->doc_id > r2->doc_id) { - return(1); + return -1; } - return(0); + return r1->doc_id > r2->doc_id; } return(1); @@ -674,8 +655,9 @@ fts_query_add_word_freq( word_freq.doc_count = 0; + static_assert(!offsetof(fts_doc_freq_t, doc_id), "ABI"); word_freq.doc_freqs = rbt_create( - sizeof(fts_doc_freq_t), fts_freq_doc_id_cmp); + sizeof(fts_doc_freq_t), fts_doc_id_cmp); parent.last = rbt_add_node( query->word_freqs, &parent, &word_freq); @@ -1253,8 +1235,9 @@ fts_query_intersect( /* Create the rb tree that will hold the doc ids of the intersection. */ + static_assert(!offsetof(fts_ranking_t, doc_id), "ABI"); query->intersection = rbt_create( - sizeof(fts_ranking_t), fts_ranking_doc_id_cmp); + sizeof(fts_ranking_t), fts_doc_id_cmp); query->total_size += SIZEOF_RBT_CREATE; @@ -1540,8 +1523,9 @@ fts_merge_doc_ids( to create a new result set for fts_query_intersect(). */ if (query->oper == FTS_EXIST) { + static_assert(!offsetof(fts_ranking_t, doc_id), "ABI"); query->intersection = rbt_create( - sizeof(fts_ranking_t), fts_ranking_doc_id_cmp); + sizeof(fts_ranking_t), fts_doc_id_cmp); query->total_size += SIZEOF_RBT_CREATE; } @@ -3012,8 +2996,9 @@ fts_query_visitor( if (query->oper == FTS_EXIST) { ut_ad(query->intersection == NULL); + static_assert(!offsetof(fts_ranking_t, doc_id), "ABI"); query->intersection = rbt_create( - sizeof(fts_ranking_t), fts_ranking_doc_id_cmp); + sizeof(fts_ranking_t), fts_doc_id_cmp); query->total_size += SIZEOF_RBT_CREATE; } @@ -3123,8 +3108,8 @@ fts_ast_visit_sub_exp( /* Create new result set to store the sub-expression result. We will merge this result set with the parent after processing. */ - query->doc_ids = rbt_create(sizeof(fts_ranking_t), - fts_ranking_doc_id_cmp); + static_assert(!offsetof(fts_ranking_t, doc_id), "ABI"); + query->doc_ids = rbt_create(sizeof(fts_ranking_t), fts_doc_id_cmp); query->total_size += SIZEOF_RBT_CREATE; @@ -3661,8 +3646,9 @@ fts_query_prepare_result( result = static_cast( ut_zalloc_nokey(sizeof(*result))); + static_assert(!offsetof(fts_ranking_t, doc_id), "ABI"); result->rankings_by_id = rbt_create( - sizeof(fts_ranking_t), fts_ranking_doc_id_cmp); + sizeof(fts_ranking_t), fts_doc_id_cmp); query->total_size += sizeof(fts_result_t) + SIZEOF_RBT_CREATE; result_is_null = true; @@ -4038,7 +4024,7 @@ fts_query( DEBUG_SYNC_C("fts_deleted_doc_ids_append"); /* Sort the vector so that we can do a binary search over the ids. */ - ib_vector_sort(query.deleted->doc_ids, fts_doc_id_cmp); + fts_doc_ids_sort(query.deleted->doc_ids); /* Convert the query string to lower case before parsing. We own the ut_malloc'ed result and so remember to free it before return. */ @@ -4065,8 +4051,9 @@ fts_query( query.heap = mem_heap_create(128); /* Create the rb tree for the doc id (current) set. */ + static_assert(!offsetof(fts_ranking_t, doc_id), "ABI"); query.doc_ids = rbt_create( - sizeof(fts_ranking_t), fts_ranking_doc_id_cmp); + sizeof(fts_ranking_t), fts_doc_id_cmp); query.parser = index->parser; query.total_size += SIZEOF_RBT_CREATE; diff --git a/storage/innobase/fut/fut0lst.cc b/storage/innobase/fut/fut0lst.cc index 1a984596d64..84b38bc6cf4 100644 --- a/storage/innobase/fut/fut0lst.cc +++ b/storage/innobase/fut/fut0lst.cc @@ -121,17 +121,18 @@ static void flst_add_to_empty(buf_block_t *base, uint16_t boffset, } /** Insert a node after another one. -@param[in,out] base base node block -@param[in] boffset byte offset of the base node -@param[in,out] cur insert position block -@param[in] coffset byte offset of the insert position -@param[in,out] add block to be added -@param[in] aoffset byte offset of the block to be added -@param[in,out] mtr mini-transaction */ +@param base base node block +@param boffset byte offset of the base node +@param cur insert position block +@param coffset byte offset of the insert position +@param add block to be added +@param aoffset byte offset of the block to be added +@param limit fil_space_t::free_limit +@param mtr mini-transaction */ static dberr_t flst_insert_after(buf_block_t *base, uint16_t boffset, buf_block_t *cur, uint16_t coffset, buf_block_t *add, uint16_t aoffset, - mtr_t *mtr) + uint32_t limit, mtr_t *mtr) { ut_ad(base != cur || boffset != coffset); ut_ad(base != add || boffset != aoffset); @@ -147,6 +148,15 @@ static dberr_t flst_insert_after(buf_block_t *base, uint16_t boffset, MTR_MEMO_PAGE_SX_FIX)); fil_addr_t next_addr= flst_get_next_addr(cur->page.frame + coffset); + if (next_addr.page >= limit) + { + if (UNIV_UNLIKELY(next_addr.page != FIL_NULL)) + return DB_CORRUPTION; + } + else if (UNIV_UNLIKELY(next_addr.boffset < FIL_PAGE_DATA || + next_addr.boffset >= base->physical_size() - + FIL_PAGE_DATA_END)) + return DB_CORRUPTION; flst_write_addr(*add, add->page.frame + aoffset + FLST_PREV, cur->page.id().page_no(), coffset, mtr); @@ -175,18 +185,19 @@ static dberr_t flst_insert_after(buf_block_t *base, uint16_t boffset, } /** Insert a node before another one. -@param[in,out] base base node block -@param[in] boffset byte offset of the base node -@param[in,out] cur insert position block -@param[in] coffset byte offset of the insert position -@param[in,out] add block to be added -@param[in] aoffset byte offset of the block to be added -@param[in,out] mtr mini-transaction +@param base base node block +@param boffset byte offset of the base node +@param cur insert position block +@param coffset byte offset of the insert position +@param add block to be added +@param aoffset byte offset of the block to be added +@param limit fil_space_t::free_limit +@param mtr mini-transaction @return error code */ static dberr_t flst_insert_before(buf_block_t *base, uint16_t boffset, buf_block_t *cur, uint16_t coffset, buf_block_t *add, uint16_t aoffset, - mtr_t *mtr) + uint32_t limit, mtr_t *mtr) { ut_ad(base != cur || boffset != coffset); ut_ad(base != add || boffset != aoffset); @@ -202,6 +213,15 @@ static dberr_t flst_insert_before(buf_block_t *base, uint16_t boffset, MTR_MEMO_PAGE_SX_FIX)); fil_addr_t prev_addr= flst_get_prev_addr(cur->page.frame + coffset); + if (prev_addr.page >= limit) + { + if (UNIV_UNLIKELY(prev_addr.page != FIL_NULL)) + return DB_CORRUPTION; + } + else if (UNIV_UNLIKELY(prev_addr.boffset < FIL_PAGE_DATA || + prev_addr.boffset >= base->physical_size() - + FIL_PAGE_DATA_END)) + return DB_CORRUPTION; flst_write_addr(*add, add->page.frame + aoffset + FLST_PREV, prev_addr.page, prev_addr.boffset, mtr); @@ -242,14 +262,9 @@ void flst_init(const buf_block_t& block, byte *base, mtr_t *mtr) flst_zero_both(block, base + FLST_FIRST, mtr); } -/** Append a file list node to a list. -@param[in,out] base base node block -@param[in] boffset byte offset of the base node -@param[in,out] add block to be added -@param[in] aoffset byte offset of the node to be added -@param[in,outr] mtr mini-transaction */ dberr_t flst_add_last(buf_block_t *base, uint16_t boffset, - buf_block_t *add, uint16_t aoffset, mtr_t *mtr) + buf_block_t *add, uint16_t aoffset, + uint32_t limit, mtr_t *mtr) { ut_ad(base != add || boffset != aoffset); ut_ad(boffset < base->physical_size()); @@ -266,6 +281,13 @@ dberr_t flst_add_last(buf_block_t *base, uint16_t boffset, else { fil_addr_t addr= flst_get_last(base->page.frame + boffset); + if (UNIV_UNLIKELY(addr.page >= limit)) + return DB_CORRUPTION; + else if (UNIV_UNLIKELY(addr.boffset < FIL_PAGE_DATA || + addr.boffset >= base->physical_size() - + FIL_PAGE_DATA_END)) + return DB_CORRUPTION; + buf_block_t *cur= add; dberr_t err; if (addr.page != add->page.id().page_no() && @@ -274,19 +296,13 @@ dberr_t flst_add_last(buf_block_t *base, uint16_t boffset, BUF_GET_POSSIBLY_FREED, mtr, &err))) return err; return flst_insert_after(base, boffset, cur, addr.boffset, - add, aoffset, mtr); + add, aoffset, limit, mtr); } } -/** Prepend a file list node to a list. -@param[in,out] base base node block -@param[in] boffset byte offset of the base node -@param[in,out] add block to be added -@param[in] aoffset byte offset of the node to be added -@param[in,out] mtr mini-transaction -@return error code */ dberr_t flst_add_first(buf_block_t *base, uint16_t boffset, - buf_block_t *add, uint16_t aoffset, mtr_t *mtr) + buf_block_t *add, uint16_t aoffset, + uint32_t limit, mtr_t *mtr) { ut_ad(base != add || boffset != aoffset); ut_ad(boffset < base->physical_size()); @@ -304,6 +320,12 @@ dberr_t flst_add_first(buf_block_t *base, uint16_t boffset, else { fil_addr_t addr= flst_get_first(base->page.frame + boffset); + if (UNIV_UNLIKELY(addr.page >= limit)) + return DB_CORRUPTION; + else if (UNIV_UNLIKELY(addr.boffset < FIL_PAGE_DATA || + addr.boffset >= base->physical_size() - + FIL_PAGE_DATA_END)) + return DB_CORRUPTION; buf_block_t *cur= add; dberr_t err; if (addr.page != add->page.id().page_no() && @@ -312,19 +334,13 @@ dberr_t flst_add_first(buf_block_t *base, uint16_t boffset, BUF_GET_POSSIBLY_FREED, mtr, &err))) return err; return flst_insert_before(base, boffset, cur, addr.boffset, - add, aoffset, mtr); + add, aoffset, limit, mtr); } } -/** Remove a file list node. -@param[in,out] base base node block -@param[in] boffset byte offset of the base node -@param[in,out] cur block to be removed -@param[in] coffset byte offset of the current record to be removed -@param[in,out] mtr mini-transaction -@return error code */ dberr_t flst_remove(buf_block_t *base, uint16_t boffset, - buf_block_t *cur, uint16_t coffset, mtr_t *mtr) + buf_block_t *cur, uint16_t coffset, + uint32_t limit, mtr_t *mtr) { ut_ad(boffset < base->physical_size()); ut_ad(coffset < cur->physical_size()); @@ -337,9 +353,27 @@ dberr_t flst_remove(buf_block_t *base, uint16_t boffset, const fil_addr_t next_addr= flst_get_next_addr(cur->page.frame + coffset); dberr_t err= DB_SUCCESS; - if (prev_addr.page == FIL_NULL) + if (next_addr.page >= limit) + { + if (next_addr.page != FIL_NULL) + return DB_CORRUPTION; + } + else if (UNIV_UNLIKELY(next_addr.boffset < FIL_PAGE_DATA || + next_addr.boffset >= base->physical_size() - + FIL_PAGE_DATA_END)) + return DB_CORRUPTION; + + if (prev_addr.page >= limit) + { + if (prev_addr.page != FIL_NULL) + return DB_CORRUPTION; flst_write_addr(*base, base->page.frame + boffset + FLST_FIRST, next_addr.page, next_addr.boffset, mtr); + } + else if (UNIV_UNLIKELY(prev_addr.boffset < FIL_PAGE_DATA || + prev_addr.boffset >= base->physical_size() - + FIL_PAGE_DATA_END)) + return DB_CORRUPTION; else { buf_block_t *b= cur; @@ -383,25 +417,19 @@ void flst_validate(const buf_block_t *base, uint16_t boffset, mtr_t *mtr) ut_ad(mtr->memo_contains_flagged(base, MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX)); - /* We use two mini-transaction handles: the first is used to lock - the base node, and prevent other threads from modifying the list. - The second is used to traverse the list. We cannot run the second - mtr without committing it at times, because if the list is long, - the x-locked pages could fill the buffer, resulting in a deadlock. */ - mtr_t mtr2; - const uint32_t len= flst_get_len(base->page.frame + boffset); fil_addr_t addr= flst_get_first(base->page.frame + boffset); for (uint32_t i= len; i--; ) { - mtr2.start(); + ut_ad(addr.boffset >= FIL_PAGE_DATA); + ut_ad(addr.boffset < base->physical_size() - FIL_PAGE_DATA_END); const buf_block_t *b= buf_page_get_gen(page_id_t(base->page.id().space(), addr.page), base->zip_size(), RW_SX_LATCH, nullptr, BUF_GET, mtr); ut_ad(b); addr= flst_get_next_addr(b->page.frame + addr.boffset); - mtr2.commit(); + mtr->release_last_page(); } ut_ad(addr.page == FIL_NULL); @@ -410,13 +438,14 @@ void flst_validate(const buf_block_t *base, uint16_t boffset, mtr_t *mtr) for (uint32_t i= len; i--; ) { - mtr2.start(); + ut_ad(addr.boffset >= FIL_PAGE_DATA); + ut_ad(addr.boffset < base->physical_size() - FIL_PAGE_DATA_END); const buf_block_t *b= buf_page_get_gen(page_id_t(base->page.id().space(), addr.page), base->zip_size(), RW_SX_LATCH, nullptr, BUF_GET, mtr); ut_ad(b); addr= flst_get_prev_addr(b->page.frame + addr.boffset); - mtr2.commit(); + mtr->release_last_page(); } ut_ad(addr.page == FIL_NULL); diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc index 65658835bb6..10a12a785df 100644 --- a/storage/innobase/gis/gis0sea.cc +++ b/storage/innobase/gis/gis0sea.cc @@ -288,10 +288,6 @@ rtr_pcur_getnext_from_path( mtr->rollback_to_savepoint(1); } - ut_ad((my_latch_mode | 4) == BTR_CONT_MODIFY_TREE - || !page_is_leaf(btr_cur_get_page(btr_cur)) - || !btr_cur->page_cur.block->page.lock.have_any()); - const auto block_savepoint = mtr->get_savepoint(); block = buf_page_get_gen( page_id_t(index->table->space_id, @@ -510,7 +506,7 @@ rtr_pcur_move_to_next( mysql_mutex_unlock(&rtr_info->matches->rtr_match_mutex); cursor->btr_cur.page_cur.rec = rec.r_rec; - cursor->btr_cur.page_cur.block = &rtr_info->matches->block; + cursor->btr_cur.page_cur.block = rtr_info->matches->block; DEBUG_SYNC_C("rtr_pcur_move_to_next_return"); return(true); @@ -671,8 +667,13 @@ dberr_t rtr_search_to_nth_level(btr_cur_t *cur, que_thr_t *thr, buf_mode, mtr, &err); if (!block) { - if (err == DB_DECRYPTION_FAILED) - btr_decryption_failed(*index); + if (err) + { + err_exit: + if (err == DB_DECRYPTION_FAILED) + btr_decryption_failed(*index); + mtr->rollback_to_savepoint(savepoint); + } func_exit: if (UNIV_LIKELY_NULL(heap)) mem_heap_free(heap); @@ -736,7 +737,8 @@ dberr_t rtr_search_to_nth_level(btr_cur_t *cur, que_thr_t *thr, #endif } - if (height == 0) { + if (height == 0) + { if (rw_latch == RW_NO_LATCH) { ut_ad(block == mtr->at_savepoint(block_savepoint)); @@ -820,7 +822,7 @@ dberr_t rtr_search_to_nth_level(btr_cur_t *cur, que_thr_t *thr, if (page_cur_search_with_match(tuple, page_mode, &up_match, &low_match, &cur->page_cur, nullptr)) { err= DB_CORRUPTION; - goto func_exit; + goto err_exit; } } @@ -1327,21 +1329,15 @@ rtr_create_rtr_info( rtr_info->thr = thr; if (init_matches) { - rtr_info->heap = mem_heap_create(sizeof(*(rtr_info->matches))); rtr_info->matches = static_cast( - mem_heap_zalloc( - rtr_info->heap, - sizeof(*rtr_info->matches))); + ut_zalloc_nokey(sizeof *rtr_info->matches)); rtr_info->matches->matched_recs = UT_NEW_NOKEY(rtr_rec_vector()); - rtr_info->matches->bufp = page_align(rtr_info->matches->rec_buf - + UNIV_PAGE_SIZE_MAX + 1); mysql_mutex_init(rtr_match_mutex_key, &rtr_info->matches->rtr_match_mutex, nullptr); - rtr_info->matches->block.page.lock.init(); } rtr_info->path = UT_NEW_NOKEY(rtr_node_path_t()); @@ -1460,18 +1456,16 @@ rtr_clean_rtr_info( if (free_all) { if (rtr_info->matches) { - if (rtr_info->matches->matched_recs != NULL) { - UT_DELETE(rtr_info->matches->matched_recs); + if (rtr_info->matches->block) { + buf_block_free(rtr_info->matches->block); + rtr_info->matches->block = nullptr; } - rtr_info->matches->block.page.lock.free(); + UT_DELETE(rtr_info->matches->matched_recs); mysql_mutex_destroy( &rtr_info->matches->rtr_match_mutex); - } - - if (rtr_info->heap) { - mem_heap_free(rtr_info->heap); + ut_free(rtr_info->matches); } if (initialized) { @@ -1581,7 +1575,7 @@ rtr_check_discard_page( if (auto matches = rtr_info->matches) { mysql_mutex_lock(&matches->rtr_match_mutex); - if (matches->block.page.id() == id) { + if (matches->block->page.id() == id) { matches->matched_recs->clear(); matches->valid = false; } @@ -1595,23 +1589,6 @@ rtr_check_discard_page( lock_sys.prdt_page_free_from_discard(id, true); } -/** Structure acts as functor to get the optimistic access of the page. -It returns true if it successfully gets the page. */ -struct optimistic_get -{ - btr_pcur_t *const r_cursor; - mtr_t *const mtr; - - optimistic_get(btr_pcur_t *r_cursor,mtr_t *mtr) - :r_cursor(r_cursor), mtr(mtr) {} - - bool operator()(buf_block_t *hint) const - { - return hint && buf_page_optimistic_get( - RW_X_LATCH, hint, r_cursor->modify_clock, mtr); - } -}; - /** Restore the stored position of a persistent cursor bufferfixing the page */ static bool @@ -1643,8 +1620,11 @@ rtr_cur_restore_position( r_cursor->modify_clock = 100; ); - if (r_cursor->block_when_stored.run_with_hint( - optimistic_get(r_cursor, mtr))) { + if (buf_page_optimistic_fix(r_cursor->btr_cur.page_cur.block, + r_cursor->old_page_id) + && buf_page_optimistic_get(r_cursor->btr_cur.page_cur.block, + RW_X_LATCH, r_cursor->modify_clock, + mtr)) { ut_ad(r_cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(r_cursor->rel_pos == BTR_PCUR_ON); @@ -1789,7 +1769,7 @@ rtr_leaf_push_match_rec( ulint data_len; rtr_rec_t rtr_rec; - buf = match_rec->block.page.frame + match_rec->used; + buf = match_rec->block->page.frame + match_rec->used; ut_ad(page_rec_is_leaf(rec)); copy = rec_copy(buf, rec, offsets); @@ -1886,43 +1866,6 @@ rtr_non_leaf_insert_stack_push( new_seq, level, child_no, my_cursor, mbr_inc); } -/** Copy a buf_block_t, except "block->page.lock". -@param[in,out] matches copy to match->block -@param[in] block block to copy */ -static -void -rtr_copy_buf( - matched_rec_t* matches, - const buf_block_t* block) -{ - /* Copy all members of "block" to "matches->block" except "lock". - We skip "lock" because it is not used - from the dummy buf_block_t we create here and because memcpy()ing - it generates (valid) compiler warnings that the vtable pointer - will be copied. */ - matches->block.page.lock.free(); - new (&matches->block.page) buf_page_t(block->page); - matches->block.page.frame = block->page.frame; - matches->block.unzip_LRU = block->unzip_LRU; - - ut_d(matches->block.in_unzip_LRU_list = block->in_unzip_LRU_list); - ut_d(matches->block.in_withdraw_list = block->in_withdraw_list); - - /* Skip buf_block_t::lock */ - matches->block.modify_clock = block->modify_clock; -#ifdef BTR_CUR_HASH_ADAPT - matches->block.n_hash_helps = block->n_hash_helps; - matches->block.n_fields = block->n_fields; - matches->block.left_side = block->left_side; -#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG - matches->block.n_pointers = 0; -#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - matches->block.curr_n_fields = block->curr_n_fields; - matches->block.curr_left_side = block->curr_left_side; - matches->block.index = block->index; -#endif /* BTR_CUR_HASH_ADAPT */ -} - /****************************************************************//** Generate a shadow copy of the page block header to save the matched records */ @@ -1936,16 +1879,18 @@ rtr_init_match( { ut_ad(matches->matched_recs->empty()); matches->locked = false; - rtr_copy_buf(matches, block); - matches->block.page.frame = matches->bufp; matches->valid = false; + if (!matches->block) { + matches->block = buf_block_alloc(); + } + + matches->block->page.init(buf_page_t::MEMORY, block->page.id()); /* We have to copy PAGE_*_SUPREMUM_END bytes so that we can use infimum/supremum of this page as normal btr page for search. */ - memcpy(matches->block.page.frame, page, page_is_comp(page) - ? PAGE_NEW_SUPREMUM_END : PAGE_OLD_SUPREMUM_END); matches->used = page_is_comp(page) ? PAGE_NEW_SUPREMUM_END : PAGE_OLD_SUPREMUM_END; + memcpy(matches->block->page.frame, page, matches->used); #ifdef RTR_SEARCH_DIAGNOSTIC ulint pageno = page_get_page_no(page); fprintf(stderr, "INNODB_RTR: Searching leaf page %d\n", @@ -2372,7 +2317,7 @@ rtr_cur_search_with_match( #endif /* UNIV_DEBUG */ /* Pop the last match record and position on it */ match_rec->matched_recs->pop_back(); - page_cur_position(test_rec.r_rec, &match_rec->block, + page_cur_position(test_rec.r_rec, match_rec->block, cursor); } } else { diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 93127bb1c3a..74e9356d044 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -47,10 +47,13 @@ this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include #include "sql_type_geom.h" #include "scope.h" #include "srv0srv.h" +extern my_bool opt_readonly; + // MYSQL_PLUGIN_IMPORT extern my_bool lower_case_file_system; // MYSQL_PLUGIN_IMPORT extern char mysql_unpacked_real_data_home[]; @@ -114,6 +117,7 @@ thread_local ha_handler_stats *mariadb_stats= &mariadb_dummy_stats; #include "snappy-c.h" #include +#include // TT_FOR_UPGRADE #define thd_get_trx_isolation(X) ((enum_tx_isolation)thd_tx_isolation(X)) @@ -349,7 +353,7 @@ static TYPELIB innodb_default_row_format_typelib = { }; /** Names of allowed values of innodb_flush_method */ -const char* innodb_flush_method_names[] = { +static const char* innodb_flush_method_names[] = { "fsync", "O_DSYNC", "littlesync", @@ -377,6 +381,18 @@ TYPELIB innodb_flush_method_typelib = { /** Deprecated parameter */ static ulong innodb_flush_method; +/** Names of allowed values of innodb_doublewrite */ +static const char *innodb_doublewrite_names[]= + {"OFF", "ON", "fast", nullptr}; + +/** Enumeration of innodb_doublewrite */ +TYPELIB innodb_doublewrite_typelib= { + array_elements(innodb_doublewrite_names) - 1, + "innodb_doublewrite_typelib", + innodb_doublewrite_names, + nullptr +}; + /** Names of allowed values of innodb_deadlock_report */ static const char *innodb_deadlock_report_names[]= { "off", /* Do not report any details of deadlocks */ @@ -855,6 +871,10 @@ static MYSQL_THDVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG, /* check_func */ NULL, /* update_func */ NULL, /* default */ TRUE); +static MYSQL_THDVAR_BOOL(snapshot_isolation, PLUGIN_VAR_OPCMDARG, + "Use snapshot isolation (write-write conflict detection).", + NULL, NULL, FALSE); + static MYSQL_THDVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG, "Use strict mode when evaluating create options.", NULL, NULL, TRUE); @@ -2123,6 +2143,9 @@ convert_error_code_to_mysql( return(HA_ERR_LOCK_DEADLOCK); + case DB_RECORD_CHANGED: + return HA_ERR_RECORD_CHANGED; + case DB_LOCK_WAIT_TIMEOUT: /* Starting from 5.0.13, we let MySQL just roll back the latest SQL statement in a lock wait timeout. Previously, we @@ -2766,6 +2789,8 @@ innobase_trx_init( trx->check_unique_secondary = !thd_test_options( thd, OPTION_RELAXED_UNIQUE_CHECKS); + trx->snapshot_isolation = THDVAR(thd, snapshot_isolation) & 1; + #ifdef WITH_WSREP trx->wsrep = wsrep_on(thd); #endif @@ -3964,7 +3989,11 @@ static int innodb_init_params() } else if (innodb_flush_method >= 4 /* O_DIRECT */ IF_WIN(&& innodb_flush_method < 8 /* normal */,)) { /* O_DIRECT and similar settings do nothing */ -#ifdef HAVE_FCNTL_DIRECT + if (innodb_flush_method == 5 /* O_DIRECT_NO_FSYNC */ + && buf_dblwr.use) { + buf_dblwr.use = buf_dblwr.USE_FAST; + } +#ifdef O_DIRECT } else if (srv_use_atomic_writes && my_may_have_atomic_write) { /* If atomic writes are enabled, do the same as with innodb_flush_method=O_DIRECT: retain the default settings */ @@ -5318,67 +5347,6 @@ test_normalize_table_name_low() } } } - -/********************************************************************* -Test ut_format_name(). */ -static -void -test_ut_format_name() -/*=================*/ -{ - char buf[NAME_LEN * 3]; - - struct { - const char* name; - ulint buf_size; - const char* expected; - } test_data[] = { - {"test/t1", sizeof(buf), "`test`.`t1`"}, - {"test/t1", 12, "`test`.`t1`"}, - {"test/t1", 11, "`test`.`t1"}, - {"test/t1", 10, "`test`.`t"}, - {"test/t1", 9, "`test`.`"}, - {"test/t1", 8, "`test`."}, - {"test/t1", 7, "`test`"}, - {"test/t1", 6, "`test"}, - {"test/t1", 5, "`tes"}, - {"test/t1", 4, "`te"}, - {"test/t1", 3, "`t"}, - {"test/t1", 2, "`"}, - {"test/t1", 1, ""}, - {"test/t1", 0, "BUF_NOT_CHANGED"}, - {"table", sizeof(buf), "`table`"}, - {"ta'le", sizeof(buf), "`ta'le`"}, - {"ta\"le", sizeof(buf), "`ta\"le`"}, - {"ta`le", sizeof(buf), "`ta``le`"}, - }; - - for (size_t i = 0; i < UT_ARR_SIZE(test_data); i++) { - - memcpy(buf, "BUF_NOT_CHANGED", strlen("BUF_NOT_CHANGED") + 1); - - char* ret; - - ret = ut_format_name(test_data[i].name, - buf, - test_data[i].buf_size); - - ut_a(ret == buf); - - if (strcmp(buf, test_data[i].expected) == 0) { - ib::info() << "ut_format_name(" << test_data[i].name - << ", buf, " << test_data[i].buf_size << ")," - " expected " << test_data[i].expected - << ", OK"; - } else { - ib::error() << "ut_format_name(" << test_data[i].name - << ", buf, " << test_data[i].buf_size << ")," - " expected " << test_data[i].expected - << ", ERROR: got " << buf; - ut_error; - } - } -} #endif /* !DBUG_OFF */ /** Match index columns between MySQL and InnoDB. @@ -5736,9 +5704,9 @@ func_exit: return ret; } -/********************************************************************//** -Get the upper limit of the MySQL integral and floating-point type. -@return maximum allowed value for the field */ +/** Get the maximum integer value of a numeric column. +@param field column definition +@return maximum allowed integer value */ ulonglong innobase_get_int_col_max_value(const Field *field) { ulonglong max_value = 0; @@ -5803,46 +5771,45 @@ ha_innobase::open(). @param[in,out] table persistent table @param[in] field the AUTO_INCREMENT column */ -static -void -initialize_auto_increment(dict_table_t* table, const Field* field) +static void initialize_auto_increment(dict_table_t *table, const Field& field, + const TABLE_SHARE &s) { - ut_ad(!table->is_temporary()); + ut_ad(!table->is_temporary()); + const unsigned col_no= innodb_col_no(&field); + table->autoinc_mutex.wr_lock(); + table->persistent_autoinc= + uint16_t(dict_table_get_nth_col_pos(table, col_no, nullptr) + 1) & + dict_index_t::MAX_N_FIELDS; + if (table->autoinc) + /* Already initialized. Our caller checked + table->persistent_autoinc without + autoinc_mutex protection, and there might be multiple + ha_innobase::open() executing concurrently. */; + else if (srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) + /* If innodb_force_recovery is set so high that writes + are disabled we force the AUTOINC counter to 0 + value effectively disabling writes to the table. + Secondly, we avoid reading the table in case the read + results in failure due to a corrupted table/index. - const unsigned col_no = innodb_col_no(field); + We will not return an error to the client, so that the + tables can be dumped with minimal hassle. If an error + were returned in this case, the first attempt to read + the table would fail and subsequent SELECTs would succeed. */; + else if (table->persistent_autoinc) + { + uint64_t max_value= innobase_get_int_col_max_value(&field); + table->autoinc= + innobase_next_autoinc(btr_read_autoinc_with_fallback(table, col_no, + s.mysql_version, + max_value), + 1 /* need */, + 1 /* auto_increment_increment */, + 0 /* auto_increment_offset */, + max_value); + } - table->autoinc_mutex.wr_lock(); - - table->persistent_autoinc = static_cast( - dict_table_get_nth_col_pos(table, col_no, NULL) + 1) - & dict_index_t::MAX_N_FIELDS; - - if (table->autoinc) { - /* Already initialized. Our caller checked - table->persistent_autoinc without - autoinc_mutex protection, and there might be multiple - ha_innobase::open() executing concurrently. */ - } else if (srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) { - /* If the recovery level is set so high that writes - are disabled we force the AUTOINC counter to 0 - value effectively disabling writes to the table. - Secondly, we avoid reading the table in case the read - results in failure due to a corrupted table/index. - - We will not return an error to the client, so that the - tables can be dumped with minimal hassle. If an error - were returned in this case, the first attempt to read - the table would fail and subsequent SELECTs would succeed. */ - } else if (table->persistent_autoinc) { - table->autoinc = innobase_next_autoinc( - btr_read_autoinc_with_fallback(table, col_no), - 1 /* need */, - 1 /* auto_increment_increment */, - 0 /* auto_increment_offset */, - innobase_get_int_col_max_value(field)); - } - - table->autoinc_mutex.wr_unlock(); + table->autoinc_mutex.wr_unlock(); } /** Open an InnoDB table @@ -5863,6 +5830,7 @@ ha_innobase::open(const char* name, int, uint) /* Will be allocated if it is needed in ::update_row() */ m_upd_buf = NULL; m_upd_buf_size = 0; + m_disable_rowid_filter = false; char* is_part = is_partition(norm_name); THD* thd = ha_thd(); @@ -6092,7 +6060,7 @@ ha_innobase::open(const char* name, int, uint) || m_prebuilt->table->persistent_autoinc || !m_prebuilt->table->is_readable()) { } else if (const Field* ai = table->found_next_number_field) { - initialize_auto_increment(m_prebuilt->table, ai); + initialize_auto_increment(m_prebuilt->table, *ai, *table->s); } /* Set plugin parser for fulltext index */ @@ -7349,7 +7317,8 @@ ha_innobase::build_template( /* Below we check column by column if we need to access the clustered index. */ - if (pushed_rowid_filter && rowid_filter_is_active) { + if (pushed_rowid_filter && rowid_filter_is_active + && !m_disable_rowid_filter) { fetch_primary_key_cols = TRUE; m_prebuilt->pk_filter = this; } else { @@ -7380,26 +7349,56 @@ ha_innobase::build_template( ulint num_v = 0; - if (active_index != MAX_KEY - && active_index == pushed_idx_cond_keyno) { - m_prebuilt->idx_cond = this; - goto icp; - } else if (pushed_rowid_filter && rowid_filter_is_active) { -icp: - /* Push down an index condition or an end_range check. */ + /* MDEV-31154: For pushed down index condition we don't support virtual + column and idx_cond_push() does check for it. For row ID filtering we + don't need such restrictions but we get into trouble trying to use the + ICP path. + + 1. It should be fine to follow no_icp path if primary key is generated. + However, with user specified primary key(PK), the row is identified by + the PK and those columns need to be converted to mysql format in + row_search_idx_cond_check before doing the comparison. Since secondary + indexes always have PK appended in innodb, it works with current ICP + handling code when fetch_primary_key_cols is set to TRUE. + + 2. Although ICP comparison and Row ID comparison works on different + columns the current ICP code can be shared by both. + + 3. In most cases, it works today by jumping to goto no_icp when we + encounter a virtual column. This is hackish and already have some + issues as it cannot handle PK and all states are not reset properly, + for example, idx_cond_n_cols is not reset. + + 4. We already encountered MDEV-28747 m_prebuilt->idx_cond was being set. + + Neither ICP nor row ID comparison needs virtual columns and the code is + simplified to handle both. It should handle the issues. */ + + const bool pushed_down = active_index != MAX_KEY + && active_index == pushed_idx_cond_keyno + && !m_disable_rowid_filter; + + m_prebuilt->idx_cond = pushed_down ? this : nullptr; + + if (m_prebuilt->idx_cond || m_prebuilt->pk_filter) { + /* Push down an index condition, end_range check or row ID + filter */ for (ulint i = 0; i < n_fields; i++) { const Field* field = table->field[i]; const bool is_v = !field->stored_in_db(); - if (is_v && skip_virtual) { - num_v++; - continue; - } + bool index_contains = index->contains_col_or_prefix( is_v ? num_v : i - num_v, is_v); - if (is_v && index_contains) { - m_prebuilt->n_template = 0; - num_v = 0; - goto no_icp; + + if (is_v) { + if (index_contains) { + /* We want to ensure that ICP is not + used with virtual columns. */ + ut_ad(!pushed_down); + m_prebuilt->idx_cond = nullptr; + } + num_v++; + continue; } /* Test if an end_range or an index condition @@ -7419,7 +7418,7 @@ icp: which would be acceptable if end_range==NULL. */ if (build_template_needs_field_in_icp( index, m_prebuilt, index_contains, - is_v ? num_v : i - num_v, is_v)) { + i - num_v, false)) { if (!whole_row) { field = build_template_needs_field( index_contains, @@ -7428,15 +7427,10 @@ icp: fetch_primary_key_cols, index, table, i, num_v); if (!field) { - if (is_v) { - num_v++; - } continue; } } - ut_ad(!is_v); - mysql_row_templ_t* templ= build_template_field( m_prebuilt, clust_index, index, table, field, i - num_v, 0); @@ -7513,15 +7507,16 @@ icp: */ } - if (is_v) { - num_v++; - } } - ut_ad(m_prebuilt->idx_cond_n_cols > 0); - ut_ad(m_prebuilt->idx_cond_n_cols == m_prebuilt->n_template); - num_v = 0; + ut_ad(m_prebuilt->idx_cond_n_cols == m_prebuilt->n_template); + if (m_prebuilt->idx_cond_n_cols == 0) { + /* No columns to push down. It is safe to jump to np ICP + path. */ + m_prebuilt->idx_cond = nullptr; + goto no_icp; + } /* Include the fields that are not needed in index condition pushdown. */ @@ -7536,7 +7531,7 @@ icp: bool index_contains = index->contains_col_or_prefix( is_v ? num_v : i - num_v, is_v); - if (!build_template_needs_field_in_icp( + if (is_v || !build_template_needs_field_in_icp( index, m_prebuilt, index_contains, is_v ? num_v : i - num_v, is_v)) { /* Not needed in ICP */ @@ -7569,7 +7564,7 @@ icp: } else { no_icp: /* No index condition pushdown */ - m_prebuilt->idx_cond = NULL; + ut_ad(!m_prebuilt->idx_cond); ut_ad(num_v == 0); for (ulint i = 0; i < n_fields; i++) { @@ -8723,6 +8718,7 @@ ha_innobase::delete_row( : PLAIN_DELETE; trx->fts_next_doc_id = 0; + ut_ad(!trx->is_bulk_insert()); error = row_update_for_mysql(m_prebuilt); #ifdef WITH_WSREP @@ -8830,47 +8826,63 @@ ha_innobase::index_end(void) DBUG_RETURN(0); } -/*********************************************************************//** -Converts a search mode flag understood by MySQL to a flag understood -by InnoDB. */ -page_cur_mode_t -convert_search_mode_to_innobase( -/*============================*/ - ha_rkey_function find_flag) +/** Convert a MariaDB search mode to an InnoDB search mode. +@tparam last_match whether last_match_mode is to be set +@param find_flag MariaDB search mode +@param mode InnoDB search mode +@param last_match_mode pointer to ha_innobase::m_last_match_mode +@return whether the search mode is unsupported */ +template +static bool convert_search_mode_to_innobase(ha_rkey_function find_flag, + page_cur_mode_t &mode, + uint *last_match_mode= nullptr) { - switch (find_flag) { - case HA_READ_KEY_EXACT: - /* this does not require the index to be UNIQUE */ - case HA_READ_KEY_OR_NEXT: - return(PAGE_CUR_GE); - case HA_READ_AFTER_KEY: - return(PAGE_CUR_G); - case HA_READ_BEFORE_KEY: - return(PAGE_CUR_L); - case HA_READ_KEY_OR_PREV: - case HA_READ_PREFIX_LAST: - case HA_READ_PREFIX_LAST_OR_PREV: - return(PAGE_CUR_LE); - case HA_READ_MBR_CONTAIN: - return(PAGE_CUR_CONTAIN); - case HA_READ_MBR_INTERSECT: - return(PAGE_CUR_INTERSECT); - case HA_READ_MBR_WITHIN: - return(PAGE_CUR_WITHIN); - case HA_READ_MBR_DISJOINT: - return(PAGE_CUR_DISJOINT); - case HA_READ_MBR_EQUAL: - return(PAGE_CUR_MBR_EQUAL); - case HA_READ_PREFIX: - return(PAGE_CUR_UNSUPP); - /* do not use "default:" in order to produce a gcc warning: - enumeration value '...' not handled in switch - (if -Wswitch or -Wall is used) */ - } + mode= PAGE_CUR_LE; + if (last_match) + *last_match_mode= 0; - my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "this functionality"); + switch (find_flag) { + case HA_READ_KEY_EXACT: + /* this does not require the index to be UNIQUE */ + if (last_match) + *last_match_mode= ROW_SEL_EXACT; + /* fall through */ + case HA_READ_KEY_OR_NEXT: + mode= PAGE_CUR_GE; + return false; + case HA_READ_AFTER_KEY: + mode= PAGE_CUR_G; + return false; + case HA_READ_BEFORE_KEY: + mode= PAGE_CUR_L; + return false; + case HA_READ_PREFIX_LAST: + if (last_match) + *last_match_mode= ROW_SEL_EXACT_PREFIX; + /* fall through */ + case HA_READ_KEY_OR_PREV: + case HA_READ_PREFIX_LAST_OR_PREV: + return false; + case HA_READ_MBR_CONTAIN: + mode= PAGE_CUR_CONTAIN; + return false; + case HA_READ_MBR_INTERSECT: + mode= PAGE_CUR_INTERSECT; + return false; + case HA_READ_MBR_WITHIN: + mode= PAGE_CUR_WITHIN; + return false; + case HA_READ_MBR_DISJOINT: + mode= PAGE_CUR_DISJOINT; + return false; + case HA_READ_MBR_EQUAL: + mode= PAGE_CUR_MBR_EQUAL; + return false; + case HA_READ_PREFIX: + break; + } - return(PAGE_CUR_UNSUPP); + return true; } /* @@ -8948,8 +8960,7 @@ ha_innobase::index_read( mariadb_set_stats set_stats_temporary(handler_stats); DEBUG_SYNC_C("ha_innobase_index_read_begin"); - ut_a(m_prebuilt->trx == thd_to_trx(m_user_thd)); - ut_ad(key_len != 0 || find_flag != HA_READ_KEY_EXACT); + ut_ad(m_prebuilt->trx == thd_to_trx(m_user_thd)); dict_index_t* index = m_prebuilt->index; @@ -8985,7 +8996,8 @@ ha_innobase::index_read( build_template(false); } - if (key_ptr != NULL) { + if (key_len) { + ut_ad(key_ptr); /* Convert the search key value to InnoDB format into m_prebuilt->search_tuple */ @@ -8995,84 +9007,58 @@ ha_innobase::index_read( m_prebuilt->srch_key_val_len, index, (byte*) key_ptr, - (ulint) key_len); + key_len); DBUG_ASSERT(m_prebuilt->search_tuple->n_fields > 0); } else { + ut_ad(find_flag != HA_READ_KEY_EXACT); /* We position the cursor to the last or the first entry in the index */ dtuple_set_n_fields(m_prebuilt->search_tuple, 0); } - page_cur_mode_t mode = convert_search_mode_to_innobase(find_flag); + page_cur_mode_t mode; - ulint match_mode = 0; - - if (find_flag == HA_READ_KEY_EXACT) { - - match_mode = ROW_SEL_EXACT; - - } else if (find_flag == HA_READ_PREFIX_LAST) { - - match_mode = ROW_SEL_EXACT_PREFIX; + if (convert_search_mode_to_innobase(find_flag, mode, + &m_last_match_mode)) { + table->status = STATUS_NOT_FOUND; + DBUG_RETURN(HA_ERR_UNSUPPORTED); } - m_last_match_mode = (uint) match_mode; - - dberr_t ret = mode == PAGE_CUR_UNSUPP ? DB_UNSUPPORTED - : row_search_mvcc(buf, mode, m_prebuilt, match_mode, 0); + dberr_t ret = + row_search_mvcc(buf, mode, m_prebuilt, m_last_match_mode, 0); DBUG_EXECUTE_IF("ib_select_query_failure", ret = DB_ERROR;); - int error; + if (UNIV_LIKELY(ret == DB_SUCCESS)) { + table->status = 0; + DBUG_RETURN(0); + } + + table->status = STATUS_NOT_FOUND; switch (ret) { - case DB_SUCCESS: - error = 0; - table->status = 0; - break; - - case DB_RECORD_NOT_FOUND: - error = HA_ERR_KEY_NOT_FOUND; - table->status = STATUS_NOT_FOUND; - break; - - case DB_END_OF_INDEX: - error = HA_ERR_KEY_NOT_FOUND; - table->status = STATUS_NOT_FOUND; - break; - case DB_TABLESPACE_DELETED: ib_senderrf( m_prebuilt->trx->mysql_thd, IB_LOG_LEVEL_ERROR, ER_TABLESPACE_DISCARDED, table->s->table_name.str); - - table->status = STATUS_NOT_FOUND; - error = HA_ERR_TABLESPACE_MISSING; - break; - + DBUG_RETURN(HA_ERR_TABLESPACE_MISSING); + case DB_RECORD_NOT_FOUND: + case DB_END_OF_INDEX: + DBUG_RETURN(HA_ERR_KEY_NOT_FOUND); case DB_TABLESPACE_NOT_FOUND: - ib_senderrf( m_prebuilt->trx->mysql_thd, IB_LOG_LEVEL_ERROR, ER_TABLESPACE_MISSING, table->s->table_name.str); - - table->status = STATUS_NOT_FOUND; - error = HA_ERR_TABLESPACE_MISSING; - break; - + DBUG_RETURN(HA_ERR_TABLESPACE_MISSING); default: - error = convert_error_code_to_mysql( - ret, m_prebuilt->table->flags, m_user_thd); - - table->status = STATUS_NOT_FOUND; - break; + DBUG_RETURN(convert_error_code_to_mysql( + ret, m_prebuilt->table->flags, + m_user_thd)); } - - DBUG_RETURN(error); } /*******************************************************************//** @@ -9422,6 +9408,11 @@ ha_innobase::rnd_init( { int err; + /* Don't use rowid filter when doing full table scan or rnd_pos calls.*/ + if (!scan) { + m_disable_rowid_filter = true; + } + /* Store the active index value so that we can restore the original value after a scan */ @@ -9431,6 +9422,12 @@ ha_innobase::rnd_init( err = change_active_index(m_primary_key); } + if (err && !scan) { + /* Restore the original value in case of error */ + m_disable_rowid_filter = false; + } + + /* Don't use semi-consistent read in random row reads (by position). This means we must disable semi_consistent_read if scan is false */ @@ -9451,6 +9448,7 @@ int ha_innobase::rnd_end(void) /*======================*/ { + m_disable_rowid_filter = false; return(index_end()); } @@ -9499,11 +9497,10 @@ ha_innobase::rnd_pos( DBUG_ENTER("rnd_pos"); DBUG_DUMP("key", pos, ref_length); - ut_a(m_prebuilt->trx == thd_to_trx(ha_thd())); - /* Note that we assume the length of the row reference is fixed for the table, and it is == ref_length */ + DBUG_ASSERT(m_disable_rowid_filter == true); int error = index_read(buf, pos, (uint)ref_length, HA_READ_KEY_EXACT); if (error != 0) { @@ -9929,7 +9926,8 @@ wsrep_append_foreign_key( } ulint rcode = DB_SUCCESS; - char cache_key[513] = {'\0'}; + char cache_key[MAX_FULL_NAME_LEN] = {'\0'}; + char db_name[MAX_DATABASE_NAME_LEN+1] = {'\0'}; size_t cache_key_len = 0; if ( !((referenced) ? @@ -10019,14 +10017,38 @@ wsrep_append_foreign_key( return DB_ERROR; } - strncpy(cache_key, + char * fk_table = (wsrep_protocol_version > 1) ? ((referenced) ? foreign->referenced_table->name.m_name : foreign->foreign_table->name.m_name) : - foreign->foreign_table->name.m_name, sizeof(cache_key) - 1); - cache_key_len = strlen(cache_key); + foreign->foreign_table->name.m_name; + /* convert db and table name parts separately to system charset */ + ulint db_name_len = dict_get_db_name_len(fk_table); + strmake(db_name, fk_table, db_name_len); + uint errors; + cache_key_len= innobase_convert_to_system_charset(cache_key, + db_name, sizeof(cache_key), &errors); + if (errors) { + WSREP_WARN("unexpected foreign key table %s %s", + foreign->referenced_table->name.m_name, + foreign->foreign_table->name.m_name); + return DB_ERROR; + } + + /* after db name adding 0 and then converted table name */ + cache_key[db_name_len]= '\0'; + cache_key_len++; + + cache_key_len+= innobase_convert_to_system_charset(cache_key+cache_key_len, + fk_table+db_name_len+1, sizeof(cache_key), &errors); + if (errors) { + WSREP_WARN("unexpected foreign key table %s %s", + foreign->referenced_table->name.m_name, + foreign->foreign_table->name.m_name); + return DB_ERROR; + } #ifdef WSREP_DEBUG_PRINT ulint j; fprintf(stderr, "FK parent key, table: %s %s len: %lu ", @@ -10036,16 +10058,6 @@ wsrep_append_foreign_key( } fprintf(stderr, "\n"); #endif - char *p = strchr(cache_key, '/'); - - if (p) { - *p = '\0'; - } else { - WSREP_WARN("unexpected foreign key table %s %s", - foreign->referenced_table->name.m_name, - foreign->foreign_table->name.m_name); - } - wsrep_buf_t wkey_part[3]; wsrep_key_t wkey = {wkey_part, 3}; @@ -12268,7 +12280,7 @@ create_table_info_t::create_foreign_keys() dict_index_t* index = NULL; fkerr_t index_error = FK_SUCCESS; dict_index_t* err_index = NULL; - ulint err_col; + ulint err_col = 0; const bool tmp_table = m_flags2 & DICT_TF2_TEMPORARY; const CHARSET_INFO* cs = thd_charset(m_thd); const char* operation = "Create "; @@ -13390,6 +13402,49 @@ ha_innobase::discard_or_import_tablespace( DBUG_RETURN(0); } +/** Report a DROP TABLE failure due to a FOREIGN KEY constraint. +@param name table name +@param foreign constraint */ +ATTRIBUTE_COLD +static void delete_table_cannot_drop_foreign(const table_name_t &name, + const dict_foreign_t &foreign) +{ + mysql_mutex_lock(&dict_foreign_err_mutex); + rewind(dict_foreign_err_file); + ut_print_timestamp(dict_foreign_err_file); + fputs(" Cannot drop table ", dict_foreign_err_file); + ut_print_name(dict_foreign_err_file, nullptr, name.m_name); + fputs("\nbecause it is referenced by ", dict_foreign_err_file); + ut_print_name(dict_foreign_err_file, nullptr, foreign.foreign_table_name); + putc('\n', dict_foreign_err_file); + mysql_mutex_unlock(&dict_foreign_err_mutex); +} + +/** Check if DROP TABLE would fail due to a FOREIGN KEY constraint. +@param table table to be dropped +@param sqlcom thd_sql_command(current_thd) +@return whether child tables that refer to this table exist */ +static bool delete_table_check_foreigns(const dict_table_t &table, + enum_sql_command sqlcom) +{ + const bool drop_db{sqlcom == SQLCOM_DROP_DB}; + for (const auto foreign : table.referenced_set) + { + /* We should allow dropping a referenced table if creating + that referenced table has failed for some reason. For example + if referenced table is created but it column types that are + referenced do not match. */ + if (foreign->foreign_table == &table || + (drop_db && + dict_tables_have_same_db(table.name.m_name, + foreign->foreign_table_name_lookup))) + continue; + delete_table_cannot_drop_foreign(table.name, *foreign); + return true; + } + + return false; +} /** DROP TABLE (possibly as part of DROP DATABASE, CREATE/ALTER TABLE) @param name table name @@ -13404,8 +13459,8 @@ int ha_innobase::delete_table(const char *name) DBUG_EXECUTE_IF("test_normalize_table_name_low", test_normalize_table_name_low();); - DBUG_EXECUTE_IF("test_ut_format_name", test_ut_format_name();); + const enum_sql_command sqlcom= enum_sql_command(thd_sql_command(thd)); trx_t *parent_trx= check_trx_exists(thd); dict_table_t *table; @@ -13442,6 +13497,13 @@ int ha_innobase::delete_table(const char *name) DBUG_RETURN(0); } + if (parent_trx->check_foreigns && + delete_table_check_foreigns(*table, sqlcom)) + { + dict_sys.unlock(); + DBUG_RETURN(HA_ERR_ROW_IS_REFERENCED); + } + table->acquire(); dict_sys.unlock(); @@ -13474,14 +13536,7 @@ int ha_innobase::delete_table(const char *name) /* FOREIGN KEY constraints cannot exist on partitioned tables. */; #endif else - { - dict_sys.freeze(SRW_LOCK_CALL); - for (const dict_foreign_t* f : table->referenced_set) - if (dict_table_t* child= f->foreign_table) - if ((err= lock_table_for_trx(child, trx, LOCK_X)) != DB_SUCCESS) - break; - dict_sys.unfreeze(); - } + err= lock_table_children(table, trx); } dict_table_t *table_stats= nullptr, *index_stats= nullptr; @@ -13491,7 +13546,6 @@ int ha_innobase::delete_table(const char *name) const bool fts= err == DB_SUCCESS && (table->flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS)); - const enum_sql_command sqlcom= enum_sql_command(thd_sql_command(thd)); if (fts) { @@ -13649,36 +13703,16 @@ err_exit: DBUG_RETURN(convert_error_code_to_mysql(err, 0, NULL)); } - if (!table->no_rollback() && trx->check_foreigns) + if (!table->no_rollback()) { - const bool drop_db= sqlcom == SQLCOM_DROP_DB; - for (auto foreign : table->referenced_set) + if (trx->check_foreigns && delete_table_check_foreigns(*table, sqlcom)) { - /* We should allow dropping a referenced table if creating - that referenced table has failed for some reason. For example - if referenced table is created but it column types that are - referenced do not match. */ - if (foreign->foreign_table == table || - (drop_db && - dict_tables_have_same_db(table->name.m_name, - foreign->foreign_table_name_lookup))) - continue; - mysql_mutex_lock(&dict_foreign_err_mutex); - rewind(dict_foreign_err_file); - ut_print_timestamp(dict_foreign_err_file); - fputs(" Cannot drop table ", dict_foreign_err_file); - ut_print_name(dict_foreign_err_file, trx, table->name.m_name); - fputs("\nbecause it is referenced by ", dict_foreign_err_file); - ut_print_name(dict_foreign_err_file, trx, foreign->foreign_table_name); - putc('\n', dict_foreign_err_file); - mysql_mutex_unlock(&dict_foreign_err_mutex); err= DB_CANNOT_DROP_CONSTRAINT; goto err_exit; } - } - if (!table->no_rollback()) err= trx->drop_table_foreign(table->name); + } if (err == DB_SUCCESS && table_stats && index_stats) err= trx->drop_table_statistics(table->name); @@ -13797,6 +13831,19 @@ int ha_innobase::truncate() update_thd(); +#ifdef UNIV_DEBUG + if (!thd_test_options(m_user_thd, OPTION_NO_FOREIGN_KEY_CHECKS)) + { + /* fk_truncate_illegal_if_parent() should have failed in + Sql_cmd_truncate_table::handler_truncate() if foreign_key_checks=ON + and child tables exist. */ + dict_sys.freeze(SRW_LOCK_CALL); + for (const auto foreign : m_prebuilt->table->referenced_set) + ut_ad(foreign->foreign_table == m_prebuilt->table); + dict_sys.unfreeze(); + } +#endif + if (is_read_only()) DBUG_RETURN(HA_ERR_TABLE_READONLY); @@ -13879,14 +13926,7 @@ int ha_innobase::truncate() dict_table_t *table_stats = nullptr, *index_stats = nullptr; MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr; - dberr_t error= DB_SUCCESS; - - dict_sys.freeze(SRW_LOCK_CALL); - for (const dict_foreign_t *f : ib_table->referenced_set) - if (dict_table_t *child= f->foreign_table) - if ((error= lock_table_for_trx(child, trx, LOCK_X)) != DB_SUCCESS) - break; - dict_sys.unfreeze(); + dberr_t error= lock_table_children(ib_table, trx); if (error == DB_SUCCESS) error= lock_table_for_trx(ib_table, trx, LOCK_X); @@ -14077,16 +14117,7 @@ ha_innobase::rename_table( /* There is no need to lock any FOREIGN KEY child tables. */ } else if (dict_table_t *table = dict_table_open_on_name( norm_from, false, DICT_ERR_IGNORE_FK_NOKEY)) { - dict_sys.freeze(SRW_LOCK_CALL); - for (const dict_foreign_t* f : table->referenced_set) { - if (dict_table_t* child = f->foreign_table) { - error = lock_table_for_trx(child, trx, LOCK_X); - if (error != DB_SUCCESS) { - break; - } - } - } - dict_sys.unfreeze(); + error = lock_table_children(table, trx); if (error == DB_SUCCESS) { error = lock_table_for_trx(table, trx, LOCK_X); } @@ -14225,14 +14256,14 @@ ha_innobase::records_in_range( dict_index_t* index; dtuple_t* range_start; dtuple_t* range_end; - ha_rows n_rows; + ha_rows n_rows = HA_POS_ERROR; page_cur_mode_t mode1; page_cur_mode_t mode2; mem_heap_t* heap; DBUG_ENTER("records_in_range"); - ut_a(m_prebuilt->trx == thd_to_trx(ha_thd())); + ut_ad(m_prebuilt->trx == thd_to_trx(ha_thd())); m_prebuilt->trx->op_info = "estimating records in index range"; @@ -14245,12 +14276,7 @@ ha_innobase::records_in_range( /* There exists possibility of not being able to find requested index due to inconsistency between MySQL and InoDB dictionary info. Necessary message should have been printed in innobase_get_index() */ - if (!m_prebuilt->table->space) { - n_rows = HA_POS_ERROR; - goto func_exit; - } - if (!index) { - n_rows = HA_POS_ERROR; + if (!index || !m_prebuilt->table->space) { goto func_exit; } if (index->is_corrupted()) { @@ -14266,61 +14292,50 @@ ha_innobase::records_in_range( + sizeof(dtuple_t))); range_start = dtuple_create(heap, key->ext_key_parts); - dict_index_copy_types(range_start, index, key->ext_key_parts); range_end = dtuple_create(heap, key->ext_key_parts); - dict_index_copy_types(range_end, index, key->ext_key_parts); - row_sel_convert_mysql_key_to_innobase( - range_start, - m_prebuilt->srch_key_val1, - m_prebuilt->srch_key_val_len, - index, - (byte*) (min_key ? min_key->key : (const uchar*) 0), - (ulint) (min_key ? min_key->length : 0)); - - DBUG_ASSERT(min_key - ? range_start->n_fields > 0 - : range_start->n_fields == 0); - - row_sel_convert_mysql_key_to_innobase( - range_end, - m_prebuilt->srch_key_val2, - m_prebuilt->srch_key_val_len, - index, - (byte*) (max_key ? max_key->key : (const uchar*) 0), - (ulint) (max_key ? max_key->length : 0)); - - DBUG_ASSERT(max_key - ? range_end->n_fields > 0 - : range_end->n_fields == 0); - - mode1 = convert_search_mode_to_innobase( - min_key ? min_key->flag : HA_READ_KEY_EXACT); - - mode2 = convert_search_mode_to_innobase( - max_key ? max_key->flag : HA_READ_KEY_EXACT); - - if (mode1 != PAGE_CUR_UNSUPP && mode2 != PAGE_CUR_UNSUPP) { - - if (dict_index_is_spatial(index)) { - /*Only min_key used in spatial index. */ - n_rows = rtr_estimate_n_rows_in_range( - index, range_start, mode1); - } else { - btr_pos_t tuple1(range_start, mode1, pages->first_page); - btr_pos_t tuple2(range_end, mode2, pages->last_page); - n_rows = btr_estimate_n_rows_in_range( - index, &tuple1, &tuple2); - pages->first_page= tuple1.page_id.raw(); - pages->last_page= tuple2.page_id.raw(); - } + if (!min_key) { + mode1 = PAGE_CUR_GE; + dtuple_set_n_fields(range_start, 0); + } else if (convert_search_mode_to_innobase(min_key->flag, mode1)) { + goto unsupported; } else { - - n_rows = HA_POS_ERROR; + dict_index_copy_types(range_start, index, key->ext_key_parts); + row_sel_convert_mysql_key_to_innobase( + range_start, + m_prebuilt->srch_key_val1, + m_prebuilt->srch_key_val_len, + index, min_key->key, min_key->length); + DBUG_ASSERT(range_start->n_fields > 0); } - mem_heap_free(heap); + if (!max_key) { + mode2 = PAGE_CUR_GE; + dtuple_set_n_fields(range_end, 0); + } else if (convert_search_mode_to_innobase(max_key->flag, mode2)) { + goto unsupported; + } else { + dict_index_copy_types(range_end, index, key->ext_key_parts); + row_sel_convert_mysql_key_to_innobase( + range_end, + m_prebuilt->srch_key_val2, + m_prebuilt->srch_key_val_len, + index, max_key->key, max_key->length); + DBUG_ASSERT(range_end->n_fields > 0); + } + + if (dict_index_is_spatial(index)) { + /*Only min_key used in spatial index. */ + n_rows = rtr_estimate_n_rows_in_range( + index, range_start, mode1); + } else { + btr_pos_t tuple1(range_start, mode1, pages->first_page); + btr_pos_t tuple2(range_end, mode2, pages->last_page); + n_rows = btr_estimate_n_rows_in_range(index, &tuple1, &tuple2); + pages->first_page= tuple1.page_id.raw(); + pages->last_page= tuple2.page_id.raw(); + } DBUG_EXECUTE_IF( "print_btr_estimate_n_rows_in_range_return_value", @@ -14331,11 +14346,7 @@ ha_innobase::records_in_range( (longlong) n_rows); ); -func_exit: - - m_prebuilt->trx->op_info = (char*)""; - - /* The MySQL optimizer seems to believe an estimate of 0 rows is + /* The MariaDB optimizer seems to believe an estimate of 0 rows is always accurate and may return the result 'Empty set' based on that. The accuracy is not guaranteed, and even if it were, for a locking read we should anyway perform the search to set the next-key lock. @@ -14345,6 +14356,10 @@ func_exit: n_rows = 1; } +unsupported: + mem_heap_free(heap); +func_exit: + m_prebuilt->trx->op_info = ""; DBUG_RETURN((ha_rows) n_rows); } @@ -15100,6 +15115,7 @@ ha_innobase::check( ulint n_rows_in_table = ULINT_UNDEFINED; bool is_ok = true; dberr_t ret; + uint handler_flags= check_opt->handler_flags; DBUG_ENTER("ha_innobase::check"); DBUG_ASSERT(thd == ha_thd()); @@ -15108,6 +15124,27 @@ ha_innobase::check( ut_a(m_prebuilt->trx == thd_to_trx(thd)); ut_ad(m_prebuilt->trx->mysql_thd == thd); + if (handler_flags || check_for_upgrade(check_opt)) { + /* The file was already checked and fixed as part of open */ + print_check_msg(thd, table->s->db.str, table->s->table_name.str, + "check", "note", + (opt_readonly || high_level_read_only + || !(check_opt->sql_flags & TT_FOR_UPGRADE)) + ? "Auto_increment will be" + " checked on each open until" + " CHECK TABLE FOR UPGRADE is executed" + : "Auto_increment checked and" + " .frm file version updated", 1); + if (handler_flags && (check_opt->sql_flags & TT_FOR_UPGRADE)) { + /* + No other issues found (as handler_flags was only + set if there as not other problems with the table + than auto_increment). + */ + DBUG_RETURN(HA_ADMIN_OK); + } + } + if (m_prebuilt->mysql_template == NULL) { /* Build the template; we will use a dummy template in index scans done in checking */ @@ -15311,6 +15348,35 @@ func_exit: DBUG_RETURN(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT); } +/** +Check if we there is a problem with the InnoDB table. +@param check_opt check options +@retval HA_ADMIN_OK if Table is ok +@retval HA_ADMIN_NEEDS_ALTER User should run ALTER TABLE FOR UPGRADE +@retval HA_ADMIN_NEEDS_CHECK User should run CHECK TABLE FOR UPGRADE +@retval HA_ADMIN_FAILED if InnoDB is in read-only mode */ +int ha_innobase::check_for_upgrade(HA_CHECK_OPT *check_opt) +{ + /* + Check if there is a possibility that the auto increment value + stored in PAGE_ROOT_AUTO_INC could be corrupt. + */ + if (table->s->mysql_version >= 100210); + else if (const Field *auto_increment= table->found_next_number_field) + { + uint col_no= innodb_col_no(auto_increment); + const dict_col_t *autoinc_col= + dict_table_get_nth_col(m_prebuilt->table, col_no); + if (m_prebuilt->table->get_index(*autoinc_col)) + { + check_opt->handler_flags= 1; + return (high_level_read_only && !opt_readonly) + ? HA_ADMIN_FAILED : HA_ADMIN_NEEDS_CHECK; + } + } + return HA_ADMIN_OK; +} + /*******************************************************************//** Gets the foreign key create info for a table stored in InnoDB. @return own: character string in the form which can be inserted to the @@ -15368,7 +15434,6 @@ get_foreign_key_info( char tmp_buff[NAME_LEN+1]; char name_buff[NAME_LEN+1]; const char* ptr; - LEX_CSTRING* referenced_key_name; LEX_CSTRING* name = NULL; if (dict_table_t::is_temporary_name(foreign->foreign_table_name)) { @@ -15469,18 +15534,16 @@ get_foreign_key_info( if (foreign->referenced_index && foreign->referenced_index->name != NULL) { - referenced_key_name = thd_make_lex_string( + f_key_info.referenced_key_name = thd_make_lex_string( thd, - f_key_info.referenced_key_name, + nullptr, foreign->referenced_index->name, strlen(foreign->referenced_index->name), 1); } else { - referenced_key_name = NULL; + f_key_info.referenced_key_name = NULL; } - f_key_info.referenced_key_name = referenced_key_name; - pf_key_info = (FOREIGN_KEY_INFO*) thd_memdup(thd, &f_key_info, sizeof(FOREIGN_KEY_INFO)); @@ -15766,7 +15829,7 @@ ha_innobase::start_stmt( } /* fall through */ default: - trx->end_bulk_insert(*m_prebuilt->table); + trx->bulk_insert_apply_for_table(m_prebuilt->table); if (!trx->bulk_insert) { break; } @@ -15960,7 +16023,7 @@ ha_innobase::external_lock( } /* fall through */ default: - trx->end_bulk_insert(*m_prebuilt->table); + trx->bulk_insert_apply_for_table(m_prebuilt->table); if (!trx->bulk_insert) { break; } @@ -16563,6 +16626,13 @@ ha_innobase::get_auto_increment( if (error != DB_SUCCESS) { *first_value = (~(ulonglong) 0); + /* This is an error case. We do the error handling by calling + the error code conversion function. Specifically, we need to + call thd_mark_transaction_to_rollback() to inform sql that we + have rolled back innodb transaction after a deadlock error. We + ignore the returned mysql error code here. */ + std::ignore = convert_error_code_to_mysql( + error, m_prebuilt->table->flags, m_user_thd); return; } @@ -17484,6 +17554,7 @@ innodb_make_page_dirty(THD*, st_mysql_sys_var*, void*, const void* save) { mtr_t mtr; uint space_id = *static_cast(save); + srv_fil_make_page_dirty_debug= space_id; mysql_mutex_unlock(&LOCK_global_system_variables); fil_space_t* space = fil_space_t::get(space_id); @@ -18201,13 +18272,15 @@ buf_flush_list_now_set(THD*, st_mysql_sys_var*, void*, const void* save) return; const uint s= srv_fil_make_page_dirty_debug; mysql_mutex_unlock(&LOCK_global_system_variables); - if (s) - buf_flush_sync(); - else + if (s == 0 || srv_is_undo_tablespace(s)) { - while (buf_flush_list_space(fil_system.sys_space, nullptr)); + fil_space_t *space= fil_system.sys_space; + if (s) { space= fil_space_get(s); } + while (buf_flush_list_space(space, nullptr)); os_aio_wait_until_no_pending_writes(true); } + else + buf_flush_sync(); mysql_mutex_lock(&LOCK_global_system_variables); } @@ -18376,6 +18449,12 @@ static void innodb_data_file_write_through_update(THD *, st_mysql_sys_var*, mysql_mutex_lock(&LOCK_global_system_variables); } +static void innodb_doublewrite_update(THD *, st_mysql_sys_var*, + void *, const void *save) +{ + fil_system.set_use_doublewrite(*static_cast(save)); +} + static void innodb_log_file_size_update(THD *thd, st_mysql_sys_var*, void *var, const void *save) { @@ -18416,7 +18495,7 @@ static void innodb_log_file_size_update(THD *thd, st_mysql_sys_var*, const bool in_progress(buf_pool.get_oldest_modification(LSN_MAX) < log_sys.resize_in_progress()); if (in_progress) - my_cond_timedwait(&buf_pool.do_flush_list, + my_cond_timedwait(&buf_pool.done_flush_list, &buf_pool.flush_list_mutex.m_mutex, &abstime); mysql_mutex_unlock(&buf_pool.flush_list_mutex); if (!log_sys.resize_in_progress()) @@ -18427,6 +18506,15 @@ static void innodb_log_file_size_update(THD *thd, st_mysql_sys_var*, mysql_mutex_lock(&LOCK_global_system_variables); } +static void innodb_log_spin_wait_delay_update(THD *, st_mysql_sys_var*, + void *, const void *save) +{ + log_sys.latch.wr_lock(SRW_LOCK_CALL); + mtr_t::spin_wait_delay= *static_cast(save); + mtr_t::finisher_update(); + log_sys.latch.wr_unlock(); +} + /** Update innodb_status_output or innodb_status_output_locks, which control InnoDB "status monitor" output to the error log. @param[out] var current value @@ -18715,11 +18803,14 @@ static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir, "The common part for InnoDB table spaces.", NULL, NULL, NULL); -static MYSQL_SYSVAR_BOOL(doublewrite, srv_use_doublewrite_buf, - PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, - "Enable InnoDB doublewrite buffer (enabled by default)." - " Disable with --skip-innodb-doublewrite.", - NULL, NULL, TRUE); +static MYSQL_SYSVAR_ENUM(doublewrite, buf_dblwr.use, + PLUGIN_VAR_OPCMDARG, + "Whether and how to use the doublewrite buffer. " + "OFF=Assume that writes of innodb_page_size are atomic; " + "ON=Prevent torn writes (the default); " + "fast=Like ON, but do not synchronize writes to data files", + nullptr, innodb_doublewrite_update, true, + &innodb_doublewrite_typelib); static MYSQL_SYSVAR_BOOL(use_atomic_writes, srv_use_atomic_writes, PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, @@ -19203,10 +19294,10 @@ static MYSQL_SYSVAR_ULONG(page_size, srv_page_size, NULL, NULL, UNIV_PAGE_SIZE_DEF, UNIV_PAGE_SIZE_MIN, UNIV_PAGE_SIZE_MAX, 0); -static MYSQL_SYSVAR_SIZE_T(log_buffer_size, log_sys.buf_size, +static MYSQL_SYSVAR_UINT(log_buffer_size, log_sys.buf_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Redo log buffer size in bytes.", - NULL, NULL, 16U << 20, 2U << 20, SIZE_T_MAX, 4096); + NULL, NULL, 16U << 20, 2U << 20, log_sys.buf_size_max, 4096); #if defined __linux__ || defined _WIN32 static MYSQL_SYSVAR_BOOL(log_file_buffering, log_sys.log_buffered, @@ -19236,6 +19327,12 @@ static MYSQL_SYSVAR_ULONGLONG(log_file_size, srv_log_file_size, nullptr, innodb_log_file_size_update, 96 << 20, 4 << 20, std::numeric_limits::max(), 4096); +static MYSQL_SYSVAR_UINT(log_spin_wait_delay, mtr_t::spin_wait_delay, + PLUGIN_VAR_OPCMDARG, + "Delay between log buffer spin lock polls (0 to use a blocking latch)", + nullptr, innodb_log_spin_wait_delay_update, + 0, 0, 6000, 0); + static MYSQL_SYSVAR_UINT(old_blocks_pct, innobase_old_blocks_pct, PLUGIN_VAR_RQCMDARG, "Percentage of the buffer pool to reserve for 'old' blocks.", @@ -19661,6 +19758,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(data_file_buffering), MYSQL_SYSVAR(data_file_write_through), MYSQL_SYSVAR(log_file_size), + MYSQL_SYSVAR(log_spin_wait_delay), MYSQL_SYSVAR(log_group_home_dir), MYSQL_SYSVAR(max_dirty_pages_pct), MYSQL_SYSVAR(max_dirty_pages_pct_lwm), @@ -19681,6 +19779,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(ft_server_stopword_table), MYSQL_SYSVAR(ft_user_stopword_table), MYSQL_SYSVAR(disable_sort_file_cache), + MYSQL_SYSVAR(snapshot_isolation), MYSQL_SYSVAR(stats_on_metadata), MYSQL_SYSVAR(stats_transient_sample_pages), MYSQL_SYSVAR(stats_persistent), diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 914f363720a..86ece0df63b 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -208,6 +208,7 @@ public: int rename_table(const char* from, const char* to) override; int check(THD* thd, HA_CHECK_OPT* check_opt) override; + int check_for_upgrade(HA_CHECK_OPT* check_opt) override; inline void reload_statistics(); @@ -521,6 +522,10 @@ protected: /** If mysql has locked with external_lock() */ bool m_mysql_has_locked; + + /** If true, disable the Rowid Filter. It is disabled when + the enigne is intialized for making rnd_pos() calls */ + bool m_disable_rowid_filter; }; @@ -914,6 +919,12 @@ unsigned innodb_col_no(const Field* field) MY_ATTRIBUTE((nonnull, warn_unused_result)); +/** Get the maximum integer value of a numeric column. +@param field column definition +@return maximum allowed integer value */ +ulonglong innobase_get_int_col_max_value(const Field *field) + MY_ATTRIBUTE((nonnull, warn_unused_result)); + /********************************************************************//** Helper function to push frm mismatch error to error log and if needed to sql-layer. */ diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 4e8e7d26d02..560840c53a0 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -864,6 +864,9 @@ my_error_innodb( case DB_DEADLOCK: my_error(ER_LOCK_DEADLOCK, MYF(0)); break; + case DB_RECORD_CHANGED: + my_error(ER_CHECKREAD, MYF(0), table); + break; case DB_LOCK_WAIT_TIMEOUT: my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0)); break; @@ -1458,11 +1461,6 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx } }; -/********************************************************************//** -Get the upper limit of the MySQL integral and floating-point type. -@return maximum allowed value for the field */ -ulonglong innobase_get_int_col_max_value(const Field *field); - /** Determine if fulltext indexes exist in a given table. @param table MySQL table @return number of fulltext indexes */ @@ -1730,11 +1728,9 @@ instant_alter_column_possible( ut_ad(!is_null || nullable); n_nullable += nullable; n_add++; - uint l; + uint l = (*af)->pack_length(); switch ((*af)->type()) { case MYSQL_TYPE_VARCHAR: - l = reinterpret_cast - (*af)->get_length(); variable_length: if (l >= min_local_len) { max_size += blob_prefix @@ -1748,7 +1744,6 @@ instant_alter_column_possible( if (!is_null) { min_size += l; } - l = (*af)->pack_length(); max_size += l; lenlen += l > 255 ? 2 : 1; } @@ -1762,7 +1757,6 @@ instant_alter_column_possible( ((*af))->get_length(); goto variable_length; default: - l = (*af)->pack_length(); if (l > 255 && ib_table.not_redundant()) { goto variable_length; } @@ -2748,6 +2742,9 @@ cannot_create_many_fulltext_index: online = false; } + static constexpr const char *not_implemented + = "Not implemented for system-versioned operations"; + if (ha_alter_info->handler_flags & ALTER_ADD_NON_UNIQUE_NON_PRIM_INDEX) { /* ADD FULLTEXT|SPATIAL INDEX requires a lock. @@ -2775,6 +2772,12 @@ cannot_create_many_fulltext_index: goto cannot_create_many_fulltext_index; } + if (altered_table->versioned()) { + ha_alter_info->unsupported_reason + = not_implemented; + DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); + } + add_fulltext = true; if (ha_alter_info->online && !ha_alter_info->unsupported_reason) { @@ -2811,12 +2814,18 @@ cannot_create_many_fulltext_index: } } - // FIXME: implement Online DDL for system-versioned operations - if (ha_alter_info->handler_flags & INNOBASE_ALTER_VERSIONED_REBUILD) { - + if (m_prebuilt->table->is_stats_table()) { if (ha_alter_info->online) { ha_alter_info->unsupported_reason = - "Not implemented for system-versioned operations"; + table_share->table_name.str; + } + online= false; + } + + // FIXME: implement Online DDL for system-versioned operations + if (ha_alter_info->handler_flags & INNOBASE_ALTER_VERSIONED_REBUILD) { + if (ha_alter_info->online) { + ha_alter_info->unsupported_reason = not_implemented; } online = false; @@ -7444,6 +7453,7 @@ error_handled: row_mysql_lock_data_dictionary(ctx->trx); } else { row_merge_drop_indexes(ctx->trx, user_table, true); + user_table->indexes.start->online_log = nullptr; ctx->trx->commit(); } @@ -9865,13 +9875,7 @@ commit_set_autoinc( const dict_col_t* autoinc_col = dict_table_get_nth_col(ctx->old_table, innodb_col_no(ai)); - dict_index_t* index - = dict_table_get_first_index(ctx->old_table); - while (index != NULL - && index->fields[0].col != autoinc_col) { - index = dict_table_get_next_index(index); - } - + auto index = ctx->old_table->get_index(*autoinc_col); ut_ad(index); ib_uint64_t max_in_table = index @@ -10246,6 +10250,7 @@ when rebuilding the table. @param ctx In-place ALTER TABLE context @param altered_table MySQL table that is being altered @param old_table MySQL table as it is before the ALTER operation +@param statistics_exist whether to update InnoDB persistent statistics @param trx Data dictionary transaction @param table_name Table name in MySQL @retval true Failure @@ -10529,6 +10534,7 @@ when not rebuilding the table. @param ha_alter_info Data used during in-place alter @param ctx In-place ALTER TABLE context @param old_table MySQL table as it is before the ALTER operation +@param statistics_exist whether to update InnoDB persistent statistics @param trx Data dictionary transaction @param table_name Table name in MySQL @retval true Failure @@ -10542,6 +10548,7 @@ commit_try_norebuild( ha_innobase_inplace_ctx*ctx, TABLE* altered_table, const TABLE* old_table, + bool statistics_exist, trx_t* trx, const char* table_name) { @@ -10656,6 +10663,10 @@ commit_try_norebuild( goto handle_error; } + if (!statistics_exist) { + continue; + } + error = dict_stats_delete_from_index_stats(db, table, index->name, trx); switch (error) { @@ -10667,7 +10678,8 @@ commit_try_norebuild( } } - if (const size_t size = ha_alter_info->rename_keys.size()) { + if (!statistics_exist) { + } else if (const size_t size = ha_alter_info->rename_keys.size()) { char tmp_name[5]; char db[MAX_DB_UTF8_LEN], table[MAX_TABLE_UTF8_LEN]; @@ -11234,16 +11246,7 @@ ha_innobase::commit_inplace_alter_table( fts_optimize_remove_table(ctx->old_table); } - dict_sys.freeze(SRW_LOCK_CALL); - for (auto f : ctx->old_table->referenced_set) { - if (dict_table_t* child = f->foreign_table) { - error = lock_table_for_trx(child, trx, LOCK_X); - if (error != DB_SUCCESS) { - break; - } - } - } - dict_sys.unfreeze(); + error = lock_table_children(ctx->old_table, trx); if (ctx->new_table->fts) { ut_ad(!ctx->new_table->fts->add_wq); @@ -11423,6 +11426,8 @@ err_index: } } + DEBUG_SYNC(m_user_thd, "innodb_commit_inplace_before_lock"); + DBUG_EXECUTE_IF("stats_lock_fail", error = DB_LOCK_WAIT_TIMEOUT; trx_rollback_for_mysql(trx);); @@ -11506,7 +11511,9 @@ fail: goto fail; } } else if (commit_try_norebuild(ha_alter_info, ctx, - altered_table, table, trx, + altered_table, table, + table_stats && index_stats, + trx, table_share->table_name.str)) { goto fail; } diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 4fff8bed133..67a89f9402d 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -264,6 +264,9 @@ func_exit: goto func_exit; } + if (page_no >= fil_system.sys_space->free_limit) + goto corrupted; + /* Since pessimistic inserts were prevented, we know that the page is still in the free list. NOTE that also deletes may take pages from the free list, but they take them from the start, and @@ -279,6 +282,7 @@ func_exit: if (page_no != flst_get_last(PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST + root->page.frame).page) { + corrupted: err= DB_CORRUPTION; goto func_exit; } @@ -288,7 +292,8 @@ func_exit: buf_page_get_gen(page_id_t{0, page_no}, 0, RW_X_LATCH, nullptr, BUF_GET, &mtr, &err)) err= flst_remove(root, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, - block, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr); + block, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, + fil_system.sys_space->free_limit, &mtr); if (err == DB_SUCCESS) buf_page_free(fil_system.sys_space, page_no, &mtr); diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index f46fae5bd2a..35a567d7bee 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -192,13 +192,16 @@ btr_read_autoinc(dict_index_t* index) /** Read the last used AUTO_INCREMENT value from PAGE_ROOT_AUTO_INC, or fall back to MAX(auto_increment_column). -@param[in] table table containing an AUTO_INCREMENT column -@param[in] col_no index of the AUTO_INCREMENT column -@return the AUTO_INCREMENT value -@retval 0 on error or if no AUTO_INCREMENT value was used yet */ -ib_uint64_t -btr_read_autoinc_with_fallback(const dict_table_t* table, unsigned col_no) - MY_ATTRIBUTE((nonnull, warn_unused_result)); +@param table table containing an AUTO_INCREMENT column +@param col_no index of the AUTO_INCREMENT column +@param mysql_version TABLE_SHARE::mysql_version +@param max the maximum value of the AUTO_INCREMENT column +@return the AUTO_INCREMENT value +@retval 0 on error or if no AUTO_INCREMENT value was used yet */ +uint64_t btr_read_autoinc_with_fallback(const dict_table_t *table, + unsigned col_no, ulong mysql_version, + uint64_t max) + MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Write the next available AUTO_INCREMENT value to PAGE_ROOT_AUTO_INC. @param[in,out] index clustered index diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h index c66a3bfa329..5f84328da19 100644 --- a/storage/innobase/include/btr0pcur.h +++ b/storage/innobase/include/btr0pcur.h @@ -28,7 +28,6 @@ Created 2/23/1996 Heikki Tuuri #include "dict0dict.h" #include "btr0cur.h" -#include "buf0block_hint.h" #include "btr0btr.h" #include "gis0rtree.h" @@ -332,8 +331,8 @@ struct btr_pcur_t /** BTR_PCUR_ON, BTR_PCUR_BEFORE, or BTR_PCUR_AFTER, depending on whether cursor was on, before, or after the old_rec record */ btr_pcur_pos_t rel_pos= btr_pcur_pos_t(0); - /** buffer block when the position was stored */ - buf::Block_hint block_when_stored; + /** the page identifier of old_rec */ + page_id_t old_page_id{0,0}; /** the modify clock value of the buffer block when the cursor position was stored */ ib_uint64_t modify_clock= 0; @@ -432,7 +431,8 @@ btr_pcur_open( } /** Open a cursor on the first user record satisfying the search condition; -in case of no match, after the last index record. */ +in case of no match, after the last index record. +@return DB_SUCCESS or error code */ MY_ATTRIBUTE((nonnull, warn_unused_result)) inline dberr_t diff --git a/storage/innobase/include/buf0block_hint.h b/storage/innobase/include/buf0block_hint.h deleted file mode 100644 index d4fee7c1e99..00000000000 --- a/storage/innobase/include/buf0block_hint.h +++ /dev/null @@ -1,76 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2020, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2020, MariaDB Corporation. -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License, version 2.0, as published by the -Free Software Foundation. - -This program is also distributed with certain software (including but not -limited to OpenSSL) that is licensed under separate terms, as designated in a -particular file or component or in included license documentation. The authors -of MySQL hereby grant you an additional permission to link the program and -your derivative works with the separately licensed software that they have -included with MySQL. - -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, version 2.0, -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., -51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -*****************************************************************************/ -#pragma once -#include "buf0buf.h" - -namespace buf { -class Block_hint { -public: - /** Stores the pointer to the block, which is currently buffer-fixed. - @param block a pointer to a buffer-fixed block to be stored */ - inline void store(buf_block_t *block) - { - ut_ad(block->page.buf_fix_count()); - m_block= block; - m_page_id= block->page.id(); - } - - /** Clears currently stored pointer. */ - inline void clear() { m_block= nullptr; } - - /** Invoke f on m_block(which may be null) - @param f The function to be executed. It will be passed the pointer. - If you wish to use the block pointer subsequently, - you need to ensure you buffer-fix it before returning from f. - @return the return value of f - */ - template - bool run_with_hint(const F &f) - { - buffer_fix_block_if_still_valid(); - /* m_block could be changed during f() call, so we use local - variable to remember which block we need to unfix */ - buf_block_t *block= m_block; - bool res= f(block); - if (block) - block->page.unfix(); - return res; - } - - buf_block_t *block() const { return m_block; } - - private: - /** The block pointer stored by store(). */ - buf_block_t *m_block= nullptr; - /** If m_block is non-null, the m_block->page.id at time it was stored. */ - page_id_t m_page_id{0, 0}; - - /** A helper function which checks if m_block is not a dangling pointer and - still points to block with page with m_page_id and if so, buffer-fixes it, - otherwise clear()s it */ - void buffer_fix_block_if_still_valid(); -}; -} // namespace buf diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 4aa7ba93348..e154f788820 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -154,14 +154,25 @@ buf_block_free( #define buf_page_get(ID, SIZE, LA, MTR) \ buf_page_get_gen(ID, SIZE, LA, NULL, BUF_GET, MTR) -/** Try to acquire a page latch. -@param rw_latch RW_S_LATCH or RW_X_LATCH +/** Try to buffer-fix a page. @param block guessed block +@param id expected block->page.id() +@return block if it was buffer-fixed +@retval nullptr if the block no longer is valid */ +buf_block_t *buf_page_optimistic_fix(buf_block_t *block, page_id_t id) + MY_ATTRIBUTE((nonnull, warn_unused_result)); + +/** Try to acquire a page latch after buf_page_optimistic_fix(). +@param block buffer-fixed block +@param rw_latch RW_S_LATCH or RW_X_LATCH @param modify_clock expected value of block->modify_clock @param mtr mini-transaction -@return whether the latch was acquired (the page is an allocated file page) */ -bool buf_page_optimistic_get(ulint rw_latch, buf_block_t *block, - uint64_t modify_clock, mtr_t *mtr); +@return block if the latch was acquired +@retval nullptr if block->unfix() was called because it no longer is valid */ +buf_block_t *buf_page_optimistic_get(buf_block_t *block, + rw_lock_type_t rw_latch, + uint64_t modify_clock, mtr_t *mtr) + MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Try to S-latch a page. Suitable for using when holding the lock_sys latches (as it avoids deadlock). @@ -256,15 +267,6 @@ on the block. */ UNIV_INLINE void buf_block_modify_clock_inc( -/*=======================*/ - buf_block_t* block); /*!< in: block */ -/********************************************************************//** -Returns the value of the modify clock. The caller must have an s-lock -or x-lock on the block. -@return value */ -UNIV_INLINE -ib_uint64_t -buf_block_get_modify_clock( /*=======================*/ buf_block_t* block); /*!< in: block */ #endif /* !UNIV_INNOCHECKSUM */ @@ -708,17 +710,16 @@ public: @retval DB_FAIL if the page contains the wrong ID */ dberr_t read_complete(const fil_node_t &node); - /** Note that a block is no longer dirty, while not removing - it from buf_pool.flush_list - @param temporary whether the page belongs to the temporary tablespace - @param error whether an error may have occurred while writing */ - inline void write_complete(bool temporary, bool error); + /** Release a write fix after a page write was completed. + @param persistent whether the page belongs to a persistent tablespace + @param error whether an error may have occurred while writing + @param state recently read state() value with the correct io-fix */ + void write_complete(bool persistent, bool error, uint32_t state); /** Write a flushable page to a file or free a freeable block. - @param evict whether to evict the page on write completion @param space tablespace @return whether a page write was initiated and buf_pool.mutex released */ - bool flush(bool evict, fil_space_t *space); + bool flush(fil_space_t *space); /** Notify that a page in a temporary tablespace has been modified. */ void set_temp_modified() @@ -1625,10 +1626,6 @@ public: /** Decrement the number of pending LRU flush */ inline void n_flush_dec(); - /** Decrement the number of pending LRU flush - while holding flush_list_mutex */ - inline void n_flush_dec_holding_mutex(); - /** @return whether flush_list flushing is active */ bool flush_list_active() const { @@ -1778,6 +1775,9 @@ public: /** Free a page whose underlying file page has been freed. */ ATTRIBUTE_COLD void release_freed_page(buf_page_t *bpage) noexcept; + /** Issue a warning that we could not free up buffer pool pages. */ + ATTRIBUTE_COLD void LRU_warn(); + private: /** Temporary memory for page_compressed and encrypted I/O */ struct io_buf_t diff --git a/storage/innobase/include/buf0buf.inl b/storage/innobase/include/buf0buf.inl index 1fc463a8341..048e3d15906 100644 --- a/storage/innobase/include/buf0buf.inl +++ b/storage/innobase/include/buf0buf.inl @@ -116,17 +116,3 @@ buf_block_modify_clock_inc( block->modify_clock++; } - -/********************************************************************//** -Returns the value of the modify clock. The caller must have an s-lock -or x-lock on the block. -@return value */ -UNIV_INLINE -ib_uint64_t -buf_block_get_modify_clock( -/*=======================*/ - buf_block_t* block) /*!< in: block */ -{ - ut_ad(block->page.lock.have_any()); - return(block->modify_clock); -} diff --git a/storage/innobase/include/buf0dblwr.h b/storage/innobase/include/buf0dblwr.h index 6e7662d9b81..f912775de59 100644 --- a/storage/innobase/include/buf0dblwr.h +++ b/storage/innobase/include/buf0dblwr.h @@ -53,9 +53,9 @@ class buf_dblwr_t element* buf_block_arr; }; - /** the page number of the first doublewrite block (block_size() pages) */ + /** the page number of the first doublewrite block (block_size pages) */ page_id_t block1{0, 0}; - /** the page number of the second doublewrite block (block_size() pages) */ + /** the page number of the second doublewrite block (block_size pages) */ page_id_t block2{0, 0}; /** mutex protecting the data members below */ @@ -74,6 +74,22 @@ class buf_dblwr_t slot slots[2]; slot *active_slot; + /** Size of the doublewrite block in pages */ + uint32_t block_size; + +public: + /** Values of use */ + enum usage { + /** Assume that writes are atomic */ + USE_NO= 0, + /** Use the doublewrite buffer with full durability */ + USE_YES, + /** Durable writes to the doublewrite buffer, not to data files */ + USE_FAST + }; + /** The value of innodb_doublewrite */ + ulong use; +private: /** Initialise the persistent storage of the doublewrite buffer. @param header doublewrite page header in the TRX_SYS page */ inline void init(const byte *header); @@ -126,9 +142,6 @@ public: @param request the completed batch write request */ void flush_buffered_writes_completed(const IORequest &request); - /** Size of the doublewrite block in pages */ - uint32_t block_size() const { return FSP_EXTENT_SIZE; } - /** Schedule a page write. If the doublewrite memory buffer is full, flush_buffered_writes() will be invoked to make space. @param request asynchronous write request @@ -139,6 +152,19 @@ public: bool is_created() const { return UNIV_LIKELY(block1 != page_id_t(0, 0)); } + /** @return whether the doublewrite buffer is in use */ + bool in_use() const { return is_created() && use; } + /** @return whether fsync() is needed on non-doublewrite pages */ + bool need_fsync() const { return use < USE_FAST; } + + void set_use(ulong use) + { + ut_ad(use <= USE_FAST); + mysql_mutex_lock(&mutex); + this->use= use; + mysql_mutex_unlock(&mutex); + } + /** @return whether a page identifier is part of the doublewrite buffer */ bool is_inside(const page_id_t id) const { @@ -147,8 +173,8 @@ public: ut_ad(block1 < block2); if (id < block1) return false; - const uint32_t size= block_size(); - return id < block1 + size || (id >= block2 && id < block2 + size); + return id < block1 + block_size || + (id >= block2 && id < block2 + block_size); } /** Wait for flush_buffered_writes() to be fully completed */ diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index 0cce514b2d2..cc32a38a4ef 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -85,16 +85,6 @@ buf_flush_init_for_writing( bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed= nullptr) MY_ATTRIBUTE((warn_unused_result)); -/** Write out dirty blocks from buf_pool.LRU, -and move clean blocks to buf_pool.free. -The caller must invoke buf_dblwr.flush_buffered_writes() -after releasing buf_pool.mutex. -@param max_n wished maximum mumber of blocks flushed -@param evict whether to evict pages after flushing -@return evict ? number of processed pages : number of pages written -@retval 0 if a buf_pool.LRU batch is already running */ -ulint buf_flush_LRU(ulint max_n, bool evict); - /** Wait until a LRU flush batch ends. */ void buf_flush_wait_LRU_batch_end(); /** Wait until all persistent pages are flushed up to a limit. diff --git a/storage/innobase/include/cache.h b/storage/innobase/include/cache.h new file mode 100644 index 00000000000..0647cbe6dc4 --- /dev/null +++ b/storage/innobase/include/cache.h @@ -0,0 +1,33 @@ +/***************************************************************************** + +Copyright (c) 2024, MariaDB plc + +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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +#pragma once +#include + +#if defined __x86_64__ || defined __aarch64__ || defined __powerpc64__ +struct pmem_control +{ + void (*persist)(const void *, size_t); +public: + pmem_control(); +}; +extern const pmem_control pmem; +# define pmem_persist(buf, size) pmem.persist(buf, size) +#else +void pmem_persist(const void *buf, size_t size); +#endif diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h index a5356e0d1a3..fcb543ebb1a 100644 --- a/storage/innobase/include/data0data.h +++ b/storage/innobase/include/data0data.h @@ -339,15 +339,12 @@ dtuple_set_types_binary( dtuple_t* tuple, /*!< in: data tuple */ ulint n) /*!< in: number of fields to set */ MY_ATTRIBUTE((nonnull)); -/**********************************************************************//** -Checks if a dtuple contains an SQL null value. -@return TRUE if some field is SQL null */ +/** Checks if a dtuple contains an SQL null value. +@param tuple tuple +@param fields_number number of fields in the tuple to check +@return true if some field is SQL null */ UNIV_INLINE -ibool -dtuple_contains_null( -/*=================*/ - const dtuple_t* tuple) /*!< in: dtuple */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); +bool dtuple_contains_null(const dtuple_t *tuple, ulint fields_number = 0); /**********************************************************//** Checks that a data field is typed. Asserts an error if not. @return TRUE if ok */ diff --git a/storage/innobase/include/data0data.inl b/storage/innobase/include/data0data.inl index 2d1bf5a2d50..b6c6ace8dc0 100644 --- a/storage/innobase/include/data0data.inl +++ b/storage/innobase/include/data0data.inl @@ -596,28 +596,18 @@ data_write_sql_null( memset(data, 0, len); } -/**********************************************************************//** -Checks if a dtuple contains an SQL null value. -@return TRUE if some field is SQL null */ +/** Checks if a dtuple contains an SQL null value. +@param tuple tuple +@param fields_number number of fields in the tuple to check +@return true if some field is SQL null */ UNIV_INLINE -ibool -dtuple_contains_null( -/*=================*/ - const dtuple_t* tuple) /*!< in: dtuple */ +bool dtuple_contains_null(const dtuple_t *tuple, ulint fields_number) { - ulint n; - ulint i; - - n = dtuple_get_n_fields(tuple); - - for (i = 0; i < n; i++) { - if (dfield_is_null(dtuple_get_nth_field(tuple, i))) { - - return(TRUE); - } - } - - return(FALSE); + ulint n= fields_number ? fields_number : dtuple_get_n_fields(tuple); + for (ulint i= 0; i < n; i++) + if (dfield_is_null(dtuple_get_nth_field(tuple, i))) + return true; + return false; } /**************************************************************//** diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h index 64182aabc38..960ec3905eb 100644 --- a/storage/innobase/include/db0err.h +++ b/storage/innobase/include/db0err.h @@ -32,23 +32,25 @@ Created 5/24/1996 Heikki Tuuri enum dberr_t { DB_SUCCESS, - DB_SUCCESS_LOCKED_REC = 9, /*!< like DB_SUCCESS, but a new + DB_SUCCESS_LOCKED_REC= 9, /*!< like DB_SUCCESS, but a new explicit record lock was created */ /* The following are error codes */ - DB_ERROR = 11, + DB_RECORD_CHANGED, + DB_ERROR, DB_INTERRUPTED, DB_OUT_OF_MEMORY, DB_OUT_OF_FILE_SPACE, DB_LOCK_WAIT, DB_DEADLOCK, - DB_ROLLBACK, DB_DUPLICATE_KEY, DB_MISSING_HISTORY, /*!< required history data has been deleted due to lack of space in rollback segment */ - DB_CLUSTER_NOT_FOUND = 30, - DB_TABLE_NOT_FOUND, +#ifdef WITH_WSREP + DB_ROLLBACK, +#endif + DB_TABLE_NOT_FOUND= 31, DB_TOO_BIG_RECORD, /*!< a record in an index would not fit on a compressed page, or it would become bigger than 1/2 free space in diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 3513f21b5ec..47350f9c863 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -35,6 +35,7 @@ Created 1/8/1996 Heikki Tuuri #include #include +class MDL_context; class MDL_ticket; /** the first table or index ID for other than hard-coded system tables */ @@ -139,6 +140,21 @@ dict_acquire_mdl_shared(dict_table_t *table, MDL_ticket **mdl, dict_table_op_t table_op= DICT_TABLE_OP_NORMAL); +/** Acquire MDL shared for the table name. +@tparam trylock whether to use non-blocking operation +@param[in,out] table table object +@param[in,out] mdl_context MDL context +@param[out] mdl MDL ticket +@param[in] table_op operation to perform when opening +@return table object after locking MDL shared +@retval nullptr if the table is not readable, or if trylock && MDL blocked */ +template +__attribute__((nonnull, warn_unused_result)) +dict_table_t* +dict_acquire_mdl_shared(dict_table_t *table, + MDL_context *mdl_context, MDL_ticket **mdl, + dict_table_op_t table_op); + /** Look up a table by numeric identifier. @param[in] table_id table identifier @param[in] dict_locked data dictionary locked @@ -1312,13 +1328,7 @@ class dict_sys_t std::atomic latch_ex_wait_start; /** the rw-latch protecting the data dictionary cache */ - alignas(CPU_LEVEL1_DCACHE_LINESIZE) srw_lock latch; -#ifdef UNIV_DEBUG - /** whether latch is being held in exclusive mode (by any thread) */ - Atomic_relaxed latch_ex; - /** number of S-latch holders */ - Atomic_counter latch_readers; -#endif + alignas(CPU_LEVEL1_DCACHE_LINESIZE) IF_DBUG(srw_lock_debug,srw_lock) latch; public: /** Indexes of SYS_TABLE[] */ enum @@ -1469,15 +1479,12 @@ public: } #ifdef UNIV_DEBUG - /** @return whether any thread (not necessarily the current thread) - is holding the latch; that is, this check may return false - positives */ - bool frozen() const { return latch_readers || latch_ex; } - /** @return whether any thread (not necessarily the current thread) - is holding a shared latch */ - bool frozen_not_locked() const { return latch_readers; } + /** @return whether the current thread is holding the latch */ + bool frozen() const { return latch.have_any(); } + /** @return whether the current thread is holding a shared latch */ + bool frozen_not_locked() const { return latch.have_rd(); } /** @return whether the current thread holds the exclusive latch */ - bool locked() const { return latch_ex == pthread_self(); } + bool locked() const { return latch.have_wr(); } #endif private: /** Acquire the exclusive latch */ @@ -1492,13 +1499,7 @@ public: /** Exclusively lock the dictionary cache. */ void lock(SRW_LOCK_ARGS(const char *file, unsigned line)) { - if (latch.wr_lock_try()) - { - ut_ad(!latch_readers); - ut_ad(!latch_ex); - ut_d(latch_ex= pthread_self()); - } - else + if (!latch.wr_lock_try()) lock_wait(SRW_LOCK_ARGS(file, line)); } @@ -1511,27 +1512,11 @@ public: ATTRIBUTE_NOINLINE void unfreeze(); #else /** Unlock the data dictionary cache. */ - void unlock() - { - ut_ad(latch_ex == pthread_self()); - ut_ad(!latch_readers); - ut_d(latch_ex= 0); - latch.wr_unlock(); - } + void unlock() { latch.wr_unlock(); } /** Acquire a shared lock on the dictionary cache. */ - void freeze() - { - latch.rd_lock(); - ut_ad(!latch_ex); - ut_d(latch_readers++); - } + void freeze() { latch.rd_lock(); } /** Release a shared lock on the dictionary cache. */ - void unfreeze() - { - ut_ad(!latch_ex); - ut_ad(latch_readers--); - latch.rd_unlock(); - } + void unfreeze() { latch.rd_unlock(); } #endif /** Estimate the used memory occupied by the data dictionary diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index b06328d7382..52bb4777202 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1006,8 +1006,6 @@ struct dict_index_t { /*!< number of columns the user defined to be in the index: in the internal representation we add more columns */ - unsigned nulls_equal:1; - /*!< if true, SQL NULL == SQL NULL */ unsigned n_uniq:10;/*!< number of fields from the beginning which are enough to determine an index entry uniquely */ @@ -2423,6 +2421,9 @@ public: /** @return number of unique columns in FTS_DOC_ID index */ unsigned fts_n_uniq() const { return versioned() ? 2 : 1; } + /** @return the index for that starts with a specific column */ + dict_index_t *get_index(const dict_col_t &col) const; + /** Create metadata. @param name table name @param space tablespace diff --git a/storage/innobase/include/dict0mem.inl b/storage/innobase/include/dict0mem.inl index d60ee5d9bf4..edb7cf92cd5 100644 --- a/storage/innobase/include/dict0mem.inl +++ b/storage/innobase/include/dict0mem.inl @@ -63,6 +63,5 @@ dict_mem_fill_index_struct( & index->MAX_N_FIELDS; /* The '1 +' above prevents allocation of an empty mem block */ - index->nulls_equal = false; ut_d(index->magic_n = DICT_INDEX_MAGIC_N); } diff --git a/storage/innobase/include/dyn0buf.h b/storage/innobase/include/dyn0buf.h index 06af4dcca88..7a4e6760019 100644 --- a/storage/innobase/include/dyn0buf.h +++ b/storage/innobase/include/dyn0buf.h @@ -57,11 +57,7 @@ public: /** Gets the number of used bytes in a block. @return number of bytes used */ - ulint used() const - MY_ATTRIBUTE((warn_unused_result)) - { - return(static_cast(m_used & ~DYN_BLOCK_FULL_FLAG)); - } + uint32_t used() const { return m_used; } /** Gets pointer to the start of data. @@ -153,8 +149,7 @@ public: /** Storage */ byte m_data[MAX_DATA_SIZE]; - /** number of data bytes used in this block; - DYN_BLOCK_FULL_FLAG is set when the block becomes full */ + /** number of data bytes used in this block */ uint32_t m_used; friend class mtr_buf_t; diff --git a/storage/innobase/include/dyn0types.h b/storage/innobase/include/dyn0types.h index 83d0b0d64c2..af7f663d970 100644 --- a/storage/innobase/include/dyn0types.h +++ b/storage/innobase/include/dyn0types.h @@ -33,7 +33,4 @@ Created 2013-03-16 Sunny Bains /** This is the initial 'payload' size of a dynamic array */ #define DYN_ARRAY_DATA_SIZE 512 -/** Flag for dyn_block_t::used that indicates a full block */ -#define DYN_BLOCK_FULL_FLAG 0x1000000UL - #endif /* dyn0types_h */ diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index f3660eff7c6..41b6c59f2c4 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -48,9 +48,6 @@ struct named_spaces_tag_t; using space_list_t= ilist; -// Forward declaration -extern my_bool srv_use_doublewrite_buf; - /** Undo tablespaces starts with space_id. */ extern uint32_t srv_undo_space_id_start; /** The number of UNDO tablespaces that are open and ready to use. */ @@ -318,7 +315,6 @@ struct fil_space_t final ~fil_space_t() { ut_ad(!latch_owner); - ut_ad(!latch_count); latch.destroy(); } @@ -382,9 +378,9 @@ private: /** The reference count */ static constexpr uint32_t PENDING= ~(STOPPING | CLOSING | NEEDS_FSYNC); /** latch protecting all page allocation bitmap pages */ - srw_lock latch; + IF_DBUG(srw_lock_debug, srw_lock) latch; + /** the thread that holds the exclusive latch, or 0 */ pthread_t latch_owner; - ut_d(Atomic_relaxed latch_count;) public: /** MariaDB encryption data */ fil_space_crypt_t *crypt_data; @@ -982,46 +978,41 @@ public: bool recheck, bool encrypt); #ifdef UNIV_DEBUG - bool is_latched() const { return latch_count != 0; } + bool is_latched() const { return latch.have_any(); } #endif - bool is_owner() const { return latch_owner == pthread_self(); } + bool is_owner() const + { + const bool owner{latch_owner == pthread_self()}; + ut_ad(owner == latch.have_wr()); + return owner; + } /** Acquire the allocation latch in exclusive mode */ void x_lock() { latch.wr_lock(SRW_LOCK_CALL); ut_ad(!latch_owner); latch_owner= pthread_self(); - ut_ad(!latch_count.fetch_add(1)); } /** Release the allocation latch from exclusive mode */ void x_unlock() { - ut_ad(latch_count.fetch_sub(1) == 1); ut_ad(latch_owner == pthread_self()); latch_owner= 0; latch.wr_unlock(); } /** Acquire the allocation latch in shared mode */ - void s_lock() - { - ut_ad(!is_owner()); - latch.rd_lock(SRW_LOCK_CALL); - ut_ad(!latch_owner); - ut_d(latch_count.fetch_add(1)); - } + void s_lock() { latch.rd_lock(SRW_LOCK_CALL); } /** Release the allocation latch from shared mode */ - void s_unlock() - { - ut_ad(latch_count.fetch_sub(1)); - ut_ad(!latch_owner); - latch.rd_unlock(); - } + void s_unlock() { latch.rd_unlock(); } typedef span name_type; /** @return the tablespace name (databasename/tablename) */ name_type name() const; + /** Update the data structures on write completion */ + void complete_write(); + private: /** @return whether the file is usable for io() */ ATTRIBUTE_COLD bool prepare_acquired(); @@ -1094,9 +1085,6 @@ struct fil_node_t final @return detached handle or OS_FILE_CLOSED */ inline pfs_os_file_t close_to_free(bool detach_handle= false); - /** Update the data structures on write completion */ - inline void complete_write(); - private: /** Does stuff common for close() and detach() */ void prepare_to_close_or_detach(); @@ -1104,8 +1092,7 @@ private: inline bool fil_space_t::use_doublewrite() const { - return !UT_LIST_GET_FIRST(chain)->atomic_write && srv_use_doublewrite_buf && - buf_dblwr.is_created(); + return !UT_LIST_GET_FIRST(chain)->atomic_write && buf_dblwr.in_use(); } inline void fil_space_t::set_imported() @@ -1366,9 +1353,9 @@ struct fil_system_t Some members may require late initialisation, thus we just mark object as uninitialised. Real initialisation happens in create(). */ - fil_system_t() : m_initialised(false) {} + fil_system_t() {} - bool is_initialised() const { return m_initialised; } + bool is_initialised() const { return spaces.array; } /** Create the file system interface at database start. @@ -1381,8 +1368,6 @@ struct fil_system_t void close(); private: - bool m_initialised; - /** Points to the last opened space in space_list. Protected with fil_system.mutex. */ fil_space_t *space_list_last_opened= nullptr; @@ -1418,19 +1403,32 @@ public: /** Map of fil_space_t::id to fil_space_t* */ hash_table_t spaces; - /** whether each write to data files is durable (O_DSYNC) */ + /** false=invoke fsync() or fdatasync() on data files before checkpoint; + true=each write is durable (O_DSYNC) */ my_bool write_through; /** whether data files are buffered (not O_DIRECT) */ my_bool buffered; + /** whether fdatasync() is needed on data files */ + Atomic_relaxed need_unflushed_spaces; /** Try to enable or disable write-through of data files */ void set_write_through(bool write_through); + /** Update innodb_doublewrite */ + void set_use_doublewrite(ulong use) + { + buf_dblwr.set_use(use); + need_unflushed_spaces= !write_through && buf_dblwr.need_fsync(); + } + /** Try to enable or disable file system caching of data files */ void set_buffered(bool buffered); TPOOL_SUPPRESS_TSAN bool is_write_through() const { return write_through; } TPOOL_SUPPRESS_TSAN bool is_buffered() const { return buffered; } + /** @return whether to update unflushed_spaces */ + bool use_unflushed_spaces() const { return need_unflushed_spaces; } + /** tablespaces for which fil_space_t::needs_flush() holds */ sized_ilist unflushed_spaces; /** number of currently open files; protected by mutex */ @@ -1624,17 +1622,34 @@ void fil_close_tablespace(uint32_t id); /*******************************************************************//** Allocates and builds a file name from a path, a table or tablespace name and a suffix. The string must be freed by caller with ut_free(). -@param[in] path NULL or the directory path or the full path and filename. +@param[in] path nullptr or the directory path or the full path and filename @param[in] name {} if path is full, or Table/Tablespace name -@param[in] ext the file extension to use -@param[in] trim_name true if the last name on the path should be trimmed. +@param[in] extension the file extension to use +@param[in] trim_name true if the last name on the path should be trimmed @return own: file name */ -char* fil_make_filepath(const char *path, const fil_space_t::name_type &name, - ib_extention ext, bool trim_name); +char* fil_make_filepath_low(const char *path, + const fil_space_t::name_type &name, + ib_extention extension, bool trim_name); char *fil_make_filepath(const char* path, const table_name_t name, ib_extention suffix, bool strip_name); +/** Wrapper function over fil_make_filepath_low to build file name. +@param path nullptr or the directory path or the full path and filename +@param name {} if path is full, or Table/Tablespace name +@param extension the file extension to use +@param trim_name true if the last name on the path should be trimmed +@return own: file name */ +static inline char* +fil_make_filepath(const char* path, const fil_space_t::name_type &name, + ib_extention extension, bool trim_name) +{ + /* If we are going to strip a name off the path, there better be a + path and a new name to put back on. */ + ut_ad(!trim_name || (path && name.data())); + return fil_make_filepath_low(path, name, extension, trim_name); +} + /** Create a tablespace file. @param[in] space_id Tablespace ID @param[in] name Tablespace name in dbname/tablename format. diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h index ddc45e53fe6..015cb48c3ce 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -209,24 +209,6 @@ typedef byte fseg_inode_t; static constexpr byte FSEG_MAGIC_N_BYTES[4]={0x05,0xd6,0x69,0xd2}; -#define FSEG_FILLFACTOR 8 /* If the number of unused but reserved - pages in a segment is less than - reserved pages / FSEG_FILLFACTOR, - and there are - at least FSEG_FRAG_LIMIT used pages, - then we allow a new empty extent to - be added to the segment in - fseg_alloc_free_page_general(). - Otherwise, we - use unused pages of the segment. */ - -#define FSEG_FRAG_LIMIT FSEG_FRAG_ARR_N_SLOTS - /* If the segment has >= this many - used pages, it may be expanded by - allocating extents to the segment; - until that only individual fragment - pages are allocated from the space */ - #define FSEG_FREE_LIST_LIMIT 40 /* If the reserved size of a segment is at least this many extents, we allow extents to be put to the free @@ -294,7 +276,7 @@ Determine if a page is marked free. @param[in] descr extent descriptor @param[in] offset page offset within extent @return whether the page is free */ -inline bool xdes_is_free(const xdes_t *descr, ulint offset) +inline bool xdes_is_free(const xdes_t *descr, uint32_t offset) { ut_ad(offset < FSP_EXTENT_SIZE); ulint index= XDES_FREE_BIT + XDES_BITS_PER_PAGE * offset; diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index c0151b44063..1d2b409be01 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -163,6 +163,9 @@ struct fts_token_t; struct fts_doc_ids_t; struct fts_index_cache_t; +/** Compare two DOC_ID. */ +int fts_doc_id_cmp(const void *p1, const void *p2) + __attribute__((nonnull, warn_unused_result)); /** Initialize the "fts_table" for internal query into FTS auxiliary tables */ @@ -412,6 +415,9 @@ inline void fts_doc_ids_free(fts_doc_ids_t* doc_ids) mem_heap_free(static_cast(doc_ids->self_heap->arg)); } +/** Sort an array of doc_id */ +void fts_doc_ids_sort(ib_vector_t *doc_ids); + /******************************************************************//** Notify the FTS system about an operation on an FTS-indexed table. */ void diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h index ae0bb036e37..04faceb995e 100644 --- a/storage/innobase/include/fts0priv.h +++ b/storage/innobase/include/fts0priv.h @@ -271,27 +271,6 @@ fts_index_fetch_nodes( word, /*!< in: the word to fetch */ fts_fetch_t* fetch) /*!< in: fetch callback.*/ MY_ATTRIBUTE((nonnull)); -/******************************************************************//** -Compare two fts_trx_table_t instances, we actually compare the -table id's here. -@return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */ -UNIV_INLINE -int -fts_trx_table_cmp( -/*==============*/ - const void* v1, /*!< in: id1 */ - const void* v2) /*!< in: id2 */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); -/******************************************************************//** -Compare a table id with a trx_table_t table id. -@return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */ -UNIV_INLINE -int -fts_trx_table_id_cmp( -/*=================*/ - const void* p1, /*!< in: id1 */ - const void* p2) /*!< in: id2 */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); #define fts_sql_commit(trx) trx_commit_for_mysql(trx) #define fts_sql_rollback(trx) (trx)->rollback() /******************************************************************//** diff --git a/storage/innobase/include/fts0priv.inl b/storage/innobase/include/fts0priv.inl index 3cb09c924db..3d937bb3cd9 100644 --- a/storage/innobase/include/fts0priv.inl +++ b/storage/innobase/include/fts0priv.inl @@ -52,47 +52,3 @@ fts_read_object_id( if the id is HEX or DEC and do the right thing with it. */ return(sscanf(str, UINT64PFx, id) == 1); } - -/******************************************************************//** -Compare two fts_trx_table_t instances. -@return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */ -UNIV_INLINE -int -fts_trx_table_cmp( -/*==============*/ - const void* p1, /*!< in: id1 */ - const void* p2) /*!< in: id2 */ -{ - const dict_table_t* table1 - = (*static_cast(p1))->table; - - const dict_table_t* table2 - = (*static_cast(p2))->table; - - return((table1->id > table2->id) - ? 1 - : (table1->id == table2->id) - ? 0 - : -1); -} - -/******************************************************************//** -Compare a table id with a fts_trx_table_t table id. -@return < 0 if n1 < n2, 0 if n1 == n2,> 0 if n1 > n2 */ -UNIV_INLINE -int -fts_trx_table_id_cmp( -/*=================*/ - const void* p1, /*!< in: id1 */ - const void* p2) /*!< in: id2 */ -{ - const uintmax_t* table_id = static_cast(p1); - const dict_table_t* table2 - = (*static_cast(p2))->table; - - return((*table_id > table2->id) - ? 1 - : (*table_id == table2->id) - ? 0 - : -1); -} diff --git a/storage/innobase/include/fts0types.h b/storage/innobase/include/fts0types.h index fb278d543c4..7b95348bbc0 100644 --- a/storage/innobase/include/fts0types.h +++ b/storage/innobase/include/fts0types.h @@ -277,44 +277,6 @@ struct fts_token_t { /** It's defined in fts/fts0fts.c */ extern const fts_index_selector_t fts_index_selector[]; -/******************************************************************//** -Compare two fts_trx_row_t instances doc_ids. */ -UNIV_INLINE -int -fts_trx_row_doc_id_cmp( -/*===================*/ - /*!< out: - < 0 if n1 < n2, - 0 if n1 == n2, - > 0 if n1 > n2 */ - const void* p1, /*!< in: id1 */ - const void* p2); /*!< in: id2 */ - -/******************************************************************//** -Compare two fts_ranking_t instances doc_ids. */ -UNIV_INLINE -int -fts_ranking_doc_id_cmp( -/*===================*/ - /*!< out: - < 0 if n1 < n2, - 0 if n1 == n2, - > 0 if n1 > n2 */ - const void* p1, /*!< in: id1 */ - const void* p2); /*!< in: id2 */ - -/******************************************************************//** -Compare two doc_ids. */ -UNIV_INLINE -int fts_doc_id_cmp( -/*==================*/ - /*!< out: - < 0 if n1 < n2, - 0 if n1 == n2, - > 0 if n1 > n2 */ - const void* p1, /*!< in: id1 */ - const void* p2); /*!< in: id2 */ - /******************************************************************//** Duplicate a string. */ UNIV_INLINE diff --git a/storage/innobase/include/fts0types.inl b/storage/innobase/include/fts0types.inl index facc1e5c40b..5b57cad70d3 100644 --- a/storage/innobase/include/fts0types.inl +++ b/storage/innobase/include/fts0types.inl @@ -46,53 +46,6 @@ fts_string_dup( dst->f_n_char = src->f_n_char; } -/******************************************************************//** -Compare two fts_trx_row_t doc_ids. -@return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */ -UNIV_INLINE -int -fts_trx_row_doc_id_cmp( -/*===================*/ - const void* p1, /*!< in: id1 */ - const void* p2) /*!< in: id2 */ -{ - const fts_trx_row_t* tr1 = (const fts_trx_row_t*) p1; - const fts_trx_row_t* tr2 = (const fts_trx_row_t*) p2; - - return((int)(tr1->doc_id - tr2->doc_id)); -} - -/******************************************************************//** -Compare two fts_ranking_t doc_ids. -@return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */ -UNIV_INLINE -int -fts_ranking_doc_id_cmp( -/*===================*/ - const void* p1, /*!< in: id1 */ - const void* p2) /*!< in: id2 */ -{ - const fts_ranking_t* rk1 = (const fts_ranking_t*) p1; - const fts_ranking_t* rk2 = (const fts_ranking_t*) p2; - - return((int)(rk1->doc_id - rk2->doc_id)); -} - -/******************************************************************//** -Compare two doc_ids. -@return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */ -UNIV_INLINE -int fts_doc_id_cmp( -/*==================*/ - const void* p1, /*!< in: id1 */ - const void* p2) /*!< in: id2 */ -{ - const doc_id_t* up1 = static_cast(p1); - const doc_id_t* up2 = static_cast(p2); - - return static_cast(*up1 - *up2); -} - /******************************************************************//** Get the first character's code position for FTS index partition */ extern diff --git a/storage/innobase/include/fut0lst.h b/storage/innobase/include/fut0lst.h index abef53c949b..dc8806a5c74 100644 --- a/storage/innobase/include/fut0lst.h +++ b/storage/innobase/include/fut0lst.h @@ -78,34 +78,40 @@ void flst_init(const buf_block_t &block, byte *base, mtr_t *mtr) MY_ATTRIBUTE((nonnull)); /** Append a file list node to a list. -@param[in,out] base base node block -@param[in] boffset byte offset of the base node -@param[in,out] add block to be added -@param[in] aoffset byte offset of the node to be added -@param[in,out] mtr mini-transaction +@param base base node block +@param boffset byte offset of the base node +@param add block to be added +@param aoffset byte offset of the node to be added +@param limit fil_space_t::free_limit +@param mtr mini-transaction @return error code */ dberr_t flst_add_last(buf_block_t *base, uint16_t boffset, - buf_block_t *add, uint16_t aoffset, mtr_t *mtr) + buf_block_t *add, uint16_t aoffset, + uint32_t limit, mtr_t *mtr) MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Prepend a file list node to a list. -@param[in,out] base base node block -@param[in] boffset byte offset of the base node -@param[in,out] add block to be added -@param[in] aoffset byte offset of the node to be added -@param[in,out] mtr mini-transaction +@param base base node block +@param boffset byte offset of the base node +@param add block to be added +@param aoffset byte offset of the node to be added +@param limit fil_space_t::free_limit +@param mtr mini-transaction @return error code */ dberr_t flst_add_first(buf_block_t *base, uint16_t boffset, - buf_block_t *add, uint16_t aoffset, mtr_t *mtr) + buf_block_t *add, uint16_t aoffset, + uint32_t limit, mtr_t *mtr) MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Remove a file list node. -@param[in,out] base base node block -@param[in] boffset byte offset of the base node -@param[in,out] cur block to be removed -@param[in] coffset byte offset of the current record to be removed -@param[in,out] mtr mini-transaction +@param base base node block +@param boffset byte offset of the base node +@param cur block to be removed +@param coffset byte offset of the current record to be removed +@param limit fil_space_t::free_limit +@param mtr mini-transaction @return error code */ dberr_t flst_remove(buf_block_t *base, uint16_t boffset, - buf_block_t *cur, uint16_t coffset, mtr_t *mtr) + buf_block_t *cur, uint16_t coffset, + uint32_t limit, mtr_t *mtr) MY_ATTRIBUTE((nonnull, warn_unused_result)); /** @return the length of a list */ @@ -117,11 +123,9 @@ inline uint32_t flst_get_len(const flst_base_node_t *base) /** @return a file address */ inline fil_addr_t flst_read_addr(const byte *faddr) { - fil_addr_t addr= { mach_read_from_4(faddr + FIL_ADDR_PAGE), - mach_read_from_2(faddr + FIL_ADDR_BYTE) }; - ut_a(addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA); - ut_a(ut_align_offset(faddr, srv_page_size) >= FIL_PAGE_DATA); - return addr; + ut_ad(ut_align_offset(faddr, srv_page_size) >= FIL_PAGE_DATA); + return fil_addr_t{mach_read_from_4(faddr + FIL_ADDR_PAGE), + mach_read_from_2(faddr + FIL_ADDR_BYTE)}; } /** @return list first node address */ diff --git a/storage/innobase/include/gis0type.h b/storage/innobase/include/gis0type.h index d6a4ef67a38..2dc25a898b7 100644 --- a/storage/innobase/include/gis0type.h +++ b/storage/innobase/include/gis0type.h @@ -66,10 +66,7 @@ typedef std::vector > rtr_rec_vector; /* Structure for matched records on the leaf page */ typedef struct matched_rec { - byte* bufp; /*!< aligned buffer point */ - byte rec_buf[UNIV_PAGE_SIZE_MAX * 2]; - /*!< buffer used to copy matching rec */ - buf_block_t block; /*!< the shadow buffer block */ + buf_block_t* block; /*!< the shadow buffer block */ ulint used; /*!< memory used */ rtr_rec_vector* matched_recs; /*!< vector holding the matching rec */ mysql_mutex_t rtr_match_mutex;/*!< mutex protect the match_recs @@ -107,7 +104,6 @@ typedef struct rtr_info{ /*!< mutex protect the "path" vector */ rtr_mbr_t mbr; /*!< the search MBR */ que_thr_t* thr; /*!< the search thread */ - mem_heap_t* heap; /*!< memory heap */ btr_cur_t* cursor; /*!< cursor used for search */ dict_index_t* index; /*!< index it is searching */ bool need_prdt_lock; diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index eca8c2cb614..cab44dd9a8e 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -431,6 +431,13 @@ dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, lock_mode mode, bool no_wait= false) MY_ATTRIBUTE((nonnull, warn_unused_result)); +/** Lock the child tables of a table. +@param table parent table +@param trx transaction +@return error code */ +dberr_t lock_table_children(dict_table_t *table, trx_t *trx) + MY_ATTRIBUTE((nonnull, warn_unused_result)); + /** Exclusively lock the data dictionary tables. @param trx dictionary transaction @return error code @@ -717,13 +724,8 @@ private: bool m_initialised; /** mutex proteting the locks */ - alignas(CPU_LEVEL1_DCACHE_LINESIZE) srw_spin_lock latch; -#ifdef UNIV_DEBUG - /** The owner of exclusive latch (0 if none); protected by latch */ - std::atomic writer{0}; - /** Number of shared latches */ - std::atomic readers{0}; -#endif + alignas(CPU_LEVEL1_DCACHE_LINESIZE) + IF_DBUG(srw_lock_debug,srw_spin_lock) latch; #ifdef SUX_LOCK_GENERIC protected: /** mutex for hash_latch::wait() */ @@ -782,71 +784,35 @@ public: void wr_lock() { mysql_mutex_assert_not_owner(&wait_mutex); - ut_ad(!is_writer()); latch.wr_lock(); - ut_ad(!writer.exchange(pthread_self(), - std::memory_order_relaxed)); } /** Release exclusive lock_sys.latch */ - void wr_unlock() - { - ut_ad(writer.exchange(0, std::memory_order_relaxed) == - pthread_self()); - latch.wr_unlock(); - } + void wr_unlock() { latch.wr_unlock(); } /** Acquire shared lock_sys.latch */ void rd_lock() { mysql_mutex_assert_not_owner(&wait_mutex); - ut_ad(!is_writer()); latch.rd_lock(); - ut_ad(!writer.load(std::memory_order_relaxed)); - ut_d(readers.fetch_add(1, std::memory_order_relaxed)); } /** Release shared lock_sys.latch */ - void rd_unlock() - { - ut_ad(!is_writer()); - ut_ad(readers.fetch_sub(1, std::memory_order_relaxed)); - latch.rd_unlock(); - } + void rd_unlock() { latch.rd_unlock(); } #endif /** Try to acquire exclusive lock_sys.latch @return whether the latch was acquired */ - bool wr_lock_try() - { - ut_ad(!is_writer()); - if (!latch.wr_lock_try()) return false; - ut_ad(!writer.exchange(pthread_self(), - std::memory_order_relaxed)); - return true; - } + bool wr_lock_try() { return latch.wr_lock_try(); } /** Try to acquire shared lock_sys.latch @return whether the latch was acquired */ - bool rd_lock_try() - { - ut_ad(!is_writer()); - if (!latch.rd_lock_try()) return false; - ut_ad(!writer.load(std::memory_order_relaxed)); - ut_d(readers.fetch_add(1, std::memory_order_relaxed)); - return true; - } + bool rd_lock_try() { return latch.rd_lock_try(); } /** Assert that wr_lock() has been invoked by this thread */ - void assert_locked() const { ut_ad(is_writer()); } + void assert_locked() const { ut_ad(latch.have_wr()); } /** Assert that wr_lock() has not been invoked by this thread */ - void assert_unlocked() const { ut_ad(!is_writer()); } + void assert_unlocked() const { ut_ad(!latch.have_wr()); } #ifdef UNIV_DEBUG /** @return whether the current thread is the lock_sys.latch writer */ - bool is_writer() const - { -# ifdef SUX_LOCK_GENERIC - return writer.load(std::memory_order_relaxed) == pthread_self(); -# else - return writer.load(std::memory_order_relaxed) == pthread_self() || - (xtest() && !latch.is_locked_or_waiting()); -# endif - } + bool is_writer() const { return latch.have_wr(); } + /** @return whether the current thread is holding lock_sys.latch */ + bool is_holder() const { return latch.have_any(); } /** Assert that a lock shard is exclusively latched (by some thread) */ void assert_locked(const lock_t &lock) const; /** Assert that a table lock shard is exclusively latched by this thread */ @@ -958,14 +924,14 @@ extern lock_sys_t lock_sys; /** @return the index of an array element */ inline ulint lock_sys_t::hash_table::calc_hash(ulint fold) const { - ut_ad(lock_sys.is_writer() || lock_sys.readers); + ut_ad(lock_sys.is_holder()); return calc_hash(fold, n_cells); } /** Get a hash table cell. */ inline hash_cell_t *lock_sys_t::hash_table::cell_get(ulint fold) const { - ut_ad(lock_sys.is_writer() || lock_sys.readers); + ut_ad(lock_sys.is_holder()); return &array[calc_hash(fold)]; } diff --git a/storage/innobase/include/log0crypt.h b/storage/innobase/include/log0crypt.h index ad32dc8faa5..1b8c4b41ca7 100644 --- a/storage/innobase/include/log0crypt.h +++ b/storage/innobase/include/log0crypt.h @@ -28,6 +28,9 @@ MDEV-11782: Rewritten for MariaDB 10.2 by Marko Mäkelä, MariaDB Corporation. #include "log0log.h" +/** innodb_encrypt_log: whether to encrypt the redo log */ +extern my_bool srv_encrypt_log; + /** Initialize the redo log encryption key and random parameters when creating a new redo log. The random parameters will be persisted in the log header. diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index ecc0b91e80f..85d01f2fc9e 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -132,6 +132,9 @@ public: /** Redo log buffer */ struct log_t { + /** The maximum buf_size */ + static constexpr unsigned buf_size_max= os_file_request_size_max; + /** The original (not version-tagged) InnoDB redo log format */ static constexpr uint32_t FORMAT_3_23= 0; /** The MySQL 5.7.9/MariaDB 10.2.2 log format */ @@ -165,60 +168,92 @@ struct log_t static constexpr lsn_t FIRST_LSN= START_OFFSET; private: - /** The log sequence number of the last change of durable InnoDB files */ + /** the lock bit in buf_free */ + static constexpr size_t buf_free_LOCK= ~(~size_t{0} >> 1); alignas(CPU_LEVEL1_DCACHE_LINESIZE) + /** first free offset within buf used; + the most significant bit is set by lock_lsn() to protect this field + as well as write_to_buf, waits */ + std::atomic buf_free; +public: + /** number of write requests (to buf); protected by lock_lsn() or lsn_lock */ + size_t write_to_buf; + /** log record buffer, written to by mtr_t::commit() */ + byte *buf; +private: + /** The log sequence number of the last change of durable InnoDB files; + protected by lock_lsn() or lsn_lock or latch.wr_lock() */ std::atomic lsn; /** the first guaranteed-durable log sequence number */ std::atomic flushed_to_disk_lsn; - /** log sequence number when log resizing was initiated, or 0 */ - std::atomic resize_lsn; - /** set when there may be need to initiate a log checkpoint. - This must hold if lsn - last_checkpoint_lsn > max_checkpoint_age. */ - std::atomic need_checkpoint; +public: + /** number of append_prepare_wait(); protected by lock_lsn() or lsn_lock */ + size_t waits; + /** innodb_log_buffer_size (size of buf,flush_buf if !is_pmem(), in bytes) */ + unsigned buf_size; + /** log file size in bytes, including the header */ + lsn_t file_size; -#if defined(__aarch64__) - /* On ARM, we do more spinning */ +#ifdef LOG_LATCH_DEBUG + typedef srw_lock_debug log_rwlock; + typedef srw_mutex log_lsn_lock; + + bool latch_have_wr() const { return latch.have_wr(); } + bool latch_have_rd() const { return latch.have_rd(); } + bool latch_have_any() const { return latch.have_any(); } +#else +# ifndef UNIV_DEBUG +# elif defined SUX_LOCK_GENERIC + bool latch_have_wr() const { return true; } + bool latch_have_rd() const { return true; } + bool latch_have_any() const { return true; } +# else + bool latch_have_wr() const { return latch.is_write_locked(); } + bool latch_have_rd() const { return latch.is_locked(); } + bool latch_have_any() const { return latch.is_locked(); } +# endif +# ifdef __aarch64__ + /* On ARM, we spin more */ typedef srw_spin_lock log_rwlock; typedef pthread_mutex_wrapper log_lsn_lock; -#else +# else typedef srw_lock log_rwlock; typedef srw_mutex log_lsn_lock; +# endif #endif - -public: - /** rw-lock protecting writes to buf; normal mtr_t::commit() - outside any log checkpoint is covered by a shared latch */ + /** exclusive latch for checkpoint, shared for mtr_t::commit() to buf */ alignas(CPU_LEVEL1_DCACHE_LINESIZE) log_rwlock latch; -private: - /** mutex protecting buf_free et al, together with latch */ - log_lsn_lock lsn_lock; -public: - /** first free offset within buf use; protected by lsn_lock */ - Atomic_relaxed buf_free; - /** number of write requests (to buf); protected by lsn_lock */ - size_t write_to_buf; - /** number of append_prepare_wait(); protected by lsn_lock */ - size_t waits; -private: - /** Last written LSN */ - lsn_t write_lsn; -public: - /** log record buffer, written to by mtr_t::commit() */ - byte *buf; - /** buffer for writing data to ib_logfile0, or nullptr if is_pmem() - In write_buf(), buf and flush_buf are swapped */ - byte *flush_buf; + /** number of std::swap(buf, flush_buf) and writes from buf to log; protected by latch.wr_lock() */ ulint write_to_log; + /** Last written LSN */ + lsn_t write_lsn; + + /** buffer for writing data to ib_logfile0, or nullptr if is_pmem() + In write_buf(), buf and flush_buf are swapped */ + byte *flush_buf; + /** set when there may be need to initiate a log checkpoint. + This must hold if lsn - last_checkpoint_lsn > max_checkpoint_age. */ + std::atomic need_checkpoint; + /** whether a checkpoint is pending; protected by latch.wr_lock() */ + Atomic_relaxed checkpoint_pending; + /** next checkpoint number (protected by latch.wr_lock()) */ + byte next_checkpoint_no; + /** recommended maximum buf_free size, after which the buffer is flushed */ + unsigned max_buf_free; /** Log sequence number when a log file overwrite (broken crash recovery) was noticed. Protected by latch.wr_lock(). */ lsn_t overwrite_warned; - /** innodb_log_buffer_size (size of buf,flush_buf if !is_pmem(), in bytes) */ - size_t buf_size; + /** latest completed checkpoint (protected by latch.wr_lock()) */ + Atomic_relaxed last_checkpoint_lsn; + /** next checkpoint LSN (protected by latch.wr_lock()) */ + lsn_t next_checkpoint_lsn; + /** Log file */ + log_file_t log; private: /** Log file being constructed during resizing; protected by latch */ log_file_t resize_log; @@ -229,18 +264,14 @@ private: /** Buffer for writing to resize_log; @see flush_buf */ byte *resize_flush_buf; - void init_lsn_lock() {lsn_lock.init(); } - void lock_lsn() { lsn_lock.wr_lock(); } - void unlock_lsn() {lsn_lock.wr_unlock(); } - void destroy_lsn_lock() { lsn_lock.destroy(); } + /** Special implementation of lock_lsn() for IA-32 and AMD64 */ + void lsn_lock_bts() noexcept; + /** Acquire a lock for updating buf_free and related fields. + @return the value of buf_free */ + size_t lock_lsn() noexcept; -public: - /** recommended maximum size of buf, after which the buffer is flushed */ - size_t max_buf_free; - - /** log file size in bytes, including the header */ - lsn_t file_size; -private: + /** log sequence number when log resizing was initiated, or 0 */ + std::atomic resize_lsn; /** the log sequence number at the start of the log file */ lsn_t first_lsn; #if defined __linux__ || defined _WIN32 @@ -250,8 +281,6 @@ private: public: /** format of the redo log: e.g., FORMAT_10_8 */ uint32_t format; - /** Log file */ - log_file_t log; #if defined __linux__ || defined _WIN32 /** whether file system caching is enabled for the log */ my_bool log_buffered; @@ -281,21 +310,29 @@ public: /*!< this is the maximum allowed value for lsn - last_checkpoint_lsn when a new query step is started */ - /** latest completed checkpoint (protected by latch.wr_lock()) */ - Atomic_relaxed last_checkpoint_lsn; - /** next checkpoint LSN (protected by log_sys.latch) */ - lsn_t next_checkpoint_lsn; - /** next checkpoint number (protected by latch.wr_lock()) */ - ulint next_checkpoint_no; - /** whether a checkpoint is pending */ - Atomic_relaxed checkpoint_pending; /** buffer for checkpoint header */ byte *checkpoint_buf; /* @} */ +private: + /** A lock when the spin-only lock_lsn() is not being used */ + log_lsn_lock lsn_lock; +public: + bool is_initialised() const noexcept { return max_buf_free != 0; } + /** whether there is capacity in the log buffer */ + bool buf_free_ok() const noexcept + { + ut_ad(!is_pmem()); + return (buf_free.load(std::memory_order_relaxed) & ~buf_free_LOCK) < + max_buf_free; + } + + void set_buf_free(size_t f) noexcept + { ut_ad(f < buf_free_LOCK); buf_free.store(f, std::memory_order_relaxed); } + #ifdef HAVE_PMEM bool is_pmem() const noexcept { return !flush_buf; } #else @@ -304,7 +341,7 @@ public: bool is_opened() const noexcept { return log.is_opened(); } - /** @return target write LSN to react on buf_free >= max_buf_free */ + /** @return target write LSN to react on !buf_free_ok() */ inline lsn_t get_write_target() const; /** @return LSN at which log resizing was started and is still in progress @@ -406,9 +443,7 @@ public: void set_recovered_lsn(lsn_t lsn) noexcept { -#ifndef SUX_LOCK_GENERIC - ut_ad(latch.is_write_locked()); -#endif /* SUX_LOCK_GENERIC */ + ut_ad(latch_have_wr()); write_lsn= lsn; this->lsn.store(lsn, std::memory_order_relaxed); flushed_to_disk_lsn.store(lsn, std::memory_order_relaxed); @@ -448,17 +483,23 @@ public: private: /** Wait in append_prepare() for buffer to become available - @param lsn log sequence number to write up to - @param ex whether log_sys.latch is exclusively locked */ - ATTRIBUTE_COLD void append_prepare_wait(lsn_t lsn, bool ex) noexcept; + @tparam spin whether to use the spin-only lock_lsn() + @param b the value of buf_free + @param ex whether log_sys.latch is exclusively locked + @param lsn log sequence number to write up to + @return the new value of buf_free */ + template + ATTRIBUTE_COLD size_t append_prepare_wait(size_t b, bool ex, lsn_t lsn) + noexcept; public: /** Reserve space in the log buffer for appending data. + @tparam spin whether to use the spin-only lock_lsn() @tparam pmem log_sys.is_pmem() @param size total length of the data to append(), in bytes @param ex whether log_sys.latch is exclusively locked @return the start LSN and the buffer position for append() */ - template - inline std::pair append_prepare(size_t size, bool ex) noexcept; + template + std::pair append_prepare(size_t size, bool ex) noexcept; /** Append a string of bytes to the redo log. @param d destination @@ -466,9 +507,7 @@ public: @param size length of str, in bytes */ void append(byte *&d, const void *s, size_t size) noexcept { -#ifndef SUX_LOCK_GENERIC - ut_ad(latch.is_locked()); -#endif + ut_ad(latch_have_any()); ut_ad(d + size <= buf + (is_pmem() ? file_size : buf_size)); memcpy(d, s, size); d+= size; diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index fe0ad3a7128..27811872c58 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -686,14 +686,40 @@ private: /** Encrypt the log */ ATTRIBUTE_NOINLINE void encrypt(); + /** Commit the mini-transaction log. + @tparam pmem log_sys.is_pmem() + @param mtr mini-transaction + @param lsns {start_lsn,flush_ahead} */ + template + static void commit_log(mtr_t *mtr, std::pair lsns); + /** Append the redo log records to the redo log buffer. @return {start_lsn,flush_ahead} */ std::pair do_write(); /** Append the redo log records to the redo log buffer. + @tparam spin whether to use the spin-only log_sys.lock_lsn() + @tparam pmem log_sys.is_pmem() + @param mtr mini-transaction @param len number of bytes to write @return {start_lsn,flush_ahead} */ - std::pair finish_write(size_t len); + template static + std::pair finish_writer(mtr_t *mtr, size_t len); + + /** The applicable variant of commit_log() */ + static void (*commit_logger)(mtr_t *, std::pair); + /** The applicable variant of finish_writer() */ + static std::pair (*finisher)(mtr_t *, size_t); + + std::pair finish_write(size_t len) + { return finisher(this, len); } +public: + /** Poll interval in log_sys.lock_lsn(); 0 to use log_sys.lsn_lock. + Protected by LOCK_global_system_variables and log_sys.latch. */ + static unsigned spin_wait_delay; + /** Update finisher when spin_wait_delay is changing to or from 0. */ + static void finisher_update(); +private: /** Release all latches. */ void release(); diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index c8374515859..ce6864754c2 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -46,6 +46,18 @@ Created 10/21/1995 Heikki Tuuri #include #endif /* !_WIN32 */ +/** The maximum size of a read or write request. + +According to Linux "man 2 read" and "man 2 write" this applies to +both 32-bit and 64-bit systems. + +On FreeBSD, the limit is close to the Linux one, INT_MAX. + +On Microsoft Windows, the limit is UINT_MAX (4 GiB - 1). + +On other systems, the limit typically is up to SSIZE_T_MAX. */ +static constexpr unsigned os_file_request_size_max= 0x7ffff000; + extern bool os_has_said_disk_full; /** File offset in bytes */ @@ -109,25 +121,21 @@ struct pfs_os_file_t /** Options for os_file_create_func @{ */ enum os_file_create_t { - OS_FILE_OPEN = 51, /*!< to open an existing file (if - doesn't exist, error) */ - OS_FILE_CREATE, /*!< to create new file (if - exists, error) */ - OS_FILE_OVERWRITE, /*!< to create a new file, if exists - the overwrite old file */ - OS_FILE_OPEN_RAW, /*!< to open a raw device or disk - partition */ - OS_FILE_CREATE_PATH, /*!< to create the directories */ - OS_FILE_OPEN_RETRY, /*!< open with retry */ + /** create a new file */ + OS_FILE_CREATE= 0, + /** open an existing file */ + OS_FILE_OPEN, + /** retry opening an existing file */ + OS_FILE_OPEN_RETRY, + /** open a raw block device */ + OS_FILE_OPEN_RAW, - /** Flags that can be combined with the above values. Please ensure - that the above values stay below 128. */ + /** do not display diagnostic messages */ + OS_FILE_ON_ERROR_SILENT= 4, - OS_FILE_ON_ERROR_NO_EXIT = 128, /*!< do not exit on unknown errors */ - OS_FILE_ON_ERROR_SILENT = 256 /*!< don't print diagnostic messages to - the log unless it is a fatal error, - this flag is only used if - ON_ERROR_NO_EXIT is set */ + OS_FILE_CREATE_SILENT= OS_FILE_CREATE | OS_FILE_ON_ERROR_SILENT, + OS_FILE_OPEN_SILENT= OS_FILE_OPEN | OS_FILE_ON_ERROR_SILENT, + OS_FILE_OPEN_RETRY_SILENT= OS_FILE_OPEN_RETRY | OS_FILE_ON_ERROR_SILENT }; static const ulint OS_FILE_READ_ONLY = 333; @@ -144,7 +152,7 @@ static const ulint OS_FILE_NORMAL = 62; /** Types for file create @{ */ static constexpr ulint OS_DATA_FILE = 100; static constexpr ulint OS_LOG_FILE = 101; -#if defined _WIN32 || defined HAVE_FCNTL_DIRECT +#if defined _WIN32 || defined O_DIRECT static constexpr ulint OS_DATA_FILE_NO_O_DIRECT = 103; #endif /* @} */ @@ -189,16 +197,16 @@ public: WRITE_SYNC= 16, /** Asynchronous write */ WRITE_ASYNC= WRITE_SYNC | 1, + /** Asynchronous doublewritten page */ + WRITE_DBL= WRITE_ASYNC | 4, /** A doublewrite batch */ DBLWR_BATCH= WRITE_ASYNC | 8, - /** Write data; evict the block on write completion */ - WRITE_LRU= WRITE_ASYNC | 32, /** Write data and punch hole for the rest */ - PUNCH= WRITE_ASYNC | 64, - /** Write data and punch hole; evict the block on write completion */ - PUNCH_LRU= PUNCH | WRITE_LRU, + PUNCH= WRITE_ASYNC | 16, + /** Write doublewritten data and punch hole for the rest */ + PUNCH_DBL= PUNCH | 4, /** Zero out a range of bytes in fil_space_t::io() */ - PUNCH_RANGE= WRITE_SYNC | 128, + PUNCH_RANGE= WRITE_SYNC | 32, }; constexpr IORequest(buf_page_t *bpage, buf_tmp_buffer_t *slot, @@ -211,8 +219,15 @@ public: bool is_read() const { return (type & READ_SYNC) != 0; } bool is_write() const { return (type & WRITE_SYNC) != 0; } - bool is_LRU() const { return (type & (WRITE_LRU ^ WRITE_ASYNC)) != 0; } bool is_async() const { return (type & (READ_SYNC ^ READ_ASYNC)) != 0; } + bool is_doublewritten() const { return (type & 4) != 0; } + + /** Create a write request for the doublewrite buffer. */ + IORequest doublewritten() const + { + ut_ad(type == WRITE_ASYNC || type == PUNCH); + return IORequest{bpage, slot, node, Type(type | 4)}; + } void write_complete(int io_error) const; void read_complete(int io_error) const; @@ -349,7 +364,7 @@ A simple function to open or create a file. pfs_os_file_t os_file_create_simple_func( const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint access_type, bool read_only, bool* success); @@ -358,7 +373,7 @@ os_file_create_simple_func( os_file_create_simple_no_error_handling(), not directly this function! A simple function to open or create a file. @param[in] name name of the file or path as a null-terminated string -@param[in] create_mode create mode +@param[in] create_mode OS_FILE_CREATE or OS_FILE_OPEN @param[in] access_type OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or OS_FILE_READ_ALLOW_DELETE; the last option is used by a backup program reading the file @@ -369,28 +384,12 @@ A simple function to open or create a file. pfs_os_file_t os_file_create_simple_no_error_handling_func( const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint access_type, bool read_only, bool* success) MY_ATTRIBUTE((warn_unused_result)); -#ifndef HAVE_FCNTL_DIRECT -#define os_file_set_nocache(fd, file_name, operation_name) do{}while(0) -#else -/** Tries to disable OS caching on an opened file descriptor. -@param[in] fd file descriptor to alter -@param[in] file_name file name, used in the diagnostic message -@param[in] name "open" or "create"; used in the diagnostic - message */ -void -os_file_set_nocache( -/*================*/ - int fd, /*!< in: file descriptor to alter */ - const char* file_name, - const char* operation_name); -#endif - #ifndef _WIN32 /* On Microsoft Windows, mandatory locking is used */ /** Obtain an exclusive lock on a file. @param fd file descriptor @@ -419,7 +418,7 @@ Opens an existing file or creates a new. pfs_os_file_t os_file_create_func( const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint purpose, ulint type, bool read_only, @@ -617,7 +616,7 @@ pfs_os_file_t pfs_os_file_create_simple_func( mysql_pfs_key_t key, const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint access_type, bool read_only, bool* success, @@ -633,7 +632,7 @@ monitor file creation/open. @param[in] key Performance Schema Key @param[in] name name of the file or path as a null-terminated string -@param[in] create_mode create mode +@param[in] create_mode OS_FILE_CREATE or OS_FILE_OPEN @param[in] access_type OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or OS_FILE_READ_ALLOW_DELETE; the last option is used by a backup program reading the file @@ -648,7 +647,7 @@ pfs_os_file_t pfs_os_file_create_simple_no_error_handling_func( mysql_pfs_key_t key, const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint access_type, bool read_only, bool* success, @@ -681,7 +680,7 @@ pfs_os_file_t pfs_os_file_create_func( mysql_pfs_key_t key, const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint purpose, ulint type, bool read_only, diff --git a/storage/innobase/include/os0file.inl b/storage/innobase/include/os0file.inl index 7de3150540d..a7603028a29 100644 --- a/storage/innobase/include/os0file.inl +++ b/storage/innobase/include/os0file.inl @@ -45,7 +45,7 @@ pfs_os_file_t pfs_os_file_create_simple_func( mysql_pfs_key_t key, const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint access_type, bool read_only, bool* success, @@ -80,7 +80,7 @@ monitor file creation/open. @param[in] key Performance Schema Key @param[in] name name of the file or path as a null-terminated string -@param[in] create_mode create mode +@param[in] create_mode OS_FILE_CREATE or OS_FILE_OPEN @param[in] access_type OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or OS_FILE_READ_ALLOW_DELETE; the last option is used by a backup program reading the file @@ -95,7 +95,7 @@ pfs_os_file_t pfs_os_file_create_simple_no_error_handling_func( mysql_pfs_key_t key, const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint access_type, bool read_only, bool* success, @@ -146,7 +146,7 @@ pfs_os_file_t pfs_os_file_create_func( mysql_pfs_key_t key, const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint purpose, ulint type, bool read_only, diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h index 93ea650d0cf..1c2af128229 100644 --- a/storage/innobase/include/row0merge.h +++ b/storage/innobase/include/row0merge.h @@ -165,14 +165,11 @@ row_merge_drop_indexes( prepare_inplace_alter_table_dict(). */ void row_merge_drop_temp_indexes(); -/** Create temporary merge files in the given paramater path, and if -UNIV_PFS_IO defined, register the file descriptor with Performance Schema. -@param[in] path location for creating temporary merge files, or NULL +/** Create a temporary file at the specified path. +@param path location for creating temporary merge files, or nullptr @return File descriptor */ -pfs_os_file_t -row_merge_file_create_low( - const char* path) - MY_ATTRIBUTE((warn_unused_result)); +pfs_os_file_t row_merge_file_create_low(const char *path) + MY_ATTRIBUTE((warn_unused_result)); /*********************************************************************//** Destroy a merge file. And de-register the file from Performance Schema if UNIV_PFS_IO is defined. */ diff --git a/storage/innobase/include/row0row.h b/storage/innobase/include/row0row.h index a26924d08a0..85c18ddea74 100644 --- a/storage/innobase/include/row0row.h +++ b/storage/innobase/include/row0row.h @@ -356,6 +356,12 @@ row_search_index_entry( mtr_t* mtr) /*!< in: mtr */ MY_ATTRIBUTE((nonnull, warn_unused_result)); +/** Get the byte offset of the DB_TRX_ID column +@param[in] rec clustered index record +@param[in] index clustered index +@return the byte offset of DB_TRX_ID, from the start of rec */ +ulint row_trx_id_offset(const rec_t* rec, const dict_index_t* index); + #define ROW_COPY_DATA 1 #define ROW_COPY_POINTERS 2 diff --git a/storage/innobase/include/row0sel.h b/storage/innobase/include/row0sel.h index 8134c60fe72..54e4a1d283f 100644 --- a/storage/innobase/include/row0sel.h +++ b/storage/innobase/include/row0sel.h @@ -115,8 +115,8 @@ row_sel_convert_mysql_key_to_innobase( ulint buf_len, /*!< in: buffer length */ dict_index_t* index, /*!< in: index of the key value */ const byte* key_ptr, /*!< in: MySQL key value */ - ulint key_len); /*!< in: MySQL key value length */ - + ulint key_len) /*!< in: MySQL key value length */ + MY_ATTRIBUTE((nonnull(1,4,5))); /** Search for rows in the database using cursor. Function is mainly used for tables that are shared across connections and diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h index 4672ce00a36..6b9a6f09681 100644 --- a/storage/innobase/include/srv0mon.h +++ b/storage/innobase/include/srv0mon.h @@ -194,7 +194,6 @@ enum monitor_id_t { MONITOR_FLUSH_ADAPTIVE_AVG_PASS, MONITOR_LRU_GET_FREE_LOOPS, - MONITOR_LRU_GET_FREE_WAITS, MONITOR_FLUSH_AVG_PAGE_RATE, MONITOR_FLUSH_LSN_AVG_RATE, @@ -215,7 +214,6 @@ enum monitor_id_t { MONITOR_LRU_BATCH_SCANNED_PER_CALL, MONITOR_LRU_BATCH_FLUSH_TOTAL_PAGE, MONITOR_LRU_BATCH_EVICT_TOTAL_PAGE, - MONITOR_LRU_SINGLE_FLUSH_FAILURE_COUNT, MONITOR_LRU_GET_FREE_SEARCH, MONITOR_LRU_SEARCH_SCANNED, MONITOR_LRU_SEARCH_SCANNED_NUM_CALL, diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 4443ac33544..df25983acab 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -121,10 +121,6 @@ struct srv_stats_t ulint_ctr_n_t n_temp_blocks_decrypted; }; -/** We are prepared for a situation that we have this many threads waiting for -a transactional lock inside InnoDB. srv_start() sets the value. */ -extern ulint srv_max_n_threads; - extern const char* srv_main_thread_op_info; /** Prefix used by MySQL to indicate pre-5.1 table name encoding */ @@ -297,7 +293,6 @@ extern my_bool srv_stats_include_delete_marked; extern unsigned long long srv_stats_modified_counter; extern my_bool srv_stats_sample_traditional; -extern my_bool srv_use_doublewrite_buf; extern ulong srv_checksum_algorithm; extern my_bool srv_force_primary_key; diff --git a/storage/innobase/include/srw_lock.h b/storage/innobase/include/srw_lock.h index 01067322a0a..98c256d3b73 100644 --- a/storage/innobase/include/srw_lock.h +++ b/storage/innobase/include/srw_lock.h @@ -153,7 +153,7 @@ template class srw_lock_impl; /** Slim shared-update-exclusive lock with no recursion */ template -class ssux_lock_impl final +class ssux_lock_impl { #ifdef UNIV_PFS_RWLOCK friend class ssux_lock; @@ -550,3 +550,51 @@ typedef srw_lock_impl srw_lock; typedef srw_lock_impl srw_spin_lock; #endif + +#ifdef UNIV_DEBUG +# include + +class srw_lock_debug : private srw_lock +{ + /** The owner of the exclusive lock (0 if none) */ + std::atomic writer; + /** Protects readers */ + mutable srw_mutex readers_lock; + /** Threads that hold the lock in shared mode */ + std::atomic*> readers; + + /** Register a read lock. */ + void readers_register(); + +public: + void SRW_LOCK_INIT(mysql_pfs_key_t key); + void destroy(); + +#ifndef SUX_LOCK_GENERIC + /** @return whether any lock may be held by any thread */ + bool is_locked_or_waiting() const noexcept + { return srw_lock::is_locked_or_waiting(); } + /** @return whether an exclusive lock may be held by any thread */ + bool is_write_locked() const noexcept { return srw_lock::is_write_locked(); } +#endif + + /** Acquire an exclusive lock */ + void wr_lock(SRW_LOCK_ARGS(const char *file, unsigned line)); + /** @return whether an exclusive lock was acquired */ + bool wr_lock_try(); + /** Release after wr_lock() */ + void wr_unlock(); + /** Acquire a shared lock */ + void rd_lock(SRW_LOCK_ARGS(const char *file, unsigned line)); + /** @return whether a shared lock was acquired */ + bool rd_lock_try(); + /** Release after rd_lock() */ + void rd_unlock(); + /** @return whether this thread is between rd_lock() and rd_unlock() */ + bool have_rd() const noexcept; + /** @return whether this thread is between wr_lock() and wr_unlock() */ + bool have_wr() const noexcept; + /** @return whether this thread is holding rd_lock() or wr_lock() */ + bool have_any() const noexcept; +}; +#endif diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h index 0f4f8afa15b..1fb6cd68538 100644 --- a/storage/innobase/include/trx0purge.h +++ b/storage/innobase/include/trx0purge.h @@ -55,80 +55,74 @@ Run a purge batch. @return number of undo log pages handled in the batch */ ulint trx_purge(ulint n_tasks, ulint history_size); -/** Rollback segements from a given transaction with trx-no -scheduled for purge. */ -class TrxUndoRsegs { -private: - typedef std::vector > - trx_rsegs_t; -public: - typedef trx_rsegs_t::iterator iterator; - typedef trx_rsegs_t::const_iterator const_iterator; - - TrxUndoRsegs() = default; - - /** Constructor */ - TrxUndoRsegs(trx_rseg_t& rseg) - : trx_no(rseg.last_trx_no()), m_rsegs(1, &rseg) {} - /** Constructor */ - TrxUndoRsegs(trx_id_t trx_no, trx_rseg_t& rseg) - : trx_no(trx_no), m_rsegs(1, &rseg) {} - - bool operator!=(const TrxUndoRsegs& other) const - { return trx_no != other.trx_no; } - bool empty() const { return m_rsegs.empty(); } - void erase(iterator& it) { m_rsegs.erase(it); } - iterator begin() { return(m_rsegs.begin()); } - iterator end() { return(m_rsegs.end()); } - const_iterator begin() const { return m_rsegs.begin(); } - const_iterator end() const { return m_rsegs.end(); } - - /** Compare two TrxUndoRsegs based on trx_no. - @param elem1 first element to compare - @param elem2 second element to compare - @return true if elem1 > elem2 else false.*/ - bool operator()(const TrxUndoRsegs& lhs, const TrxUndoRsegs& rhs) - { - return(lhs.trx_no > rhs.trx_no); - } - - /** Copy of trx_rseg_t::last_trx_no() */ - trx_id_t trx_no= 0; -private: - /** Rollback segments of a transaction, scheduled for purge. */ - trx_rsegs_t m_rsegs{}; -}; - -typedef std::priority_queue< - TrxUndoRsegs, - std::vector >, - TrxUndoRsegs> purge_pq_t; - -/** Chooses the rollback segment with the oldest committed transaction */ -struct TrxUndoRsegsIterator { - /** Constructor */ - TrxUndoRsegsIterator(); - /** Sets the next rseg to purge in purge_sys. - Executed in the purge coordinator thread. - @retval false when nothing is to be purged - @retval true when purge_sys.rseg->latch was locked */ - inline bool set_next(); - -private: - // Disable copying - TrxUndoRsegsIterator(const TrxUndoRsegsIterator&); - TrxUndoRsegsIterator& operator=(const TrxUndoRsegsIterator&); - - /** The current element to process */ - TrxUndoRsegs m_rsegs; - /** Track the current element in m_rsegs */ - TrxUndoRsegs::const_iterator m_iter; -}; - /** The control structure used in the purge operation */ class purge_sys_t { - friend TrxUndoRsegsIterator; + /** Min-heap based priority queue of (trx_no, trx_sys.rseg_array index) + pairs, ordered on trx_no. The highest 64-TRX_NO_SHIFT bits of each element is + trx_no, the lowest 8 bits is rseg's index in trx_sys.rseg_array. */ + class purge_queue + { + public: + typedef std::vector> container_type; + /** Number of bits reseved to shift trx_no in purge queue element */ + static constexpr unsigned TRX_NO_SHIFT= 8; + + bool empty() const { return m_array.empty(); } + void clear() { m_array.clear(); } + + /** Push (trx_no, trx_sys.rseg_array index) into min-heap. + @param trx_no_rseg (trx_no << TRX_NO_SHIFT | (trx_sys.rseg_array index)) */ + void push_trx_no_rseg(container_type::value_type trx_no_rseg) + { + m_array.push_back(trx_no_rseg); + std::push_heap(m_array.begin(), m_array.end(), + std::greater()); + } + + /** Push rseg to priority queue. + @param trx_no trx_no of committed transaction + @param rseg rseg of committed transaction*/ + void push(trx_id_t trx_no, const trx_rseg_t &rseg) + { + ut_ad(trx_no < 1ULL << (DATA_TRX_ID_LEN * CHAR_BIT)); + ut_ad(&rseg >= trx_sys.rseg_array); + ut_ad(&rseg < trx_sys.rseg_array + TRX_SYS_N_RSEGS); + push_trx_no_rseg(trx_no << TRX_NO_SHIFT | + byte(&rseg - trx_sys.rseg_array)); + } + + /** Extracts rseg from (trx_no, trx_sys.rseg_array index) pair. + @param trx_no_rseg (trx_no << TRX_NO_SHIFT | (trx_sys.rseg_array index) + @return pointer to rseg in trx_sys.rseg_array */ + static trx_rseg_t *rseg(container_type::value_type trx_no_rseg) { + byte i= static_cast(trx_no_rseg); + ut_ad(i < TRX_SYS_N_RSEGS); + return &trx_sys.rseg_array[i]; + } + + /** Pop rseg from priority queue. + @return pointer to popped trx_rseg_t object */ + trx_rseg_t *pop() + { + ut_ad(!empty()); + std::pop_heap(m_array.begin(), m_array.end(), + std::greater()); + trx_rseg_t *r = rseg(m_array.back()); + m_array.pop_back(); + return r; + } + + /** Clone m_array. + @return m_array clone */ + container_type clone_container() const{ return m_array; } + + private: + /** Array of (trx_no, trx_sys.rseg_array index) pairs. */ + container_type m_array; + }; + + public: /** latch protecting view, m_enabled */ alignas(CPU_LEVEL1_DCACHE_LINESIZE) mutable srw_spin_lock latch; @@ -244,15 +238,36 @@ private: record */ uint16_t hdr_offset; /*!< Header byte offset on the page */ + /** Binary min-heap of (trx_no, trx_sys.rseg_array index) pairs, ordered on + trx_no. It is protected by the pq_mutex */ + purge_queue purge_queue; + + /** Mutex protecting purge_queue */ + mysql_mutex_t pq_mutex; - TrxUndoRsegsIterator - rseg_iter; /*!< Iterator to get the next rseg - to process */ public: - purge_pq_t purge_queue; /*!< Binary min-heap, ordered on - TrxUndoRsegs::trx_no. It is protected - by the pq_mutex */ - mysql_mutex_t pq_mutex; /*!< Mutex protecting purge_queue */ + + void enqueue(trx_id_t trx_no, const trx_rseg_t &rseg) { + mysql_mutex_assert_owner(&pq_mutex); + purge_queue.push(trx_no, rseg); + } + + /** Push to purge queue without acquiring pq_mutex. + @param rseg rseg to push */ + void enqueue(const trx_rseg_t &rseg) { enqueue(rseg.last_trx_no(), rseg); } + + /** Clone purge queue container. + @return purge queue container clone */ + purge_queue::container_type clone_queue_container() const { + mysql_mutex_assert_owner(&pq_mutex); + return purge_queue.clone_container(); + } + + /** Acquare purge_queue_mutex */ + void queue_lock() { mysql_mutex_lock(&pq_mutex); } + + /** Release purge queue mutex */ + void queue_unlock() { mysql_mutex_unlock(&pq_mutex); } /** innodb_undo_log_truncate=ON state; only modified by purge_coordinator_callback() */ @@ -332,8 +347,9 @@ private: /** Update the last not yet purged history log info in rseg when we have purged a whole undo log. Advances also purge_trx_no - past the purged log. */ - void rseg_get_next_history_log(); + past the purged log. + @return whether anything is to be purged */ + bool rseg_get_next_history_log(); public: /** @@ -438,6 +454,11 @@ public: @param already_stopped True indicates purge threads were already stopped */ void stop_FTS(const dict_table_t &table, bool already_stopped=false); + + /** Cleanse purge queue to remove the rseg that reside in undo-tablespace + marked for truncate. + @param space undo tablespace being truncated */ + void cleanse_purge_queue(const fil_space_t &space); }; /** The global data structure coordinating a purge */ diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h index 7fa43047b18..e0051b2a1d0 100644 --- a/storage/innobase/include/trx0rseg.h +++ b/storage/innobase/include/trx0rseg.h @@ -59,7 +59,7 @@ struct alignas(CPU_LEVEL1_DCACHE_LINESIZE) trx_rseg_t /** tablespace containing the rollback segment; constant after init() */ fil_space_t *space; /** latch protecting everything except page_no, space */ - srw_spin_lock latch; + IF_DBUG(srw_lock_debug,srw_spin_lock) latch; /** rollback segment header page number; constant after init() */ uint32_t page_no; /** length of the TRX_RSEG_HISTORY list (number of transactions) */ @@ -170,19 +170,21 @@ public: /** Last not yet purged undo log header; FIL_NULL if all purged */ uint32_t last_page_no; - /** trx_t::no | last_offset << 48 */ + /** trx_t::no << 16 | last_offset */ uint64_t last_commit_and_offset; /** @return the commit ID of the last committed transaction */ trx_id_t last_trx_no() const - { return last_commit_and_offset & ((1ULL << 48) - 1); } + { return last_commit_and_offset >> 16; } /** @return header offset of the last committed transaction */ uint16_t last_offset() const - { return static_cast(last_commit_and_offset >> 48); } + { + return static_cast(last_commit_and_offset); + } void set_last_commit(uint16_t last_offset, trx_id_t trx_no) { - last_commit_and_offset= static_cast(last_offset) << 48 | trx_no; + last_commit_and_offset= trx_no << 16 | static_cast(last_offset); } /** @return the page identifier */ diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 7682932392e..7457addbbb6 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -787,6 +787,9 @@ public: string */ /** TRX_ISO_REPEATABLE_READ, ... */ unsigned isolation_level:2; + /** when set, REPEATABLE READ will actually be Snapshot Isolation, due to + detecting write/write conflicts and disabling "semi-consistent read" */ + unsigned snapshot_isolation:1; /** normally set; "SET foreign_key_checks=0" can be issued to suppress foreign key checks, in table imports, for example */ unsigned check_foreigns:1; @@ -1186,10 +1189,16 @@ public: return UNIV_UNLIKELY(bulk_insert) ? bulk_insert_apply_low(): DB_SUCCESS; } + /** Do the bulk insert for the buffered insert operation of a table. + @param table bulk insert operation + @return DB_SUCCESS or error code. */ + dberr_t bulk_insert_apply_for_table(dict_table_t *table); private: /** Apply the buffered bulk inserts. */ dberr_t bulk_insert_apply_low(); + /** Rollback the bulk insert operation for the transaction */ + void bulk_rollback_low(); /** Assign a rollback segment for modifying temporary tables. @return the assigned rollback segment */ trx_rseg_t *assign_temp_rseg(); diff --git a/storage/innobase/include/trx0undo.inl b/storage/innobase/include/trx0undo.inl index 9f05989f634..023e2b98fb2 100644 --- a/storage/innobase/include/trx0undo.inl +++ b/storage/innobase/include/trx0undo.inl @@ -125,5 +125,6 @@ trx_undo_page_get_next_rec(const buf_block_t *undo_page, uint16_t rec, { uint16_t end= trx_undo_page_get_end(undo_page, page_no, offset); uint16_t next= mach_read_from_2(undo_page->page.frame + rec); - return next == end ? nullptr : undo_page->page.frame + next; + ut_ad(next <= end); + return next >= end ? nullptr : undo_page->page.frame + next; } diff --git a/storage/innobase/include/ut0new.h b/storage/innobase/include/ut0new.h index f4183e4c61a..3ff5f8853e0 100644 --- a/storage/innobase/include/ut0new.h +++ b/storage/innobase/include/ut0new.h @@ -1071,9 +1071,8 @@ static inline void *ut_malloc_dontdump(size_t n_bytes, ...) { void *ptr = my_large_malloc(&n_bytes, MYF(0)); - ut_dontdump(ptr, n_bytes, true); - if (ptr) { + ut_dontdump(ptr, n_bytes, true); os_total_large_mem_allocated += n_bytes; } return ptr; diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h index fe16ce149da..500b64552f9 100644 --- a/storage/innobase/include/ut0ut.h +++ b/storage/innobase/include/ut0ut.h @@ -242,20 +242,6 @@ ut_print_name( FILE* ef, /*!< in: stream */ const trx_t* trx, /*!< in: transaction */ const char* name); /*!< in: table name to print */ -/** Format a table name, quoted as an SQL identifier. -If the name contains a slash '/', the result will contain two -identifiers separated by a period (.), as in SQL -database_name.table_name. -@see table_name_t -@param[in] name table or index name -@param[out] formatted formatted result, will be NUL-terminated -@param[in] formatted_size size of the buffer in bytes -@return pointer to 'formatted' */ -char* -ut_format_name( - const char* name, - char* formatted, - ulint formatted_size); /**********************************************************************//** Catenate files. */ diff --git a/storage/innobase/include/ut0vec.h b/storage/innobase/include/ut0vec.h index f4660f9646c..ad43e1c8d7d 100644 --- a/storage/innobase/include/ut0vec.h +++ b/storage/innobase/include/ut0vec.h @@ -200,15 +200,6 @@ ib_vector_last_const( /* out: pointer to last element */ const ib_vector_t* vec); /* in: vector */ -/******************************************************************** -Sort the vector elements. */ -UNIV_INLINE -void -ib_vector_sort( -/*===========*/ - ib_vector_t* vec, /* in/out: vector */ - ib_compare_t compare); /* in: the comparator to use for sort */ - /******************************************************************** The default ib_vector_t heap free. Does nothing. */ UNIV_INLINE diff --git a/storage/innobase/include/ut0vec.inl b/storage/innobase/include/ut0vec.inl index 531f0f22ae0..1a844dd835d 100644 --- a/storage/innobase/include/ut0vec.inl +++ b/storage/innobase/include/ut0vec.inl @@ -304,19 +304,6 @@ ib_vector_remove( return((old_used_count != vec->used) ? current : NULL); } -/******************************************************************** -Sort the vector elements. */ -UNIV_INLINE -void -ib_vector_sort( -/*===========*/ - /* out: void */ - ib_vector_t* vec, /* in: vector */ - ib_compare_t compare)/* in: the comparator to use for sort */ -{ - qsort(vec->data, vec->used, vec->sizeof_value, compare); -} - /******************************************************************** Destroy the vector. Make sure the vector owns the allocator, e.g., the heap in the the heap allocator. */ diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 101735b5d6a..27a0d15482c 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -47,6 +47,7 @@ Created 5/7/1996 Heikki Tuuri #include "que0que.h" #include "scope.h" #include +#include #include @@ -173,7 +174,7 @@ void lock_sys_t::assert_locked(const dict_table_t &table) const ut_ad(!table.is_temporary()); if (is_writer()) return; - ut_ad(readers); + ut_ad(latch.have_rd()); ut_ad(table.lock_mutex_is_owner()); } @@ -182,7 +183,7 @@ void lock_sys_t::hash_table::assert_locked(const page_id_t id) const { if (lock_sys.is_writer()) return; - ut_ad(lock_sys.readers); + ut_ad(lock_sys.is_holder()); ut_ad(latch(cell_get(id.fold()))->is_locked()); } @@ -191,7 +192,7 @@ void lock_sys_t::assert_locked(const hash_cell_t &cell) const { if (is_writer()) return; - ut_ad(lock_sys.readers); + ut_ad(lock_sys.is_holder()); ut_ad(hash_table::latch(const_cast(&cell))->is_locked()); } #endif @@ -426,13 +427,10 @@ void lock_sys_t::wr_lock(const char *file, unsigned line) { mysql_mutex_assert_not_owner(&wait_mutex); latch.wr_lock(file, line); - ut_ad(!writer.exchange(pthread_self(), std::memory_order_relaxed)); } /** Release exclusive lock_sys.latch */ void lock_sys_t::wr_unlock() { - ut_ad(writer.exchange(0, std::memory_order_relaxed) == - pthread_self()); latch.wr_unlock(); } @@ -441,15 +439,11 @@ void lock_sys_t::rd_lock(const char *file, unsigned line) { mysql_mutex_assert_not_owner(&wait_mutex); latch.rd_lock(file, line); - ut_ad(!writer.load(std::memory_order_relaxed)); - ut_d(readers.fetch_add(1, std::memory_order_relaxed)); } /** Release shared lock_sys.latch */ void lock_sys_t::rd_unlock() { - ut_ad(!writer.load(std::memory_order_relaxed)); - ut_ad(readers.fetch_sub(1, std::memory_order_relaxed)); latch.rd_unlock(); } #endif @@ -976,8 +970,31 @@ func_exit: for (lock_t *lock= UT_LIST_GET_FIRST(table->locks); lock; lock= UT_LIST_GET_NEXT(un_member.tab_lock.locks, lock)) { - /* if victim has also BF status, but has earlier seqno, we have to wait */ - if (lock->trx != trx && + /* Victim trx needs to be different from BF trx and it has to have a + THD so that we can kill it. Victim might not have THD in two cases: + + (1) An incomplete transaction that was recovered from undo logs + on server startup (and not yet rolled back). + + (2) Transaction that is in XA PREPARE state and whose client + connection was disconnected. + + Neither of these can complete before lock_wait_wsrep() releases + lock_sys.latch. + + (1) trx_t::commit_in_memory() is clearing both + trx_t::state and trx_t::is_recovered before it invokes + lock_release(trx_t*) (which would be blocked by the exclusive + lock_sys.latch that we are holding here). Hence, it is not + possible to write a debug assertion to document this scenario. + + (2) If is in XA PREPARE state, it would eventually be rolled + back and the lock conflict would be resolved when an XA COMMIT + or XA ROLLBACK statement is executed in some other connection. + + If victim has also BF status, but has earlier seqno, we have to wait. + */ + if (lock->trx != trx && lock->trx->mysql_thd && !(wsrep_thd_is_BF(lock->trx->mysql_thd, false) && wsrep_thd_order_before(lock->trx->mysql_thd, trx->mysql_thd))) { @@ -1009,8 +1026,11 @@ func_exit: lock= lock_rec_get_next(heap_no, lock); do { - /* if victim has also BF status, but has earlier seqno, we have to wait */ - if (lock->trx != trx && + /* This is similar case as above except here we have + record-locks instead of table locks. See details + from comment above. + */ + if (lock->trx != trx && lock->trx->mysql_thd && !(wsrep_thd_is_BF(lock->trx->mysql_thd, false) && wsrep_thd_order_before(lock->trx->mysql_thd, trx->mysql_thd))) { @@ -1036,8 +1056,12 @@ func_exit: std::vector> victim_id; for (trx_t *v : victims) + { + /* Victim must have THD */ + ut_ad(v->mysql_thd); victim_id.emplace_back(std::pair {thd_get_thread_id(v->mysql_thd), v->id}); + } DBUG_EXECUTE_IF("sync.before_wsrep_thd_abort", { @@ -3940,6 +3964,8 @@ static void lock_table_dequeue(lock_t *in_lock, bool owns_wait_mutex) dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, lock_mode mode, bool no_wait) { + ut_ad(!dict_sys.frozen()); + mem_heap_t *heap= mem_heap_create(512); sel_node_t *node= sel_node_create(heap); que_thr_t *thr= pars_complete_graph_for_exec(node, trx, heap, nullptr); @@ -3976,6 +4002,67 @@ run_again: return err; } +/** Lock the child tables of a table. +@param table parent table +@param trx transaction +@return error code */ +dberr_t lock_table_children(dict_table_t *table, trx_t *trx) +{ + MDL_context *mdl_context= + static_cast(thd_mdl_context(trx->mysql_thd)); + ut_ad(mdl_context); + struct table_mdl{dict_table_t* table; MDL_ticket *mdl;}; + std::vector children; + children.emplace_back(table_mdl{table, nullptr}); + + dberr_t err= DB_SUCCESS; + dict_sys.freeze(SRW_LOCK_CALL); + + rescan: + for (auto f : table->referenced_set) + if (dict_table_t *child= f->foreign_table) + { + if (std::find_if(children.begin(), children.end(), + [&](const table_mdl &c){ return c.table == child; }) != + children.end()) + continue; /* We already acquired MDL on this child table. */ + MDL_ticket *mdl= nullptr; + child->acquire(); + child= dict_acquire_mdl_shared(child, mdl_context, &mdl, + DICT_TABLE_OP_NORMAL); + if (child) + { + if (!mdl) + child->release(); + children.emplace_back(table_mdl{child, mdl}); + goto rescan; + } + err= DB_LOCK_WAIT_TIMEOUT; + break; + } + dict_sys.unfreeze(); + + if (err == DB_SUCCESS) + for (const table_mdl &child : children) + if (child.mdl) + if ((err= lock_table_for_trx(child.table, trx, LOCK_X)) != DB_SUCCESS) + break; + + dict_sys.freeze(SRW_LOCK_CALL); + for (table_mdl &child : children) + { + if (child.mdl) + { + child.table->release(); + mdl_context->release_lock(child.mdl); + } + } + dict_sys.unfreeze(); + + return err; +} + + /** Exclusively lock the data dictionary tables. @param trx dictionary transaction @return error code @@ -4125,7 +4212,7 @@ restart: ulint count= 1000; /* We will not attempt hardware lock elision (memory transaction) here. Both lock_rec_dequeue_from_page() and lock_table_dequeue() - would likely lead to a memory transaction due to a system call, to + would likely lead to a memory transaction abort due to a system call, to wake up a waiting transaction. */ lock_sys.rd_lock(SRW_LOCK_CALL); trx->mutex_lock(); @@ -4295,28 +4382,82 @@ void lock_release_on_drop(trx_t *trx) } } -/** Reset lock bit for supremum and rebuild waiting queue. +/** Reset a lock bit and rebuild waiting queue. @param cell rec hash cell of in_lock @param lock the lock with supemum bit set */ -static void lock_rec_unlock_supremum(hash_cell_t &cell, lock_t *lock) +static void lock_rec_unlock(hash_cell_t &cell, lock_t *lock, ulint heap_no) { - ut_ad(lock_rec_get_nth_bit(lock, PAGE_HEAP_NO_SUPREMUM)); + ut_ad(lock_rec_get_nth_bit(lock, heap_no)); #ifdef SAFE_MUTEX ut_ad(!mysql_mutex_is_owner(&lock_sys.wait_mutex)); #endif /* SAFE_MUTEX */ ut_ad(!lock->is_table()); ut_ad(lock_sys.is_writer() || lock->trx->mutex_is_owner()); - lock_rec_reset_nth_bit(lock, PAGE_HEAP_NO_SUPREMUM); + lock_rec_reset_nth_bit(lock, heap_no); - lock_t *first_lock= lock_sys_t::get_first( - cell, lock->un_member.rec_lock.page_id, PAGE_HEAP_NO_SUPREMUM); + lock_t *first_lock= + lock_sys_t::get_first(cell, lock->un_member.rec_lock.page_id, heap_no); lock_rec_rebuild_waiting_queue( #if defined(UNIV_DEBUG) || !defined(DBUG_OFF) lock->trx, #endif /* defined(UNIV_DEBUG) || !defined(DBUG_OFF) */ - cell, first_lock, PAGE_HEAP_NO_SUPREMUM); + cell, first_lock, heap_no); +} + +/** Release locks to unmodified records on a clustered index page. +@param cell lock_sys.rec_hash cell of lock +@param lock record lock +@param offsets storage for rec_get_offsets() +@param heap storage for rec_get_offsets() +@param mtr mini-transaction (will be started and committed) */ +static void lock_rec_unlock_unmodified(hash_cell_t &cell, lock_t *lock, + rec_offs *&offsets, mem_heap_t *&heap, + mtr_t &mtr) +{ + ut_ad(!lock->is_waiting()); + + dict_index_t *const index= lock->index; + + mtr.start(); + if (buf_block_t *block= + btr_block_get(*index, lock->un_member.rec_lock.page_id.page_no(), + RW_S_LATCH, &mtr)) + { + if (UNIV_UNLIKELY(!page_is_leaf(block->page.frame))) + { + ut_ad("corrupted lock system" == 0); + goto func_exit; + } + + for (ulint i= PAGE_HEAP_NO_USER_LOW; i < lock_rec_get_n_bits(lock); ++i) + { + if (!lock_rec_get_nth_bit(lock, i)); + else if (const rec_t *rec= + page_find_rec_with_heap_no(block->page.frame, i)) + { + if (index->is_clust()) + { + if (trx_read_trx_id(rec + row_trx_id_offset(rec, index)) == + lock->trx->id) + continue; + unlock_rec: + lock_rec_unlock(cell, lock, i); + } + else + { + offsets= rec_get_offsets(rec, index, offsets, index->n_core_fields, + ULINT_UNDEFINED, &heap); + if (lock->trx != + lock_sec_rec_some_has_impl(lock->trx, rec, index, offsets)) + goto unlock_rec; + } + } + } + } +func_exit: + mtr.commit(); } /** Release non-exclusive locks on XA PREPARE, @@ -4334,6 +4475,12 @@ static bool lock_release_on_prepare_try(trx_t *trx) DBUG_ASSERT(trx->state == TRX_STATE_PREPARED); bool all_released= true; + mtr_t mtr; + rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; + rec_offs *offsets= offsets_; + mem_heap_t *heap= nullptr; + rec_offs_init(offsets_); + lock_sys.rd_lock(SRW_LOCK_CALL); trx->mutex_lock(); @@ -4350,20 +4497,24 @@ static bool lock_release_on_prepare_try(trx_t *trx) if (!lock->is_table()) { ut_ad(!lock->index->table->is_temporary()); - bool supremum_bit = lock_rec_get_nth_bit(lock, PAGE_HEAP_NO_SUPREMUM); - bool rec_granted_exclusive_not_gap = + bool supremum_bit= lock_rec_get_nth_bit(lock, PAGE_HEAP_NO_SUPREMUM); + bool rec_granted_exclusive_not_gap= lock->is_rec_granted_exclusive_not_gap(); if (!supremum_bit && rec_granted_exclusive_not_gap) continue; - auto &lock_hash= lock_sys.hash_get(lock->type_mode); - auto cell= lock_hash.cell_get(lock->un_member.rec_lock.page_id.fold()); + if (UNIV_UNLIKELY(lock->type_mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE))) + continue; /* SPATIAL INDEX locking is broken. */ + auto cell= + lock_sys.rec_hash.cell_get(lock->un_member.rec_lock.page_id.fold()); auto latch= lock_sys_t::hash_table::latch(cell); if (latch->try_acquire()) { if (!rec_granted_exclusive_not_gap) lock_rec_dequeue_from_page(lock, false); else if (supremum_bit) - lock_rec_unlock_supremum(*cell, lock); + lock_rec_unlock(*cell, lock, PAGE_HEAP_NO_SUPREMUM); + else + lock_rec_unlock_unmodified(*cell, lock, offsets, heap, mtr); latch->release(); } else @@ -4396,6 +4547,8 @@ static bool lock_release_on_prepare_try(trx_t *trx) lock_sys.rd_unlock(); trx->mutex_unlock(); + if (UNIV_LIKELY_NULL(heap)) + mem_heap_free(heap); return all_released; } @@ -4409,52 +4562,71 @@ void lock_release_on_prepare(trx_t *trx) if (lock_release_on_prepare_try(trx)) return; - LockMutexGuard g{SRW_LOCK_CALL}; - trx->mutex_lock(); + mtr_t mtr; + rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; + rec_offs *offsets= offsets_; + mem_heap_t *heap= nullptr; + + rec_offs_init(offsets_); - for (lock_t *prev, *lock= UT_LIST_GET_LAST(trx->lock.trx_locks); lock; - lock= prev) { - ut_ad(lock->trx == trx); - prev= UT_LIST_GET_PREV(trx_locks, lock); - if (!lock->is_table()) + LockMutexGuard g{SRW_LOCK_CALL}; + trx->mutex_lock(); + + for (lock_t *prev, *lock= UT_LIST_GET_LAST(trx->lock.trx_locks); lock; + lock= prev) { - ut_ad(!lock->index->table->is_temporary()); - if (!lock->is_rec_granted_exclusive_not_gap()) - lock_rec_dequeue_from_page(lock, false); - else if (lock_rec_get_nth_bit(lock, PAGE_HEAP_NO_SUPREMUM)) + ut_ad(lock->trx == trx); + prev= UT_LIST_GET_PREV(trx_locks, lock); + if (!lock->is_table()) { - auto &lock_hash= lock_sys.hash_get(lock->type_mode); - auto cell= lock_hash.cell_get(lock->un_member.rec_lock.page_id.fold()); - lock_rec_unlock_supremum(*cell, lock); + ut_ad(!lock->index->table->is_temporary()); + if (!lock->is_rec_granted_exclusive_not_gap()) + lock_rec_dequeue_from_page(lock, false); + else if (UNIV_UNLIKELY(lock->type_mode & + (LOCK_PREDICATE | LOCK_PRDT_PAGE))) + /* SPATIAL INDEX locking is broken. */; + else + { + auto cell= lock_sys.rec_hash.cell_get(lock->un_member.rec_lock. + page_id.fold()); + if (lock_rec_get_nth_bit(lock, PAGE_HEAP_NO_SUPREMUM)) + lock_rec_unlock(*cell, lock, PAGE_HEAP_NO_SUPREMUM); + else + { + ut_ad(lock->trx->isolation_level > TRX_ISO_READ_COMMITTED || + /* Insert-intention lock is valid for supremum for isolation + level > TRX_ISO_READ_COMMITTED */ + lock->mode() == LOCK_X || + !lock_rec_get_nth_bit(lock, PAGE_HEAP_NO_SUPREMUM)); + lock_rec_unlock_unmodified(*cell, lock, offsets, heap, mtr); + } + } } else - ut_ad(lock->trx->isolation_level > TRX_ISO_READ_COMMITTED || - /* Insert-intention lock is valid for supremum for isolation - level > TRX_ISO_READ_COMMITTED */ - lock->mode() == LOCK_X || - !lock_rec_get_nth_bit(lock, PAGE_HEAP_NO_SUPREMUM)); - } - else - { - ut_d(dict_table_t *table= lock->un_member.tab_lock.table); - ut_ad(!table->is_temporary()); - switch (lock->mode()) { - case LOCK_IS: - case LOCK_S: - lock_table_dequeue(lock, false); - break; - case LOCK_IX: - case LOCK_X: - ut_ad(table->id >= DICT_HDR_FIRST_ID || trx->dict_operation); - /* fall through */ - default: - break; + { + ut_d(dict_table_t *table= lock->un_member.tab_lock.table); + ut_ad(!table->is_temporary()); + switch (lock->mode()) { + case LOCK_IS: + case LOCK_S: + lock_table_dequeue(lock, false); + break; + case LOCK_IX: + case LOCK_X: + ut_ad(table->id >= DICT_HDR_FIRST_ID || trx->dict_operation); + /* fall through */ + default: + break; + } } } } trx->mutex_unlock(); + + if (UNIV_LIKELY_NULL(heap)) + mem_heap_free(heap); } /** Release locks on a table whose creation is being rolled back */ @@ -5414,47 +5586,43 @@ lock_rec_insert_check_and_lock( return err; } -/*********************************************************************//** -Creates an explicit record lock for a running transaction that currently only -has an implicit lock on the record. The transaction instance must have a -reference count > 0 so that it can't be committed and freed before this -function has completed. */ -static -bool -lock_rec_convert_impl_to_expl_for_trx( -/*==================================*/ - trx_t* trx, /*!< in/out: active transaction */ - const page_id_t id, /*!< in: page identifier */ - const rec_t* rec, /*!< in: user record on page */ - dict_index_t* index) /*!< in: index of record */ +/** Create an explicit record lock for a transaction that currently only +has an implicit lock on the record. +@param trx referenced, active transaction, or nullptr +@param id page identifier +@param rec record in the page +@param index the index B-tree that the record belongs to +@return trx, with the reference released */ +static trx_t *lock_rec_convert_impl_to_expl_for_trx(trx_t *trx, + const page_id_t id, + const rec_t *rec, + dict_index_t *index) { - if (!trx) - return false; - - ut_ad(trx->is_referenced()); - ut_ad(page_rec_is_leaf(rec)); - ut_ad(!rec_is_metadata(rec, *index)); - - DEBUG_SYNC_C("before_lock_rec_convert_impl_to_expl_for_trx"); - ulint heap_no= page_rec_get_heap_no(rec); - + if (trx) { - LockGuard g{lock_sys.rec_hash, id}; - trx->mutex_lock(); - ut_ad(!trx_state_eq(trx, TRX_STATE_NOT_STARTED)); + ut_ad(trx->is_referenced()); + ut_ad(page_rec_is_leaf(rec)); + ut_ad(!rec_is_metadata(rec, *index)); - if (!trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY) && - !lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, g.cell(), id, heap_no, - trx)) - lock_rec_add_to_queue(LOCK_X | LOCK_REC_NOT_GAP, g.cell(), id, - page_align(rec), heap_no, index, trx, true); + ulint heap_no= page_rec_get_heap_no(rec); + + { + LockGuard g{lock_sys.rec_hash, id}; + trx->mutex_lock(); + ut_ad(!trx_state_eq(trx, TRX_STATE_NOT_STARTED)); + + if (!trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY) && + !lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, g.cell(), id, heap_no, + trx)) + lock_rec_add_to_queue(LOCK_X | LOCK_REC_NOT_GAP, g.cell(), id, + page_align(rec), heap_no, index, trx, true); + } + + trx->release_reference(); + trx->mutex_unlock(); } - trx->mutex_unlock(); - trx->release_reference(); - - DEBUG_SYNC_C("after_lock_rec_convert_impl_to_expl_for_trx"); - return false; + return trx; } @@ -5545,10 +5713,11 @@ should be created. @param[in] rec record on the leaf page @param[in] index the index of the record @param[in] offsets rec_get_offsets(rec,index) -@return whether caller_trx already holds an exclusive lock on rec */ +@return unsafe pointer to a transaction that held an exclusive lock on rec +@retval nullptr if no transaction held an exclusive lock */ template static -bool +const trx_t * lock_rec_convert_impl_to_expl( trx_t* caller_trx, page_id_t id, @@ -5572,10 +5741,10 @@ lock_rec_convert_impl_to_expl( trx_id = lock_clust_rec_some_has_impl(rec, index, offsets); if (trx_id == 0) { - return false; + return nullptr; } if (UNIV_UNLIKELY(trx_id == caller_trx->id)) { - return true; + return caller_trx; } trx = trx_sys.find(caller_trx, trx_id); @@ -5586,7 +5755,7 @@ lock_rec_convert_impl_to_expl( offsets); if (trx == caller_trx) { trx->release_reference(); - return true; + return trx; } ut_d(lock_rec_other_trx_holds_expl(caller_trx, trx, rec, id)); @@ -5631,11 +5800,18 @@ lock_clust_rec_modify_check_and_lock( /* If a transaction has no explicit x-lock set on the record, set one for it */ - if (lock_rec_convert_impl_to_expl(thr_get_trx(thr), - block->page.id(), + trx_t *trx = thr_get_trx(thr); + if (const trx_t *owner = + lock_rec_convert_impl_to_expl(trx, block->page.id(), rec, index, offsets)) { - /* We already hold an implicit exclusive lock. */ - return DB_SUCCESS; + if (owner == trx) { + /* We already hold an exclusive lock. */ + return DB_SUCCESS; + } + + if (trx->snapshot_isolation && trx->read_view.is_open()) { + return DB_RECORD_CHANGED; + } } err = lock_rec_lock(true, LOCK_X | LOCK_REC_NOT_GAP, @@ -5798,12 +5974,19 @@ lock_sec_rec_read_check_and_lock( return DB_SUCCESS; } - if (!page_rec_is_supremum(rec) - && lock_rec_convert_impl_to_expl( - trx, block->page.id(), rec, index, offsets) - && gap_mode == LOCK_REC_NOT_GAP) { - /* We already hold an implicit exclusive lock. */ - return DB_SUCCESS; + if (page_rec_is_supremum(rec)) { + } else if (const trx_t *owner = + lock_rec_convert_impl_to_expl(trx, block->page.id(), + rec, index, offsets)) { + if (owner == trx) { + if (gap_mode == LOCK_REC_NOT_GAP) { + /* We already hold an exclusive lock. */ + return DB_SUCCESS; + } + } else if (trx->snapshot_isolation + && trx->read_view.is_open()) { + return DB_RECORD_CHANGED; + } } #ifdef WITH_WSREP @@ -5883,13 +6066,28 @@ lock_clust_rec_read_check_and_lock( ulint heap_no = page_rec_get_heap_no(rec); trx_t *trx = thr_get_trx(thr); - if (!lock_table_has(trx, index->table, LOCK_X) - && heap_no != PAGE_HEAP_NO_SUPREMUM - && lock_rec_convert_impl_to_expl(trx, id, - rec, index, offsets) - && gap_mode == LOCK_REC_NOT_GAP) { - /* We already hold an implicit exclusive lock. */ - return DB_SUCCESS; + if (lock_table_has(trx, index->table, LOCK_X) + || heap_no == PAGE_HEAP_NO_SUPREMUM) { + } else if (const trx_t *owner = + lock_rec_convert_impl_to_expl(trx, id, + rec, index, offsets)) { + if (owner == trx) { + if (gap_mode == LOCK_REC_NOT_GAP) { + /* We already hold an exclusive lock. */ + return DB_SUCCESS; + } + } else if (trx->snapshot_isolation + && trx->read_view.is_open()) { + return DB_RECORD_CHANGED; + } + } + + if (heap_no > PAGE_HEAP_NO_SUPREMUM && gap_mode != LOCK_GAP + && trx->snapshot_isolation + && trx->read_view.is_open() + && !trx->read_view.changes_visible( + trx_read_trx_id(rec + row_trx_id_offset(rec, index)))) { + return DB_RECORD_CHANGED; } dberr_t err = lock_rec_lock(false, gap_mode | mode, @@ -6656,6 +6854,7 @@ and less modified rows. Bit 0 is used to prefer orig_trx in case of a tie. print(buf); } + DBUG_EXECUTE_IF("innodb_deadlock_victim_self", victim= trx;); ut_ad(victim->state == TRX_STATE_ACTIVE); /* victim->lock.was_chosen_as_deadlock_victim must always be set before diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index f3deeca9381..9d239ce80b6 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -68,9 +68,7 @@ log_t log_sys; void log_t::set_capacity() { -#ifndef SUX_LOCK_GENERIC - ut_ad(log_sys.latch.is_write_locked()); -#endif + ut_ad(log_sys.latch_have_wr()); /* Margin for the free space in the smallest log, before a new query step which modifies the database, is started */ @@ -133,7 +131,6 @@ bool log_t::create() #endif latch.SRW_LOCK_INIT(log_latch_key); - init_lsn_lock(); last_checkpoint_lsn= FIRST_LSN; log_capacity= 0; @@ -142,7 +139,7 @@ bool log_t::create() next_checkpoint_lsn= 0; checkpoint_pending= false; - buf_free= 0; + set_buf_free(0); ut_ad(is_initialised()); #ifndef HAVE_PMEM @@ -174,11 +171,13 @@ void log_file_t::write(os_offset_t offset, span buf) noexcept ut_ad(is_opened()); if (dberr_t err= os_file_write_func(IORequestWrite, "ib_logfile0", m_file, buf.data(), offset, buf.size())) - ib::fatal() << "write(\"ib_logfile0\") returned " << err; + ib::fatal() << "write(\"ib_logfile0\") returned " << err + << ". Operating system error number " + << IF_WIN(GetLastError(), errno) << "."; } #ifdef HAVE_PMEM -# include +# include "cache.h" /** Attempt to memory map a file. @param file log file handle @@ -235,12 +234,13 @@ void log_t::attach_low(log_file_t file, os_offset_t size) log.close(); mprotect(ptr, size_t(size), PROT_READ); buf= static_cast(ptr); - max_buf_free= size; + max_buf_free= 1; # if defined __linux__ || defined _WIN32 set_block_size(CPU_LEVEL1_DCACHE_LINESIZE); # endif log_maybe_unbuffered= true; log_buffered= false; + mtr_t::finisher_update(); return true; } } @@ -275,6 +275,7 @@ void log_t::attach_low(log_file_t file, os_offset_t size) block_size); #endif + mtr_t::finisher_update(); #ifdef HAVE_PMEM checkpoint_buf= static_cast(aligned_malloc(block_size, block_size)); memset_aligned<64>(checkpoint_buf, 0, block_size); @@ -310,9 +311,7 @@ void log_t::header_write(byte *buf, lsn_t lsn, bool encrypted) void log_t::create(lsn_t lsn) noexcept { -#ifndef SUX_LOCK_GENERIC - ut_ad(latch.is_write_locked()); -#endif + ut_ad(latch_have_wr()); ut_ad(!recv_no_log_write); ut_ad(is_latest()); ut_ad(this == &log_sys); @@ -329,12 +328,12 @@ void log_t::create(lsn_t lsn) noexcept { mprotect(buf, size_t(file_size), PROT_READ | PROT_WRITE); memset_aligned<4096>(buf, 0, 4096); - buf_free= START_OFFSET; + set_buf_free(START_OFFSET); } else #endif { - buf_free= 0; + set_buf_free(0); memset_aligned<4096>(flush_buf, 0, buf_size); memset_aligned<4096>(buf, 0, buf_size); } @@ -488,8 +487,7 @@ log_t::resize_start_status log_t::resize_start(os_offset_t size) noexcept resize_lsn.store(1, std::memory_order_relaxed); resize_target= 0; resize_log.m_file= - os_file_create_func(path.c_str(), - OS_FILE_CREATE | OS_FILE_ON_ERROR_NO_EXIT, + os_file_create_func(path.c_str(), OS_FILE_CREATE, OS_FILE_NORMAL, OS_LOG_FILE, false, &success); if (success) { @@ -836,9 +834,7 @@ ATTRIBUTE_COLD void log_t::resize_write_buf(size_t length) noexcept @return the current log sequence number */ template inline lsn_t log_t::write_buf() noexcept { -#ifndef SUX_LOCK_GENERIC - ut_ad(latch.is_write_locked()); -#endif + ut_ad(latch_have_wr()); ut_ad(!is_pmem()); ut_ad(!srv_read_only_mode); @@ -954,7 +950,7 @@ wait and check if an already running write is covering the request. void log_write_up_to(lsn_t lsn, bool durable, const completion_callback *callback) { - ut_ad(!srv_read_only_mode || (log_sys.buf_free < log_sys.max_buf_free)); + ut_ad(!srv_read_only_mode || log_sys.buf_free_ok()); ut_ad(lsn != LSN_MAX); ut_ad(lsn != 0); ut_ad(lsn <= log_sys.get_lsn()); @@ -1083,7 +1079,7 @@ NOTE that this function may only be called while not holding any synchronization objects except dict_sys.latch. */ void log_free_check() { - ut_ad(!lock_sys.is_writer()); + ut_ad(!lock_sys.is_holder()); if (log_sys.check_for_checkpoint()) { ut_ad(!recv_no_log_write); @@ -1299,6 +1295,7 @@ log_print( void log_t::close() { ut_ad(this == &log_sys); + ut_ad(!(buf_free & buf_free_LOCK)); if (!is_initialised()) return; close_file(); @@ -1316,7 +1313,6 @@ void log_t::close() #endif latch.destroy(); - destroy_lsn_lock(); recv_sys.close(); diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index ef31a4d00c1..f73b409e85d 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -832,8 +832,7 @@ processed: inside recv_sys_t::recover_deferred(). */ bool success; handle= os_file_create(innodb_data_file_key, filename, - OS_FILE_CREATE | OS_FILE_ON_ERROR_NO_EXIT | - OS_FILE_ON_ERROR_SILENT, + OS_FILE_CREATE_SILENT, OS_FILE_AIO, OS_DATA_FILE, false, &success); } space->add(filename, handle, size, false, false); @@ -1623,7 +1622,7 @@ dberr_t recv_sys_t::find_checkpoint() std::string path{get_log_file_path()}; bool success; os_file_t file{os_file_create_func(path.c_str(), - OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT, + OS_FILE_OPEN, OS_FILE_NORMAL, OS_LOG_FILE, srv_read_only_mode, &success)}; if (file == OS_FILE_CLOSED) @@ -1653,8 +1652,7 @@ dberr_t recv_sys_t::find_checkpoint() { path= get_log_file_path(LOG_FILE_NAME_PREFIX).append(std::to_string(i)); file= os_file_create_func(path.c_str(), - OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT | - OS_FILE_ON_ERROR_SILENT, + OS_FILE_OPEN_SILENT, OS_FILE_NORMAL, OS_LOG_FILE, true, &success); if (file == OS_FILE_CLOSED) break; @@ -2429,11 +2427,9 @@ recv_sys_t::parse_mtr_result recv_sys_t::parse(source &l, bool if_exists) noexcept { restart: -#ifndef SUX_LOCK_GENERIC - ut_ad(log_sys.latch.is_write_locked() || + ut_ad(log_sys.latch_have_wr() || srv_operation == SRV_OPERATION_BACKUP || srv_operation == SRV_OPERATION_BACKUP_NO_DEFER); -#endif mysql_mutex_assert_owner(&mutex); ut_ad(log_sys.next_checkpoint_lsn); ut_ad(log_sys.is_latest()); @@ -3999,9 +3995,7 @@ static bool recv_scan_log(bool last_phase) lsn_t rewound_lsn= 0; for (ut_d(lsn_t source_offset= 0);;) { -#ifndef SUX_LOCK_GENERIC - ut_ad(log_sys.latch.is_write_locked()); -#endif + ut_ad(log_sys.latch_have_wr()); #ifdef UNIV_DEBUG const bool wrap{source_offset + recv_sys.len == log_sys.file_size}; #endif @@ -4067,9 +4061,10 @@ static bool recv_scan_log(bool last_phase) const lsn_t end{recv_sys.file_checkpoint}; ut_ad(!end || end == recv_sys.lsn); + bool corrupt_fs= recv_sys.is_corrupt_fs(); mysql_mutex_unlock(&recv_sys.mutex); - if (!end) + if (!end && !corrupt_fs) { recv_sys.set_corrupt_log(); sql_print_error("InnoDB: Missing FILE_CHECKPOINT(" LSN_PF @@ -4395,9 +4390,7 @@ recv_init_crash_recovery_spaces(bool rescan, bool& missing_tablespace) static dberr_t recv_rename_files() { mysql_mutex_assert_owner(&recv_sys.mutex); -#ifndef SUX_LOCK_GENERIC - ut_ad(log_sys.latch.is_write_locked()); -#endif + ut_ad(log_sys.latch_have_wr()); dberr_t err= DB_SUCCESS; @@ -4549,6 +4542,9 @@ read_only_recovery: LSN_PF, recv_sys.lsn); goto err_exit; } + if (recv_sys.is_corrupt_fs()) { + goto err_exit; + } ut_ad(recv_sys.file_checkpoint); if (rewind) { recv_sys.lsn = log_sys.next_checkpoint_lsn; @@ -4587,9 +4583,9 @@ read_only_recovery: do { rescan = recv_scan_log(false); - ut_ad(!recv_sys.is_corrupt_fs()); - if (recv_sys.is_corrupt_log()) { + if (recv_sys.is_corrupt_log() || + recv_sys.is_corrupt_fs()) { goto err_exit; } @@ -4677,7 +4673,7 @@ err_exit: PROT_READ | PROT_WRITE); #endif } - log_sys.buf_free = recv_sys.offset; + log_sys.set_buf_free(recv_sys.offset); if (recv_needed_recovery && srv_operation <= SRV_OPERATION_EXPORT_RESTORED) { /* Write a FILE_CHECKPOINT marker as the first thing, diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 0f0a28a54c1..90a2007a48d 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -37,6 +37,31 @@ Created 11/26/1995 Heikki Tuuri #include "srv0start.h" #include "log.h" #include "mariadb_stats.h" +#include "my_cpu.h" + +#ifdef HAVE_PMEM +void (*mtr_t::commit_logger)(mtr_t *, std::pair); +#endif +std::pair (*mtr_t::finisher)(mtr_t *, size_t); +unsigned mtr_t::spin_wait_delay; + +void mtr_t::finisher_update() +{ + ut_ad(log_sys.latch_have_wr()); +#ifdef HAVE_PMEM + if (log_sys.is_pmem()) + { + commit_logger= mtr_t::commit_log; + finisher= spin_wait_delay + ? mtr_t::finish_writer : mtr_t::finish_writer; + return; + } + commit_logger= mtr_t::commit_log; +#endif + finisher= + (spin_wait_delay + ? mtr_t::finish_writer : mtr_t::finish_writer); +} void mtr_memo_slot_t::release() const { @@ -82,9 +107,7 @@ void mtr_memo_slot_t::release() const inline buf_page_t *buf_pool_t::prepare_insert_into_flush_list(lsn_t lsn) noexcept { -#ifndef SUX_LOCK_GENERIC - ut_ad(recv_recovery_is_on() || log_sys.latch.is_locked()); -#endif + ut_ad(recv_recovery_is_on() || log_sys.latch_have_any()); ut_ad(lsn >= log_sys.last_checkpoint_lsn); mysql_mutex_assert_owner(&flush_list_mutex); static_assert(log_t::FIRST_LSN >= 2, "compatibility"); @@ -233,7 +256,14 @@ static void insert_imported(buf_block_t *block) if (block->page.oldest_modification() <= 1) { log_sys.latch.rd_lock(SRW_LOCK_CALL); - const lsn_t lsn= log_sys.last_checkpoint_lsn; + /* For unlogged mtrs (MTR_LOG_NO_REDO), we use the current system LSN. The + mtr that generated the LSN is either already committed or in mtr_t::commit. + Shared latch and relaxed atomics should be fine here as it is guaranteed + that both the current mtr and the mtr that generated the LSN would have + added the dirty pages to flush list before we access the minimum LSN during + checkpoint. log_checkpoint_low() acquires exclusive log_sys.latch before + commencing. */ + const lsn_t lsn= log_sys.get_lsn(); mysql_mutex_lock(&buf_pool.flush_list_mutex); buf_pool.insert_into_flush_list (buf_pool.prepare_insert_into_flush_list(lsn), block, lsn); @@ -309,12 +339,9 @@ void mtr_t::release() inline lsn_t log_t::get_write_target() const { -#ifndef SUX_LOCK_GENERIC - ut_ad(latch.is_locked()); -#endif - if (UNIV_LIKELY(buf_free < max_buf_free)) + ut_ad(latch_have_any()); + if (UNIV_LIKELY(buf_free_ok())) return 0; - ut_ad(!is_pmem()); /* The LSN corresponding to the end of buf is write_lsn - (first_lsn & 4095) + buf_free, but we use simpler arithmetics to return a smaller write target in @@ -323,6 +350,134 @@ inline lsn_t log_t::get_write_target() const return write_lsn + max_buf_free / 2; } +template +void mtr_t::commit_log(mtr_t *mtr, std::pair lsns) +{ + size_t modified= 0; + const lsn_t write_lsn= pmem ? 0 : log_sys.get_write_target(); + + if (mtr->m_made_dirty) + { + auto it= mtr->m_memo.rbegin(); + + mysql_mutex_lock(&buf_pool.flush_list_mutex); + + buf_page_t *const prev= + buf_pool.prepare_insert_into_flush_list(lsns.first); + + while (it != mtr->m_memo.rend()) + { + const mtr_memo_slot_t &slot= *it++; + if (slot.type & MTR_MEMO_MODIFY) + { + ut_ad(slot.type == MTR_MEMO_PAGE_X_MODIFY || + slot.type == MTR_MEMO_PAGE_SX_MODIFY); + modified++; + buf_block_t *b= static_cast(slot.object); + ut_ad(b->page.id() < end_page_id); + ut_d(const auto s= b->page.state()); + ut_ad(s > buf_page_t::FREED); + ut_ad(s < buf_page_t::READ_FIX); + ut_ad(mach_read_from_8(b->page.frame + FIL_PAGE_LSN) <= + mtr->m_commit_lsn); + mach_write_to_8(b->page.frame + FIL_PAGE_LSN, mtr->m_commit_lsn); + if (UNIV_LIKELY_NULL(b->page.zip.data)) + memcpy_aligned<8>(FIL_PAGE_LSN + b->page.zip.data, + FIL_PAGE_LSN + b->page.frame, 8); + buf_pool.insert_into_flush_list(prev, b, lsns.first); + } + } + + ut_ad(modified); + buf_pool.flush_list_requests+= modified; + buf_pool.page_cleaner_wakeup(); + mysql_mutex_unlock(&buf_pool.flush_list_mutex); + + if (mtr->m_latch_ex) + { + log_sys.latch.wr_unlock(); + mtr->m_latch_ex= false; + } + else + log_sys.latch.rd_unlock(); + + mtr->release(); + } + else + { + if (mtr->m_latch_ex) + { + log_sys.latch.wr_unlock(); + mtr->m_latch_ex= false; + } + else + log_sys.latch.rd_unlock(); + + for (auto it= mtr->m_memo.rbegin(); it != mtr->m_memo.rend(); ) + { + const mtr_memo_slot_t &slot= *it++; + ut_ad(slot.object); + switch (slot.type) { + case MTR_MEMO_S_LOCK: + static_cast(slot.object)->s_unlock(); + break; + case MTR_MEMO_SPACE_X_LOCK: + static_cast(slot.object)->set_committed_size(); + static_cast(slot.object)->x_unlock(); + break; + case MTR_MEMO_X_LOCK: + case MTR_MEMO_SX_LOCK: + static_cast(slot.object)-> + u_or_x_unlock(slot.type == MTR_MEMO_SX_LOCK); + break; + default: + buf_page_t *bpage= static_cast(slot.object); + ut_d(const auto s=) + bpage->unfix(); + if (slot.type & MTR_MEMO_MODIFY) + { + ut_ad(slot.type == MTR_MEMO_PAGE_X_MODIFY || + slot.type == MTR_MEMO_PAGE_SX_MODIFY); + ut_ad(bpage->oldest_modification() > 1); + ut_ad(bpage->oldest_modification() < mtr->m_commit_lsn); + ut_ad(bpage->id() < end_page_id); + ut_ad(s >= buf_page_t::FREED); + ut_ad(s < buf_page_t::READ_FIX); + ut_ad(mach_read_from_8(bpage->frame + FIL_PAGE_LSN) <= + mtr->m_commit_lsn); + mach_write_to_8(bpage->frame + FIL_PAGE_LSN, mtr->m_commit_lsn); + if (UNIV_LIKELY_NULL(bpage->zip.data)) + memcpy_aligned<8>(FIL_PAGE_LSN + bpage->zip.data, + FIL_PAGE_LSN + bpage->frame, 8); + modified++; + } + switch (auto latch= slot.type & ~MTR_MEMO_MODIFY) { + case MTR_MEMO_PAGE_S_FIX: + bpage->lock.s_unlock(); + continue; + case MTR_MEMO_PAGE_SX_FIX: + case MTR_MEMO_PAGE_X_FIX: + bpage->lock.u_or_x_unlock(latch == MTR_MEMO_PAGE_SX_FIX); + continue; + default: + ut_ad(latch == MTR_MEMO_BUF_FIX); + } + } + } + + buf_pool.add_flush_list_requests(modified); + mtr->m_memo.clear(); + } + + mariadb_increment_pages_updated(modified); + + if (UNIV_UNLIKELY(lsns.second != PAGE_FLUSH_NO)) + buf_flush_ahead(mtr->m_commit_lsn, lsns.second == PAGE_FLUSH_SYNC); + + if (!pmem && UNIV_UNLIKELY(write_lsn != 0)) + log_write_up_to(write_lsn, false); +} + /** Commit a mini-transaction. */ void mtr_t::commit() { @@ -344,129 +499,11 @@ void mtr_t::commit() ut_ad(!srv_read_only_mode); std::pair lsns{do_write()}; process_freed_pages(); - size_t modified= 0; - const lsn_t write_lsn= log_sys.get_write_target(); - - if (m_made_dirty) - { - auto it= m_memo.rbegin(); - - mysql_mutex_lock(&buf_pool.flush_list_mutex); - - buf_page_t *const prev= - buf_pool.prepare_insert_into_flush_list(lsns.first); - - while (it != m_memo.rend()) - { - const mtr_memo_slot_t &slot= *it++; - if (slot.type & MTR_MEMO_MODIFY) - { - ut_ad(slot.type == MTR_MEMO_PAGE_X_MODIFY || - slot.type == MTR_MEMO_PAGE_SX_MODIFY); - modified++; - buf_block_t *b= static_cast(slot.object); - ut_ad(b->page.id() < end_page_id); - ut_d(const auto s= b->page.state()); - ut_ad(s > buf_page_t::FREED); - ut_ad(s < buf_page_t::READ_FIX); - ut_ad(mach_read_from_8(b->page.frame + FIL_PAGE_LSN) <= - m_commit_lsn); - mach_write_to_8(b->page.frame + FIL_PAGE_LSN, m_commit_lsn); - if (UNIV_LIKELY_NULL(b->page.zip.data)) - memcpy_aligned<8>(FIL_PAGE_LSN + b->page.zip.data, - FIL_PAGE_LSN + b->page.frame, 8); - buf_pool.insert_into_flush_list(prev, b, lsns.first); - } - } - - ut_ad(modified); - buf_pool.flush_list_requests+= modified; - buf_pool.page_cleaner_wakeup(); - mysql_mutex_unlock(&buf_pool.flush_list_mutex); - - if (m_latch_ex) - { - log_sys.latch.wr_unlock(); - m_latch_ex= false; - } - else - log_sys.latch.rd_unlock(); - - release(); - } - else - { - if (m_latch_ex) - { - log_sys.latch.wr_unlock(); - m_latch_ex= false; - } - else - log_sys.latch.rd_unlock(); - - for (auto it= m_memo.rbegin(); it != m_memo.rend(); ) - { - const mtr_memo_slot_t &slot= *it++; - ut_ad(slot.object); - switch (slot.type) { - case MTR_MEMO_S_LOCK: - static_cast(slot.object)->s_unlock(); - break; - case MTR_MEMO_SPACE_X_LOCK: - static_cast(slot.object)->set_committed_size(); - static_cast(slot.object)->x_unlock(); - break; - case MTR_MEMO_X_LOCK: - case MTR_MEMO_SX_LOCK: - static_cast(slot.object)-> - u_or_x_unlock(slot.type == MTR_MEMO_SX_LOCK); - break; - default: - buf_page_t *bpage= static_cast(slot.object); - ut_d(const auto s=) - bpage->unfix(); - if (slot.type & MTR_MEMO_MODIFY) - { - ut_ad(slot.type == MTR_MEMO_PAGE_X_MODIFY || - slot.type == MTR_MEMO_PAGE_SX_MODIFY); - ut_ad(bpage->oldest_modification() > 1); - ut_ad(bpage->oldest_modification() < m_commit_lsn); - ut_ad(bpage->id() < end_page_id); - ut_ad(s >= buf_page_t::FREED); - ut_ad(s < buf_page_t::READ_FIX); - ut_ad(mach_read_from_8(bpage->frame + FIL_PAGE_LSN) <= - m_commit_lsn); - mach_write_to_8(bpage->frame + FIL_PAGE_LSN, m_commit_lsn); - if (UNIV_LIKELY_NULL(bpage->zip.data)) - memcpy_aligned<8>(FIL_PAGE_LSN + bpage->zip.data, - FIL_PAGE_LSN + bpage->frame, 8); - modified++; - } - switch (auto latch= slot.type & ~MTR_MEMO_MODIFY) { - case MTR_MEMO_PAGE_S_FIX: - bpage->lock.s_unlock(); - continue; - case MTR_MEMO_PAGE_SX_FIX: - case MTR_MEMO_PAGE_X_FIX: - bpage->lock.u_or_x_unlock(latch == MTR_MEMO_PAGE_SX_FIX); - continue; - default: - ut_ad(latch == MTR_MEMO_BUF_FIX); - } - } - } - - buf_pool.add_flush_list_requests(modified); - m_memo.clear(); - } - - mariadb_increment_pages_updated(modified); - - if (UNIV_UNLIKELY(lsns.second != PAGE_FLUSH_NO)) - buf_flush_ahead(m_commit_lsn, lsns.second == PAGE_FLUSH_SYNC); - - if (UNIV_UNLIKELY(write_lsn != 0)) - log_write_up_to(write_lsn, false); +#ifdef HAVE_PMEM + commit_logger(this, lsns); +#else + commit_log(this, lsns); +#endif } else { @@ -511,10 +548,8 @@ void mtr_t::rollback_to_savepoint(ulint begin, ulint end) /** Set create_lsn. */ inline void fil_space_t::set_create_lsn(lsn_t lsn) { -#ifndef SUX_LOCK_GENERIC /* Concurrent log_checkpoint_low() must be impossible. */ - ut_ad(latch.is_write_locked()); -#endif + ut_ad(latch.have_wr()); create_lsn= lsn; } @@ -526,7 +561,6 @@ void mtr_t::commit_shrink(fil_space_t &space, uint32_t size) ut_ad(is_active()); ut_ad(!high_level_read_only); ut_ad(m_modifications); - ut_ad(!space.id || m_made_dirty); ut_ad(!m_memo.empty()); ut_ad(!recv_recovery_is_on()); ut_ad(m_log_mode == MTR_LOG_ALL); @@ -557,9 +591,7 @@ void mtr_t::commit_shrink(fil_space_t &space, uint32_t size) /* Durably write the reduced FSP_SIZE before truncating the data file. */ log_write_and_flush(); -#ifndef SUX_LOCK_GENERIC - ut_ad(log_sys.latch.is_write_locked()); -#endif + ut_ad(log_sys.latch_have_wr()); os_file_truncate(file->name, file->handle, os_offset_t{file->size} << srv_page_size_shift, true); @@ -715,9 +747,7 @@ This is to be used at log_checkpoint(). @return current LSN */ ATTRIBUTE_COLD lsn_t mtr_t::commit_files(lsn_t checkpoint_lsn) { -#ifndef SUX_LOCK_GENERIC - ut_ad(log_sys.latch.is_write_locked()); -#endif + ut_ad(log_sys.latch_have_wr()); ut_ad(is_active()); ut_ad(m_log_mode == MTR_LOG_ALL); ut_ad(!m_made_dirty); @@ -871,13 +901,111 @@ ATTRIBUTE_COLD static void log_overwrite_warning(lsn_t lsn) ? ". Shutdown is in progress" : ""); } -/** Wait in append_prepare() for buffer to become available -@param lsn log sequence number to write up to -@param ex whether log_sys.latch is exclusively locked */ -ATTRIBUTE_COLD void log_t::append_prepare_wait(lsn_t lsn, bool ex) noexcept +static ATTRIBUTE_NOINLINE void lsn_delay(size_t delay, size_t mult) noexcept +{ + delay*= mult * 2; // GCC 13.2.0 -O2 targeting AMD64 wants to unroll twice + HMT_low(); + do + MY_RELAX_CPU(); + while (--delay); + HMT_medium(); +} + +#if defined __clang_major__ && __clang_major__ < 10 +/* Only clang-10 introduced support for asm goto */ +#elif defined __APPLE__ +/* At least some versions of Apple Xcode do not support asm goto */ +#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__) +# if SIZEOF_SIZE_T == 8 +# define LOCK_TSET \ + __asm__ goto("lock btsq $63, %0\n\t" "jnc %l1" \ + : : "m"(buf_free) : "cc", "memory" : got) +# else +# define LOCK_TSET \ + __asm__ goto("lock btsl $31, %0\n\t" "jnc %l1" \ + : : "m"(buf_free) : "cc", "memory" : got) +# endif +#elif defined _MSC_VER && (defined _M_IX86 || defined _M_X64) +# if SIZEOF_SIZE_T == 8 +# define LOCK_TSET \ + if (!_interlockedbittestandset64 \ + (reinterpret_cast(&buf_free), 63)) return +# else +# define LOCK_TSET \ + if (!_interlockedbittestandset \ + (reinterpret_cast(&buf_free), 31)) return +# endif +#endif + +#ifdef LOCK_TSET +ATTRIBUTE_NOINLINE +void log_t::lsn_lock_bts() noexcept +{ + LOCK_TSET; + { + const size_t m= mtr_t::spin_wait_delay; + constexpr size_t DELAY= 10, MAX_ITERATIONS= 10; + for (size_t delay_count= DELAY, delay_iterations= 1;; + lsn_delay(delay_iterations, m)) + { + if (!(buf_free.load(std::memory_order_relaxed) & buf_free_LOCK)) + LOCK_TSET; + if (!delay_count); + else if (delay_iterations < MAX_ITERATIONS) + delay_count= DELAY, delay_iterations++; + else + delay_count--; + } + } + +# ifdef __GNUC__ + got: + return; +# endif +} + +inline +#else +ATTRIBUTE_NOINLINE +#endif +size_t log_t::lock_lsn() noexcept +{ +#ifdef LOCK_TSET + lsn_lock_bts(); + return ~buf_free_LOCK & buf_free.load(std::memory_order_relaxed); +# undef LOCK_TSET +#else + size_t b= buf_free.fetch_or(buf_free_LOCK, std::memory_order_acquire); + if (b & buf_free_LOCK) + { + const size_t m= mtr_t::spin_wait_delay; + constexpr size_t DELAY= 10, MAX_ITERATIONS= 10; + for (size_t delay_count= DELAY, delay_iterations= 1; + ((b= buf_free.load(std::memory_order_relaxed)) & buf_free_LOCK) || + (buf_free_LOCK & (b= buf_free.fetch_or(buf_free_LOCK, + std::memory_order_acquire))); + lsn_delay(delay_iterations, m)) + if (!delay_count); + else if (delay_iterations < MAX_ITERATIONS) + delay_count= DELAY, delay_iterations++; + else + delay_count--; + } + return b; +#endif +} + +template +ATTRIBUTE_COLD size_t log_t::append_prepare_wait(size_t b, bool ex, lsn_t lsn) + noexcept { waits++; - unlock_lsn(); + ut_ad(buf_free.load(std::memory_order_relaxed) == + (spin ? (b | buf_free_LOCK) : b)); + if (spin) + buf_free.store(b, std::memory_order_release); + else + lsn_lock.wr_unlock(); if (ex) latch.wr_unlock(); @@ -891,51 +1019,57 @@ ATTRIBUTE_COLD void log_t::append_prepare_wait(lsn_t lsn, bool ex) noexcept else latch.rd_lock(SRW_LOCK_CALL); - lock_lsn(); + if (spin) + return lock_lsn(); + + lsn_lock.wr_lock(); + return buf_free.load(std::memory_order_relaxed); } /** Reserve space in the log buffer for appending data. +@tparam spin whether to use the spin-only lock_lsn() @tparam pmem log_sys.is_pmem() @param size total length of the data to append(), in bytes @param ex whether log_sys.latch is exclusively locked @return the start LSN and the buffer position for append() */ -template +template inline std::pair log_t::append_prepare(size_t size, bool ex) noexcept { -#ifndef SUX_LOCK_GENERIC - ut_ad(latch.is_locked()); -# ifndef _WIN32 // there is no accurate is_write_locked() on SRWLOCK - ut_ad(ex == latch.is_write_locked()); -# endif -#endif + ut_ad(ex ? latch_have_wr() : latch_have_rd()); ut_ad(pmem == is_pmem()); - lock_lsn(); + if (!spin) + lsn_lock.wr_lock(); + size_t b{spin ? lock_lsn() : buf_free.load(std::memory_order_relaxed)}; write_to_buf++; const lsn_t l{lsn.load(std::memory_order_relaxed)}, end_lsn{l + size}; - size_t b{buf_free}; if (UNIV_UNLIKELY(pmem ? (end_lsn - get_flushed_lsn(std::memory_order_relaxed)) > capacity() : b + size >= buf_size)) - { - append_prepare_wait(l, ex); - b= buf_free; - } + b= append_prepare_wait(b, ex, l); - lsn.store(end_lsn, std::memory_order_relaxed); size_t new_buf_free= b + size; if (pmem && new_buf_free >= file_size) new_buf_free-= size_t(capacity()); - buf_free= new_buf_free; - unlock_lsn(); + + lsn.store(end_lsn, std::memory_order_relaxed); if (UNIV_UNLIKELY(end_lsn >= last_checkpoint_lsn + log_capacity)) - set_check_for_checkpoint(); + set_check_for_checkpoint(true); - return {l, &buf[b]}; + byte *our_buf= buf; + if (spin) + buf_free.store(new_buf_free, std::memory_order_release); + else + { + buf_free.store(new_buf_free, std::memory_order_relaxed); + lsn_lock.wr_unlock(); + } + + return {l, our_buf + b}; } /** Finish appending data to the log. @@ -943,9 +1077,7 @@ std::pair log_t::append_prepare(size_t size, bool ex) noexcept @return whether buf_flush_ahead() will have to be invoked */ static mtr_t::page_flush_ahead log_close(lsn_t lsn) noexcept { -#ifndef SUX_LOCK_GENERIC - ut_ad(log_sys.latch.is_locked()); -#endif + ut_ad(log_sys.latch_have_any()); const lsn_t checkpoint_age= lsn - log_sys.last_checkpoint_lsn; @@ -1010,9 +1142,7 @@ std::pair mtr_t::do_write() ut_ad(!recv_no_log_write); ut_ad(is_logged()); ut_ad(m_log.size()); -#ifndef SUX_LOCK_GENERIC - ut_ad(!m_latch_ex || log_sys.latch.is_write_locked()); -#endif + ut_ad(!m_latch_ex || log_sys.latch_have_wr()); #ifndef DBUG_OFF do @@ -1070,9 +1200,7 @@ func_exit: inline void log_t::resize_write(lsn_t lsn, const byte *end, size_t len, size_t seq) noexcept { -#ifndef SUX_LOCK_GENERIC - ut_ad(latch.is_locked()); -#endif + ut_ad(latch_have_any()); if (UNIV_LIKELY_NULL(resize_buf)) { @@ -1177,50 +1305,47 @@ inline void log_t::resize_write(lsn_t lsn, const byte *end, size_t len, } } +template std::pair -mtr_t::finish_write(size_t len) +mtr_t::finish_writer(mtr_t *mtr, size_t len) { + ut_ad(log_sys.is_latest()); ut_ad(!recv_no_log_write); - ut_ad(is_logged()); -#ifndef SUX_LOCK_GENERIC -# ifndef _WIN32 // there is no accurate is_write_locked() on SRWLOCK - ut_ad(m_latch_ex == log_sys.latch.is_write_locked()); -# endif -#endif + ut_ad(mtr->is_logged()); + ut_ad(mtr->m_latch_ex ? log_sys.latch_have_wr() : log_sys.latch_have_rd()); - const size_t size{m_commit_lsn ? 5U + 8U : 5U}; - std::pair start; + const size_t size{mtr->m_commit_lsn ? 5U + 8U : 5U}; + std::pair start= + log_sys.append_prepare(len, mtr->m_latch_ex); - if (!log_sys.is_pmem()) + if (!pmem) { - start= log_sys.append_prepare(len, m_latch_ex); - m_log.for_each_block([&start](const mtr_buf_t::block_t *b) + mtr->m_log.for_each_block([&start](const mtr_buf_t::block_t *b) { log_sys.append(start.second, b->begin(), b->used()); return true; }); #ifdef HAVE_PMEM write_trailer: #endif *start.second++= log_sys.get_sequence_bit(start.first + len - size); - if (m_commit_lsn) + if (mtr->m_commit_lsn) { - mach_write_to_8(start.second, m_commit_lsn); - m_crc= my_crc32c(m_crc, start.second, 8); + mach_write_to_8(start.second, mtr->m_commit_lsn); + mtr->m_crc= my_crc32c(mtr->m_crc, start.second, 8); start.second+= 8; } - mach_write_to_4(start.second, m_crc); + mach_write_to_4(start.second, mtr->m_crc); start.second+= 4; } #ifdef HAVE_PMEM else { - start= log_sys.append_prepare(len, m_latch_ex); if (UNIV_LIKELY(start.second + len <= &log_sys.buf[log_sys.file_size])) { - m_log.for_each_block([&start](const mtr_buf_t::block_t *b) + mtr->m_log.for_each_block([&start](const mtr_buf_t::block_t *b) { log_sys.append(start.second, b->begin(), b->used()); return true; }); goto write_trailer; } - m_log.for_each_block([&start](const mtr_buf_t::block_t *b) + mtr->m_log.for_each_block([&start](const mtr_buf_t::block_t *b) { size_t size{b->used()}; const size_t size_left(&log_sys.buf[log_sys.file_size] - start.second); @@ -1243,14 +1368,14 @@ mtr_t::finish_write(size_t len) byte tail[5 + 8]; tail[0]= log_sys.get_sequence_bit(start.first + len - size); - if (m_commit_lsn) + if (mtr->m_commit_lsn) { - mach_write_to_8(tail + 1, m_commit_lsn); - m_crc= my_crc32c(m_crc, tail + 1, 8); - mach_write_to_4(tail + 9, m_crc); + mach_write_to_8(tail + 1, mtr->m_commit_lsn); + mtr->m_crc= my_crc32c(mtr->m_crc, tail + 1, 8); + mach_write_to_4(tail + 9, mtr->m_crc); } else - mach_write_to_4(tail + 1, m_crc); + mach_write_to_4(tail + 1, mtr->m_crc); ::memcpy(start.second, tail, size_left); ::memcpy(log_sys.buf + log_sys.START_OFFSET, tail + size_left, @@ -1259,12 +1384,14 @@ mtr_t::finish_write(size_t len) ((size >= size_left) ? log_sys.START_OFFSET : log_sys.file_size) + (size - size_left); } +#else + static_assert(!pmem, ""); #endif log_sys.resize_write(start.first, start.second, len, size); - m_commit_lsn= start.first + len; - return {start.first, log_close(m_commit_lsn)}; + mtr->m_commit_lsn= start.first + len; + return {start.first, log_close(mtr->m_commit_lsn)}; } bool mtr_t::have_x_latch(const buf_block_t &block) const @@ -1386,7 +1513,7 @@ void mtr_t::upgrade_buffer_fix(ulint savepoint, rw_lock_type_t rw_latch) ut_ad(slot.type == MTR_MEMO_BUF_FIX); buf_block_t *block= static_cast(slot.object); ut_d(const auto state= block->page.state()); - ut_ad(state > buf_page_t::UNFIXED); + ut_ad(state > buf_page_t::FREED); ut_ad(state > buf_page_t::WRITE_FIX || state < buf_page_t::READ_FIX); static_assert(int{MTR_MEMO_PAGE_S_FIX} == int{RW_S_LATCH}, ""); static_assert(int{MTR_MEMO_PAGE_X_FIX} == int{RW_X_LATCH}, ""); diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index bd9ed24f14b..8f067110099 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -202,17 +202,10 @@ os_file_handle_error_cond_exit( bool on_error_silent); /** Does error handling when a file operation fails. -@param[in] name name of a file or NULL -@param[in] operation operation name that failed -@return true if we should retry the operation */ -static -bool -os_file_handle_error( - const char* name, - const char* operation) +@param operation name of operation that failed */ +static void os_file_handle_error(const char *operation) { - /* Exit in case of unknown error */ - return(os_file_handle_error_cond_exit(name, operation, true, false)); + os_file_handle_error_cond_exit(nullptr, operation, true, false); } /** Does error handling when a file operation fails. @@ -329,6 +322,12 @@ private: ssize_t m_n; /** Offset from where to read/write */ os_offset_t m_offset; + + /** Do the read/write + @param request The IO context and type + @param n Number of bytes to read/write + @return the number of bytes read/written or negative value on error */ + ssize_t execute_low(const IORequest& request, ssize_t n); }; #ifndef _WIN32 /* On Microsoft Windows, mandatory locking is used */ @@ -680,30 +679,48 @@ os_file_create_subdirs_if_needed( +/** Do the read/write +@param[in] request The IO context and type +@param[in] n Number of bytes to read/write +@return the number of bytes read/written or negative value on error */ +ssize_t +SyncFileIO::execute_low(const IORequest& request, ssize_t n) +{ + ut_ad(n > 0); + ut_ad(size_t(n) <= os_file_request_size_max); + + if (request.is_read()) + return IF_WIN(tpool::pread(m_fh, m_buf, n, m_offset), pread(m_fh, m_buf, n, m_offset)); + return IF_WIN(tpool::pwrite(m_fh, m_buf, n, m_offset), pwrite(m_fh, m_buf, n, m_offset)); +} + /** Do the read/write @param[in] request The IO context and type @return the number of bytes read/written or negative value on error */ ssize_t SyncFileIO::execute(const IORequest& request) { - ssize_t n_bytes; + ssize_t n_bytes= 0; + ut_ad(m_n > 0); - if (request.is_read()) { -#ifdef _WIN32 - n_bytes = tpool::pread(m_fh, m_buf, m_n, m_offset); -#else - n_bytes = pread(m_fh, m_buf, m_n, m_offset); -#endif - } else { - ut_ad(request.is_write()); -#ifdef _WIN32 - n_bytes = tpool::pwrite(m_fh, m_buf, m_n, m_offset); -#else - n_bytes = pwrite(m_fh, m_buf, m_n, m_offset); -#endif - } + while (size_t(m_n) > os_file_request_size_max) + { + ssize_t n_partial_bytes= execute_low(request, os_file_request_size_max); + if (n_partial_bytes < 0) + return n_partial_bytes; + n_bytes+= n_partial_bytes; + if (n_partial_bytes != os_file_request_size_max) + return n_bytes; + advance(os_file_request_size_max); + } - return(n_bytes); + if (ssize_t n= execute_low(request, m_n)) + { + if (n < 0) + return n; + n_bytes += n; + } + return n_bytes; } #ifndef _WIN32 @@ -946,7 +963,7 @@ os_file_flush_func( ib::error() << "The OS said file flush did not succeed"; - os_file_handle_error(NULL, "flush"); + os_file_handle_error("flush"); /* It is a fatal error if a file flush does not succeed, because then the database can get corrupt on disk */ @@ -969,7 +986,7 @@ A simple function to open or create a file. pfs_os_file_t os_file_create_simple_func( const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint access_type, bool read_only, bool* success) @@ -978,45 +995,18 @@ os_file_create_simple_func( *success = false; - int create_flag = O_RDONLY; - - ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT)); - ut_a(!(create_mode & OS_FILE_ON_ERROR_NO_EXIT)); + int create_flag = O_RDONLY | O_CLOEXEC; if (read_only) { - } else if (create_mode == OS_FILE_OPEN) { - if (access_type != OS_FILE_READ_ONLY) { - create_flag = O_RDWR; - } } else if (create_mode == OS_FILE_CREATE) { - create_flag = O_RDWR | O_CREAT | O_EXCL; - } else if (create_mode == OS_FILE_CREATE_PATH) { - /* Create subdirs along the path if needed. */ - - *success = os_file_create_subdirs_if_needed(name); - - if (!*success) { - - ib::error() - << "Unable to create subdirectories '" - << name << "'"; - - return(OS_FILE_CLOSED); - } - - create_flag = O_RDWR | O_CREAT | O_EXCL; - create_mode = OS_FILE_CREATE; + create_flag = O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC; } else { - - ib::error() - << "Unknown file create mode (" - << create_mode - << " for file '" << name << "'"; - - return(OS_FILE_CLOSED); + ut_ad(create_mode == OS_FILE_OPEN); + if (access_type != OS_FILE_READ_ONLY) { + create_flag = O_RDWR | O_CLOEXEC; + } } - create_flag |= O_CLOEXEC; if (fil_system.is_write_through()) create_flag |= O_DSYNC; #ifdef O_DIRECT int direct_flag = fil_system.is_buffered() ? 0 : O_DIRECT; @@ -1035,11 +1025,10 @@ os_file_create_simple_func( } #endif - *success = false; - if (!os_file_handle_error( - name, - create_mode == OS_FILE_OPEN - ? "open" : "create")) { + if (!os_file_handle_error_no_exit( + name, + create_mode == OS_FILE_CREATE + ? "create" : "open", false)) { break; } } else { @@ -1091,6 +1080,61 @@ os_file_create_directory( return(true); } +#ifdef O_DIRECT +# ifdef __linux__ +/** Note that the log file uses buffered I/O. */ +static ATTRIBUTE_COLD void os_file_log_buffered() +{ + log_sys.log_maybe_unbuffered= false; + log_sys.log_buffered= true; + log_sys.set_block_size(512); +} +# endif + +/** @return whether the log file may work with unbuffered I/O. */ +static ATTRIBUTE_COLD bool os_file_log_maybe_unbuffered(const struct stat &st) +{ + MSAN_STAT_WORKAROUND(&st); +# ifdef __linux__ + char b[20 + sizeof "/sys/dev/block/" ":" "/../queue/physical_block_size"]; + if (snprintf(b, sizeof b, "/sys/dev/block/%u:%u/queue/physical_block_size", + major(st.st_dev), minor(st.st_dev)) >= + static_cast(sizeof b)) + return false; + int f= open(b, O_RDONLY); + if (f == -1) + { + if (snprintf(b, sizeof b, "/sys/dev/block/%u:%u/../queue/" + "physical_block_size", + major(st.st_dev), minor(st.st_dev)) >= + static_cast(sizeof b)) + return false; + f= open(b, O_RDONLY); + } + unsigned long s= 0; + if (f != -1) + { + ssize_t l= read(f, b, sizeof b); + if (l > 0 && size_t(l) < sizeof b && b[l - 1] == '\n') + { + char *end= b; + s= strtoul(b, &end, 10); + if (b == end || *end != '\n') + s = 0; + } + close(f); + } + if (s > 4096 || s < 64 || !ut_is_2pow(s)) + return false; + log_sys.set_block_size(uint32_t(s)); +# else + constexpr unsigned long s= 4096; +# endif + + return !(st.st_size & (s - 1)); +} +#endif + /** NOTE! Use the corresponding macro os_file_create(), not directly this function! Opens an existing file or creates a new. @@ -1111,78 +1155,78 @@ Opens an existing file or creates a new. pfs_os_file_t os_file_create_func( const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint purpose, ulint type, bool read_only, bool* success) { - bool on_error_no_exit; - bool on_error_silent; - *success = false; DBUG_EXECUTE_IF( "ib_create_table_fail_disk_full", - *success = false; errno = ENOSPC; return(OS_FILE_CLOSED); ); - int create_flag = O_RDONLY | O_CLOEXEC; -#ifdef HAVE_FCNTL_DIRECT - const char* mode_str = "OPEN"; -#endif - - on_error_no_exit = create_mode & OS_FILE_ON_ERROR_NO_EXIT - ? true : false; - on_error_silent = create_mode & OS_FILE_ON_ERROR_SILENT - ? true : false; - - create_mode &= ulint(~(OS_FILE_ON_ERROR_NO_EXIT - | OS_FILE_ON_ERROR_SILENT)); + int create_flag; if (read_only) { - } else if (create_mode == OS_FILE_OPEN - || create_mode == OS_FILE_OPEN_RAW - || create_mode == OS_FILE_OPEN_RETRY) { - create_flag = O_RDWR | O_CLOEXEC; - } else if (create_mode == OS_FILE_CREATE) { -#ifdef HAVE_FCNTL_DIRECT - mode_str = "CREATE"; -#endif + create_flag = O_RDONLY | O_CLOEXEC; + } else if (create_mode == OS_FILE_CREATE + || create_mode == OS_FILE_CREATE_SILENT) { create_flag = O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC; - } else if (create_mode == OS_FILE_OVERWRITE) { -#ifdef HAVE_FCNTL_DIRECT - mode_str = "OVERWRITE"; -#endif - create_flag = O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC; } else { - ib::error() - << "Unknown file create mode (" << create_mode << ")" - << " for file '" << name << "'"; - - return(OS_FILE_CLOSED); + ut_ad(create_mode == OS_FILE_OPEN + || create_mode == OS_FILE_OPEN_SILENT + || create_mode == OS_FILE_OPEN_RETRY + || create_mode == OS_FILE_OPEN_RETRY_SILENT + || create_mode == OS_FILE_OPEN_RAW); + create_flag = O_RDWR | O_CLOEXEC; } ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL); - create_flag |= O_CLOEXEC; - -#ifdef HAVE_FCNTL_DIRECT +#ifdef O_DIRECT + struct stat st; ut_a(type == OS_LOG_FILE - || type == OS_DATA_FILE - || type == OS_DATA_FILE_NO_O_DIRECT); - int direct_flag = type == OS_DATA_FILE && create_mode != OS_FILE_CREATE - && !fil_system.is_buffered() - ? O_DIRECT : 0; + || type == OS_DATA_FILE || type == OS_DATA_FILE_NO_O_DIRECT); + int direct_flag = 0; + + if (type == OS_DATA_FILE) { + if (!fil_system.is_buffered()) { + direct_flag = O_DIRECT; + } +# ifdef __linux__ + } else if (type != OS_LOG_FILE) { + } else if (log_sys.log_buffered) { + skip_o_direct: + os_file_log_buffered(); + } else if (create_mode != OS_FILE_CREATE + && create_mode != OS_FILE_CREATE_SILENT + && !log_sys.is_opened()) { + if (stat(name, &st)) { + if (errno == ENOENT) { + goto not_found; + } + goto skip_o_direct; + } + + if (!os_file_log_maybe_unbuffered(st)) { + goto skip_o_direct; + } + + direct_flag = O_DIRECT; + log_sys.log_maybe_unbuffered= true; +# endif + } #else ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE); constexpr int direct_flag = 0; #endif if (read_only) { - } else if ((type == OS_LOG_FILE) + } else if (type == OS_LOG_FILE ? log_sys.log_write_through : fil_system.is_write_through()) { create_flag |= O_DSYNC; @@ -1194,97 +1238,49 @@ os_file_create_func( file = open(name, create_flag | direct_flag, os_innodb_umask); if (file == -1) { -#ifdef HAVE_FCNTL_DIRECT +#ifdef O_DIRECT if (direct_flag && errno == EINVAL) { direct_flag = 0; +# ifdef __linux__ + if (type == OS_LOG_FILE) { + os_file_log_buffered(); + } +# endif + if (create_mode == OS_FILE_CREATE + || create_mode == OS_FILE_CREATE_SILENT) { + /* Linux may create the file + before rejecting the O_DIRECT. */ + unlink(name); + } continue; } +# ifdef __linux__ +not_found: +# endif #endif - - const char* operation; - - operation = (create_mode == OS_FILE_CREATE - && !read_only) ? "create" : "open"; - - *success = false; - - if (on_error_no_exit) { - if (os_file_handle_error_no_exit( - name, operation, on_error_silent)) - continue; - } else { - if (os_file_handle_error(name, operation)) - continue; + if (os_file_handle_error_no_exit( + name, (create_flag & O_CREAT) + ? "create" : "open", + create_mode & OS_FILE_ON_ERROR_SILENT)) { + continue; } - return file; + return OS_FILE_CLOSED; } else { *success = true; break; } } -#ifdef HAVE_FCNTL_DIRECT - if (type == OS_DATA_FILE && create_mode == OS_FILE_CREATE - && !fil_system.is_buffered()) { -# ifdef __linux__ -use_o_direct: -# endif - os_file_set_nocache(file, name, mode_str); -# ifdef __linux__ - } else if (type == OS_LOG_FILE && !log_sys.is_opened()) { - struct stat st; - char b[20 + sizeof "/sys/dev/block/" ":" - "/../queue/physical_block_size"]; - int f; - if (fstat(file, &st)) { - goto skip_o_direct; - } - MSAN_STAT_WORKAROUND(&st); - if (snprintf(b, sizeof b, - "/sys/dev/block/%u:%u/queue/physical_block_size", - major(st.st_dev), minor(st.st_dev)) - >= static_cast(sizeof b)) { - goto skip_o_direct; - } - if ((f = open(b, O_RDONLY)) == -1) { - if (snprintf(b, sizeof b, - "/sys/dev/block/%u:%u/../queue/" - "physical_block_size", - major(st.st_dev), minor(st.st_dev)) - >= static_cast(sizeof b)) { - goto skip_o_direct; - } - f = open(b, O_RDONLY); - } - if (f != -1) { - ssize_t l = read(f, b, sizeof b); - unsigned long s = 0; - - if (l > 0 && static_cast(l) < sizeof b - && b[l - 1] == '\n') { - char* end = b; - s = strtoul(b, &end, 10); - if (b == end || *end != '\n') { - s = 0; - } - } - close(f); - if (s > 4096 || s < 64 || !ut_is_2pow(s)) { - goto skip_o_direct; - } - log_sys.log_maybe_unbuffered= true; - log_sys.set_block_size(uint32_t(s)); - if (!log_sys.log_buffered && !(st.st_size & (s - 1))) { - goto use_o_direct; - } +#ifdef __linux__ + if ((create_flag & O_CREAT) && type == OS_LOG_FILE) { + if (fstat(file, &st) || !os_file_log_maybe_unbuffered(st)) { + os_file_log_buffered(); } else { -skip_o_direct: - log_sys.log_maybe_unbuffered= false; - log_sys.log_buffered= true; - log_sys.set_block_size(512); + close(file); + return os_file_create_func(name, OS_FILE_OPEN, purpose, + type, false, success); } -# endif } #endif @@ -1293,7 +1289,8 @@ skip_o_direct: && !my_disable_locking && os_file_lock(file, name)) { - if (create_mode == OS_FILE_OPEN_RETRY) { + if (create_mode == OS_FILE_OPEN_RETRY + || create_mode == OS_FILE_OPEN_RETRY_SILENT) { ib::info() << "Retrying to lock the first data file"; @@ -1324,7 +1321,7 @@ os_file_create_simple_no_error_handling(), not directly this function! A simple function to open or create a file. @param[in] name name of the file or path as a null-terminated string -@param[in] create_mode create mode +@param[in] create_mode OS_FILE_CREATE or OS_FILE_OPEN @param[in] access_type OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or OS_FILE_READ_ALLOW_DELETE; the last option is used by a backup program reading the file @@ -1335,59 +1332,33 @@ A simple function to open or create a file. pfs_os_file_t os_file_create_simple_no_error_handling_func( const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint access_type, bool read_only, bool* success) { os_file_t file; - int create_flag; - - ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT)); - ut_a(!(create_mode & OS_FILE_ON_ERROR_NO_EXIT)); + int create_flag = O_RDONLY | O_CLOEXEC; *success = false; - if (create_mode == OS_FILE_OPEN) { - - if (access_type == OS_FILE_READ_ONLY) { - - create_flag = O_RDONLY; - - } else if (read_only) { - - create_flag = O_RDONLY; - - } else { - + if (read_only) { + } else if (create_mode == OS_FILE_CREATE) { + create_flag = O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC; + } else { + ut_ad(create_mode == OS_FILE_OPEN); + if (access_type != OS_FILE_READ_ONLY) { ut_a(access_type == OS_FILE_READ_WRITE || access_type == OS_FILE_READ_ALLOW_DELETE); create_flag = O_RDWR; } - - } else if (read_only) { - - create_flag = O_RDONLY; - - } else if (create_mode == OS_FILE_CREATE) { - - create_flag = O_RDWR | O_CREAT | O_EXCL; - - } else { - - ib::error() - << "Unknown file create mode " - << create_mode << " for file '" << name << "'"; - - return(OS_FILE_CLOSED); } - file = open(name, create_flag | O_CLOEXEC, os_innodb_umask); + file = open(name, create_flag, os_innodb_umask); *success = (file != -1); -#ifndef _WIN32 if (!read_only && *success && access_type == OS_FILE_READ_WRITE @@ -1399,7 +1370,6 @@ os_file_create_simple_no_error_handling_func( file = -1; } -#endif /* !_WIN32 */ return(file); } @@ -1505,7 +1475,7 @@ bool os_file_close_func(os_file_t file) if (!ret) return true; - os_file_handle_error(NULL, "close"); + os_file_handle_error("close"); return false; } @@ -1781,7 +1751,7 @@ bool os_file_flush_func(os_file_t file) if (srv_start_raw_disk_in_use && GetLastError() == ERROR_INVALID_FUNCTION) return true; - os_file_handle_error(nullptr, "flush"); + os_file_handle_error("flush"); /* It is a fatal error if a file flush does not succeed, because then the database can get corrupt on disk */ @@ -1895,7 +1865,7 @@ A simple function to open or create a file. pfs_os_file_t os_file_create_simple_func( const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint access_type, bool read_only, bool* success) @@ -1904,77 +1874,28 @@ os_file_create_simple_func( *success = false; - DWORD access; + DWORD access = GENERIC_READ; DWORD create_flag; DWORD attributes = 0; - ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT)); - ut_a(!(create_mode & OS_FILE_ON_ERROR_NO_EXIT)); ut_ad(srv_operation == SRV_OPERATION_NORMAL); - if (create_mode == OS_FILE_OPEN) { - + if (read_only || create_mode == OS_FILE_OPEN) { create_flag = OPEN_EXISTING; - - } else if (read_only) { - - create_flag = OPEN_EXISTING; - - } else if (create_mode == OS_FILE_CREATE) { - - create_flag = CREATE_NEW; - - } else if (create_mode == OS_FILE_CREATE_PATH) { - - /* Create subdirs along the path if needed. */ - *success = os_file_create_subdirs_if_needed(name); - - if (!*success) { - - ib::error() - << "Unable to create subdirectories '" - << name << "'"; - - return(OS_FILE_CLOSED); - } - - create_flag = CREATE_NEW; - create_mode = OS_FILE_CREATE; - } else { - - ib::error() - << "Unknown file create mode (" - << create_mode << ") for file '" - << name << "'"; - - return(OS_FILE_CLOSED); + ut_ad(create_mode == OS_FILE_CREATE); + create_flag = CREATE_NEW; } if (access_type == OS_FILE_READ_ONLY) { - - access = GENERIC_READ; - } else if (read_only) { - ib::info() << "Read only mode set. Unable to" " open file '" << name << "' in RW mode, " << "trying RO mode"; - - access = GENERIC_READ; - - } else if (access_type == OS_FILE_READ_WRITE) { - - access = GENERIC_READ | GENERIC_WRITE; - } else { - - ib::error() - << "Unknown file access type (" << access_type << ") " - "for file '" << name << "'"; - - return(OS_FILE_CLOSED); + ut_ad(access_type == OS_FILE_READ_WRITE); + access = GENERIC_READ | GENERIC_WRITE; } if (fil_system.is_write_through()) @@ -1982,9 +1903,7 @@ os_file_create_simple_func( if (!fil_system.is_buffered()) attributes |= FILE_FLAG_NO_BUFFERING; - bool retry; - - do { + for (;;) { /* Use default security attributes and no template file. */ file = CreateFile( @@ -1992,22 +1911,18 @@ os_file_create_simple_func( FILE_SHARE_READ | FILE_SHARE_DELETE, my_win_file_secattr(), create_flag, attributes, NULL); - if (file == INVALID_HANDLE_VALUE) { - - *success = false; - - retry = os_file_handle_error( - name, create_mode == OS_FILE_OPEN ? - "open" : "create"); - - } else { - - retry = false; - + if (file != INVALID_HANDLE_VALUE) { *success = true; + break; } - } while (retry); + if (!os_file_handle_error_no_exit(name, + create_flag == CREATE_NEW + ? "create" : "open", + false)) { + break; + } + } return(file); } @@ -2076,16 +1991,13 @@ Opens an existing file or creates a new. pfs_os_file_t os_file_create_func( const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint purpose, ulint type, bool read_only, bool* success) { os_file_t file; - bool retry; - bool on_error_no_exit; - bool on_error_silent; *success = false; @@ -2096,54 +2008,30 @@ os_file_create_func( return(OS_FILE_CLOSED); ); - DWORD create_flag; + DWORD create_flag = OPEN_EXISTING; DWORD share_mode = read_only ? FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE : FILE_SHARE_READ | FILE_SHARE_DELETE; - on_error_no_exit = create_mode & OS_FILE_ON_ERROR_NO_EXIT - ? true : false; - - on_error_silent = create_mode & OS_FILE_ON_ERROR_SILENT - ? true : false; - - create_mode &= ~(OS_FILE_ON_ERROR_NO_EXIT | OS_FILE_ON_ERROR_SILENT); - - if (create_mode == OS_FILE_OPEN_RAW) { - + switch (create_mode) { + case OS_FILE_OPEN_RAW: ut_a(!read_only); - /* On Windows Physical devices require admin privileges and have to have the write-share mode set. See the remarks section for the CreateFile() function documentation in MSDN. */ share_mode |= FILE_SHARE_WRITE; - - create_flag = OPEN_EXISTING; - - } else if (create_mode == OS_FILE_OPEN - || create_mode == OS_FILE_OPEN_RETRY) { - - create_flag = OPEN_EXISTING; - - } else if (read_only) { - - create_flag = OPEN_EXISTING; - - } else if (create_mode == OS_FILE_CREATE) { - + break; + case OS_FILE_CREATE_SILENT: + case OS_FILE_CREATE: create_flag = CREATE_NEW; - - } else if (create_mode == OS_FILE_OVERWRITE) { - - create_flag = CREATE_ALWAYS; - - } else { - ib::error() - << "Unknown file create mode (" << create_mode << ") " - << " for file '" << name << "'"; - - return(OS_FILE_CLOSED); + break; + default: + ut_ad(create_mode == OS_FILE_OPEN + || create_mode == OS_FILE_OPEN_SILENT + || create_mode == OS_FILE_OPEN_RETRY_SILENT + || create_mode == OS_FILE_OPEN_RETRY); + break; } DWORD attributes = (purpose == OS_FILE_AIO && srv_use_native_aio) @@ -2192,18 +2080,11 @@ os_file_create_func( break; } - operation = (create_mode == OS_FILE_CREATE && !read_only) ? - "create" : "open"; + operation = create_flag == CREATE_NEW ? "create" : "open"; - if (on_error_no_exit) { - retry = os_file_handle_error_no_exit( - name, operation, on_error_silent); - } - else { - retry = os_file_handle_error(name, operation); - } - - if (!retry) { + if (!os_file_handle_error_no_exit(name, operation, + create_mode + & OS_FILE_ON_ERROR_SILENT)) { break; } } @@ -2230,79 +2111,42 @@ A simple function to open or create a file. pfs_os_file_t os_file_create_simple_no_error_handling_func( const char* name, - ulint create_mode, + os_file_create_t create_mode, ulint access_type, bool read_only, bool* success) { os_file_t file; - *success = false; - - DWORD access; - DWORD create_flag; + DWORD access = GENERIC_READ; + DWORD create_flag = OPEN_EXISTING; DWORD attributes = 0; - DWORD share_mode = read_only - ? FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE - : FILE_SHARE_READ | FILE_SHARE_DELETE; + DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_DELETE; ut_a(name); - ut_a(!(create_mode & OS_FILE_ON_ERROR_SILENT)); - ut_a(!(create_mode & OS_FILE_ON_ERROR_NO_EXIT)); - - if (create_mode == OS_FILE_OPEN) { - - create_flag = OPEN_EXISTING; - - } else if (read_only) { - - create_flag = OPEN_EXISTING; - - } else if (create_mode == OS_FILE_CREATE) { - - create_flag = CREATE_NEW; - + if (read_only) { + share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE + | FILE_SHARE_DELETE; } else { + if (create_mode == OS_FILE_CREATE) { + create_flag = CREATE_NEW; + } else { + ut_ad(create_mode == OS_FILE_OPEN); + } - ib::error() - << "Unknown file create mode (" << create_mode << ") " - << " for file '" << name << "'"; - - return(OS_FILE_CLOSED); - } - - if (access_type == OS_FILE_READ_ONLY) { - - access = GENERIC_READ; - - } else if (read_only) { - - access = GENERIC_READ; - - } else if (access_type == OS_FILE_READ_WRITE) { - - access = GENERIC_READ | GENERIC_WRITE; - - } else if (access_type == OS_FILE_READ_ALLOW_DELETE) { - - ut_a(!read_only); - - access = GENERIC_READ; - - /*!< A backup program has to give mysqld the maximum - freedom to do what it likes with the file */ - - share_mode |= FILE_SHARE_DELETE | FILE_SHARE_WRITE - | FILE_SHARE_READ; - - } else { - - ib::error() - << "Unknown file access type (" << access_type << ") " - << "for file '" << name << "'"; - - return(OS_FILE_CLOSED); + switch (access_type) { + case OS_FILE_READ_ONLY: break; + case OS_FILE_READ_WRITE: + access = GENERIC_READ | GENERIC_WRITE; + break; + default: + ut_ad(access_type == OS_FILE_READ_ALLOW_DELETE); + /* A backup program has to give mariadbd the maximum + freedom to do what it likes with the file */ + share_mode |= FILE_SHARE_DELETE | FILE_SHARE_WRITE + | FILE_SHARE_READ; + } } file = CreateFile((LPCTSTR) name, @@ -2470,7 +2314,7 @@ bool os_file_close_func(os_file_t file) ut_ad(file); if (!CloseHandle(file)) { - os_file_handle_error(NULL, "close"); + os_file_handle_error("close"); return false; } @@ -2908,8 +2752,8 @@ os_file_read_func( if (ulint(n_bytes) == n || err != DB_SUCCESS) return err; - os_file_handle_error_cond_exit(type.node ? type.node->name : nullptr, "read", - false, false); + os_file_handle_error_no_exit(type.node ? type.node->name : nullptr, "read", + false); sql_print_error("InnoDB: Tried to read %zu bytes at offset %llu" " of file %s, but was only able to read %zd", n, offset, type.node ? type.node->name : "(unknown)", @@ -3012,36 +2856,6 @@ os_file_handle_error_cond_exit( return(false); } -#ifdef HAVE_FCNTL_DIRECT -/** Tries to disable OS caching on an opened file descriptor. -@param[in] fd file descriptor to alter -@param[in] file_name file name, used in the diagnostic message -@param[in] name "open" or "create"; used in the diagnostic - message */ -void -os_file_set_nocache(int fd, const char *file_name, const char *operation_name) -{ - if (fcntl(fd, F_SETFL, O_DIRECT) == -1) { - int errno_save = errno; - static bool warning_message_printed = false; - if (errno_save == EINVAL) { - if (!warning_message_printed) { - warning_message_printed = true; - ib::info() - << "Setting O_DIRECT on file " - << file_name << " failed"; - } - } else { - ib::warn() - << "Failed to set O_DIRECT on file " - << file_name << "; " << operation_name - << " : " << strerror(errno_save) - << ", continuing anyway."; - } - } -} -#endif /* HAVE_FCNTL_DIRECT */ - /** Check if the file system supports sparse files. @param fh file handle @return true if the file system supports sparse files */ @@ -3826,8 +3640,9 @@ func_exit: if (srv_thread_pool->submit_io(cb)) { slots->release(cb); - os_file_handle_error(type.node->name, type.is_read() - ? "aio read" : "aio write"); + os_file_handle_error_no_exit(type.node->name, type.is_read() + ? "aio read" : "aio write", + false); err = DB_IO_ERROR; type.node->space->release(); } diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index 830a4bef9d9..4eda832253b 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -3265,7 +3265,6 @@ page_zip_validate_low( ibool sloppy) /*!< in: FALSE=strict, TRUE=ignore the MIN_REC_FLAG */ { - page_zip_des_t temp_page_zip; ibool valid; if (memcmp(page_zip->data + FIL_PAGE_PREV, page + FIL_PAGE_PREV, @@ -3306,7 +3305,7 @@ page_zip_validate_low( MEM_CHECK_DEFINED(page, srv_page_size); MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip)); - temp_page_zip = *page_zip; + page_zip_des_t temp_page_zip(*page_zip); valid = page_zip_decompress_low(&temp_page_zip, temp_page, TRUE); if (!valid) { fputs("page_zip_validate(): failed to decompress\n", stderr); diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc index ca81c910c69..46dcfb1ba83 100644 --- a/storage/innobase/rem/rem0rec.cc +++ b/storage/innobase/rem/rem0rec.cc @@ -427,7 +427,7 @@ start: } if (!field->fixed_len - || (format == REC_LEAF_TEMP + || (format <= REC_LEAF_TEMP_INSTANT && !dict_col_get_fixed_size(col, true))) { /* Variable-length field: read the length */ len = *lens--; diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index d3c8839e500..5febd6dfa27 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -45,9 +45,11 @@ Created 2012-02-08 by Sunny Bains. #include "lzo/lzo1x.h" #include "snappy-c.h" #include "log.h" +#include "table.h" +#include "ha_innodb.h" #include "scope.h" - +#include "dict0crea.h" #include #ifdef HAVE_MY_AES_H @@ -192,6 +194,60 @@ struct row_import { dberr_t match_flags(THD *thd) const ; + ulint find_fts_idx_offset() const + { + for (ulint i= 0; i < m_n_indexes; i++) + { + const char* index_name= + reinterpret_cast(m_indexes[i].m_name); + if (!strcmp(index_name, FTS_DOC_ID_INDEX_NAME)) + return i; + } + return ULINT_UNDEFINED; + } + + const row_index_t *find_index_by_name(const char *name) const + { + for (ulint i= 0; i < m_n_indexes; i++) + { + const char* index_name= + reinterpret_cast(m_indexes[i].m_name); + if (!strcmp(index_name, name)) + return &m_indexes[i]; + } + return nullptr; + } + + /** @return whether cfg file has FTS_DOC_ID + & FTS_DOC_ID_INDEX*/ + bool has_hidden_fts() const + { + if (m_missing) return false; + ulint col_offset= find_col(FTS_DOC_ID_COL_NAME); + if (col_offset == ULINT_UNDEFINED) return false; + + const dict_col_t *col= &m_cols[col_offset]; + if (col->mtype != DATA_INT + || (col->prtype & ~(DATA_NOT_NULL + | DATA_UNSIGNED | DATA_BINARY_TYPE + | DATA_FTS_DOC_ID)) + || col->len != sizeof(doc_id_t)) + return false; + + return find_index_by_name(FTS_DOC_ID_INDEX_NAME) != nullptr; + } + + /** Need to check whether the table need to add system + generated fts column and system generated fts document index + @param table table to be imported + @return whether the table has to add system generated + fts column and fts index */ + bool need_hidden_fts(dict_table_t *table) const + { + return has_hidden_fts() && !table->fts_doc_id_index && + m_n_cols == static_cast(table->n_cols + 1) && + m_n_indexes == UT_LIST_GET_LEN(table->indexes) + 1; + } dict_table_t* m_table; /*!< Table instance */ @@ -548,7 +604,7 @@ protected: if (m_xdes != 0) { const xdes_t* xdesc = xdes(page_no, m_xdes); - ulint pos = page_no % FSP_EXTENT_SIZE; + uint32_t pos = page_no % FSP_EXTENT_SIZE; return xdes_is_free(xdesc, pos); } @@ -1109,7 +1165,6 @@ row_import::find_col( return(i); } } - return(ULINT_UNDEFINED); } @@ -1830,14 +1885,39 @@ PageConverter::update_records( bool clust_index = m_index->m_srv_index == m_cluster_index; /* This will also position the cursor on the first user record. */ + rec_t* rec = m_rec_iter.open(block, m_index->m_srv_index); - if (!m_rec_iter.open(block, m_index->m_srv_index)) { + if (!rec) { return DB_CORRUPTION; } + ulint deleted; + + if (!page_has_prev(block->page.frame) + && m_index->m_srv_index->is_instant()) { + /* Expect to find the hidden metadata record */ + if (page_rec_is_supremum(rec)) { + return DB_CORRUPTION; + } + + const ulint info_bits = rec_get_info_bits(rec, comp); + + if (!(info_bits & REC_INFO_MIN_REC_FLAG)) { + return DB_CORRUPTION; + } + + if (!(info_bits & REC_INFO_DELETED_FLAG) + != !m_index->m_srv_index->table->instant) { + return DB_CORRUPTION; + } + + deleted = 0; + goto first; + } + while (!m_rec_iter.end()) { - rec_t* rec = m_rec_iter.current(); - ibool deleted = rec_get_deleted_flag(rec, comp); + rec = m_rec_iter.current(); + deleted = rec_get_deleted_flag(rec, comp); /* For the clustered index we have to adjust the BLOB reference and the system fields irrespective of the @@ -1845,6 +1925,7 @@ PageConverter::update_records( cluster records is required for purge to work later. */ if (deleted || clust_index) { +first: m_offsets = rec_get_offsets( rec, m_index->m_srv_index, m_offsets, m_index->m_srv_index->n_core_fields, @@ -2131,14 +2212,30 @@ dberr_t PageConverter::operator()(buf_block_t* block) UNIV_NOTHROW return DB_SUCCESS; } -/*****************************************************************//** -Clean up after import tablespace. */ -static MY_ATTRIBUTE((nonnull, warn_unused_result)) +static void reload_fts_table(row_prebuilt_t *prebuilt, + dict_table_t* table) +{ + ut_ad(prebuilt->table != table); + /* Reload the table in case of hidden fts column */ + const table_id_t id= prebuilt->table->id; + prebuilt->table->release(); + dict_sys.remove(prebuilt->table); + prebuilt->table= + dict_table_open_on_id(id, true, DICT_TABLE_OP_NORMAL); + prebuilt->table->space= table->space; +} + +/** Clean up after import tablespace. +@param prebuilt prebuilt from handler +@param err error code +@param fts_table constructed table which has system generated + fulltext document id +@return error code or DB_SUCCESS */ +static dberr_t -row_import_cleanup( -/*===============*/ - row_prebuilt_t* prebuilt, /*!< in/out: prebuilt from handler */ - dberr_t err) /*!< in: error code */ +row_import_cleanup(row_prebuilt_t* prebuilt, + dberr_t err, + dict_table_t* fts_table = nullptr) { dict_table_t* table = prebuilt->table; @@ -2159,11 +2256,45 @@ row_import_cleanup( index = UT_LIST_GET_NEXT(indexes, index)) { index->page = FIL_NULL; } + + prebuilt->trx->rollback(); + } + else { + DBUG_EXECUTE_IF("ib_import_before_commit_crash", DBUG_SUICIDE();); + prebuilt->trx->commit(); } - DBUG_EXECUTE_IF("ib_import_before_commit_crash", DBUG_SUICIDE();); + if (fts_table && fts_table != prebuilt->table) { - prebuilt->trx->commit(); + if (err == DB_SUCCESS) { + reload_fts_table(prebuilt, fts_table); + table= prebuilt->table; + ib::warn() << "Added system generated FTS_DOC_ID " + "and FTS_DOC_ID_INDEX while importing " + "the tablespace " << prebuilt->table->name; + } else if (fts_table->space) { + fil_close_tablespace(fts_table->space_id); + fts_table->space = NULL; + } + + if (!prebuilt->trx->dict_operation_lock_mode) { + dict_sys.lock(SRW_LOCK_CALL); + } + + dict_index_t* index = UT_LIST_GET_FIRST( + fts_table->indexes); + while (index) { + dict_index_t* next_index = + UT_LIST_GET_NEXT(indexes, index); + dict_index_remove_from_cache(fts_table, index); + index = next_index; + } + dict_mem_table_free(fts_table); + + if (!prebuilt->trx->dict_operation_lock_mode) { + dict_sys.unlock(); + } + } if (prebuilt->trx->dict_operation_lock_mode) { row_mysql_unlock_data_dictionary(prebuilt->trx); @@ -2194,14 +2325,17 @@ row_import_cleanup( return err; } -/*****************************************************************//** -Report error during tablespace import. */ -static MY_ATTRIBUTE((nonnull, warn_unused_result)) +/** Report error during tablespace import. +@param prebuilt prebuilt from the handler +@param err error code +@param fts_table table definition containing hidden FTS_DOC_ID column +@return error code or DB_SUCCESS */ +static dberr_t row_import_error( -/*=============*/ - row_prebuilt_t* prebuilt, /*!< in/out: prebuilt from handler */ - dberr_t err) /*!< in: error code */ + row_prebuilt_t* prebuilt, + dberr_t err, + dict_table_t* fts_table=nullptr) { if (!trx_is_interrupted(prebuilt->trx)) { char table_name[MAX_FULL_NAME_LEN + 1]; @@ -2216,7 +2350,7 @@ row_import_error( table_name, (ulong) err, ut_strerr(err)); } - return row_import_cleanup(prebuilt, err); + return row_import_cleanup(prebuilt, err, fts_table); } /*****************************************************************//** @@ -3067,7 +3201,139 @@ static size_t get_buf_size() ); } -/* find, parse instant metadata, performing variaous checks, +/** Add fts index to the table +@param table fts index to be added on the table */ +static void add_fts_index(dict_table_t *table) +{ + dict_index_t *fts_index= dict_mem_index_create( + table, FTS_DOC_ID_INDEX_NAME, DICT_UNIQUE, 2); + fts_index->page= FIL_NULL; + fts_index->cached= 1; + fts_index->n_uniq= 1; + /* Add fields for FTS_DOC_ID_INDEX */ + dict_index_add_col( + fts_index, table, + &table->cols[table->n_cols - (DATA_N_SYS_COLS + 1)], 0); + dict_index_t *clust_index= UT_LIST_GET_FIRST(table->indexes); + for (ulint i= 0; i < clust_index->n_uniq; i++) + dict_index_add_col(fts_index, table, clust_index->fields[i].col, + clust_index->fields[i].prefix_len); +#ifdef BTR_CUR_HASH_ADAPT + fts_index->search_info= btr_search_info_create(fts_index->heap); + fts_index->search_info->ref_count= 0; +#endif /* BTR_CUR_HASH_ADAPT */ + UT_LIST_ADD_LAST(fts_index->table->indexes, fts_index); +} + +/** Append the hidden fts column and fts doc index to the +existing table +@param table table to be imported +@param thd thread +@param cfg metadata required by import +@return table which has fts doc id and fts doc id index */ +static dict_table_t *build_fts_hidden_table( + dict_table_t *table, const row_import &cfg) +{ + dict_table_t *new_table= dict_table_t::create( + {table->name.m_name, strlen(table->name.m_name)}, + table->space, table->n_t_cols - (DATA_N_SYS_COLS - 1), + table->n_v_cols, table->flags, + table->flags2); + + new_table->id= table->id; + new_table->space_id= table->space_id; + const char* col_name= &table->col_names[0]; + /* Copy columns from old table to new fts table */ + for (ulint new_i= 0; + new_i < ulint(new_table->n_cols - (DATA_N_SYS_COLS + 1)); + new_i++) + { + dict_mem_table_add_col(new_table, new_table->heap, col_name, + table->cols[new_i].mtype, + table->cols[new_i].prtype, + table->cols[new_i].len); + col_name+= strlen(col_name) + 1; + } + + unsigned fts_col_ind= unsigned(table->n_cols - DATA_N_SYS_COLS); + fts_add_doc_id_column(new_table, new_table->heap); + new_table->cols[fts_col_ind].ind= + fts_col_ind & dict_index_t::MAX_N_FIELDS; + new_table->cols[fts_col_ind].ord_part= 1; + dict_table_add_system_columns(new_table, new_table->heap); + + col_name= &table->v_col_names[0]; + for (ulint new_i= 0; new_i < new_table->n_v_cols; new_i++) + { + dict_col_t old_vcol= table->v_cols[new_i].m_col; + dict_mem_table_add_v_col(new_table, new_table->heap, col_name, + old_vcol.mtype, old_vcol.prtype, + old_vcol.len, old_vcol.ind + 1, + table->v_cols[new_i].num_base); + for (ulint i= 0; i < table->v_cols[new_i].num_base; i++) + { + dict_col_t *base_col= dict_table_get_nth_col( + new_table, table->v_cols[new_i].base_col[i]->ind); + new_table->v_cols[new_i].base_col[i]= base_col; + } + col_name+= strlen(col_name) + 1; + } + + bool is_clustered= true; + /* Copy indexes from old table to new table */ + for (dict_index_t *old_index= UT_LIST_GET_FIRST(table->indexes); + old_index; is_clustered= false) + { + dict_index_t *new_index= dict_mem_index_create( + new_table, old_index->name, old_index->type, + old_index->n_fields + is_clustered); + + new_index->id= old_index->id; + new_index->n_uniq= old_index->n_uniq; + new_index->type= old_index->type; + new_index->cached= 1; + new_index->n_user_defined_cols= old_index->n_user_defined_cols; + new_index->n_core_null_bytes= old_index->n_core_null_bytes; + /* Copy all fields from old index to new index */ + for (ulint i= 0; i < old_index->n_fields; i++) + { + dict_field_t *field= dict_index_get_nth_field(old_index, i); + dict_col_t *col= field->col; + if (col->is_virtual()) + { + dict_v_col_t *v_col= reinterpret_cast(col); + col= &new_table->v_cols[v_col->v_pos].m_col; + } + else + { + unsigned ind= field->col->ind; + if (ind >= fts_col_ind) ind++; + col= &new_table->cols[ind]; + } + dict_index_add_col(new_index, new_table, col, + field->prefix_len); + if (i < old_index->n_uniq) col->ord_part= 1; + } + + if (is_clustered) + { + /* Add fts doc id in clustered index */ + dict_index_add_col( + new_index, new_table, &table->cols[fts_col_ind], 0); + new_index->fields[old_index->n_fields].fixed_len= sizeof(doc_id_t); + } + + new_index->search_info= old_index->search_info; + UT_LIST_ADD_LAST(new_index->table->indexes, new_index); + old_index= UT_LIST_GET_NEXT(indexes, old_index); + if (UT_LIST_GET_LEN(new_table->indexes) + == cfg.find_fts_idx_offset()) + add_fts_index(new_table); + } + return new_table; +} + +/* find, parse instant metadata, performing various checks, and apply it to dict_table_t @return DB_SUCCESS or some error */ static dberr_t handle_instant_metadata(dict_table_t *table, @@ -4330,6 +4596,107 @@ static dberr_t fil_tablespace_iterate(dict_table_t *table, ulint n_io_buffers, data_dir_path); } +static void row_import_autoinc(dict_table_t *table, row_prebuilt_t *prebuilt, + uint64_t autoinc) +{ + if (!table->persistent_autoinc) + { + ut_ad(!autoinc); + return; + } + + if (autoinc) + { + btr_write_autoinc(dict_table_get_first_index(table), autoinc - 1); + autoinc_set: + table->autoinc= autoinc; + sql_print_information("InnoDB: %`.*s.%`s autoinc value set to " UINT64PF, + int(table->name.dblen()), table->name.m_name, + table->name.basename(), autoinc); + } + else if (TABLE *t= prebuilt->m_mysql_table) + { + if (const Field *ai= t->found_next_number_field) + { + autoinc= 1 + + btr_read_autoinc_with_fallback(table, innodb_col_no(ai), + t->s->mysql_version, + innobase_get_int_col_max_value(ai)); + goto autoinc_set; + } + } +} + +/** Update the virtual column position in SYS_COLUMNS and SYS_VIRTUAL +@param table_id table identifier +@param new_pos position value +@param trx transaction +@return DB_SUCCESS or error code */ +dberr_t update_vcol_pos(table_id_t table_id, ulint new_pos, trx_t *trx) +{ + pars_info_t *info= pars_info_create(); + pars_info_add_ull_literal(info, "id", table_id); + pars_info_add_int4_literal(info, "old_pos", new_pos - 1); + DBUG_EXECUTE_IF("ib_import_vcol_update_fail", + return DB_DUPLICATE_KEY;); + return que_eval_sql(info, + "PROCEDURE UPDATE_VCOL () IS\n" + "BEGIN\n" + "UPDATE SYS_COLUMNS SET POS = POS + 1 " + "WHERE TABLE_ID= :id AND POS = :old_pos;\n" + "UPDATE SYS_VIRTUAL SET POS = POS + 1 " + "WHERE TABLE_ID= :id AND POS = :old_pos;\n" + "END\n;", trx); +} + +/** +1) Update the position of the columns and +2) Insert the hidden fts doc id in the sys columns table +3) Insert the hidden fts doc id in the sys indexes and +sys_fields table +@param table table to be imported +@param fts_pos position of fts doc id column +@param trx transaction +@return DB_SUCCESS or error code */ +static +dberr_t innodb_insert_hidden_fts_col(dict_table_t* table, + ulint fts_pos, + trx_t* trx) +{ + dict_index_t* fts_idx= + dict_table_get_index_on_name(table, FTS_DOC_ID_INDEX_NAME); + if (!fts_idx) return DB_ERROR; + for (ulint new_i= 0; new_i < table->n_v_cols; new_i++) + { + ulint pos= dict_create_v_col_pos( + table->v_cols[new_i].v_pos, + table->v_cols[new_i].m_col.ind); + if (dberr_t err= update_vcol_pos(table->id, pos, trx)) + return err; + } + pars_info_t *info= pars_info_create(); + pars_info_add_ull_literal(info, "id", table->id); + dict_hdr_get_new_id(NULL, &fts_idx->id, NULL); + pars_info_add_ull_literal(info, "idx_id", fts_idx->id); + pars_info_add_int4_literal(info, "pos", fts_pos); + pars_info_add_int4_literal(info, "space", fts_idx->table->space_id); + pars_info_add_int4_literal(info, "page_no", fts_idx->page); + + return que_eval_sql(info, + "PROCEDURE ADD_FTS_COL () IS\n" + "BEGIN\n" + "INSERT INTO SYS_COLUMNS VALUES" + "(:id,:pos,'FTS_DOC_ID',6, 1795, 8, 0);\n" + "UPDATE SYS_TABLES SET N_COLS = N_COLS + 1" + " WHERE ID = :id;\n" + "INSERT INTO SYS_INDEXES VALUES" + "(:id, :idx_id, 'FTS_DOC_ID_INDEX', 1," + " 2, :space, :page_no, 50);\n" + "INSERT INTO SYS_FIELDS VALUES" + "(:idx_id, 1, 'FTS_DOC_ID');\n" + "END;\n", trx); +} + /*****************************************************************//** Imports a tablespace. The space id in the .ibd file must match the space id of the table in the data dictionary. @@ -4355,6 +4722,24 @@ row_import_for_mysql( ut_ad(trx); ut_ad(trx->state == TRX_STATE_ACTIVE); ut_ad(!table->is_readable()); + ut_ad(prebuilt->table == table); + +#ifdef BTR_CUR_HASH_ADAPT + /* On DISCARD TABLESPACE, we did not drop any adaptive hash + index entries. If we replaced the discarded tablespace with a + smaller one here, there could still be some adaptive hash + index entries that point to cached garbage pages in the buffer + pool, because PageConverter::operator() only evicted those + pages that were replaced by the imported pages. We must + detach any remaining adaptive hash index entries, because the + adaptive hash index must be a subset of the table contents; + false positives are not tolerated. */ + for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); index; + index = UT_LIST_GET_NEXT(indexes, index)) { + index = index->clone_if_needed(); + } +#endif /* BTR_CUR_HASH_ADAPT */ + UT_LIST_GET_FIRST(table->indexes)->clear_instant_alter(); /* Assign an undo segment for the transaction, so that the transaction will be recovered after a crash. */ @@ -4381,7 +4766,6 @@ row_import_for_mysql( row_import cfg; THD* thd = trx->mysql_thd; - err = row_import_read_cfg(table, thd, cfg); /* Check if the table column definitions match the contents @@ -4389,8 +4773,16 @@ row_import_for_mysql( if (err == DB_SUCCESS) { - if (dberr_t err = handle_instant_metadata(table, cfg)) { - return row_import_error(prebuilt, err); + if (cfg.need_hidden_fts(table)) { + cfg.m_table = table = build_fts_hidden_table( + table, cfg); + } + + err = handle_instant_metadata(table, cfg); + if (err != DB_SUCCESS) { +import_error: + return row_import_error( + prebuilt, err, table); } /* We have a schema file, try and match it with our @@ -4426,7 +4818,7 @@ row_import_for_mysql( "table %s when .cfg file is missing.", table->name.m_name); err = DB_ERROR; - return row_import_error(prebuilt, err); + goto import_error; } FetchIndexRootPages fetchIndexRootPages(table, trx); @@ -4455,7 +4847,7 @@ row_import_for_mysql( } if (err != DB_SUCCESS) { - return row_import_error(prebuilt, err); + goto import_error; } trx->op_info = "importing tablespace"; @@ -4475,21 +4867,6 @@ row_import_for_mysql( DBUG_EXECUTE_IF("ib_import_reset_space_and_lsn_failure", err = DB_TOO_MANY_CONCURRENT_TRXS;); -#ifdef BTR_CUR_HASH_ADAPT - /* On DISCARD TABLESPACE, we did not drop any adaptive hash - index entries. If we replaced the discarded tablespace with a - smaller one here, there could still be some adaptive hash - index entries that point to cached garbage pages in the buffer - pool, because PageConverter::operator() only evicted those - pages that were replaced by the imported pages. We must - detach any remaining adaptive hash index entries, because the - adaptive hash index must be a subset of the table contents; - false positives are not tolerated. */ - for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); index; - index = UT_LIST_GET_NEXT(indexes, index)) { - index = index->clone_if_needed(); - } -#endif /* BTR_CUR_HASH_ADAPT */ if (err != DB_SUCCESS) { char table_name[MAX_FULL_NAME_LEN + 1]; @@ -4506,7 +4883,7 @@ row_import_for_mysql( table_name, ut_strerr(err)); } - return row_import_cleanup(prebuilt, err); + goto import_error; } /* If the table is stored in a remote tablespace, we need to @@ -4563,7 +4940,8 @@ row_import_for_mysql( dict_index_t* index = dict_table_get_first_index(table); if (!dict_index_is_clust(index)) { - return row_import_error(prebuilt, DB_CORRUPTION); + err = DB_CORRUPTION; + goto import_error; } /* Update the Btree segment headers for index node and @@ -4575,7 +4953,7 @@ row_import_for_mysql( err = DB_CORRUPTION;); if (err != DB_SUCCESS) { - return row_import_error(prebuilt, err); + goto import_error; } else if (cfg.requires_purge(index->name)) { /* Purge any delete-marked records that couldn't be @@ -4594,7 +4972,7 @@ row_import_for_mysql( DBUG_EXECUTE_IF("ib_import_cluster_failure", err = DB_CORRUPTION;); if (err != DB_SUCCESS) { - return row_import_error(prebuilt, err); + goto import_error; } /* For secondary indexes, purge any records that couldn't be purged @@ -4607,7 +4985,7 @@ row_import_for_mysql( err = DB_CORRUPTION;); if (err != DB_SUCCESS) { - return row_import_error(prebuilt, err); + goto import_error; } ib::info() << "Phase III - Flush changes to disk"; @@ -4615,9 +4993,9 @@ row_import_for_mysql( /* Ensure that all pages dirtied during the IMPORT make it to disk. The only dirty pages generated should be from the pessimistic purge of delete marked records that couldn't be purged in Phase I. */ - while (buf_flush_list_space(prebuilt->table->space)); + while (buf_flush_list_space(table->space)); - for (ulint count = 0; prebuilt->table->space->referenced(); count++) { + for (ulint count = 0; table->space->referenced(); count++) { /* Issue a warning every 10.24 seconds, starting after 2.56 seconds */ if ((count & 511) == 128) { @@ -4628,40 +5006,50 @@ row_import_for_mysql( } ib::info() << "Phase IV - Flush complete"; - prebuilt->table->space->set_imported(); + /* Set tablespace purpose as FIL_TYPE_TABLESPACE, + so that rollback can go ahead smoothly */ + table->space->set_imported(); + err = lock_sys_tables(trx); + if (err != DB_SUCCESS) { + goto import_error; + } /* The dictionary latches will be released in in row_import_cleanup() after the transaction commit, for both success and error. */ row_mysql_lock_data_dictionary(trx); + if (prebuilt->table != table) { + /* Add fts_doc_id and fts_doc_idx in data dictionary */ + err = innodb_insert_hidden_fts_col( + table, cfg.find_col(FTS_DOC_ID_COL_NAME), trx); + DBUG_EXECUTE_IF("ib_import_fts_error", + err= DB_DUPLICATE_KEY;); + if (err != DB_SUCCESS) { + goto import_error; + } + } /* Update the root pages of the table's indexes. */ err = row_import_update_index_root(trx, table, false); if (err != DB_SUCCESS) { - return row_import_error(prebuilt, err); + goto import_error; } err = row_import_update_discarded_flag(trx, table->id, false); if (err != DB_SUCCESS) { - return row_import_error(prebuilt, err); + goto import_error; } table->file_unreadable = false; table->flags2 &= ~DICT_TF2_DISCARDED & ((1U << DICT_TF2_BITS) - 1); /* Set autoinc value read from .cfg file, if one was specified. - Otherwise, keep the PAGE_ROOT_AUTO_INC as is. */ - if (autoinc) { - ib::info() << table->name << " autoinc value set to " - << autoinc; + Otherwise, read the PAGE_ROOT_AUTO_INC and set it to table autoinc. */ + row_import_autoinc(table, prebuilt, autoinc); - table->autoinc = autoinc--; - btr_write_autoinc(dict_table_get_first_index(table), autoinc); - } - - return row_import_cleanup(prebuilt, err); + return row_import_cleanup(prebuilt, err, table); } /** Prepare the create info to create a new stub table for import. diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 770675c5e43..952ccee4b24 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1999,7 +1999,7 @@ row_ins_dupl_error_with_rec( /* In a unique secondary index we allow equal key values if they contain SQL NULLs */ - if (!dict_index_is_clust(index) && !index->nulls_equal) { + if (!dict_index_is_clust(index)) { for (i = 0; i < n_unique; i++) { if (dfield_is_null(dtuple_get_nth_field(entry, i))) { @@ -2101,16 +2101,8 @@ row_ins_scan_sec_index_for_duplicate( /* If the secondary index is unique, but one of the fields in the n_unique first fields is NULL, a unique key violation cannot occur, since we define NULL != NULL in this case */ - - if (!index->nulls_equal) { - for (ulint i = 0; i < n_unique; i++) { - if (UNIV_SQL_NULL == dfield_get_len( - dtuple_get_nth_field(entry, i))) { - - DBUG_RETURN(DB_SUCCESS); - } - } - } + if (index->n_nullable && dtuple_contains_null(entry, n_unique)) + DBUG_RETURN(DB_SUCCESS); /* Store old value on n_fields_cmp */ @@ -2568,12 +2560,6 @@ row_ins_index_entry_big_rec( return(error); } -#ifdef HAVE_REPLICATION /* Working around MDEV-24622 */ -extern "C" int thd_is_slave(const MYSQL_THD thd); -#else -# define thd_is_slave(thd) 0 -#endif - #if defined __aarch64__&&defined __GNUC__&&__GNUC__==4&&!defined __clang__ /* Avoid GCC 4.8.5 internal compiler error due to srw_mutex::wr_unlock(). We would only need this for row_ins_clust_index_entry_low(), @@ -2725,7 +2711,8 @@ err_exit: && !index->table->is_active_ddl() && !index->table->has_spatial_index() && !index->table->versioned() - && !thd_is_slave(trx->mysql_thd) /* FIXME: MDEV-24622 */) { + && (!dict_table_is_partition(index->table) + || thd_sql_command(trx->mysql_thd) == SQLCOM_INSERT)) { DEBUG_SYNC_C("empty_root_page_insert"); trx->bulk_insert = true; diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index f95e97fb6b5..08ccaea279f 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -528,8 +528,6 @@ static ulint row_merge_bulk_buf_add(row_merge_buf_t* buf, @param[in,out] row table row @param[in] ext cache of externally stored column prefixes, or NULL -@param[in] history_fts row is historical in a system-versioned table - on which a FTS_DOC_ID_INDEX(FTS_DOC_ID) exists @param[in,out] doc_id Doc ID if we are creating FTS index @param[in,out] conv_heap memory heap where to allocate data when @@ -552,7 +550,6 @@ row_merge_buf_add( fts_psort_t* psort_info, dtuple_t* row, const row_ext_t* ext, - const bool history_fts, doc_id_t* doc_id, mem_heap_t* conv_heap, dberr_t* err, @@ -617,7 +614,7 @@ error: : NULL; /* Process the Doc ID column */ - if (!v_col && (history_fts || *doc_id) + if (!v_col && *doc_id && col->ind == index->table->fts->doc_col) { fts_write_doc_id((byte*) &write_doc_id, *doc_id); @@ -678,7 +675,7 @@ error: } /* Tokenize and process data for FTS */ - if (!history_fts && (index->type & DICT_FTS)) { + if (index->type & DICT_FTS) { fts_doc_item_t* doc_item; byte* value; void* ptr; @@ -1897,6 +1894,7 @@ row_merge_read_clustered_index( DBUG_ENTER("row_merge_read_clustered_index"); ut_ad((old_table == new_table) == !col_map); + ut_ad(old_table->fts || !new_table->fts || !new_table->versioned()); ut_ad(!defaults || col_map); ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); ut_ad(trx->id); @@ -2122,7 +2120,6 @@ corrupted_metadata: dtuple_t* row; row_ext_t* ext; page_cur_t* cur = btr_pcur_get_page_cur(&pcur); - bool history_row, history_fts = false; stage->n_pk_recs_inc(); @@ -2384,11 +2381,6 @@ end_of_index: row_heap); ut_ad(row); - history_row = new_table->versioned() - && dtuple_get_nth_field(row, new_table->vers_end) - ->vers_history_row(); - history_fts = history_row && new_table->fts; - for (ulint i = 0; i < n_nonnull; i++) { dfield_t* field = &row->fields[nonnull[i]]; @@ -2417,7 +2409,7 @@ end_of_index: } /* Get the next Doc ID */ - if (add_doc_id && !history_fts) { + if (add_doc_id) { doc_id++; } else { doc_id = 0; @@ -2457,7 +2449,9 @@ end_of_index: add_autoinc); if (new_table->versioned()) { - if (history_row) { + if (dtuple_get_nth_field(row, + new_table->vers_end) + ->vers_history_row()) { if (dfield_get_type(dfield)->prtype & DATA_NOT_NULL) { err = DB_UNSUPPORTED; my_error(ER_UNSUPPORTED_EXTENSION, MYF(0), @@ -2573,7 +2567,7 @@ write_buffers: if (UNIV_LIKELY (row && (rows_added = row_merge_buf_add( buf, fts_index, old_table, new_table, - psort_info, row, ext, history_fts, + psort_info, row, ext, &doc_id, conv_heap, &err, &v_heap, eval_table, trx, col_collate)))) { @@ -2906,7 +2900,7 @@ write_buffers: (!(rows_added = row_merge_buf_add( buf, fts_index, old_table, new_table, psort_info, - row, ext, history_fts, &doc_id, + row, ext, &doc_id, conv_heap, &err, &v_heap, eval_table, trx, col_collate)))) { /* An empty buffer should have enough @@ -4355,9 +4349,7 @@ void row_merge_drop_temp_indexes() UNIV_PFS_IO defined, register the file descriptor with Performance Schema. @param[in] path location for creating temporary merge files, or NULL @return File descriptor */ -pfs_os_file_t -row_merge_file_create_low( - const char* path) +static pfs_os_file_t row_merge_file_create_mode(const char *path, int mode) { if (!path) { path = mysql_tmpdir; @@ -4398,6 +4390,13 @@ row_merge_file_create_low( return(fd); } +/** Create a temporary file at the specified path. +@param path location for creating temporary merge files, or nullptr +@return File descriptor */ +pfs_os_file_t row_merge_file_create_low(const char *path) +{ + return row_merge_file_create_mode(path, O_BINARY | O_SEQUENTIAL); +} /** Create a merge file in the given location. @param[out] merge_file merge file structure @@ -4408,17 +4407,16 @@ row_merge_file_create( merge_file_t* merge_file, const char* path) { - merge_file->fd = row_merge_file_create_low(path); merge_file->offset = 0; merge_file->n_rec = 0; -#ifdef HAVE_FCNTL_DIRECT - if (merge_file->fd != OS_FILE_CLOSED) { - if (srv_disable_sort_file_cache) { - os_file_set_nocache(merge_file->fd, - "row0merge.cc", "sort"); - } - } + merge_file->fd = + row_merge_file_create_mode(path, +#if !defined _WIN32 && defined O_DIRECT + srv_disable_sort_file_cache + ? O_DIRECT | O_BINARY | O_SEQUENTIAL + : #endif + O_BINARY | O_SEQUENTIAL); return(merge_file->fd); } @@ -5353,18 +5351,8 @@ dberr_t trx_mod_table_time_t::write_bulk(dict_table_t *table, trx_t *trx) return err; } -dberr_t trx_t::bulk_insert_apply_low() +void trx_t::bulk_rollback_low() { - ut_ad(bulk_insert); - ut_ad(!check_unique_secondary); - ut_ad(!check_foreigns); - dberr_t err; - for (auto& t : mod_tables) - if (t.second.is_bulk_insert()) - if ((err= t.second.write_bulk(t.first, this)) != DB_SUCCESS) - goto bulk_rollback; - return DB_SUCCESS; -bulk_rollback: undo_no_t low_limit= UINT64_MAX; for (auto& t : mod_tables) { @@ -5374,9 +5362,37 @@ bulk_rollback: low_limit= t.second.get_first(); delete t.second.bulk_store; t.second.bulk_store= nullptr; + t.second.end_bulk_insert(); } } trx_savept_t bulk_save{low_limit}; rollback(&bulk_save); - return err; +} + +dberr_t trx_t::bulk_insert_apply_for_table(dict_table_t *table) +{ + auto it= mod_tables.find(table); + if (it != mod_tables.end()) + { + if (dberr_t err= it->second.write_bulk(table, this)) + { + bulk_rollback_low(); + return err; + } + it->second.end_bulk_insert(); + } + return DB_SUCCESS; +} + +dberr_t trx_t::bulk_insert_apply_low() +{ + ut_ad(bulk_insert); + for (auto& t : mod_tables) + if (t.second.is_bulk_insert()) + if (dberr_t err= t.second.write_bulk(t.first, this)) + { + bulk_rollback_low(); + return err; + } + return DB_SUCCESS; } diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index b7ff6ce46dc..4b570779742 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -694,6 +694,7 @@ handle_new_error: DBUG_RETURN(true); case DB_DEADLOCK: + case DB_RECORD_CHANGED: case DB_LOCK_TABLE_FULL: rollback: /* Roll back the whole transaction; this resolution was added @@ -1584,7 +1585,8 @@ init_fts_doc_id_for_ref( for (dict_foreign_t* foreign : table->referenced_set) { ut_ad(foreign->foreign_table); - if (foreign->foreign_table->fts) { + if (foreign->foreign_table->space + && foreign->foreign_table->fts) { fts_init_doc_id(foreign->foreign_table); } @@ -2377,7 +2379,6 @@ row_discard_tablespace( dict_table_change_id_in_cache(table, new_id); dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); - if (index) index->clear_instant_alter(); /* Reset the root page numbers. */ for (; index; index = UT_LIST_GET_NEXT(indexes, index)) { diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index f28953f5bb6..f86dbf2ff77 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -430,6 +430,10 @@ row_quiesce_write_header( /*********************************************************************//** Write the table meta data after quiesce. @return DB_SUCCESS or error code */ + +/* Stack size 20904 with clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_quiesce_write_cfg( @@ -487,6 +491,7 @@ row_quiesce_write_cfg( return(err); } +PRAGMA_REENABLE_CHECK_STACK_FRAME /*********************************************************************//** Check whether a table has an FTS index defined on it. diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index b5dd0e380df..0a38e30bf34 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -864,6 +864,11 @@ row_sel_build_committed_vers_for_mysql( column version if any */ mtr_t* mtr) /*!< in: mtr */ { + if (prebuilt->trx->snapshot_isolation) { + *old_vers = rec; + return; + } + if (prebuilt->old_vers_heap) { mem_heap_empty(prebuilt->old_vers_heap); } else { @@ -1184,11 +1189,11 @@ sel_set_rtr_rec_lock( ut_ad(page_align(first_rec) == cur_block->page.frame); ut_ad(match->valid); - match->block.page.lock.x_lock(); + match->block->page.lock.x_lock(); retry: cur_block = btr_pcur_get_block(pcur); - ut_ad(match->block.page.lock.have_x() - || match->block.page.lock.have_s()); + ut_ad(match->block->page.lock.have_x() + || match->block->page.lock.have_s()); ut_ad(page_is_leaf(cur_block->page.frame)); err = lock_sec_rec_read_check_and_lock( @@ -1288,7 +1293,7 @@ re_scan: ULINT_UNDEFINED, &heap); err = lock_sec_rec_read_check_and_lock( - 0, &match->block, rtr_rec->r_rec, index, + 0, match->block, rtr_rec->r_rec, index, my_offsets, static_cast(mode), type, thr); @@ -1304,7 +1309,7 @@ re_scan: match->locked = true; func_end: - match->block.page.lock.x_unlock(); + match->block->page.lock.x_unlock(); if (heap != NULL) { mem_heap_free(heap); } @@ -3401,7 +3406,7 @@ Row_sel_get_clust_rec_for_mysql::operator()( if (dict_index_is_spatial(sec_index) && btr_cur->rtr_info->matches && (page_align(rec) - == btr_cur->rtr_info->matches->block.page.frame + == btr_cur->rtr_info->matches->block->page.frame || rec != btr_pcur_get_rec(prebuilt->pcur))) { #ifdef UNIV_DEBUG rtr_info_t* rtr_info = btr_cur->rtr_info; @@ -4458,13 +4463,11 @@ early_not_found: DBUG_RETURN(DB_RECORD_NOT_FOUND); } +#if SIZEOF_SIZE_T < 8 + if (UNIV_LIKELY(~prebuilt->n_rows_fetched)) +#endif prebuilt->n_rows_fetched++; - if (prebuilt->n_rows_fetched > 1000000000) { - /* Prevent wrap-over */ - prebuilt->n_rows_fetched = 500000000; - } - mode = pcur->search_mode; } diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index bcc598e6523..38d19882de2 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -189,7 +189,7 @@ row_undo_mod_clust_low( @param[in] rec clustered index record @param[in] index clustered index @return the byte offset of DB_TRX_ID, from the start of rec */ -static ulint row_trx_id_offset(const rec_t* rec, const dict_index_t* index) +ulint row_trx_id_offset(const rec_t* rec, const dict_index_t* index) { ut_ad(index->n_uniq <= MAX_REF_PARTS); ulint trx_id_offset = index->trx_id_offset; diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc index 2bc1c2e6922..2a22403e125 100644 --- a/storage/innobase/srv/srv0mon.cc +++ b/storage/innobase/srv/srv0mon.cc @@ -363,11 +363,6 @@ static monitor_info_t innodb_counter_info[] = MONITOR_NONE, MONITOR_DEFAULT_START, MONITOR_LRU_GET_FREE_LOOPS}, - {"buffer_LRU_get_free_waits", "buffer", - "Total sleep waits in LRU get free.", - MONITOR_NONE, - MONITOR_DEFAULT_START, MONITOR_LRU_GET_FREE_WAITS}, - {"buffer_flush_avg_page_rate", "buffer", "Average number of pages at which flushing is happening", MONITOR_NONE, @@ -471,11 +466,6 @@ static monitor_info_t innodb_counter_info[] = MONITOR_EXISTING | MONITOR_DEFAULT_ON), MONITOR_DEFAULT_START, MONITOR_LRU_BATCH_EVICT_TOTAL_PAGE}, - {"buffer_LRU_single_flush_failure_count", "Buffer", - "Number of times attempt to flush a single page from LRU failed", - MONITOR_NONE, - MONITOR_DEFAULT_START, MONITOR_LRU_SINGLE_FLUSH_FAILURE_COUNT}, - {"buffer_LRU_get_free_search", "Buffer", "Number of searches performed for a clean page", MONITOR_NONE, diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index ceb739d8508..7d2a6072c3c 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -304,8 +304,6 @@ unsigned long long srv_stats_modified_counter; based on number of configured pages */ my_bool srv_stats_sample_traditional; -my_bool srv_use_doublewrite_buf; - /** innodb_sync_spin_loops */ ulong srv_n_spin_wait_rounds; /** innodb_spin_wait_delay */ diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 55e5c5d0e7f..35958324932 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -90,10 +90,6 @@ Created 2/16/1996 Heikki Tuuri #include "zlib.h" #include "log.h" -/** We are prepared for a situation that we have this many threads waiting for -a transactional lock inside InnoDB. srv_start() sets the value. */ -ulint srv_max_n_threads; - /** Log sequence number at shutdown */ lsn_t srv_shutdown_lsn; @@ -200,7 +196,7 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn) bool ret; os_file_t file{ os_file_create_func(logfile0.c_str(), - OS_FILE_CREATE | OS_FILE_ON_ERROR_NO_EXIT, + OS_FILE_CREATE, OS_FILE_NORMAL, OS_LOG_FILE, false, &ret) }; @@ -632,15 +628,15 @@ static uint32_t srv_undo_tablespace_open(bool create, const char* name, } } - pfs_os_file_t fh= os_file_create(innodb_data_file_key, name, OS_FILE_OPEN | - OS_FILE_ON_ERROR_NO_EXIT | - OS_FILE_ON_ERROR_SILENT, + pfs_os_file_t fh= os_file_create(innodb_data_file_key, name, + OS_FILE_OPEN_SILENT, OS_FILE_AIO, OS_DATA_FILE, srv_read_only_mode, &success); if (!success) return 0; + ulint n_retries = 5; os_offset_t size= os_file_get_size(fh); ut_a(size != os_offset_t(-1)); @@ -648,15 +644,25 @@ static uint32_t srv_undo_tablespace_open(bool create, const char* name, { page_t *page= static_cast(aligned_malloc(srv_page_size, srv_page_size)); +undo_retry: if (os_file_read(IORequestRead, fh, page, 0, srv_page_size, nullptr) != DB_SUCCESS) { err_exit: + if (n_retries && srv_operation == SRV_OPERATION_BACKUP) + { + sql_print_information("InnoDB: Retrying to read undo " + "tablespace %s", name); + n_retries--; + goto undo_retry; + } ib::error() << "Unable to read first page of file " << name; aligned_free(page); return ~0U; } + DBUG_EXECUTE_IF("undo_space_read_fail", goto err_exit;); + uint32_t id= mach_read_from_4(FIL_PAGE_SPACE_ID + page); if (id == 0 || id >= SRV_SPACE_ID_UPPER_BOUND || memcmp_aligned<2>(FIL_PAGE_SPACE_ID + page, @@ -731,9 +737,7 @@ srv_check_undo_redo_logs_exists() fh = os_file_create_func( name, - OS_FILE_OPEN_RETRY - | OS_FILE_ON_ERROR_NO_EXIT - | OS_FILE_ON_ERROR_SILENT, + OS_FILE_OPEN_RETRY_SILENT, OS_FILE_NORMAL, OS_DATA_FILE, srv_read_only_mode, @@ -755,8 +759,7 @@ srv_check_undo_redo_logs_exists() auto logfilename = get_log_file_path(); fh = os_file_create_func(logfilename.c_str(), - OS_FILE_OPEN_RETRY | OS_FILE_ON_ERROR_NO_EXIT - | OS_FILE_ON_ERROR_SILENT, + OS_FILE_OPEN_RETRY_SILENT, OS_FILE_NORMAL, OS_LOG_FILE, srv_read_only_mode, &ret); @@ -1200,7 +1203,7 @@ dberr_t srv_start(bool create_new_db) if (srv_read_only_mode) { sql_print_information("InnoDB: Started in read only mode"); - srv_use_doublewrite_buf = false; + buf_dblwr.use = buf_dblwr.USE_NO; } high_level_read_only = srv_read_only_mode @@ -1246,12 +1249,6 @@ dberr_t srv_start(bool create_new_db) mysql_stage_register("innodb", srv_stages, static_cast(UT_ARR_SIZE(srv_stages))); - srv_max_n_threads = - 1 /* dict_stats_thread */ - + 1 /* fts_optimize_thread */ - + 128 /* safety margin */ - + max_connections; - srv_boot(); ib::info() << my_crc32c_implementation(); @@ -1637,6 +1634,24 @@ dberr_t srv_start(bool create_new_db) fil_system.space_id_reuse_warned = false; + if (srv_operation > SRV_OPERATION_EXPORT_RESTORED) { + ut_ad(srv_operation == SRV_OPERATION_RESTORE_EXPORT + || srv_operation == SRV_OPERATION_RESTORE); + return(err); + } + + /* Upgrade or resize or rebuild the redo logs before + generating any dirty pages, so that the old redo log + file will not be written to. */ + + err = srv_log_rebuild_if_needed(); + + if (err != DB_SUCCESS) { + return srv_init_abort(err); + } + + recv_sys.debug_free(); + if (!srv_read_only_mode) { const uint32_t flags = FSP_FLAGS_PAGE_SSIZE(); for (uint32_t id = srv_undo_space_id_start; @@ -1721,23 +1736,6 @@ dberr_t srv_start(bool create_new_db) return(srv_init_abort(DB_ERROR)); } } - - if (srv_operation > SRV_OPERATION_EXPORT_RESTORED) { - ut_ad(srv_operation == SRV_OPERATION_RESTORE_EXPORT - || srv_operation == SRV_OPERATION_RESTORE); - return(err); - } - - /* Upgrade or resize or rebuild the redo logs before - generating any dirty pages, so that the old redo log - file will not be written to. */ - err = srv_log_rebuild_if_needed(); - - if (err != DB_SUCCESS) { - return(srv_init_abort(err)); - } - - recv_sys.debug_free(); } ut_ad(err == DB_SUCCESS); diff --git a/storage/innobase/sync/cache.cc b/storage/innobase/sync/cache.cc new file mode 100644 index 00000000000..43d642d05b5 --- /dev/null +++ b/storage/innobase/sync/cache.cc @@ -0,0 +1,160 @@ +/***************************************************************************** + +Copyright (c) 2024, MariaDB plc + +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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +/* This is based on the implementation of pmem_persist() in +https://github.com/pmem/pmdk/, Copyright 2014-2020, Intel Corporation, +last revised in libpmem-1.12.0. */ + +#include "my_global.h" +#include "cache.h" +#include + +#if defined __x86_64__ || defined __aarch64__ || defined __powerpc64__ +# ifdef __x86_64__ +static void pmem_clflush(const void *buf, size_t size) +{ + for (uintptr_t u= uintptr_t(buf) & ~(CPU_LEVEL1_DCACHE_LINESIZE), + end= uintptr_t(buf) + size; + u < end; u+= CPU_LEVEL1_DCACHE_LINESIZE) + __asm__ __volatile__("clflush %0" :: + "m"(*reinterpret_cast(u)) : "memory"); +} + +static void pmem_clflushopt(const void *buf, size_t size) +{ + for (uintptr_t u= uintptr_t(buf) & ~(CPU_LEVEL1_DCACHE_LINESIZE), + end= uintptr_t(buf) + size; + u < end; u+= CPU_LEVEL1_DCACHE_LINESIZE) + __asm__ __volatile__(".byte 0x66; clflush %0" /* clflushopt */ :: + "m"(*reinterpret_cast(u)) : "memory"); + __asm__ __volatile__("sfence" ::: "memory"); +} + +static void pmem_clwb(const void *buf, size_t size) +{ + for (uintptr_t u= uintptr_t(buf) & ~(CPU_LEVEL1_DCACHE_LINESIZE), + end= uintptr_t(buf) + size; + u < end; u+= CPU_LEVEL1_DCACHE_LINESIZE) + __asm__ __volatile__(".byte 0x66; xsaveopt %0" /* clwb */ :: + "m"(*reinterpret_cast(u)) : "memory"); + __asm__ __volatile__("sfence" ::: "memory"); +} + +# include +static decltype(pmem_control::persist) pmem_persist_init() +{ + uint32_t eax= 0, ebx= 0, ecx= 0, edx= 0; + __cpuid_count(7, 0, eax, ebx, ecx, edx); + if (ebx & 1U<<24 /* CLWB */) + return pmem_clwb; + else if (ebx & 1U<<23 /* CLFLUSHOPT */) + return pmem_clflushopt; + else + return pmem_clflush; +} +# elif defined __aarch64__ +static void pmem_cvac(const void* buf, size_t size) +{ + for (uintptr_t u= uintptr_t(buf) & ~(CPU_LEVEL1_DCACHE_LINESIZE), + end= uintptr_t(buf) + size; + u < end; u+= CPU_LEVEL1_DCACHE_LINESIZE) + __asm__ __volatile__("dc cvac, %0" :: "r"(u) : "memory"); + __asm__ __volatile__("dmb ishst" ::: "memory"); +} + +static void pmem_cvap(const void* buf, size_t size) +{ + for (uintptr_t u= uintptr_t(buf) & ~(CPU_LEVEL1_DCACHE_LINESIZE), + end= uintptr_t(buf) + size; + u < end; u+= CPU_LEVEL1_DCACHE_LINESIZE) + __asm__ __volatile__(".arch armv8.2-a\n dc cvap, %0" :: "r"(u) : "memory"); + __asm__ __volatile__("dmb ishst" ::: "memory"); +} + +# include +# include +# ifndef HWCAP_DCPOP +# define HWCAP_DCPOP (1 << 16) +# endif + +static decltype(pmem_control::persist) pmem_persist_init() +{ + return (getauxval(AT_HWCAP) & HWCAP_DCPOP) ? pmem_cvap : pmem_cvac; +} +# elif defined __powerpc64__ +static void pmem_phwsync(const void* buf, size_t size) +{ + for (uintptr_t u= uintptr_t(buf) & ~(CPU_LEVEL1_DCACHE_LINESIZE), + end= uintptr_t(buf) + size; + u < end; u+= CPU_LEVEL1_DCACHE_LINESIZE) + { + /* GCC is just passing the inline asm snippets to the assembler, + and it does not even define these mnemonics by itself. Clang does, + and it includes a built-in assembler. + + Let us hope that having a recent enough GCC is an adequate proxy + for having a recent enough assembler. */ +# if __GNUC__ >= 11 || (defined __clang_major__ && __clang_major__ >= 12) + __asm__ __volatile__("dcbstps 0,%0" :: "r"(u) : "memory"); +# else + __asm__ __volatile__(".long (0x7cc000AC | %0 << 11)" :: "r"(u) : "memory"); +# endif + } + +# if __GNUC__ >= 11 || (defined __clang_major__ && __clang_major__ >= 18) + __asm__ __volatile__("phwsync" ::: "memory"); +# else + __asm__ __volatile__(".long 0x7c80040a" ::: "memory"); +# endif +} + +# include +static void pmem_fence(const void*, size_t) +{ + std::atomic_thread_fence(std::memory_order_seq_cst); +} + +# include +# ifndef AT_HWCAP2 +# define AT_HWCAP2 26 +# endif +# ifndef PPC_FEATURE2_ARCH_3_1 +# define PPC_FEATURE2_ARCH_3_1 4 +# endif + +static decltype(pmem_control::persist) pmem_persist_init() +{ + return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_1) + ? pmem_phwsync : pmem_fence; +} +# endif + +pmem_control::pmem_control() : persist(pmem_persist_init()) {} +const pmem_control pmem; +#else +void pmem_persist(const void *buf, size_t size) +{ +# if defined __riscv && __riscv_xlen == 64 + __asm__ __volatile__("fence w,w" ::: "memory"); +# elif defined __loongarch64 + __asm__ __volatile__("dbar 0" ::: "memory"); +# else +# error "Missing implementation; recompile with cmake -DWITH_INNODB_PMEM=OFF" +# endif +} +#endif diff --git a/storage/innobase/sync/srw_lock.cc b/storage/innobase/sync/srw_lock.cc index 5afb79f24ff..19db12452f9 100644 --- a/storage/innobase/sync/srw_lock.cc +++ b/storage/innobase/sync/srw_lock.cc @@ -548,3 +548,124 @@ template void ssux_lock_impl::rd_unlock(); template void ssux_lock_impl::u_unlock(); template void ssux_lock_impl::wr_unlock(); #endif /* UNIV_PFS_RWLOCK */ + +#ifdef UNIV_DEBUG +void srw_lock_debug::SRW_LOCK_INIT(mysql_pfs_key_t key) +{ + srw_lock::SRW_LOCK_INIT(key); + readers_lock.init(); + ut_ad(!readers.load(std::memory_order_relaxed)); + ut_ad(!have_any()); +} + +void srw_lock_debug::destroy() +{ + ut_ad(!writer); + if (auto r= readers.load(std::memory_order_relaxed)) + { + readers.store(0, std::memory_order_relaxed); + ut_ad(r->empty()); + delete r; + } + srw_lock::destroy(); +} + +bool srw_lock_debug::wr_lock_try() +{ + ut_ad(!have_any()); + if (!srw_lock::wr_lock_try()) + return false; + ut_ad(!writer); + writer.store(pthread_self(), std::memory_order_relaxed); + return true; +} + +void srw_lock_debug::wr_lock(SRW_LOCK_ARGS(const char *file, unsigned line)) +{ + ut_ad(!have_any()); + srw_lock::wr_lock(SRW_LOCK_ARGS(file, line)); + ut_ad(!writer); + writer.store(pthread_self(), std::memory_order_relaxed); +} + +void srw_lock_debug::wr_unlock() +{ + ut_ad(have_wr()); + writer.store(0, std::memory_order_relaxed); + srw_lock::wr_unlock(); +} + +void srw_lock_debug::readers_register() +{ + readers_lock.wr_lock(); + auto r= readers.load(std::memory_order_relaxed); + if (!r) + { + r= new std::unordered_multiset(); + readers.store(r, std::memory_order_relaxed); + } + r->emplace(pthread_self()); + readers_lock.wr_unlock(); +} + +bool srw_lock_debug::rd_lock_try() +{ + ut_ad(!have_any()); + if (!srw_lock::rd_lock_try()) + return false; + readers_register(); + return true; +} + +void srw_lock_debug::rd_lock(SRW_LOCK_ARGS(const char *file, unsigned line)) +{ + ut_ad(!have_any()); + srw_lock::rd_lock(SRW_LOCK_ARGS(file, line)); + readers_register(); +} + +void srw_lock_debug::rd_unlock() +{ + const pthread_t self= pthread_self(); + ut_ad(writer != self); + readers_lock.wr_lock(); + auto r= readers.load(std::memory_order_relaxed); + ut_ad(r); + auto i= r->find(self); + ut_ad(i != r->end()); + r->erase(i); + readers_lock.wr_unlock(); + + srw_lock::rd_unlock(); +} + +bool srw_lock_debug::have_rd() const noexcept +{ + if (auto r= readers.load(std::memory_order_relaxed)) + { + readers_lock.wr_lock(); + bool found= r->find(pthread_self()) != r->end(); + readers_lock.wr_unlock(); +# ifndef SUX_LOCK_GENERIC + ut_ad(!found || is_locked()); +# endif + return found; + } + return false; +} + +bool srw_lock_debug::have_wr() const noexcept +{ + if (writer != pthread_self()) + return false; +# ifndef SUX_LOCK_GENERIC + ut_ad(is_write_locked()); +# endif + return true; +} + +bool srw_lock_debug::have_any() const noexcept +{ + return have_wr() || have_rd(); +} +#endif diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index 9a295e0b2c1..85c6dfdb5c1 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -56,84 +56,6 @@ purge_sys_t purge_sys; my_bool srv_purge_view_update_only_debug; #endif /* UNIV_DEBUG */ -/** Sentinel value */ -static const TrxUndoRsegs NullElement; - -/** Default constructor */ -TrxUndoRsegsIterator::TrxUndoRsegsIterator() - : m_rsegs(NullElement), m_iter(m_rsegs.begin()) -{ -} - -/** Sets the next rseg to purge in purge_sys. -Executed in the purge coordinator thread. -@retval false when nothing is to be purged -@retval true when purge_sys.rseg->latch was locked */ -inline bool TrxUndoRsegsIterator::set_next() -{ - ut_ad(!purge_sys.next_stored); - mysql_mutex_lock(&purge_sys.pq_mutex); - - /* Only purge consumes events from the priority queue, user - threads only produce the events. */ - - /* Check if there are more rsegs to process in the - current element. */ - if (m_iter != m_rsegs.end()) { - /* We are still processing rollback segment from - the same transaction and so expected transaction - number shouldn't increase. Undo the increment of - expected commit done by caller assuming rollback - segments from given transaction are done. */ - purge_sys.tail.trx_no = (*m_iter)->last_trx_no(); - } else if (!purge_sys.purge_queue.empty()) { - m_rsegs = purge_sys.purge_queue.top(); - purge_sys.purge_queue.pop(); - ut_ad(purge_sys.purge_queue.empty() - || purge_sys.purge_queue.top() != m_rsegs); - m_iter = m_rsegs.begin(); - } else { - /* Queue is empty, reset iterator. */ - purge_sys.rseg = NULL; - mysql_mutex_unlock(&purge_sys.pq_mutex); - m_rsegs = NullElement; - m_iter = m_rsegs.begin(); - return false; - } - - purge_sys.rseg = *m_iter++; - mysql_mutex_unlock(&purge_sys.pq_mutex); - - /* We assume in purge of externally stored fields that space - id is in the range of UNDO tablespace space ids */ - ut_ad(purge_sys.rseg->space->id == TRX_SYS_SPACE - || srv_is_undo_tablespace(purge_sys.rseg->space->id)); - - purge_sys.rseg->latch.wr_lock(SRW_LOCK_CALL); - trx_id_t last_trx_no = purge_sys.rseg->last_trx_no(); - purge_sys.hdr_offset = purge_sys.rseg->last_offset(); - purge_sys.hdr_page_no = purge_sys.rseg->last_page_no; - - /* Only the purge_coordinator_task will access this object - purge_sys.rseg_iter, or any of purge_sys.hdr_page_no, - purge_sys.tail. - The field purge_sys.head and purge_sys.view are modified by - purge_sys_t::clone_end_view() - in the purge_coordinator_task - while holding exclusive purge_sys.latch. - The purge_sys.view may also be modified by - purge_sys_t::wake_if_not_active() while holding exclusive - purge_sys.latch. - The purge_sys.head may be read by - purge_truncation_callback(). */ - ut_ad(last_trx_no == m_rsegs.trx_no); - ut_a(purge_sys.hdr_page_no != FIL_NULL); - ut_a(purge_sys.tail.trx_no <= last_trx_no); - purge_sys.tail.trx_no = last_trx_no; - - return(true); -} - /** Build a purge 'query' graph. The actual purge is performed by executing this query graph. @return own: the query graph */ @@ -344,7 +266,8 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr) that is known to be corrupted. */ ut_a(flst_add_first(rseg_header, TRX_RSEG + TRX_RSEG_HISTORY, undo_page, uint16_t(page_offset(undo_header) + - TRX_UNDO_HISTORY_NODE), mtr) == DB_SUCCESS); + TRX_UNDO_HISTORY_NODE), rseg->space->free_limit, + mtr) == DB_SUCCESS); mtr->write<2>(*undo_page, TRX_UNDO_SEG_HDR + TRX_UNDO_STATE + undo_page->page.frame, undo_state); @@ -393,9 +316,7 @@ static void trx_purge_free_segment(buf_block_t *rseg_hdr, buf_block_t *block, void purge_sys_t::rseg_enable(trx_rseg_t &rseg) { ut_ad(this == &purge_sys); -#ifndef SUX_LOCK_GENERIC - ut_ad(rseg.latch.is_write_locked()); -#endif + ut_ad(rseg.latch.have_wr()); uint8_t skipped= skipped_rseg; ut_ad(skipped < TRX_SYS_N_RSEGS); if (&rseg == &trx_sys.rseg_array[skipped]) @@ -434,6 +355,19 @@ inline dberr_t purge_sys_t::iterator::free_history_rseg(trx_rseg_t &rseg) const mtr_t mtr; bool freed= false; uint32_t rseg_ref= 0; + const auto last_boffset= srv_page_size - TRX_UNDO_LOG_OLD_HDR_SIZE; + /* Technically, rseg.space->free_limit is not protected by + rseg.latch, which we are holding, but rseg.space->latch. The value + that we are reading may become stale (too small) if other pages are + being allocated in this tablespace, for other rollback + segments. Nothing can be added to this rseg without holding + rseg.latch, and hence we can validate the entire file-based list + against the limit that we are reading here. + + Note: The read here may look like a data race. On none of our target + architectures this should be an actual problem, because the uint32_t + value should always fit in a register and be correctly aligned. */ + const auto last_page= rseg.space->free_limit; mtr.start(); @@ -449,13 +383,23 @@ func_exit: } hdr_addr= flst_get_last(TRX_RSEG + TRX_RSEG_HISTORY + rseg_hdr->page.frame); + + if (hdr_addr.page == FIL_NULL) + goto func_exit; + + if (hdr_addr.page >= last_page || + hdr_addr.boffset < TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE || + hdr_addr.boffset >= last_boffset) + { + corrupted: + err= DB_CORRUPTION; + goto func_exit; + } + hdr_addr.boffset= static_cast(hdr_addr.boffset - TRX_UNDO_HISTORY_NODE); loop: - if (hdr_addr.page == FIL_NULL) - goto func_exit; - buf_block_t *b= buf_page_get_gen(page_id_t(rseg.space->id, hdr_addr.page), 0, RW_X_LATCH, nullptr, BUF_GET_POSSIBLY_FREED, @@ -504,11 +448,18 @@ loop: fil_addr_t prev_hdr_addr= flst_get_prev_addr(b->page.frame + hdr_addr.boffset + TRX_UNDO_HISTORY_NODE); + if (prev_hdr_addr.page == FIL_NULL); + else if (prev_hdr_addr.page >= last_page || + prev_hdr_addr.boffset < TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE || + prev_hdr_addr.boffset >= last_boffset) + goto corrupted; + prev_hdr_addr.boffset= static_cast(prev_hdr_addr.boffset - TRX_UNDO_HISTORY_NODE); err= flst_remove(rseg_hdr, TRX_RSEG + TRX_RSEG_HISTORY, b, - uint16_t(hdr_addr.boffset + TRX_UNDO_HISTORY_NODE), &mtr); + uint16_t(hdr_addr.boffset + TRX_UNDO_HISTORY_NODE), + last_page, &mtr); if (UNIV_UNLIKELY(err != DB_SUCCESS)) goto func_exit; @@ -568,45 +519,21 @@ loop: ut_ad(rseg_hdr->page.id() == rseg.page_id()); mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_FIX); + if (hdr_addr.page == FIL_NULL) + goto func_exit; + goto loop; } -/** Cleanse purge queue to remove the rseg that reside in undo-tablespace -marked for truncate. -@param[in] space undo tablespace being truncated */ -static void trx_purge_cleanse_purge_queue(const fil_space_t& space) +void purge_sys_t::cleanse_purge_queue(const fil_space_t &space) { - typedef std::vector purge_elem_list_t; - purge_elem_list_t purge_elem_list; - - mysql_mutex_lock(&purge_sys.pq_mutex); - - /* Remove rseg instances that are in the purge queue before we start - truncate of corresponding UNDO truncate. */ - while (!purge_sys.purge_queue.empty()) { - purge_elem_list.push_back(purge_sys.purge_queue.top()); - purge_sys.purge_queue.pop(); - } - - for (purge_elem_list_t::iterator it = purge_elem_list.begin(); - it != purge_elem_list.end(); - ++it) { - - for (TrxUndoRsegs::iterator it2 = it->begin(); - it2 != it->end(); - ++it2) { - if ((*it2)->space == &space) { - it->erase(it2); - break; - } - } - - if (!it->empty()) { - purge_sys.purge_queue.push(*it); - } - } - - mysql_mutex_unlock(&purge_sys.pq_mutex); + mysql_mutex_lock(&pq_mutex); + auto purge_elem_list= clone_queue_container(); + purge_queue.clear(); + for (auto elem : purge_elem_list) + if (purge_queue::rseg(elem)->space != &space) + purge_queue.push_trx_no_rseg(elem); + mysql_mutex_unlock(&pq_mutex); } dberr_t purge_sys_t::iterator::free_history() const @@ -669,7 +596,9 @@ fil_space_t *purge_sys_t::truncating_tablespace() if (space || srv_undo_tablespaces_active < 2 || !srv_undo_log_truncate) return space; - const uint32_t size= uint32_t(srv_max_undo_log_size >> srv_page_size_shift); + const uint32_t size= + uint32_t(std::min(ulonglong{std::numeric_limits::max()}, + srv_max_undo_log_size >> srv_page_size_shift)); for (uint32_t i= truncate_undo_space.last, j= i;; ) { if (fil_space_t *s= undo_truncate_try(srv_undo_space_id_start + i, size)) @@ -748,7 +677,7 @@ not_free: const char *file_name= UT_LIST_GET_FIRST(space->chain)->name; sql_print_information("InnoDB: Truncating %s", file_name); - trx_purge_cleanse_purge_queue(*space); + purge_sys.cleanse_purge_queue(*space); /* Lock all modified pages of the tablespace. @@ -867,13 +796,11 @@ buf_block_t *purge_sys_t::get_page(page_id_t id) return nullptr; } -void purge_sys_t::rseg_get_next_history_log() +bool purge_sys_t::rseg_get_next_history_log() { fil_addr_t prev_log_addr; -#ifndef SUX_LOCK_GENERIC - ut_ad(rseg->latch.is_write_locked()); -#endif + ut_ad(rseg->latch.have_wr()); ut_a(rseg->last_page_no != FIL_NULL); tail.trx_no= rseg->last_trx_no() + 1; @@ -885,21 +812,24 @@ void purge_sys_t::rseg_get_next_history_log() { const byte *log_hdr= undo_page->page.frame + rseg->last_offset(); prev_log_addr= flst_get_prev_addr(log_hdr + TRX_UNDO_HISTORY_NODE); + if (prev_log_addr.boffset < TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE || + prev_log_addr.boffset >= srv_page_size - TRX_UNDO_LOG_OLD_HDR_SIZE) + goto corrupted; prev_log_addr.boffset = static_cast(prev_log_addr.boffset - TRX_UNDO_HISTORY_NODE); } else - prev_log_addr.page= FIL_NULL; + goto corrupted; - if (prev_log_addr.page == FIL_NULL) + if (prev_log_addr.page >= rseg->space->free_limit) + corrupted: rseg->last_page_no= FIL_NULL; else { /* Read the previous log header. */ trx_id_t trx_no= 0; if (const buf_block_t* undo_page= - get_page(page_id_t(rseg->space->id, - prev_log_addr.page))) + get_page(page_id_t(rseg->space->id, prev_log_addr.page))) { const byte *log_hdr= undo_page->page.frame + prev_log_addr.boffset; trx_no= mach_read_from_8(log_hdr + TRX_UNDO_TRX_NO); @@ -916,12 +846,13 @@ void purge_sys_t::rseg_get_next_history_log() can never produce events from an empty rollback segment. */ mysql_mutex_lock(&pq_mutex); - purge_queue.push(*rseg); + enqueue(*rseg); mysql_mutex_unlock(&pq_mutex); } } rseg->latch.wr_unlock(); + return choose_next_log(); } /** Position the purge sys "iterator" on the undo record to use for purging. @@ -929,11 +860,37 @@ void purge_sys_t::rseg_get_next_history_log() @retval true when purge_sys.rseg->latch was locked */ bool purge_sys_t::choose_next_log() { - if (!rseg_iter.set_next()) - return false; + ut_ad(!next_stored); - hdr_offset= rseg->last_offset(); - hdr_page_no= rseg->last_page_no; + mysql_mutex_lock(&pq_mutex); + if (purge_queue.empty()) { + rseg = nullptr; + mysql_mutex_unlock(&purge_sys.pq_mutex); + return false; + } + rseg= purge_queue.pop(); + mysql_mutex_unlock(&purge_sys.pq_mutex); + + /* We assume in purge of externally stored fields that space + id is in the range of UNDO tablespace space ids */ + ut_ad(rseg->space == fil_system.sys_space || + srv_is_undo_tablespace(rseg->space->id)); + + rseg->latch.wr_lock(SRW_LOCK_CALL); + trx_id_t last_trx_no = rseg->last_trx_no(); + hdr_offset = rseg->last_offset(); + hdr_page_no = rseg->last_page_no; + + /* Only the purge_coordinator_task will access this any of + purge_sys.hdr_page_no, purge_sys.tail. The field purge_sys.head and + purge_sys.view are modified by clone_end_view() in the + purge_coordinator_task while holding exclusive purge_sys.latch. The + purge_sys.view may also be modified by wake_if_not_active() while holding + exclusive purge_sys.latch. The purge_sys.head may be read by + purge_truncation_callback(). */ + ut_a(hdr_page_no != FIL_NULL); + ut_a(tail.trx_no <= last_trx_no); + tail.trx_no = last_trx_no; if (!rseg->needs_purge) { @@ -964,7 +921,7 @@ bool purge_sys_t::choose_next_log() if (!b) goto purge_nothing; undo_rec= - trx_undo_page_get_first_rec(b, page_no, hdr_offset); + trx_undo_page_get_first_rec(b, hdr_page_no, hdr_offset); if (!undo_rec) goto purge_nothing; } @@ -988,18 +945,13 @@ inline trx_purge_rec_t purge_sys_t::get_next_rec(roll_ptr_t roll_ptr) { ut_ad(next_stored); ut_ad(tail.trx_no < low_limit_no()); -#ifndef SUX_LOCK_GENERIC - ut_ad(rseg->latch.is_write_locked()); -#endif + ut_ad(rseg->latch.have_wr()); if (!offset) { - /* It is the dummy undo log record, which means that there is no - need to purge this undo log */ - rseg_get_next_history_log(); - - /* Look for the next undo log and record to purge */ - if (choose_next_log()) + /* It is the dummy undo log record, which means that there is no need to + purge this undo log. Look for the next undo log and record to purge */ + if (rseg_get_next_history_log()) rseg->latch.wr_unlock(); return {nullptr, 1}; } @@ -1047,9 +999,8 @@ inline trx_purge_rec_t purge_sys_t::get_next_rec(roll_ptr_t roll_ptr) else { got_no_rec: - rseg_get_next_history_log(); /* Look for the next undo log and record to purge */ - locked= choose_next_log(); + locked= rseg_get_next_history_log(); } if (locked) diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index d0231d54090..abfdc9202df 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -201,7 +201,7 @@ bool trx_rseg_read_wsrep_checkpoint(const buf_block_t *rseg_header, XID &xid) memcpy(xid.data, TRX_RSEG + TRX_RSEG_WSREP_XID_DATA + rseg_header->page.frame, XIDDATASIZE); - return true; + return wsrep_is_wsrep_xid(&xid); } /** Read the WSREP XID from the TRX_SYS page (in case of upgrade). @@ -210,6 +210,11 @@ bool trx_rseg_read_wsrep_checkpoint(const buf_block_t *rseg_header, XID &xid) @return whether the WSREP XID is present */ static bool trx_rseg_init_wsrep_xid(const page_t* page, XID& xid) { + if (memcmp(TRX_SYS + TRX_SYS_WSREP_XID_INFO + page, + field_ref_zero, TRX_SYS_WSREP_XID_LEN) == 0) { + return false; + } + if (mach_read_from_4(TRX_SYS + TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_MAGIC_N_FLD + page) @@ -232,7 +237,8 @@ static bool trx_rseg_init_wsrep_xid(const page_t* page, XID& xid) memcpy(xid.data, TRX_SYS + TRX_SYS_WSREP_XID_INFO + TRX_SYS_WSREP_XID_DATA + page, XIDDATASIZE); - return true; + + return wsrep_is_wsrep_xid(&xid); } /** Recover the latest WSREP checkpoint XID. @@ -448,7 +454,14 @@ static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, mtr_t *mtr) { if (!rseg->space) return DB_TABLESPACE_NOT_FOUND; + + /* Access the tablespace header page to recover rseg->space->free_limit */ + page_id_t page_id{rseg->space->id, 0}; dberr_t err; + if (!buf_page_get_gen(page_id, 0, RW_X_LATCH, nullptr, BUF_GET, mtr, &err)) + return err; + mtr->release_last_page(); + page_id.set_page_no(rseg->page_no); const buf_block_t *rseg_hdr= buf_page_get_gen(rseg->page_id(), 0, RW_X_LATCH, nullptr, BUF_GET, mtr, &err); @@ -493,10 +506,17 @@ static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, mtr_t *mtr) trx_sys.recovered_binlog_offset= binlog_offset; trx_sys.recovered_binlog_is_legacy_pos= false; } -#ifdef WITH_WSREP - trx_rseg_read_wsrep_checkpoint(rseg_hdr, trx_sys.recovered_wsrep_xid); -#endif } +#ifdef WITH_WSREP + XID tmp_xid; + tmp_xid.null(); + /* Update recovered wsrep xid only if we found wsrep xid from + rseg header page and read xid seqno is larger than currently + recovered xid seqno. */ + if (trx_rseg_read_wsrep_checkpoint(rseg_hdr, tmp_xid) && + wsrep_xid_seqno(&tmp_xid) > wsrep_xid_seqno(&trx_sys.recovered_wsrep_xid)) + trx_sys.recovered_wsrep_xid.set(&tmp_xid); +#endif } if (srv_operation == SRV_OPERATION_RESTORE) @@ -518,6 +538,11 @@ static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, mtr_t *mtr) fil_addr_t node_addr= flst_get_last(TRX_RSEG + TRX_RSEG_HISTORY + rseg_hdr->page.frame); + if (node_addr.page >= rseg->space->free_limit || + node_addr.boffset < TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE || + node_addr.boffset >= srv_page_size - TRX_UNDO_LOG_OLD_HDR_SIZE) + return DB_CORRUPTION; + node_addr.boffset= static_cast(node_addr.boffset - TRX_UNDO_HISTORY_NODE); rseg->last_page_no= node_addr.page; @@ -542,7 +567,7 @@ static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, mtr_t *mtr) if (rseg->last_page_no != FIL_NULL) /* There is no need to cover this operation by the purge mutex because we are still bootstrapping. */ - purge_sys.purge_queue.push(*rseg); + purge_sys.enqueue(*rseg); } trx_sys.set_undo_non_empty(rseg->history_size > 0); @@ -565,10 +590,6 @@ static void trx_rseg_init_binlog_info(const page_t* page) + TRX_SYS + page); trx_sys.recovered_binlog_is_legacy_pos= true; } - -#ifdef WITH_WSREP - trx_rseg_init_wsrep_xid(page, trx_sys.recovered_wsrep_xid); -#endif } /** Initialize or recover the rollback segments at startup. */ @@ -587,7 +608,17 @@ dberr_t trx_rseg_array_init() #endif mtr_t mtr; dberr_t err = DB_SUCCESS; - + /* mariabackup --prepare only deals with the redo log and the data + files, not with transactions or the data dictionary, that's why + trx_lists_init_at_db_start() does not invoke purge_sys.create() and + purge queue mutex stays uninitialized, and trx_rseg_mem_restore() quits + before initializing undo log lists. */ + if (srv_operation != SRV_OPERATION_RESTORE) + /* Acquiring purge queue mutex here should be fine from the + deadlock prevention point of view, because executing that + function is a prerequisite for starting the purge subsystem or + any transactions. */ + purge_sys.queue_lock(); for (ulint rseg_id = 0; rseg_id < TRX_SYS_N_RSEGS; rseg_id++) { mtr.start(); if (const buf_block_t* sys = trx_sysf_get(&mtr, true)) { @@ -600,7 +631,11 @@ dberr_t trx_rseg_array_init() + sys->page.frame); trx_rseg_init_binlog_info(sys->page.frame); #ifdef WITH_WSREP - wsrep_sys_xid.set(&trx_sys.recovered_wsrep_xid); + if (trx_rseg_init_wsrep_xid( + sys->page.frame, trx_sys.recovered_wsrep_xid)) { + wsrep_sys_xid.set( + &trx_sys.recovered_wsrep_xid); + } #endif } @@ -653,7 +688,8 @@ dberr_t trx_rseg_array_init() mtr.commit(); } - + if (srv_operation != SRV_OPERATION_RESTORE) + purge_sys.queue_unlock(); if (err != DB_SUCCESS) { for (auto& rseg : trx_sys.rseg_array) { while (auto u = UT_LIST_GET_FIRST(rseg.undo_list)) { @@ -665,7 +701,7 @@ dberr_t trx_rseg_array_init() } #ifdef WITH_WSREP - if (!wsrep_sys_xid.is_null()) { + if (srv_operation == SRV_OPERATION_NORMAL && !wsrep_sys_xid.is_null()) { /* Upgrade from a version prior to 10.3.5, where WSREP XID was stored in TRX_SYS page. If no rollback segment has a WSREP XID set, diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 7d21e34dfac..ff9d8c55119 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -413,7 +413,7 @@ void trx_t::free() read_view.mem_noaccess(); MEM_NOACCESS(&lock, sizeof lock); MEM_NOACCESS(&op_info, sizeof op_info + - sizeof(unsigned) /* isolation_level, + sizeof(unsigned) /* isolation_level, snapshot_isolation, check_foreigns, check_unique_secondary, bulk_insert */); MEM_NOACCESS(&is_registered, sizeof is_registered); @@ -1142,15 +1142,23 @@ inline void trx_t::write_serialisation_history(mtr_t *mtr) } else if (rseg->last_page_no == FIL_NULL) { - mysql_mutex_lock(&purge_sys.pq_mutex); + /* trx_sys.assign_new_trx_no() and + purge_sys.enqueue() must be invoked in the same + critical section protected with purge queue mutex to avoid rseg with + greater last commit number to be pushed to purge queue prior to rseg with + lesser last commit number. In other words pushing to purge queue must be + serialized along with assigning trx_no. Otherwise purge coordinator + thread can also fetch redo log records from rseg with greater last commit + number before rseg with lesser one. */ + purge_sys.queue_lock(); trx_sys.assign_new_trx_no(this); const trx_id_t end{rw_trx_hash_element->no}; + rseg->last_page_no= undo->hdr_page_no; /* end cannot be less than anything in rseg. User threads only produce events when a rollback segment is empty. */ - purge_sys.purge_queue.push(TrxUndoRsegs{end, *rseg}); - mysql_mutex_unlock(&purge_sys.pq_mutex); - rseg->last_page_no= undo->hdr_page_no; rseg->set_last_commit(undo->hdr_offset, end); + purge_sys.enqueue(end, *rseg); + purge_sys.queue_unlock(); } else trx_sys.assign_new_trx_no(this); diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc index 566a753fe9e..a249fbaf14e 100644 --- a/storage/innobase/trx/trx0undo.cc +++ b/storage/innobase/trx/trx0undo.cc @@ -134,8 +134,9 @@ trx_undo_page_get_first_rec(const buf_block_t *block, uint32_t page_no, uint16_t offset) { uint16_t start= trx_undo_page_get_start(block, page_no, offset); - return start == trx_undo_page_get_end(block, page_no, offset) - ? nullptr : block->page.frame + start; + uint16_t end= trx_undo_page_get_end(block, page_no, offset); + ut_ad(start <= end); + return start >= end ? nullptr : block->page.frame + start; } /** Get the last undo log record on a page. @@ -149,8 +150,10 @@ trx_undo_rec_t* trx_undo_page_get_last_rec(const buf_block_t *block, uint32_t page_no, uint16_t offset) { + uint16_t start= trx_undo_page_get_start(block, page_no, offset); uint16_t end= trx_undo_page_get_end(block, page_no, offset); - return trx_undo_page_get_start(block, page_no, offset) == end + ut_ad(start <= end); + return start >= end ? nullptr : block->page.frame + mach_read_from_2(block->page.frame + end - 2); } @@ -510,7 +513,7 @@ trx_undo_seg_create(fil_space_t *space, buf_block_t *rseg_hdr, ulint *id, *err = flst_add_last(block, TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST, block, TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE, - mtr); + space->free_limit, mtr); *id = slot_no; mtr->write<4>(*rseg_hdr, TRX_RSEG + TRX_RSEG_UNDO_SLOTS @@ -688,7 +691,8 @@ buf_block_t *trx_undo_add_page(trx_undo_t *undo, mtr_t *mtr, dberr_t *err) mtr->undo_create(*new_block); trx_undo_page_init(*new_block); *err= flst_add_last(header_block, TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST, - new_block, TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE, mtr); + new_block, TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE, + rseg->space->free_limit, mtr); if (UNIV_UNLIKELY(*err != DB_SUCCESS)) new_block= nullptr; else @@ -739,9 +743,11 @@ trx_undo_free_page( buf_page_make_young_if_needed(&header_block->page); + const uint32_t limit = rseg->space->free_limit; + *err = flst_remove(header_block, TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST, undo_block, TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE, - mtr); + limit, mtr); if (UNIV_UNLIKELY(*err != DB_SUCCESS)) { return FIL_NULL; @@ -750,7 +756,13 @@ trx_undo_free_page( const fil_addr_t last_addr = flst_get_last( TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + header_block->page.frame); - if (UNIV_UNLIKELY(last_addr.page == page_no)) { + if (UNIV_UNLIKELY(last_addr.page == page_no) + || UNIV_UNLIKELY(last_addr.page != FIL_NULL + && last_addr.page >= limit) + || UNIV_UNLIKELY(last_addr.boffset < TRX_UNDO_PAGE_HDR + + TRX_UNDO_PAGE_NODE) + || UNIV_UNLIKELY(last_addr.boffset >= srv_page_size + - TRX_UNDO_LOG_OLD_HDR_SIZE)) { *err = DB_CORRUPTION; return FIL_NULL; } @@ -967,8 +979,8 @@ trx_undo_mem_create_at_db_start(trx_rseg_t *rseg, ulint id, uint32_t page_no) ut_ad(id < TRX_RSEG_N_SLOTS); mtr.start(); - const buf_block_t* block = buf_page_get( - page_id_t(rseg->space->id, page_no), 0, RW_X_LATCH, &mtr); + const page_id_t page_id{rseg->space->id, page_no}; + const buf_block_t* block = buf_page_get(page_id, 0, RW_X_LATCH, &mtr); if (UNIV_UNLIKELY(!block)) { corrupted: mtr.commit(); @@ -1070,6 +1082,15 @@ corrupted_type: fil_addr_t last_addr = flst_get_last( TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + block->page.frame); + if (last_addr.page >= rseg->space->free_limit + || last_addr.boffset < TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE + || last_addr.boffset >= srv_page_size + - TRX_UNDO_LOG_OLD_HDR_SIZE) { + corrupted_undo: + ut_free(undo); + goto corrupted; + } + undo->last_page_no = last_addr.page; undo->top_page_no = last_addr.page; @@ -1078,8 +1099,7 @@ corrupted_type: RW_X_LATCH, &mtr); if (UNIV_UNLIKELY(!last)) { - ut_free(undo); - goto corrupted; + goto corrupted_undo; } if (const trx_undo_rec_t* rec = trx_undo_page_get_last_rec( diff --git a/storage/innobase/unittest/CMakeLists.txt b/storage/innobase/unittest/CMakeLists.txt index 7dd7c111baa..9330d231f06 100644 --- a/storage/innobase/unittest/CMakeLists.txt +++ b/storage/innobase/unittest/CMakeLists.txt @@ -17,6 +17,10 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/unittest/mytap ${CMAKE_SOURCE_DIR}/storage/innobase/include ${CMAKE_SOURCE_DIR}/tpool) +ADD_EXECUTABLE(innodb_rbt-t innodb_rbt-t.cc ../ut/ut0rbt.cc) +TARGET_LINK_LIBRARIES(innodb_rbt-t mysys mytap) +ADD_DEPENDENCIES(innodb_rbt-t GenError) +MY_ADD_TEST(innodb_rbt) ADD_EXECUTABLE(innodb_fts-t innodb_fts-t.cc) TARGET_LINK_LIBRARIES(innodb_fts-t mysys mytap) ADD_DEPENDENCIES(innodb_fts-t GenError) diff --git a/storage/innobase/unittest/innodb_rbt-t.cc b/storage/innobase/unittest/innodb_rbt-t.cc new file mode 100644 index 00000000000..38b980da7d9 --- /dev/null +++ b/storage/innobase/unittest/innodb_rbt-t.cc @@ -0,0 +1,83 @@ +#include "tap.h" +#include "ut0rbt.h" +#include "ut0new.h" + +const size_t alloc_max_retries= 0; +void os_thread_sleep(ulint) { abort(); } +void ut_dbg_assertion_failed(const char *, const char *, unsigned) +{ abort(); } +namespace ib { fatal_or_error::~fatal_or_error() { abort(); } } +#ifdef UNIV_PFS_MEMORY +PSI_memory_key mem_key_other, mem_key_std; +PSI_memory_key ut_new_get_key_by_file(uint32_t) { return mem_key_std; } +#endif + +static const uint64_t doc_ids[]= +{ + 103571, 104018, 106821, 108647, 109352, 109379, + 110325, 122868, 210682130, 231275441, 234172769, 366236849, + 526467159, 1675241735, 1675243405, 1947751899, 1949940363, 2033691953, + 2148227299, 2256289791, 2294223591, 2367501260, 2792700091, 2792701220, + 2817121627, 2820680352, 2821165664, 3253312130, 3404918378, 3532599429, + 3538712078, 3539373037, 3546479309, 3566641838, 3580209634, 3580871267, + 3693930556, 3693932734, 3693932983, 3781949558, 3839877411, 3930968983 +}; + +static int fts_doc_id_cmp(const void *p1, const void *p2) +{ + uint64_t a= *static_cast(p1), + b= *static_cast(p2); + return b > a ? -1 : a > b; +} + + +static int fts_doc_id_buggy_cmp(const void *p1, const void *p2) +{ + return int(*static_cast(p1) - + *static_cast(p2)); +} + +typedef int (*comparator) (const void*, const void*); + +static void rbt_populate(ib_rbt_t *rbt) +{ + ib_rbt_bound_t parent; + for (const uint64_t &doc_id : doc_ids) + { + if (rbt_search(rbt, &parent, &doc_id)) + rbt_add_node(rbt, &parent, &doc_id); + } +} + +static void rbt_populate2(ib_rbt_t *rbt) +{ + for (const uint64_t &doc_id : doc_ids) + rbt_insert(rbt, &doc_id, &doc_id); +} + +static bool rbt_search_all(ib_rbt_t *rbt) +{ + ib_rbt_bound_t parent; + for (const uint64_t &doc_id : doc_ids) + if (rbt_search(rbt, &parent, &doc_id)) + return false; + return true; +} + +static void rbt_test(comparator cmp, bool buggy) +{ + ib_rbt_t *rbt= rbt_create(sizeof(uint64_t), cmp); + rbt_populate(rbt); + ok(rbt_search_all(rbt) != buggy, "search after populate"); + rbt_free(rbt); + rbt= rbt_create(sizeof(uint64_t), cmp); + rbt_populate2(rbt); + ok(rbt_search_all(rbt) != buggy, "search after populate2"); + rbt_free(rbt); +} + +int main () +{ + rbt_test(fts_doc_id_buggy_cmp, true); + rbt_test(fts_doc_id_cmp, false); +} diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index 7b69042c0a5..5b3bc185779 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -258,47 +258,6 @@ ut_print_name( } } -/** Format a table name, quoted as an SQL identifier. -If the name contains a slash '/', the result will contain two -identifiers separated by a period (.), as in SQL -database_name.table_name. -@see table_name_t -@param[in] name table or index name -@param[out] formatted formatted result, will be NUL-terminated -@param[in] formatted_size size of the buffer in bytes -@return pointer to 'formatted' */ -char* -ut_format_name( - const char* name, - char* formatted, - ulint formatted_size) -{ - switch (formatted_size) { - case 1: - formatted[0] = '\0'; - /* FALL-THROUGH */ - case 0: - return(formatted); - } - - char* end; - - end = innobase_convert_name(formatted, formatted_size, - name, strlen(name), NULL); - - /* If the space in 'formatted' was completely used, then sacrifice - the last character in order to write '\0' at the end. */ - if ((ulint) (end - formatted) == formatted_size) { - end--; - } - - ut_a((ulint) (end - formatted) < formatted_size); - - *end = '\0'; - - return(formatted); -} - /**********************************************************************//** Catenate files. */ void @@ -353,14 +312,16 @@ ut_strerr( return("Lock wait"); case DB_DEADLOCK: return("Deadlock"); + case DB_RECORD_CHANGED: + return("Record changed"); +#ifdef WITH_WSREP case DB_ROLLBACK: return("Rollback"); +#endif case DB_DUPLICATE_KEY: return("Duplicate key"); case DB_MISSING_HISTORY: return("Required history data has been deleted"); - case DB_CLUSTER_NOT_FOUND: - return("Cluster not found"); case DB_TABLE_NOT_FOUND: return("Table not found"); case DB_TOO_BIG_RECORD: diff --git a/storage/maria/CMakeLists.txt b/storage/maria/CMakeLists.txt index 033e88bb8e5..9bdd7298400 100644 --- a/storage/maria/CMakeLists.txt +++ b/storage/maria/CMakeLists.txt @@ -124,7 +124,7 @@ ENDIF() IF (CURL_FOUND) INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIRS}) MYSQL_ADD_PLUGIN(s3 ha_s3.cc ${S3_SOURCES} COMPONENT s3-engine - LINK_LIBRARIES ${CURL_LIBRARIES} z STORAGE_ENGINE NOT_EMBEDDED CONFIG s3.cnf) + LINK_LIBRARIES ${CURL_LIBRARIES} ${ZLIB_LIBRARIES} STORAGE_ENGINE NOT_EMBEDDED CONFIG s3.cnf) ENDIF() SET(CPACK_RPM_s3-engine_PACKAGE_SUMMARY "Amazon S3 archival storage engine for MariaDB" PARENT_SCOPE) @@ -132,7 +132,7 @@ SET(CPACK_RPM_s3-engine_PACKAGE_DESCRIPTION "The S3 storage engine allows one to IF(TARGET s3) MYSQL_ADD_EXECUTABLE(aria_s3_copy aria_s3_copy.cc ${S3_SOURCES} COMPONENT s3-engine) - TARGET_LINK_LIBRARIES(aria_s3_copy aria myisam mysys mysys_ssl ${CURL_LIBRARIES} ${ZLIB_LIBRARY}) + TARGET_LINK_LIBRARIES(aria_s3_copy aria myisam mysys mysys_ssl ${CURL_LIBRARIES} ${ZLIB_LIBRARIES}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/libmarias3) ADD_DEFINITIONS(-DWITH_S3_STORAGE_ENGINE) INSTALL_MANPAGES(s3-engine aria_s3_copy.1) diff --git a/storage/maria/aria_chk.c b/storage/maria/aria_chk.c index 62f794a6291..b7ce90bb40a 100644 --- a/storage/maria/aria_chk.c +++ b/storage/maria/aria_chk.c @@ -146,7 +146,8 @@ int main(int argc, char **argv) { if ((ma_control_file_open(FALSE, opt_require_control_file || !(check_param.testflag & T_SILENT), - TRUE))) + TRUE, + control_file_open_flags))) { if (opt_require_control_file || (opt_transaction_logging && (check_param.testflag & T_REP_ANY))) diff --git a/storage/maria/aria_pack.c b/storage/maria/aria_pack.c index eab4d512e8b..ee694931a6d 100644 --- a/storage/maria/aria_pack.c +++ b/storage/maria/aria_pack.c @@ -241,7 +241,8 @@ int main(int argc, char **argv) if (!opt_ignore_control_file && (no_control_file= ma_control_file_open(FALSE, (opt_require_control_file || - !silent), FALSE)) && + !silent), FALSE, + control_file_open_flags)) && opt_require_control_file) { error= 1; diff --git a/storage/maria/aria_read_log.c b/storage/maria/aria_read_log.c index 85a6f4a5e97..cde28e91c0a 100644 --- a/storage/maria/aria_read_log.c +++ b/storage/maria/aria_read_log.c @@ -104,7 +104,7 @@ int main(int argc, char **argv) goto end; } /* we don't want to create a control file, it MUST exist */ - if (ma_control_file_open(FALSE, TRUE, TRUE)) + if (ma_control_file_open(FALSE, TRUE, TRUE, control_file_open_flags)) { fprintf(stderr, "Can't open control file (%d)\n", errno); goto err; diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 2e93d32fe93..eeb613acc4f 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -38,6 +38,7 @@ C_MODE_START #include "ma_recovery.h" C_MODE_END #include "ma_trnman.h" +#include "ma_loghandler.h" //#include "sql_priv.h" #include "protocol.h" @@ -45,6 +46,7 @@ C_MODE_END #include "key.h" #include "log.h" #include "sql_parse.h" +#include "mysql/service_print_check_msg.h" #include "debug.h" /* @@ -428,10 +430,8 @@ static void _ma_check_print_msg(HA_CHECK *param, const LEX_CSTRING *msg_type, const char *fmt, va_list args) { THD *thd= (THD *) param->thd; - Protocol *protocol= thd->protocol; - size_t length, msg_length; + size_t msg_length __attribute__((unused)); char msgbuf[MYSQL_ERRMSG_SIZE]; - char name[NAME_LEN * 2 + 2]; if (param->testflag & T_SUPPRESS_ERR_HANDLING) return; @@ -460,27 +460,10 @@ static void _ma_check_print_msg(HA_CHECK *param, const LEX_CSTRING *msg_type, _ma_check_print(param, msg_type, msgbuf); return; } - length= (uint) (strxmov(name, param->db_name, ".", param->table_name, - NullS) - name); - /* - TODO: switch from protocol to push_warning here. The main reason we didn't - it yet is parallel repair, which threads have no THD object accessible via - current_thd. - - Also we likely need to lock mutex here (in both cases with protocol and - push_warning). - */ - protocol->prepare_for_resend(); - protocol->store(name, (uint)length, system_charset_info); - protocol->store(param->op_name, strlen(param->op_name), system_charset_info); - protocol->store(msg_type, system_charset_info); - protocol->store(msgbuf, msg_length, system_charset_info); - if (protocol->write()) - sql_print_error("Failed on my_net_write, writing to stderr instead: %s.%s: %s\n", - param->db_name, param->table_name, msgbuf); - else if (thd->variables.log_warnings > 2) + print_check_msg(thd, param->db_name, param->table_name, + param->op_name, msg_type->str, msgbuf, 0); + if (thd->variables.log_warnings > 2) _ma_check_print(param, msg_type, msgbuf); - return; } @@ -1984,40 +1967,45 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt) SYNOPSIS disable_indexes() - mode mode of operation: - HA_KEY_SWITCH_NONUNIQ disable all non-unique keys - HA_KEY_SWITCH_ALL disable all keys - HA_KEY_SWITCH_NONUNIQ_SAVE dis. non-uni. and make persistent - HA_KEY_SWITCH_ALL_SAVE dis. all keys and make persistent - IMPLEMENTATION - HA_KEY_SWITCH_NONUNIQ is not implemented. - HA_KEY_SWITCH_ALL_SAVE is not implemented. + DESCRIPTION + See handler::ha_disable_indexes() RETURN 0 ok HA_ERR_WRONG_COMMAND mode not implemented. */ -int ha_maria::disable_indexes(uint mode) +int ha_maria::disable_indexes(key_map map, bool persist) { int error; - if (mode == HA_KEY_SWITCH_ALL) + if (!persist) { /* call a storage engine function to switch the key map */ + DBUG_ASSERT(map.is_clear_all()); error= maria_disable_indexes(file); } - else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE) - { - maria_extra(file, HA_EXTRA_NO_KEYS, 0); - info(HA_STATUS_CONST); // Read new key info - error= 0; - } else { - /* mode not implemented */ - error= HA_ERR_WRONG_COMMAND; + /* auto-inc key cannot be disabled */ + if (table->s->next_number_index < MAX_KEY) + DBUG_ASSERT(map.is_set(table->s->next_number_index)); + + /* unique keys cannot be disabled either */ + for (uint i=0; i < table->s->keys; i++) + DBUG_ASSERT(!(table->key_info[i].flags & HA_NOSAME) || map.is_set(i)); + + ulonglong ullmap= map.to_ulonglong(); + + /* make sure auto-inc key is enabled even if it's > 64 */ + if (map.length() > MARIA_KEYMAP_BITS && + table->s->next_number_index < MAX_KEY) + maria_set_key_active(ullmap, table->s->next_number_index); + + maria_extra(file, HA_EXTRA_NO_KEYS, &ullmap); + info(HA_STATUS_CONST); // Read new key info + error= 0; } return error; } @@ -2028,21 +2016,14 @@ int ha_maria::disable_indexes(uint mode) SYNOPSIS enable_indexes() - mode mode of operation: - HA_KEY_SWITCH_NONUNIQ enable all non-unique keys - HA_KEY_SWITCH_ALL enable all keys - HA_KEY_SWITCH_NONUNIQ_SAVE en. non-uni. and make persistent - HA_KEY_SWITCH_ALL_SAVE en. all keys and make persistent DESCRIPTION Enable indexes, which might have been disabled by disable_index() before. - The modes without _SAVE work only if both data and indexes are empty, - since the MARIA repair would enable them persistently. + If persist=false, it works only if both data and indexes are empty, + since the Aria repair would enable them persistently. To be sure in these cases, call handler::delete_all_rows() before. - IMPLEMENTATION - HA_KEY_SWITCH_NONUNIQ is not implemented. - HA_KEY_SWITCH_ALL_SAVE is not implemented. + See also handler::ha_enable_indexes() RETURN 0 ok @@ -2051,18 +2032,19 @@ int ha_maria::disable_indexes(uint mode) HA_ERR_WRONG_COMMAND mode not implemented. */ -int ha_maria::enable_indexes(uint mode) +int ha_maria::enable_indexes(key_map map, bool persist) { int error; ha_rows start_rows= file->state->records; - DBUG_PRINT("info", ("ha_maria::enable_indexes mode: %d", mode)); + DBUG_PRINT("info", ("ha_maria::enable_indexes mode: %d", persist)); if (maria_is_all_keys_active(file->s->state.key_map, file->s->base.keys)) { /* All indexes are enabled already. */ return 0; } - if (mode == HA_KEY_SWITCH_ALL) + DBUG_ASSERT(map.is_prefix(table->s->keys)); + if (!persist) { error= maria_enable_indexes(file); /* @@ -2071,7 +2053,7 @@ int ha_maria::enable_indexes(uint mode) but mode==HA_KEY_SWITCH_ALL forbids it. */ } - else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE) + else { THD *thd= table->in_use; HA_CHECK *param= (HA_CHECK*) thd->alloc(sizeof *param); @@ -2136,11 +2118,6 @@ int ha_maria::enable_indexes(uint mode) info(HA_STATUS_CONST); thd_proc_info(thd, save_proc_info); } - else - { - /* mode not implemented */ - error= HA_ERR_WRONG_COMMAND; - } DBUG_EXECUTE_IF("maria_flush_whole_log", { DBUG_PRINT("maria_flush_whole_log", ("now")); @@ -2343,7 +2320,7 @@ int ha_maria::end_bulk_insert() { int first_error, first_errno= 0, error; my_bool abort= file->s->deleting, empty_table= 0; - uint enable_index_mode= HA_KEY_SWITCH_NONUNIQ_SAVE; + bool enable_persistently= true; DBUG_ENTER("ha_maria::end_bulk_insert"); if ((first_error= maria_end_bulk_insert(file, abort))) @@ -2372,7 +2349,7 @@ int ha_maria::end_bulk_insert() first_error= 1; first_errno= my_errno; } - enable_index_mode= HA_KEY_SWITCH_ALL; + enable_persistently= false; empty_table= 1; /* Ignore all changed pages, required by _ma_renable_logging_for_table() @@ -2384,7 +2361,7 @@ int ha_maria::end_bulk_insert() if (!abort && can_enable_indexes) { - if ((error= enable_indexes(enable_index_mode))) + if ((error= enable_indexes(key_map(table->s->keys), enable_persistently))) { if (!first_error) { @@ -3402,6 +3379,8 @@ int ha_maria::create(const char *name, TABLE *table_arg, if (ha_create_info->tmp_table()) { create_flags|= HA_CREATE_TMP_TABLE | HA_CREATE_DELAY_KEY_WRITE; + if (ha_create_info->options & HA_LEX_CREATE_GLOBAL_TMP_TABLE) + create_flags|= HA_CREATE_GLOBAL_TMP_TABLE; create_info.transactional= 0; } if (ha_create_info->options & HA_CREATE_KEEP_FILES) @@ -3940,7 +3919,8 @@ static int ha_maria_init(void *p) if (!aria_readonly) res= maria_upgrade(); res= res || maria_init(); - tmp= ma_control_file_open(!aria_readonly, !aria_readonly, !aria_readonly); + tmp= ma_control_file_open(!aria_readonly, !aria_readonly, !aria_readonly, + control_file_open_flags); res= res || aria_readonly ? tmp == CONTROL_FILE_LOCKED : tmp != 0; res= res || ((force_start_after_recovery_failures != 0 && !aria_readonly) && diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h index c974a7e3bf6..3c0d0cc463e 100644 --- a/storage/maria/ha_maria.h +++ b/storage/maria/ha_maria.h @@ -122,8 +122,8 @@ public: int external_lock(THD * thd, int lock_type) override; int start_stmt(THD *thd, thr_lock_type lock_type) override final; int delete_all_rows(void) override final; - int disable_indexes(uint mode) override final; - int enable_indexes(uint mode) override final; + int disable_indexes(key_map map, bool persist) override final; + int enable_indexes(key_map map, bool persist) override final; int indexes_are_disabled(void) override final; void start_bulk_insert(ha_rows rows, uint flags) override final; int end_bulk_insert() override final; diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c index ec1b0955655..dfd1cf9a4cb 100644 --- a/storage/maria/ma_bitmap.c +++ b/storage/maria/ma_bitmap.c @@ -232,7 +232,7 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file, uint max_page_size; MARIA_FILE_BITMAP *bitmap= &share->bitmap; uint size= share->block_size; - myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); + myf flag= MY_WME | share->malloc_flag; pgcache_page_no_t first_bitmap_with_space; #ifndef DBUG_OFF /* We want to have a copy of the bitmap to be able to print differences */ diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index bc1d44d42a3..561cc324ed1 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -488,7 +488,7 @@ my_bool _ma_init_block_record(MARIA_HA *info) { MARIA_ROW *row= &info->cur_row, *new_row= &info->new_row; MARIA_SHARE *share= info->s; - myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); + myf flag= MY_WME | share->malloc_flag; uint default_extents; DBUG_ENTER("_ma_init_block_record"); @@ -2654,7 +2654,6 @@ static my_bool write_block_record(MARIA_HA *info, LSN lsn; my_off_t position; uint save_my_errno; - myf myflag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("write_block_record"); head_block= bitmap_blocks->block; @@ -2721,7 +2720,7 @@ static my_bool write_block_record(MARIA_HA *info, for every data segment we want to store. */ if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size, - row->head_length, myflag)) + row->head_length, MY_WME | share->malloc_flag)) DBUG_RETURN(1); tmp_data_used= 0; /* Either 0 or last used uchar in 'data' */ @@ -4750,7 +4749,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record, MARIA_EXTENT_CURSOR extent; MARIA_COLUMNDEF *column, *end_column; MARIA_ROW *cur_row= &info->cur_row; - myf myflag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); + myf myflag= MY_WME | share->malloc_flag; DBUG_ENTER("_ma_read_block_record2"); start_of_data= data; @@ -5089,7 +5088,6 @@ static my_bool read_row_extent_info(MARIA_HA *info, uchar *buff, uint flag, row_extents, row_extents_size; uint field_lengths __attribute__ ((unused)); uchar *extents, *end; - myf myflag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("read_row_extent_info"); if (!(data= get_record_position(share, buff, @@ -5113,7 +5111,7 @@ static my_bool read_row_extent_info(MARIA_HA *info, uchar *buff, if (info->cur_row.extents_buffer_length < row_extents_size && _ma_alloc_buffer(&info->cur_row.extents, &info->cur_row.extents_buffer_length, - row_extents_size, myflag)) + row_extents_size, MY_WME | share->malloc_flag)) DBUG_RETURN(1); memcpy(info->cur_row.extents, data, ROW_EXTENT_SIZE); data+= ROW_EXTENT_SIZE; @@ -5283,8 +5281,7 @@ my_bool _ma_cmp_block_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def, my_bool _ma_scan_init_block_record(MARIA_HA *info) { MARIA_SHARE *share= info->s; - myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); - my_bool res; + myf flag= MY_WME | share->malloc_flag; DBUG_ENTER("_ma_scan_init_block_record"); DBUG_ASSERT(info->dfile.file == share->bitmap.file.file); @@ -5311,8 +5308,7 @@ my_bool _ma_scan_init_block_record(MARIA_HA *info) _ma_scan_block_record()), we may miss recently inserted rows (bitmap page in page cache would be too old). */ - res= _ma_bitmap_flush(info->s); - DBUG_RETURN(res); + DBUG_RETURN(_ma_bitmap_flush(info->s)); } diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index f30e2c78ffc..8c07e3c67f6 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -125,6 +125,7 @@ void maria_chk_init(HA_CHECK *param) param->max_stage= 1; param->stack_end_ptr= &my_thread_var->stack_ends_here; param->max_allowed_lsn= (LSN) ~0ULL; + /* Flag when initializing buffers possible used by parallel repair threads */ param->malloc_flags= MY_THREAD_SPECIFIC; } @@ -1305,7 +1306,6 @@ static int check_dynamic_record(HA_CHECK *param, MARIA_HA *info, int extend, ulong UNINIT_VAR(left_length); uint b_type; char llbuff[22],llbuff2[22],llbuff3[22]; - myf myflag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("check_dynamic_record"); pos= 0; @@ -1413,7 +1413,8 @@ static int check_dynamic_record(HA_CHECK *param, MARIA_HA *info, int extend, { if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size, block_info.rec_len + - share->base.extra_rec_buff_size, myflag)) + share->base.extra_rec_buff_size, + MY_WME | share->malloc_flag)) { _ma_check_print_error(param, @@ -2130,7 +2131,7 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend) if (!(record= (uchar*) my_malloc(PSI_INSTRUMENT_ME, share->base.default_rec_buff_size, - MYF(param->malloc_flags)))) + MYF(MY_THREAD_SPECIFIC)))) { _ma_check_print_error(param,"Not enough memory for record"); DBUG_RETURN(-1); @@ -2507,6 +2508,11 @@ static int initialize_variables_for_repair(HA_CHECK *param, maria_versioning(info, 0); /* remember original number of rows */ *info->state= info->s->state.state; + if (share->data_file_type == BLOCK_RECORD) + share->state.state.data_file_length= MY_ALIGN(sort_info->filelength, + share->block_size); + else + share->state.state.data_file_length= sort_info->filelength; return 0; } @@ -2743,7 +2749,7 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, READ_CACHE, share->pack.header_length, 1, MYF(MY_WME))) goto err; } - if (sort_info.new_info->s->data_file_type != BLOCK_RECORD) + if (!block_record) { /* When writing to not block records, we need a write buffer */ if (!rep_quick) @@ -2756,7 +2762,7 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, sort_info.new_info->opt_flag|=WRITE_CACHE_USED; } } - else if (block_record) + else { scan_inited= 1; if (maria_scan_init(sort_info.info)) @@ -2766,10 +2772,10 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, if (!(sort_param.record= (uchar *) my_malloc(PSI_INSTRUMENT_ME, (uint) share->base.default_rec_buff_size, - MYF(param->malloc_flags))) || + MYF(MY_THREAD_SPECIFIC))) || _ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size, share->base.default_rec_buff_size, - MYF(param->malloc_flags))) + MYF(MY_THREAD_SPECIFIC))) { _ma_check_print_error(param, "Not enough memory for extra record"); goto err; @@ -3389,7 +3395,7 @@ static int sort_one_index(HA_CHECK *param, MARIA_HA *info, length= page.size; bzero(buff+length,keyinfo->block_length-length); if (write_page(share, new_file, buff, keyinfo->block_length, - new_page_pos, MYF(MY_NABP | MY_WAIT_IF_FULL))) + new_page_pos, MYF(MY_NABP | MY_WAIT_IF_FULL) & param->myf_rw)) { _ma_check_print_error(param,"Can't write indexblock, error: %d",my_errno); goto err; @@ -3728,7 +3734,7 @@ int maria_filecopy(HA_CHECK *param, File to,File from,my_off_t start, buff_length=(ulong) MY_MIN(param->write_buffer_length,length); if (!(buff=my_malloc(PSI_INSTRUMENT_ME, buff_length, - MYF(param->malloc_flags)))) + MYF(MY_THREAD_SPECIFIC)))) { buff=tmp_buff; buff_length=IO_SIZE; } @@ -3874,10 +3880,10 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, if (!(sort_param.record= (uchar*) my_malloc(PSI_INSTRUMENT_ME, (size_t) share->base.default_rec_buff_size, - MYF(param->malloc_flags))) || + MYF(MY_THREAD_SPECIFIC))) || _ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size, share->base.default_rec_buff_size, - MYF(param->malloc_flags))) + MYF(MY_THREAD_SPECIFIC))) { _ma_check_print_error(param, "Not enough memory for extra record"); goto err; @@ -3896,7 +3902,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, sort_param.wordlist=NULL; init_alloc_root(PSI_INSTRUMENT_ME, &sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, - MYF(param->malloc_flags)); + MYF(MY_THREAD_SPECIFIC)); sort_param.key_cmp=sort_key_cmp; sort_param.lock_in_memory=maria_lock_memory; @@ -4116,6 +4122,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, _ma_check_print_error(param, "Couldn't change to new data file"); goto err; } + /* Inform sort_delete_record that we are using the new file */ + sort_info.new_info->dfile.file= info->rec_cache.file= info->dfile.file; + if (param->testflag & T_UNPACK) restore_data_file_type(share); @@ -4464,7 +4473,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, if (!(sort_param=(MARIA_SORT_PARAM *) my_malloc(PSI_INSTRUMENT_ME, (uint) share->base.keys * (sizeof(MARIA_SORT_PARAM) + share->base.pack_reclength), - MYF(MY_ZEROFILL | param->malloc_flags)))) + MYF(MY_ZEROFILL | MY_THREAD_SPECIFIC)))) { _ma_check_print_error(param,"Not enough memory for key!"); goto err; @@ -4522,9 +4531,10 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, sort_param[i].record= (((uchar *)(sort_param+share->base.keys))+ (share->base.pack_reclength * i)); + /* These buffers are per thread */ if (_ma_alloc_buffer(&sort_param[i].rec_buff, &sort_param[i].rec_buff_size, share->base.default_rec_buff_size, - MYF(param->malloc_flags))) + MYF(0))) { _ma_check_print_error(param,"Not enough memory!"); goto err; @@ -4553,7 +4563,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, sort_param[i].key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN; init_alloc_root(PSI_INSTRUMENT_ME, &sort_param[i].wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, - MYF(param->malloc_flags)); + MYF(MY_THREAD_SPECIFIC)); } } sort_info.total_keys=i; @@ -6112,7 +6122,7 @@ static MA_SORT_KEY_BLOCKS *alloc_key_blocks(HA_CHECK *param, uint blocks, if (!(block= (MA_SORT_KEY_BLOCKS*) my_malloc(PSI_INSTRUMENT_ME, (sizeof(MA_SORT_KEY_BLOCKS)+buffer_length+IO_SIZE)*blocks, - MYF(param->malloc_flags)))) + MYF(MY_THREAD_SPECIFIC)))) { _ma_check_print_error(param,"Not enough memory for sort-key-blocks"); return(0); diff --git a/storage/maria/ma_control_file.c b/storage/maria/ma_control_file.c index 237b75b99b7..a90a12612d8 100644 --- a/storage/maria/ma_control_file.c +++ b/storage/maria/ma_control_file.c @@ -272,7 +272,8 @@ static int lock_control_file(const char *name, my_bool do_retry) CONTROL_FILE_ERROR ma_control_file_open(my_bool create_if_missing, my_bool print_error, - my_bool wait_for_lock) + my_bool wait_for_lock, + int open_flags) { uchar buffer[CF_MAX_SIZE]; char name[FN_REFLEN], errmsg_buff[256]; @@ -280,7 +281,6 @@ CONTROL_FILE_ERROR ma_control_file_open(my_bool create_if_missing, " file is probably in use by another process"; uint new_cf_create_time_size, new_cf_changeable_size, new_block_size; my_off_t file_size; - int open_flags= O_BINARY | /*O_DIRECT |*/ O_RDWR | O_CLOEXEC; int error= CONTROL_FILE_UNKNOWN_ERROR; DBUG_ENTER("ma_control_file_open"); @@ -460,6 +460,15 @@ err: DBUG_RETURN(error); } +/* + The most common way to open the control file when writing tests +*/ + +CONTROL_FILE_ERROR ma_control_file_open_or_create() +{ + return ma_control_file_open(TRUE, TRUE, TRUE, + control_file_open_flags); +} /* Write information durably to the control file; stores this information into @@ -630,7 +639,7 @@ my_bool print_aria_log_control() int error= CONTROL_FILE_UNKNOWN_ERROR; uint recovery_fails; File file; - DBUG_ENTER("ma_control_file_open"); + DBUG_ENTER("print_aria_log_control"); if (fn_format(name, CONTROL_FILE_BASE_NAME, maria_data_root, "", MYF(MY_WME)) == NullS) diff --git a/storage/maria/ma_control_file.h b/storage/maria/ma_control_file.h index c74957b8322..35ad4a671ea 100644 --- a/storage/maria/ma_control_file.h +++ b/storage/maria/ma_control_file.h @@ -68,10 +68,13 @@ typedef enum enum_control_file_error { CONTROL_FILE_ERROR ma_control_file_open(my_bool create_if_missing, my_bool print_error, - my_bool wait_for_lock); + my_bool wait_for_lock, + int open_flags); int ma_control_file_write_and_force(LSN last_checkpoint_lsn_arg, uint32 last_logno_arg, TrID max_trid_arg, uint8 recovery_failures_arg); +/* For simple programs that creates Aria files*/ +CONTROL_FILE_ERROR ma_control_file_open_or_create(); int ma_control_file_end(void); my_bool ma_control_file_inited(void); my_bool print_aria_log_control(void); diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c index 7fd739d13a8..9ce48ae9e7f 100644 --- a/storage/maria/ma_create.c +++ b/storage/maria/ma_create.c @@ -101,7 +101,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, DBUG_ASSERT(maria_inited); - if (flags & HA_CREATE_TMP_TABLE) + if ((flags & HA_CREATE_TMP_TABLE) && !(flags & HA_CREATE_GLOBAL_TMP_TABLE)) common_flag|= MY_THREAD_SPECIFIC; if (!ci) diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c index 33f238d9754..fed1bf411f4 100644 --- a/storage/maria/ma_dynrec.c +++ b/storage/maria/ma_dynrec.c @@ -1488,7 +1488,6 @@ int _ma_read_dynamic_record(MARIA_HA *info, uchar *buf, uchar *UNINIT_VAR(to); uint UNINIT_VAR(left_length); MARIA_SHARE *share= info->s; - myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("_ma_read_dynamic_record"); if (filepos == HA_OFFSET_ERROR) @@ -1525,7 +1524,8 @@ int _ma_read_dynamic_record(MARIA_HA *info, uchar *buf, { if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size, block_info.rec_len + - share->base.extra_rec_buff_size, flag)) + share->base.extra_rec_buff_size, + MY_WME | share->malloc_flag)) goto err; } to= info->rec_buff; @@ -1784,7 +1784,6 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info, uchar *UNINIT_VAR(to); MARIA_BLOCK_INFO block_info; MARIA_SHARE *share= info->s; - myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("_ma_read_rnd_dynamic_record"); #ifdef MARIA_EXTERNAL_LOCKING @@ -1875,7 +1874,8 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info, { if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size, block_info.rec_len + - share->base.extra_rec_buff_size, flag)) + share->base.extra_rec_buff_size, + MY_WME | share->malloc_flag)) goto err; } to= info->rec_buff; diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c index 087100e3d8c..e73ac95cd35 100644 --- a/storage/maria/ma_extra.c +++ b/storage/maria/ma_extra.c @@ -239,25 +239,17 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, break; /* we're going to modify pieces of the state, stall Checkpoint */ - mysql_mutex_lock(&share->intern_lock); if (info->lock_type == F_UNLCK) { - mysql_mutex_unlock(&share->intern_lock); error= 1; /* Not possibly if not lock */ break; } + mysql_mutex_lock(&share->intern_lock); if (maria_is_any_key_active(share->state.key_map)) { - MARIA_KEYDEF *key= share->keyinfo; - uint i; - for (i =0 ; i < share->base.keys ; i++,key++) - { - if (!(key->flag & HA_NOSAME) && info->s->base.auto_key != i+1) - { - maria_clear_key_active(share->state.key_map, i); - info->update|= HA_STATE_CHANGED; - } - } + if (share->state.key_map != *(ulonglong*)extra_arg) + info->update|= HA_STATE_CHANGED; + share->state.key_map= *(ulonglong*)extra_arg; if (!share->changed) { @@ -551,7 +543,7 @@ int maria_reset(MARIA_HA *info) { int error= 0; MARIA_SHARE *share= info->s; - myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); + myf flag= MY_WME | share->malloc_flag; DBUG_ENTER("maria_reset"); /* Free buffers and reset the following flags: @@ -610,6 +602,20 @@ uint _ma_file_callback_to_id(void *callback_data) return share ? share->id : 0; } +/* + Disable MY_WAIT_IF_FULL flag for temporary tables + + Temporary tables does not have MY_WAIT_IF_FULL in share->write_flags +*/ + +uint _ma_write_flags_callback(void *callback_data, myf flags) +{ + MARIA_SHARE *share= (MARIA_SHARE*) callback_data; + if (share) + flags&= ~(~share->write_flag & MY_WAIT_IF_FULL); + return flags; +} + /** @brief flushes the data and/or index file of a table diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index d62ec3c8c89..ca19720245e 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -1099,10 +1099,6 @@ static TRANSLOG_FILE *get_current_logfile() uchar maria_trans_file_magic[]= { (uchar) 254, (uchar) 254, (uchar) 11, '\001', 'M', 'A', 'R', 'I', 'A', 'L', 'O', 'G' }; -#define LOG_HEADER_DATA_SIZE (sizeof(maria_trans_file_magic) + \ - 8 + 4 + 4 + 4 + 2 + 3 + \ - LSN_STORE_SIZE) - /* Write log file page header in the just opened new log file @@ -3613,6 +3609,9 @@ static my_bool translog_is_LSN_chunk(uchar type) @retval 1 Error */ +/* Stack size 26120 from clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + my_bool translog_init_with_table(const char *directory, uint32 log_file_max_size, uint32 server_version, @@ -4265,6 +4264,7 @@ err: ma_message_no_user(0, "log initialization failed"); DBUG_RETURN(1); } +PRAGMA_REENABLE_CHECK_STACK_FRAME /* diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h index abe85a12727..02d7b747d09 100644 --- a/storage/maria/ma_loghandler.h +++ b/storage/maria/ma_loghandler.h @@ -538,5 +538,13 @@ typedef enum } enum_maria_sync_log_dir; extern ulong sync_log_dir; +/* sizeof(maria_trans_file_magic) */ +#define LOG_MAGIC_SIZE 12 +#define LOG_HEADER_DATA_SIZE (LOG_MAGIC_SIZE + \ + 8 + 4 + 4 + 4 + 2 + 3 + \ + LSN_STORE_SIZE) +/* Flags when creating aria_log_control */ +#define control_file_open_flags (O_BINARY | /*O_DIRECT |*/ O_RDWR | O_CLOEXEC) + C_MODE_END #endif diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index ad98a534393..35578877a2f 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -94,7 +94,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, uint errpos; MARIA_HA info,*m_info; my_bitmap_map *changed_fields_bitmap; - myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); + myf flag= MY_WME | share->malloc_flag; DBUG_ENTER("maria_clone_internal"); errpos= 0; @@ -171,7 +171,6 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, mysql_mutex_lock(&share->intern_lock); info.read_record= share->read_record; share->reopen++; - share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL); if (share->options & HA_OPTION_READ_ONLY_DATA) { info.lock_type=F_RDLCK; @@ -266,7 +265,9 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags, uint i,j,len,errpos,head_length,base_pos,keys, realpath_err, key_parts,base_key_parts,unique_key_parts,fulltext_keys,uniques; uint internal_table= MY_TEST(open_flags & HA_OPEN_INTERNAL_TABLE); - myf common_flag= open_flags & HA_OPEN_TMP_TABLE ? MY_THREAD_SPECIFIC : 0; + myf common_flag= (((open_flags & HA_OPEN_TMP_TABLE) && + !(open_flags & HA_OPEN_GLOBAL_TMP_TABLE)) ? + MY_THREAD_SPECIFIC : 0); uint file_version; size_t info_length; char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN], @@ -984,11 +985,13 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags, share->options|= HA_OPTION_READ_ONLY_DATA; share->is_log_table= FALSE; + share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL); if (open_flags & HA_OPEN_TMP_TABLE || share->options & HA_OPTION_TMP_TABLE) { - common_flag|= MY_THREAD_SPECIFIC; share->options|= HA_OPTION_TMP_TABLE; share->temporary= share->delay_key_write= 1; + share->malloc_flag= + (open_flags & HA_OPEN_GLOBAL_TMP_TABLE) ? 0 : MY_THREAD_SPECIFIC; share->write_flag=MYF(MY_NABP); share->w_locks++; /* We don't have to update status */ share->tot_locks++; @@ -1555,6 +1558,9 @@ uint _ma_state_info_write(MARIA_SHARE *share, uint pWrite) @retval 1 Error */ +/* Stack size 26376 from clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + uint _ma_state_info_write_sub(File file, MARIA_STATE_INFO *state, uint pWrite) { uchar buff[MARIA_STATE_INFO_SIZE + MARIA_STATE_EXTRA_SIZE]; @@ -1629,6 +1635,7 @@ uint _ma_state_info_write_sub(File file, MARIA_STATE_INFO *state, uint pWrite) MYF(MY_NABP)); DBUG_RETURN(res != 0); } +PRAGMA_REENABLE_CHECK_STACK_FRAME static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state, myf flag) @@ -2046,9 +2053,8 @@ void _ma_set_index_pagecache_callbacks(PAGECACHE_FILE *file, int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share) { - myf flags= (share->mode & O_NOFOLLOW) ? MY_NOSYMLINKS | MY_WME : MY_WME; - if (share->temporary) - flags|= MY_THREAD_SPECIFIC; + myf flags= ((share->mode & O_NOFOLLOW) ? MY_NOSYMLINKS | MY_WME : MY_WME) | + share->malloc_flag; DEBUG_SYNC_C("mi_open_datafile"); info->dfile.file= share->bitmap.file.file= mysql_file_open(key_file_dfile, share->data_file_name.str, diff --git a/storage/maria/ma_packrec.c b/storage/maria/ma_packrec.c index 19783423ab5..57926ee49a7 100644 --- a/storage/maria/ma_packrec.c +++ b/storage/maria/ma_packrec.c @@ -1417,7 +1417,6 @@ uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_buff, uchar *header= info->header; uint head_length,UNINIT_VAR(ref_length); MARIA_SHARE *share= maria->s; - myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); if (file >= 0) { @@ -1444,7 +1443,8 @@ uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_buff, */ if (_ma_alloc_buffer(rec_buff_p, rec_buff_size_p, info->rec_len + info->blob_len + - share->base.extra_rec_buff_size, flag)) + share->base.extra_rec_buff_size, + MY_WME | share->malloc_flag)) return BLOCK_FATAL_ERROR; /* not enough memory */ bit_buff->blob_pos= *rec_buff_p + info->rec_len; bit_buff->blob_end= bit_buff->blob_pos + info->blob_len; @@ -1586,7 +1586,6 @@ _ma_mempack_get_block_info(MARIA_HA *maria, uchar *header) { MARIA_SHARE *share= maria->s; - myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); header+= read_pack_length((uint) share->pack.version, header, &info->rec_len); @@ -1596,7 +1595,8 @@ _ma_mempack_get_block_info(MARIA_HA *maria, &info->blob_len); /* _ma_alloc_rec_buff sets my_errno on error */ if (_ma_alloc_buffer(rec_buff_p, rec_buff_size_p, - info->blob_len + share->base.extra_rec_buff_size, flag)) + info->blob_len + share->base.extra_rec_buff_size, + MY_WME | share->malloc_flag)) return 0; /* not enough memory */ bit_buff->blob_pos= *rec_buff_p; bit_buff->blob_end= *rec_buff_p + info->blob_len; diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index c4c85d0bdd0..bc92eb66168 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -687,6 +687,8 @@ static my_bool pagecache_fwrite(PAGECACHE *pagecache, /* FIXME: ENGINE=Aria occasionally writes uninitialized data */ __msan_unpoison(args.page, pagecache->block_size); #endif + /* Reset MY_WAIT_IF_FULL for temporary tables */ + flags= _ma_write_flags_callback(filedesc->callback_data, flags); res= (int)my_pwrite(filedesc->file, args.page, pagecache->block_size, ((my_off_t) pageno << pagecache->shift), flags); (*filedesc->post_write_hook)(res, &args); diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index 90d0ed3c708..f05b366f0bf 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -1165,11 +1165,12 @@ end: /* The record may come from REPAIR, ALTER TABLE ENABLE KEYS, OPTIMIZE. */ + prototype_redo_exec_hook(REDO_REPAIR_TABLE) { int error= 1; MARIA_HA *info; - HA_CHECK param; + HA_CHECK *param; char *name; my_bool quick_repair; DBUG_ENTER("exec_REDO_LOGREC_REDO_REPAIR_TABLE"); @@ -1201,35 +1202,39 @@ prototype_redo_exec_hook(REDO_REPAIR_TABLE) */ tprint(tracef, " repairing...\n"); - maria_chk_init(¶m); - param.isam_file_name= name= info->s->open_file_name.str; - param.testflag= uint8korr(rec->header + FILEID_STORE_SIZE); - param.tmpdir= maria_tmpdir; - param.max_trid= max_long_trid; + if (!(param= my_malloc(PSI_INSTRUMENT_ME, sizeof(*param), MYF(MY_WME)))) + DBUG_RETURN(0); + + maria_chk_init(param); + param->isam_file_name= name= info->s->open_file_name.str; + param->testflag= uint8korr(rec->header + FILEID_STORE_SIZE); + param->tmpdir= maria_tmpdir; + param->max_trid= max_long_trid; DBUG_ASSERT(maria_tmpdir); info->s->state.key_map= uint8korr(rec->header + FILEID_STORE_SIZE + 8); - quick_repair= MY_TEST(param.testflag & T_QUICK); + quick_repair= MY_TEST(param->testflag & T_QUICK); - if (param.testflag & T_REP_PARALLEL) + if (param->testflag & T_REP_PARALLEL) { - if (maria_repair_parallel(¶m, info, name, quick_repair)) + if (maria_repair_parallel(param, info, name, quick_repair)) goto end; } - else if (param.testflag & T_REP_BY_SORT) + else if (param->testflag & T_REP_BY_SORT) { - if (maria_repair_by_sort(¶m, info, name, quick_repair)) + if (maria_repair_by_sort(param, info, name, quick_repair)) goto end; } - else if (maria_repair(¶m, info, name, quick_repair)) + else if (maria_repair(param, info, name, quick_repair)) goto end; if (_ma_update_state_lsns(info->s, rec->lsn, trnman_get_min_safe_trid(), - TRUE, !(param.testflag & T_NO_CREATE_RENAME_LSN))) + TRUE, !(param->testflag & T_NO_CREATE_RENAME_LSN))) goto end; error= 0; end: + my_free(param); DBUG_RETURN(error); } @@ -2581,6 +2586,8 @@ prototype_undo_exec_hook(UNDO_BULK_INSERT) return error; } +/* Stack size 18776 in clang. Ok as this is during recover */ +PRAGMA_DISABLE_CHECK_STACK_FRAME static int run_redo_phase(LSN lsn, LSN lsn_end, enum maria_apply_log_way apply) { @@ -2824,6 +2831,7 @@ err: translog_free_record_header(&rec); DBUG_RETURN(1); } +PRAGMA_REENABLE_CHECK_STACK_FRAME /** diff --git a/storage/maria/ma_rt_test.c b/storage/maria/ma_rt_test.c index 3af7d93879e..17145231409 100644 --- a/storage/maria/ma_rt_test.c +++ b/storage/maria/ma_rt_test.c @@ -101,7 +101,7 @@ int main(int argc, char *argv[]) if (maria_init() || (init_pagecache(maria_pagecache, maria_block_size * 16, 0, 0, maria_block_size, 0, MY_WME) == 0) || - ma_control_file_open(TRUE, TRUE, TRUE) || + ma_control_file_open_or_create() || (init_pagecache(maria_log_pagecache, TRANSLOG_PAGECACHE_SIZE, 0, 0, TRANSLOG_PAGE_SIZE, 0, MY_WME) == 0) || diff --git a/storage/maria/ma_test1.c b/storage/maria/ma_test1.c index 22f80ca2d9e..a14679d3a60 100644 --- a/storage/maria/ma_test1.c +++ b/storage/maria/ma_test1.c @@ -81,7 +81,7 @@ int main(int argc,char *argv[]) if (maria_init() || (init_pagecache(maria_pagecache, maria_block_size * 16, 0, 0, maria_block_size, 0, MY_WME) == 0) || - ma_control_file_open(TRUE, TRUE, TRUE) || + ma_control_file_open_or_create() || (init_pagecache(maria_log_pagecache, TRANSLOG_PAGECACHE_SIZE, 0, 0, TRANSLOG_PAGE_SIZE, 0, MY_WME) == 0) || diff --git a/storage/maria/ma_test2.c b/storage/maria/ma_test2.c index 6628465365f..400e6193695 100644 --- a/storage/maria/ma_test2.c +++ b/storage/maria/ma_test2.c @@ -90,7 +90,7 @@ int main(int argc, char *argv[]) if (maria_init() || (init_pagecache(maria_pagecache, pagecache_size, 0, 0, maria_block_size, 0, MY_WME) == 0) || - ma_control_file_open(TRUE, TRUE, TRUE) || + ma_control_file_open_or_create() || (init_pagecache(maria_log_pagecache, TRANSLOG_PAGECACHE_SIZE, 0, 0, TRANSLOG_PAGE_SIZE, 0, MY_WME) == 0) || diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index 705562eb795..147dc83d78a 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -761,6 +761,11 @@ typedef struct st_maria_share ulong max_pack_length; ulong state_diff_length; uint rec_reflength; /* rec_reflength in use now */ + /* + Extra flag to use for my_malloc(); set to MY_THREAD_SPECIFIC for temporary + tables whose memory allocation should be accounted to the current THD. + */ + uint malloc_flag; uint keypage_header; uint32 ftkeys; /* Number of distinct full-text keys + 1 */ @@ -1773,6 +1778,7 @@ extern my_bool ma_yield_and_check_if_killed(MARIA_HA *info, int inx); extern my_bool ma_killed_standalone(MARIA_HA *); extern uint _ma_file_callback_to_id(void *callback_data); +extern uint _ma_write_flags_callback(void *callback_data, myf flags); extern void free_maria_share(MARIA_SHARE *share); static inline void unmap_file(MARIA_HA *info __attribute__((unused))) diff --git a/storage/maria/test_ma_backup.c b/storage/maria/test_ma_backup.c index c57ec6ece0d..5cb2b074887 100644 --- a/storage/maria/test_ma_backup.c +++ b/storage/maria/test_ma_backup.c @@ -47,7 +47,7 @@ int main(int argc __attribute__((unused)), char *argv[]) if (maria_init() || (init_pagecache(maria_pagecache, maria_block_size * 2000, 0, 0, maria_block_size, 0, MY_WME) == 0) || - ma_control_file_open(TRUE, TRUE, TRUE) || + ma_control_file_open_or_create() || (init_pagecache(maria_log_pagecache, TRANSLOG_PAGECACHE_SIZE, 0, 0, TRANSLOG_PAGE_SIZE, 0, MY_WME) == 0) || diff --git a/storage/maria/unittest/CMakeLists.txt b/storage/maria/unittest/CMakeLists.txt index a2da1507c97..a7b3441044d 100644 --- a/storage/maria/unittest/CMakeLists.txt +++ b/storage/maria/unittest/CMakeLists.txt @@ -15,7 +15,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/unittest/mytap) -LINK_LIBRARIES(aria myisam mytap mysys dbug strings ${ZLIB_LIBRARY}) +LINK_LIBRARIES(aria myisam mytap mysys dbug strings ${ZLIB_LIBRARIES}) MY_ADD_TESTS(ma_control_file trnman) diff --git a/storage/maria/unittest/ma_control_file-t.c b/storage/maria/unittest/ma_control_file-t.c index 859d5514ffa..fdbe86de01b 100644 --- a/storage/maria/unittest/ma_control_file-t.c +++ b/storage/maria/unittest/ma_control_file-t.c @@ -114,7 +114,7 @@ static CONTROL_FILE_ERROR local_ma_control_file_open(void) { CONTROL_FILE_ERROR error; error_handler_hook= my_ignore_message; - error= ma_control_file_open(TRUE, TRUE, TRUE); + error= ma_control_file_open(TRUE, TRUE, TRUE, control_file_open_flags); error_handler_hook= default_error_handler_hook; return error; } diff --git a/storage/maria/unittest/ma_test_loghandler-t.c b/storage/maria/unittest/ma_test_loghandler-t.c index ccda66af755..0a1d396e42e 100644 --- a/storage/maria/unittest/ma_test_loghandler-t.c +++ b/storage/maria/unittest/ma_test_loghandler-t.c @@ -143,6 +143,8 @@ static my_bool read_and_check_content(TRANSLOG_HEADER_BUFFER *rec, } +PRAGMA_DISABLE_CHECK_STACK_FRAME + int main(int argc __attribute__((unused)), char *argv[]) { uint32 i; @@ -197,7 +199,7 @@ int main(int argc __attribute__((unused)), char *argv[]) } #endif - if (ma_control_file_open(TRUE, TRUE, TRUE)) + if (ma_control_file_open(TRUE, TRUE, TRUE, control_file_open_flags)) { fprintf(stderr, "Can't init control file (%d)\n", errno); exit(1); @@ -664,5 +666,6 @@ err: my_end(0); return(MY_TEST(exit_status())); } +PRAGMA_REENABLE_CHECK_STACK_FRAME #include "../ma_check_standalone.h" diff --git a/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c b/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c index 21f6b7d7b44..5c4045cc659 100644 --- a/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c +++ b/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c @@ -66,7 +66,7 @@ int main(int argc __attribute__((unused)), char *argv[]) } #endif - if (ma_control_file_open(TRUE, TRUE,TRUE)) + if (ma_control_file_open(TRUE, TRUE,TRUE, control_file_open_flags)) { fprintf(stderr, "Can't init control file (%d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c b/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c index 391d785159a..eedeb9d70d4 100644 --- a/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c +++ b/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c @@ -64,7 +64,7 @@ int main(int argc __attribute__((unused)), char *argv[]) } #endif - if (ma_control_file_open(TRUE, TRUE, TRUE)) + if (ma_control_file_open(TRUE, TRUE, TRUE, control_file_open_flags)) { fprintf(stderr, "Can't init control file (%d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c index e8e114dd155..b0e1be8f0d9 100644 --- a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c +++ b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c @@ -280,7 +280,7 @@ int main(int argc __attribute__((unused)), char *argv[]) bzero(long_tr_id, 6); - if (ma_control_file_open(TRUE, TRUE, TRUE)) + if (ma_control_file_open(TRUE, TRUE, TRUE, control_file_open_flags)) { fprintf(stderr, "Can't init control file (%d)\n", errno); exit(1); @@ -443,7 +443,7 @@ int main(int argc __attribute__((unused)), char *argv[]) end_pagecache(&pagecache, 1); ma_control_file_end(); - if (ma_control_file_open(TRUE,TRUE,TRUE)) + if (ma_control_file_open(TRUE,TRUE,TRUE, control_file_open_flags)) { fprintf(stderr, "pass2: Can't init control file (%d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_multithread-t.c b/storage/maria/unittest/ma_test_loghandler_multithread-t.c index be6046abab4..9b7e239b4cd 100644 --- a/storage/maria/unittest/ma_test_loghandler_multithread-t.c +++ b/storage/maria/unittest/ma_test_loghandler_multithread-t.c @@ -331,7 +331,7 @@ int main(int argc __attribute__((unused)), exit(1); } - if (ma_control_file_open(TRUE, TRUE, TRUE)) + if (ma_control_file_open(TRUE, TRUE, TRUE, control_file_open_flags)) { fprintf(stderr, "Can't init control file (%d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_noflush-t.c b/storage/maria/unittest/ma_test_loghandler_noflush-t.c index 46b3a8e71aa..28cac2ee1cf 100644 --- a/storage/maria/unittest/ma_test_loghandler_noflush-t.c +++ b/storage/maria/unittest/ma_test_loghandler_noflush-t.c @@ -65,7 +65,7 @@ int main(int argc __attribute__((unused)), char *argv[]) } #endif - if (ma_control_file_open(TRUE, TRUE, TRUE)) + if (ma_control_file_open(TRUE, TRUE, TRUE, control_file_open_flags)) { fprintf(stderr, "Can't init control file (%d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_nologs-t.c b/storage/maria/unittest/ma_test_loghandler_nologs-t.c index b95d8bee24c..a7c526b2e17 100644 --- a/storage/maria/unittest/ma_test_loghandler_nologs-t.c +++ b/storage/maria/unittest/ma_test_loghandler_nologs-t.c @@ -66,7 +66,7 @@ int main(int argc __attribute__((unused)), char *argv[]) } #endif - if (ma_control_file_open(TRUE, TRUE, TRUE)) + if (ma_control_file_open(TRUE, TRUE, TRUE, control_file_open_flags)) { fprintf(stderr, "Can't init control file (%d)\n", errno); exit(1); @@ -139,7 +139,7 @@ int main(int argc __attribute__((unused)), char *argv[]) } } - if (ma_control_file_open(TRUE, TRUE, TRUE)) + if (ma_control_file_open(TRUE, TRUE, TRUE, control_file_open_flags)) { fprintf(stderr, "Can't init control file (%d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_pagecache-t.c b/storage/maria/unittest/ma_test_loghandler_pagecache-t.c index 892a773b475..4ecc8f1f8e7 100644 --- a/storage/maria/unittest/ma_test_loghandler_pagecache-t.c +++ b/storage/maria/unittest/ma_test_loghandler_pagecache-t.c @@ -69,7 +69,7 @@ int main(int argc __attribute__((unused)), char *argv[]) } #endif - if (ma_control_file_open(TRUE, TRUE, TRUE)) + if (ma_control_file_open(TRUE, TRUE, TRUE, control_file_open_flags)) { fprintf(stderr, "Can't init control file (%d)\n", errno); exit(1); diff --git a/storage/maria/unittest/ma_test_loghandler_purge-t.c b/storage/maria/unittest/ma_test_loghandler_purge-t.c index 07b50f197de..b26a2f99ae7 100644 --- a/storage/maria/unittest/ma_test_loghandler_purge-t.c +++ b/storage/maria/unittest/ma_test_loghandler_purge-t.c @@ -67,7 +67,7 @@ int main(int argc __attribute__((unused)), char *argv[]) } #endif - if (ma_control_file_open(TRUE, TRUE, TRUE)) + if (ma_control_file_open(TRUE, TRUE, TRUE, control_file_open_flags)) { fprintf(stderr, "Can't init control file (%d)\n", errno); exit(1); diff --git a/storage/mroonga/CMakeLists.txt b/storage/mroonga/CMakeLists.txt index bea0eecc8b7..4553fd432b0 100644 --- a/storage/mroonga/CMakeLists.txt +++ b/storage/mroonga/CMakeLists.txt @@ -57,6 +57,11 @@ if(MRN_BUNDLED) "${PLUGIN_MROONGA}" STREQUAL "NO") return() endif() + if(WITHOUT_DYNAMIC_PLUGINS) + if(NOT (PLUGIN_MROONGA STREQUAL STATIC)) + return() + endif() + endif() endif() set(MRN_BUNDLED_GROONGA_RELATIVE_DIR "vendor/groonga") diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index 44fd09e74ed..49a319002d9 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -4348,9 +4348,9 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint open_options) // TODO: implemented by "reindex" instead of "remove and recreate". // Because "remove and recreate" invalidates opened indexes by // other threads. - error = wrapper_disable_indexes_mroonga(HA_KEY_SWITCH_ALL); + error = wrapper_disable_indexes_mroonga(key_map(table->s->keys), false); if (!error) { - error = wrapper_enable_indexes_mroonga(HA_KEY_SWITCH_ALL); + error = wrapper_enable_indexes_mroonga(key_map(table->s->keys), false); } } } @@ -13674,197 +13674,184 @@ int ha_mroonga::generic_disable_index(int i, KEY *key_info) DBUG_RETURN(error); } -int ha_mroonga::wrapper_disable_indexes_mroonga(uint mode) +int ha_mroonga::wrapper_disable_indexes_mroonga(key_map map, bool persist) { int error = 0; MRN_DBUG_ENTER_METHOD(); - if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE || mode == HA_KEY_SWITCH_ALL) { - uint i; - for (i = 0; i < table_share->keys; i++) { - if (i == table->s->primary_key) { - continue; - } - if (share->wrap_key_nr[i] < MAX_KEY) { - continue; - } - if (!grn_index_tables[i]) { - DBUG_PRINT("info", ("mroonga: keys are disabled already %u", i)); - DBUG_RETURN(0); - } + uint i; + for (i = 0; i < table_share->keys; i++) { + if (i == table->s->primary_key) { + continue; + } + if (share->wrap_key_nr[i] < MAX_KEY) { + continue; + } + if (!grn_index_tables[i]) { + DBUG_PRINT("info", ("mroonga: keys are disabled already %u", i)); + DBUG_RETURN(0); + } + } + KEY *key_info = table_share->key_info; + for (i = 0; i < table_share->keys; i++) { + if (!(key_info[i].flags & HA_FULLTEXT) && + !mrn_is_geo_key(&key_info[i])) { + continue; } - KEY *key_info = table_share->key_info; - for (i = 0; i < table_share->keys; i++) { - if (!(key_info[i].flags & HA_FULLTEXT) && - !mrn_is_geo_key(&key_info[i])) { - continue; - } - int sub_error = generic_disable_index(i, key_info); - if (error != 0 && sub_error != 0) { - error = sub_error; - } + int sub_error = generic_disable_index(i, key_info); + if (error != 0 && sub_error != 0) { + error = sub_error; } - } else { - error = HA_ERR_WRONG_COMMAND; } DBUG_RETURN(error); } -int ha_mroonga::wrapper_disable_indexes(uint mode) +int ha_mroonga::wrapper_disable_indexes(key_map map, bool persist) { int error = 0; MRN_DBUG_ENTER_METHOD(); MRN_SET_WRAP_SHARE_KEY(share, table->s); MRN_SET_WRAP_TABLE_KEY(this, table); - error = wrap_handler->ha_disable_indexes(mode); + error = wrap_handler->ha_disable_indexes(map, persist); MRN_SET_BASE_SHARE_KEY(share, table->s); MRN_SET_BASE_TABLE_KEY(this, table); if (error == HA_ERR_WRONG_COMMAND) { error = 0; } if (!error) { - error = wrapper_disable_indexes_mroonga(mode); + error = wrapper_disable_indexes_mroonga(map, persist); } DBUG_RETURN(error); } -int ha_mroonga::storage_disable_indexes(uint mode) +int ha_mroonga::storage_disable_indexes(key_map map, bool persist) { int error = 0; MRN_DBUG_ENTER_METHOD(); - if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE || mode == HA_KEY_SWITCH_ALL) { - uint i; - for (i = 0; i < table_share->keys; i++) { - if (i == table->s->primary_key) { - continue; - } - if (!grn_index_tables[i]) { - DBUG_PRINT("info", ("mroonga: keys are disabled already %u", i)); - DBUG_RETURN(0); - } + uint i; + for (i = 0; i < table_share->keys; i++) { + if (i == table->s->primary_key) { + continue; + } + if (!grn_index_tables[i]) { + DBUG_PRINT("info", ("mroonga: keys are disabled already %u", i)); + DBUG_RETURN(0); + } + } + KEY *key_info = table_share->key_info; + for (i = 0; i < table_share->keys; i++) { + if (i == table->s->primary_key) { + continue; + } + if (map.is_set(i)) { + continue; } - KEY *key_info = table_share->key_info; - for (i = 0; i < table_share->keys; i++) { - if (i == table->s->primary_key) { - continue; - } - if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE && - (key_info[i].flags & HA_NOSAME)) { - continue; - } - int sub_error = generic_disable_index(i, key_info); - if (error != 0 && sub_error != 0) { - error = sub_error; - } + int sub_error = generic_disable_index(i, key_info); + if (error != 0 && sub_error != 0) { + error = sub_error; } - } else { - DBUG_RETURN(HA_ERR_WRONG_COMMAND); } DBUG_RETURN(error); } -int ha_mroonga::disable_indexes(uint mode) +int ha_mroonga::disable_indexes(key_map map, bool persist) { int error = 0; MRN_DBUG_ENTER_METHOD(); if (share->wrapper_mode) { - error = wrapper_disable_indexes(mode); + error = wrapper_disable_indexes(map, persist); } else { - error = storage_disable_indexes(mode); + error = storage_disable_indexes(map, persist); } DBUG_RETURN(error); } -int ha_mroonga::wrapper_enable_indexes_mroonga(uint mode) +int ha_mroonga::wrapper_enable_indexes_mroonga(key_map map, bool persist) { int error = 0; MRN_DBUG_ENTER_METHOD(); - if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE || mode == HA_KEY_SWITCH_ALL) { - uint i, j; - for (i = 0; i < table_share->keys; i++) { - if (i == table->s->primary_key) { - continue; - } - if (share->wrap_key_nr[i] < MAX_KEY) { - continue; - } - if (!grn_index_columns[i]) { - break; - } + uint i, j; + for (i = 0; i < table_share->keys; i++) { + if (i == table->s->primary_key) { + continue; } - if (i == table_share->keys) { - DBUG_PRINT("info", ("mroonga: keys are enabled already")); - DBUG_RETURN(0); + if (share->wrap_key_nr[i] < MAX_KEY) { + continue; + } + if (!grn_index_columns[i]) { + break; + } + } + if (i == table_share->keys) { + DBUG_PRINT("info", ("mroonga: keys are enabled already")); + DBUG_RETURN(0); + } + KEY *p_key_info = &table->key_info[table_share->primary_key]; + KEY *key_info = table_share->key_info; + uint n_keys = table_share->keys; + MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(grn_obj *, index_tables, n_keys); + MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(grn_obj *, index_columns, n_keys); + bitmap_clear_all(table->read_set); + mrn_set_bitmap_by_key(table->read_set, p_key_info); + mrn::PathMapper mapper(share->table_name); + for (i = 0, j = 0; i < n_keys; i++) { + if (!(key_info[i].flags & HA_FULLTEXT) && + !mrn_is_geo_key(&key_info[i])) { + j++; + continue; } - KEY *p_key_info = &table->key_info[table_share->primary_key]; - KEY *key_info = table_share->key_info; - uint n_keys = table_share->keys; - MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(grn_obj *, index_tables, n_keys); - MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(grn_obj *, index_columns, n_keys); - bitmap_clear_all(table->read_set); - mrn_set_bitmap_by_key(table->read_set, p_key_info); - mrn::PathMapper mapper(share->table_name); - for (i = 0, j = 0; i < n_keys; i++) { - if (!(key_info[i].flags & HA_FULLTEXT) && - !mrn_is_geo_key(&key_info[i])) { - j++; - continue; - } - if ((error = mrn_add_index_param(share, &key_info[i], i))) - { - break; - } - index_tables[i] = NULL; - index_columns[i] = NULL; - if (!grn_index_columns[i]) { - if ( - (key_info[i].flags & HA_FULLTEXT) && - (error = wrapper_create_index_fulltext(mapper.table_name(), - i, &key_info[i], - index_tables, index_columns, - share)) - ) { - break; - } else if ( - mrn_is_geo_key(&key_info[i]) && - (error = wrapper_create_index_geo(mapper.table_name(), - i, &key_info[i], - index_tables, index_columns, - share)) - ) { - break; - } - grn_index_columns[i] = index_columns[i]; - } - mrn_set_bitmap_by_key(table->read_set, &key_info[i]); - } - if (!error && i > j) + if ((error = mrn_add_index_param(share, &key_info[i], i))) { - error = wrapper_fill_indexes(ha_thd(), table->key_info, index_columns, - n_keys); + break; } - bitmap_set_all(table->read_set); - MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables); - MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns); - } else { - error = HA_ERR_WRONG_COMMAND; + index_tables[i] = NULL; + index_columns[i] = NULL; + if (!grn_index_columns[i]) { + if ( + (key_info[i].flags & HA_FULLTEXT) && + (error = wrapper_create_index_fulltext(mapper.table_name(), + i, &key_info[i], + index_tables, index_columns, + share)) + ) { + break; + } else if ( + mrn_is_geo_key(&key_info[i]) && + (error = wrapper_create_index_geo(mapper.table_name(), + i, &key_info[i], + index_tables, index_columns, + share)) + ) { + break; + } + grn_index_columns[i] = index_columns[i]; + } + mrn_set_bitmap_by_key(table->read_set, &key_info[i]); } + if (!error && i > j) + { + error = wrapper_fill_indexes(ha_thd(), table->key_info, index_columns, + n_keys); + } + bitmap_set_all(table->read_set); + MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables); + MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns); DBUG_RETURN(error); } -int ha_mroonga::wrapper_enable_indexes(uint mode) +int ha_mroonga::wrapper_enable_indexes(key_map map, bool persist) { int error = 0; MRN_DBUG_ENTER_METHOD(); - int mroonga_error = wrapper_enable_indexes_mroonga(mode); + int mroonga_error = wrapper_enable_indexes_mroonga(map, persist); MRN_SET_WRAP_SHARE_KEY(share, table->s); MRN_SET_WRAP_TABLE_KEY(this, table); - error = wrap_handler->ha_enable_indexes(mode); + error = wrap_handler->ha_enable_indexes(map, persist); MRN_SET_BASE_SHARE_KEY(share, table->s); MRN_SET_BASE_TABLE_KEY(this, table); if (error == HA_ERR_WRONG_COMMAND) { @@ -13873,95 +13860,86 @@ int ha_mroonga::wrapper_enable_indexes(uint mode) DBUG_RETURN(error); } -int ha_mroonga::storage_enable_indexes(uint mode) +int ha_mroonga::storage_enable_indexes(key_map map, bool persist) { int error = 0; uint n_keys = table_share->keys; MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(grn_obj *, index_tables, n_keys); MRN_ALLOCATE_VARIABLE_LENGTH_ARRAYS(grn_obj *, index_columns, n_keys); bool have_multiple_column_index = false; - bool skip_unique_key = (mode == HA_KEY_SWITCH_NONUNIQ_SAVE); MRN_DBUG_ENTER_METHOD(); - if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE || mode == HA_KEY_SWITCH_ALL) { - uint i; - for (i = 0; i < table_share->keys; i++) { - if (i == table->s->primary_key) { - continue; - } - if (!grn_index_columns[i]) { - break; - } + uint i; + for (i = 0; i < n_keys; i++) { + if (i == table->s->primary_key) { + continue; } - if (i == table_share->keys) { - DBUG_PRINT("info", ("mroonga: keys are enabled already")); - MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables); - MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns); - DBUG_RETURN(0); + if (!grn_index_columns[i]) { + break; + } + } + if (i == n_keys) { + DBUG_PRINT("info", ("mroonga: keys are enabled already")); + MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables); + MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns); + DBUG_RETURN(0); + } + KEY *key_info = table->key_info; + bitmap_clear_all(table->read_set); + mrn::PathMapper mapper(share->table_name); + for (; i < n_keys; i++) { + if (!map.is_set(i)) { + continue; } - KEY *key_info = table->key_info; - bitmap_clear_all(table->read_set); - mrn::PathMapper mapper(share->table_name); - for (i = 0; i < n_keys; i++) { - if (i == table->s->primary_key) { - continue; - } - if (skip_unique_key && (key_info[i].flags & HA_NOSAME)) { - continue; - } - if ((error = mrn_add_index_param(share, &key_info[i], i))) + if ((error = mrn_add_index_param(share, &key_info[i], i))) + { + break; + } + index_tables[i] = NULL; + if (!grn_index_columns[i]) { + if ((error = storage_create_index(table, mapper.table_name(), grn_table, + share, &key_info[i], index_tables, + index_columns, i))) { break; } - index_tables[i] = NULL; - if (!grn_index_columns[i]) { - if ((error = storage_create_index(table, mapper.table_name(), grn_table, - share, &key_info[i], index_tables, - index_columns, i))) - { - break; - } - if ( - KEY_N_KEY_PARTS(&(key_info[i])) != 1 && - !(key_info[i].flags & HA_FULLTEXT) - ) { - mrn_set_bitmap_by_key(table->read_set, &key_info[i]); - have_multiple_column_index = true; - } - grn_index_tables[i] = index_tables[i]; - grn_index_columns[i] = index_columns[i]; - } else { - index_columns[i] = NULL; + if ( + KEY_N_KEY_PARTS(&(key_info[i])) != 1 && + !(key_info[i].flags & HA_FULLTEXT) + ) { + mrn_set_bitmap_by_key(table->read_set, &key_info[i]); + have_multiple_column_index = true; } + grn_index_tables[i] = index_tables[i]; + grn_index_columns[i] = index_columns[i]; + } else { + index_columns[i] = NULL; } - if (!error && have_multiple_column_index) - { - error = storage_add_index_multiple_columns(key_info, n_keys, - index_tables, - index_columns, - skip_unique_key); - } - bitmap_set_all(table->read_set); - } else { - MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables); - MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); } + if (!error && have_multiple_column_index) + { + bool skip_unique_key= !table->s->keys_in_use.is_clear_all(); + error = storage_add_index_multiple_columns(key_info, n_keys, + index_tables, + index_columns, + skip_unique_key); + } + bitmap_set_all(table->read_set); MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables); MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns); DBUG_RETURN(error); } -int ha_mroonga::enable_indexes(uint mode) +int ha_mroonga::enable_indexes(key_map map, bool persist) { int error = 0; MRN_DBUG_ENTER_METHOD(); share->disable_keys = false; if (share->wrapper_mode) { - error = wrapper_enable_indexes(mode); + error = wrapper_enable_indexes(map, persist); } else { - error = storage_enable_indexes(mode); + error = storage_enable_indexes(map, persist); } DBUG_RETURN(error); } diff --git a/storage/mroonga/ha_mroonga.hpp b/storage/mroonga/ha_mroonga.hpp index 52fd0ef9a0e..394eba7eb0e 100644 --- a/storage/mroonga/ha_mroonga.hpp +++ b/storage/mroonga/ha_mroonga.hpp @@ -544,8 +544,8 @@ public: bool is_crashed() const mrn_override; bool auto_repair(int error) const mrn_override; bool auto_repair() const; - int disable_indexes(uint mode) mrn_override; - int enable_indexes(uint mode) mrn_override; + int disable_indexes(key_map map, bool persist) mrn_override; + int enable_indexes(key_map map, bool persist) mrn_override; int check(THD* thd, HA_CHECK_OPT* check_opt) mrn_override; int repair(THD* thd, HA_CHECK_OPT* check_opt) mrn_override; bool check_and_repair(THD *thd) mrn_override; @@ -1146,12 +1146,12 @@ private: bool wrapper_auto_repair(int error) const; bool storage_auto_repair(int error) const; int generic_disable_index(int i, KEY *key_info); - int wrapper_disable_indexes_mroonga(uint mode); - int wrapper_disable_indexes(uint mode); - int storage_disable_indexes(uint mode); - int wrapper_enable_indexes_mroonga(uint mode); - int wrapper_enable_indexes(uint mode); - int storage_enable_indexes(uint mode); + int wrapper_disable_indexes_mroonga(key_map map, bool persist); + int wrapper_disable_indexes(key_map map, bool persist); + int storage_disable_indexes(key_map map, bool persist); + int wrapper_enable_indexes_mroonga(key_map map, bool persist); + int wrapper_enable_indexes(key_map map, bool persist); + int storage_enable_indexes(key_map map, bool persist); int wrapper_check(THD* thd, HA_CHECK_OPT* check_opt); int storage_check(THD* thd, HA_CHECK_OPT* check_opt); int wrapper_fill_indexes(THD *thd, KEY *key_info, diff --git a/storage/mroonga/vendor/groonga/CMakeLists.txt b/storage/mroonga/vendor/groonga/CMakeLists.txt index 5b25ada4f5b..cdbfb8f160b 100644 --- a/storage/mroonga/vendor/groonga/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/CMakeLists.txt @@ -200,6 +200,7 @@ endif() include_directories( BEFORE + ${CMAKE_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/lib diff --git a/storage/mroonga/vendor/groonga/lib/db.c b/storage/mroonga/vendor/groonga/lib/db.c index c3bbb64f703..65463bdad20 100644 --- a/storage/mroonga/vendor/groonga/lib/db.c +++ b/storage/mroonga/vendor/groonga/lib/db.c @@ -38,6 +38,7 @@ #include "grn_util.h" #include "grn_cache.h" #include "grn_window_functions.h" +#include #include #include @@ -1060,6 +1061,8 @@ grn_table_create_validate(grn_ctx *ctx, const char *name, unsigned int name_size return ctx->rc; } +PRAGMA_DISABLE_CHECK_STACK_FRAME + static grn_obj * grn_table_create_with_max_n_subrecs(grn_ctx *ctx, const char *name, unsigned int name_size, const char *path, @@ -1238,6 +1241,7 @@ grn_table_create_with_max_n_subrecs(grn_ctx *ctx, const char *name, } return res; } +PRAGMA_REENABLE_CHECK_STACK_FRAME grn_obj * grn_table_create(grn_ctx *ctx, const char *name, unsigned int name_size, @@ -4776,6 +4780,9 @@ _grn_table_key(grn_ctx *ctx, grn_obj *table, grn_id id, uint32_t *key_size) /* column */ + +PRAGMA_DISABLE_CHECK_STACK_FRAME + grn_obj * grn_column_create(grn_ctx *ctx, grn_obj *table, const char *name, unsigned int name_size, @@ -4978,6 +4985,7 @@ exit : if (!res && id) { grn_obj_delete_by_id(ctx, db, id, GRN_TRUE); } GRN_API_RETURN(res); } +PRAGMA_REENABLE_CHECK_STACK_FRAME grn_obj * grn_column_open(grn_ctx *ctx, grn_obj *table, @@ -8540,6 +8548,8 @@ grn_obj_spec_save(grn_ctx *ctx, grn_db_obj *obj) grn_obj_close(ctx, &v); } +PRAGMA_DISABLE_CHECK_STACK_FRAME + inline static void grn_obj_set_info_source_invalid_lexicon_error(grn_ctx *ctx, const char *message, @@ -8590,6 +8600,8 @@ grn_obj_set_info_source_invalid_lexicon_error(grn_ctx *ctx, source_name_size, source_name); } +PRAGMA_REENABLE_CHECK_STACK_FRAME + inline static grn_rc grn_obj_set_info_source_validate(grn_ctx *ctx, grn_obj *obj, grn_obj *value) { @@ -8597,7 +8609,7 @@ grn_obj_set_info_source_validate(grn_ctx *ctx, grn_obj *obj, grn_obj *value) grn_obj *lexicon = NULL; grn_id lexicon_domain_id; grn_obj *lexicon_domain = NULL; - grn_bool lexicon_domain_is_table; + grn_bool lexicon_domain_is_table __attribute__((unused)); grn_bool lexicon_have_tokenizer; grn_id *source_ids; int i, n_source_ids; @@ -9330,7 +9342,7 @@ remove_reference_tables(grn_ctx *ctx, grn_obj *table, grn_obj *db) grn_bool is_close_opened_object_mode = GRN_FALSE; grn_id table_id; char table_name[GRN_TABLE_MAX_KEY_SIZE]; - int table_name_size; + int table_name_size __attribute__((unused)); grn_table_cursor *cursor; if (grn_thread_get_limit() == 1) { @@ -10317,12 +10329,10 @@ grn_db_spec_unpack(grn_ctx *ctx, const char *error_message_tag) { grn_obj *db; - grn_db *db_raw; grn_rc rc; uint32_t spec_size; db = ctx->impl->db; - db_raw = (grn_db *)db; rc = grn_vector_decode(ctx, decoded_spec, diff --git a/storage/mroonga/vendor/groonga/lib/load.c b/storage/mroonga/vendor/groonga/lib/load.c index eb77f2b3849..25d621e7f56 100644 --- a/storage/mroonga/vendor/groonga/lib/load.c +++ b/storage/mroonga/vendor/groonga/lib/load.c @@ -20,6 +20,9 @@ #include "grn_ctx_impl.h" #include "grn_db.h" #include "grn_util.h" +#include + +PRAGMA_DISABLE_CHECK_STACK_FRAME static void grn_loader_save_error(grn_ctx *ctx, grn_loader *loader) @@ -1228,3 +1231,5 @@ grn_load(grn_ctx *ctx, grn_content_type input_type, } GRN_API_RETURN(ctx->rc); } + +PRAGMA_REENABLE_CHECK_STACK_FRAME diff --git a/storage/mroonga/vendor/groonga/lib/operator.c b/storage/mroonga/vendor/groonga/lib/operator.c index 1e1f2cf7e4d..940c0b14a09 100644 --- a/storage/mroonga/vendor/groonga/lib/operator.c +++ b/storage/mroonga/vendor/groonga/lib/operator.c @@ -20,6 +20,7 @@ #include "grn_db.h" #include "grn_str.h" #include "grn_normalizer.h" +#include #include @@ -31,6 +32,8 @@ # include #endif +PRAGMA_DISABLE_CHECK_STACK_FRAME + static const char *operator_names[] = { "push", "pop", @@ -1360,3 +1363,5 @@ grn_operator_exec_regexp(grn_ctx *ctx, grn_obj *target, grn_obj *pattern) } GRN_API_RETURN(matched); } + +PRAGMA_REENABLE_CHECK_STACK_FRAME diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_object_list.c b/storage/mroonga/vendor/groonga/lib/proc/proc_object_list.c index adb4c91bc1f..eaf5504d1fa 100644 --- a/storage/mroonga/vendor/groonga/lib/proc/proc_object_list.c +++ b/storage/mroonga/vendor/groonga/lib/proc/proc_object_list.c @@ -18,6 +18,7 @@ #include "../grn_proc.h" #include "../grn_db.h" +#include #include @@ -73,6 +74,8 @@ command_object_list_dump_flags(grn_ctx *ctx, grn_obj_spec *spec) GRN_OBJ_FIN(ctx, &flags); } +PRAGMA_DISABLE_CHECK_STACK_FRAME + static grn_obj * command_object_list(grn_ctx *ctx, int nargs, @@ -401,6 +404,7 @@ command_object_list(grn_ctx *ctx, return NULL; } +PRAGMA_REENABLE_CHECK_STACK_FRAME void grn_proc_init_object_list(grn_ctx *ctx) diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_schema.c b/storage/mroonga/vendor/groonga/lib/proc/proc_schema.c index 061c145a112..7c632f45e53 100644 --- a/storage/mroonga/vendor/groonga/lib/proc/proc_schema.c +++ b/storage/mroonga/vendor/groonga/lib/proc/proc_schema.c @@ -17,9 +17,8 @@ */ #include "../grn_proc.h" - #include "../grn_db.h" - +#include #include typedef struct { @@ -572,6 +571,8 @@ command_schema_table_output_token_filters(grn_ctx *ctx, grn_obj *table) GRN_OBJ_FIN(ctx, &token_filters); } +PRAGMA_DISABLE_CHECK_STACK_FRAME + static void command_schema_table_command_collect_arguments(grn_ctx *ctx, grn_obj *table, @@ -692,6 +693,7 @@ command_schema_table_command_collect_arguments(grn_ctx *ctx, #undef ADD_OBJECT_NAME #undef ADD } +PRAGMA_REENABLE_CHECK_STACK_FRAME static void command_schema_table_output_command(grn_ctx *ctx, grn_obj *table) @@ -875,6 +877,8 @@ command_schema_output_indexes(grn_ctx *ctx, grn_obj *object) } } +PRAGMA_DISABLE_CHECK_STACK_FRAME + static void command_schema_column_command_collect_arguments(grn_ctx *ctx, grn_obj *table, @@ -973,6 +977,7 @@ command_schema_column_command_collect_arguments(grn_ctx *ctx, #undef ADD_OBJECT_NAME #undef ADD } +PRAGMA_REENABLE_CHECK_STACK_FRAME static void command_schema_column_output_command(grn_ctx *ctx, diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_select.c b/storage/mroonga/vendor/groonga/lib/proc/proc_select.c index a665b1cc898..7588b18a17c 100644 --- a/storage/mroonga/vendor/groonga/lib/proc/proc_select.c +++ b/storage/mroonga/vendor/groonga/lib/proc/proc_select.c @@ -24,6 +24,7 @@ #include "../grn_util.h" #include "../grn_cache.h" #include "../grn_ii.h" +#include #include "../grn_ts.h" @@ -2912,7 +2913,7 @@ grn_select(grn_ctx *ctx, grn_select_data *data) uint32_t nhits; grn_obj *outbuf = ctx->impl->output.buf; grn_content_type output_type = ctx->impl->output.type; - char cache_key[GRN_CACHE_MAX_KEY_SIZE]; + char *cache_key_buffer= 0; uint32_t cache_key_size; long long int threshold, original_threshold = 0; grn_cache *cache_obj = grn_cache_current_get(ctx); @@ -2985,8 +2986,9 @@ grn_select(grn_ctx *ctx, grn_select_data *data) } GRN_HASH_EACH_END(ctx, cursor); } #undef DRILLDOWN_CACHE_SIZE - if (cache_key_size <= GRN_CACHE_MAX_KEY_SIZE) { - char *cp = cache_key; + if (cache_key_size <= GRN_CACHE_MAX_KEY_SIZE && + (cache_key_buffer= (char*) malloc(cache_key_size+1))) { + char *cp = cache_key_buffer; #define PUT_CACHE_KEY(string) \ if ((string).value) \ @@ -3066,11 +3068,12 @@ grn_select(grn_ctx *ctx, grn_select_data *data) { grn_rc rc; - rc = grn_cache_fetch(ctx, cache_obj, cache_key, cache_key_size, outbuf); + rc = grn_cache_fetch(ctx, cache_obj, cache_key_buffer, cache_key_size, outbuf); if (rc == GRN_SUCCESS) { GRN_QUERY_LOG(ctx, GRN_QUERY_LOG_CACHE, ":", "cache(%" GRN_FMT_LLD ")", (long long int)GRN_TEXT_LEN(outbuf)); + free(cache_key_buffer); return ctx->rc; } } @@ -3119,7 +3122,7 @@ grn_select(grn_ctx *ctx, grn_select_data *data) data->cache.length != 2 || data->cache.value[0] != 'n' || data->cache.value[1] != 'o')) { - grn_cache_update(ctx, cache_obj, cache_key, cache_key_size, outbuf); + grn_cache_update(ctx, cache_obj, cache_key_buffer, cache_key_size, outbuf); } goto exit; } @@ -3186,7 +3189,7 @@ grn_select(grn_ctx *ctx, grn_select_data *data) data->cache.length != 2 || data->cache.value[0] != 'n' || data->cache.value[1] != 'o')) { - grn_cache_update(ctx, cache_obj, cache_key, cache_key_size, outbuf); + grn_cache_update(ctx, cache_obj, cache_key_buffer, cache_key_size, outbuf); } if (data->taintable > 0) { grn_db_touch(ctx, DB_OBJ(data->tables.target)->db); @@ -3200,6 +3203,7 @@ exit : /* GRN_LOG(ctx, GRN_LOG_NONE, "%d", ctx->seqno); */ + free(cache_key_buffer); return ctx->rc; } @@ -3424,6 +3428,9 @@ grn_select_data_fill_drilldown_columns(grn_ctx *ctx, strlen(prefix)); } + +PRAGMA_DISABLE_CHECK_STACK_FRAME + static grn_bool grn_select_data_fill_drilldowns(grn_ctx *ctx, grn_user_data *user_data, @@ -3562,6 +3569,7 @@ grn_select_data_fill_drilldowns(grn_ctx *ctx, return succeeded; } } +PRAGMA_REENABLE_CHECK_STACK_FRAME static grn_obj * command_select(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c index f69f1869383..3d95fffacaf 100644 --- a/storage/myisam/ft_boolean_search.c +++ b/storage/myisam/ft_boolean_search.c @@ -287,6 +287,8 @@ static int ftb_parse_query_internal(MYSQL_FTPARSER_PARAM *param, uchar *end= (uchar*) query + len; FT_WORD w; + w.pos= NULL; + w.len= 0; info.prev= ' '; info.quot= 0; while (ft_get_word(cs, start, end, &w, &info)) diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index e050e46c8db..ef798499399 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1581,40 +1581,37 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt) SYNOPSIS disable_indexes() - mode mode of operation: - HA_KEY_SWITCH_NONUNIQ disable all non-unique keys - HA_KEY_SWITCH_ALL disable all keys - HA_KEY_SWITCH_NONUNIQ_SAVE dis. non-uni. and make persistent - HA_KEY_SWITCH_ALL_SAVE dis. all keys and make persistent - IMPLEMENTATION - HA_KEY_SWITCH_NONUNIQ is not implemented. - HA_KEY_SWITCH_ALL_SAVE is not implemented. + DESCRIPTION + See handler::ha_disable_indexes() RETURN 0 ok HA_ERR_WRONG_COMMAND mode not implemented. */ -int ha_myisam::disable_indexes(uint mode) +int ha_myisam::disable_indexes(key_map map, bool persist) { int error; - if (mode == HA_KEY_SWITCH_ALL) + if (!persist) { /* call a storage engine function to switch the key map */ + DBUG_ASSERT(map.is_clear_all()); error= mi_disable_indexes(file); } - else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE) - { - mi_extra(file, HA_EXTRA_NO_KEYS, 0); - info(HA_STATUS_CONST); // Read new key info - error= 0; - } else { - /* mode not implemented */ - error= HA_ERR_WRONG_COMMAND; + ulonglong ullmap= map.to_ulonglong(); + + /* make sure auto-inc key is enabled even if it's > 64 */ + if (map.length() > MI_KEYMAP_BITS && + table->s->next_number_index < MAX_KEY) + mi_set_key_active(ullmap, table->s->next_number_index); + + mi_extra(file, HA_EXTRA_NO_KEYS, &ullmap); + info(HA_STATUS_CONST); // Read new key info + error= 0; } return error; } @@ -1625,21 +1622,14 @@ int ha_myisam::disable_indexes(uint mode) SYNOPSIS enable_indexes() - mode mode of operation: - HA_KEY_SWITCH_NONUNIQ enable all non-unique keys - HA_KEY_SWITCH_ALL enable all keys - HA_KEY_SWITCH_NONUNIQ_SAVE en. non-uni. and make persistent - HA_KEY_SWITCH_ALL_SAVE en. all keys and make persistent DESCRIPTION Enable indexes, which might have been disabled by disable_index() before. - The modes without _SAVE work only if both data and indexes are empty, + If persist=false, it works only if both data and indexes are empty, since the MyISAM repair would enable them persistently. To be sure in these cases, call handler::delete_all_rows() before. - IMPLEMENTATION - HA_KEY_SWITCH_NONUNIQ is not implemented. - HA_KEY_SWITCH_ALL_SAVE is not implemented. + See also handler::ha_enable_indexes() RETURN 0 ok @@ -1648,7 +1638,7 @@ int ha_myisam::disable_indexes(uint mode) HA_ERR_WRONG_COMMAND mode not implemented. */ -int ha_myisam::enable_indexes(uint mode) +int ha_myisam::enable_indexes(key_map map, bool persist) { int error; DBUG_ENTER("ha_myisam::enable_indexes"); @@ -1662,7 +1652,8 @@ int ha_myisam::enable_indexes(uint mode) DBUG_RETURN(0); } - if (mode == HA_KEY_SWITCH_ALL) + DBUG_ASSERT(map.is_prefix(table->s->keys)); + if (!persist) { error= mi_enable_indexes(file); /* @@ -1671,7 +1662,7 @@ int ha_myisam::enable_indexes(uint mode) but mode==HA_KEY_SWITCH_ALL forbids it. */ } - else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE) + else { THD *thd= table->in_use; int was_error= thd->is_error(); @@ -1731,11 +1722,6 @@ int ha_myisam::enable_indexes(uint mode) restore_vcos_after_repair(); } - else - { - /* mode not implemented */ - error= HA_ERR_WRONG_COMMAND; - } DBUG_RETURN(error); } @@ -1898,7 +1884,7 @@ int ha_myisam::end_bulk_insert() setting the indexes as active and trying to recreate them. */ - if (((first_error= enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE)) != 0) && + if (((first_error= enable_indexes(key_map(table->s->keys), true))) && table->in_use->killed) { delete_all_rows(); diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index 0914d531788..52d23faf3c4 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -111,8 +111,8 @@ class ha_myisam final : public handler int external_lock(THD *thd, int lock_type) override; int delete_all_rows(void) override; int reset_auto_increment(ulonglong value) override; - int disable_indexes(uint mode) override; - int enable_indexes(uint mode) override; + int disable_indexes(key_map map, bool persist) override; + int enable_indexes(key_map map, bool persist) override; int indexes_are_disabled(void) override; void start_bulk_insert(ha_rows rows, uint flags) override; int end_bulk_insert() override; diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c index e7e64edd926..96927a0b57b 100644 --- a/storage/myisam/mi_extra.c +++ b/storage/myisam/mi_extra.c @@ -225,16 +225,9 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) } if (mi_is_any_key_active(share->state.key_map)) { - MI_KEYDEF *key=share->keyinfo; - uint i; - for (i=0 ; i < share->base.keys ; i++,key++) - { - if (!(key->flag & HA_NOSAME) && info->s->base.auto_key != i+1) - { - mi_clear_key_active(share->state.key_map, i); - info->update|= HA_STATE_CHANGED; - } - } + if (share->state.key_map != *(ulonglong*)extra_arg) + info->update|= HA_STATE_CHANGED; + share->state.key_map= *(ulonglong*)extra_arg; if (!share->changed) { diff --git a/storage/perfschema/pfs_buffer_container.h b/storage/perfschema/pfs_buffer_container.h index d5745e76249..b5506fe0195 100644 --- a/storage/perfschema/pfs_buffer_container.h +++ b/storage/perfschema/pfs_buffer_container.h @@ -1084,8 +1084,7 @@ template class PFS_buffer_processor { public: - virtual ~PFS_buffer_processor () - {} + virtual ~PFS_buffer_processor()= default; virtual void operator()(T *element) = 0; }; diff --git a/storage/perfschema/pfs_instr_class.cc b/storage/perfschema/pfs_instr_class.cc index 2b1a80d3e11..fa85d8610bf 100644 --- a/storage/perfschema/pfs_instr_class.cc +++ b/storage/perfschema/pfs_instr_class.cc @@ -55,7 +55,7 @@ Indicate if the performance schema is enabled. This flag is set at startup, and never changes. */ -my_bool pfs_enabled= TRUE; +my_bool pfs_enabled= FALSE; /** PFS_INSTRUMENT option settings array diff --git a/storage/perfschema/table_replication_applier_status.cc b/storage/perfschema/table_replication_applier_status.cc index fda3c9274d9..94981482e56 100644 --- a/storage/perfschema/table_replication_applier_status.cc +++ b/storage/perfschema/table_replication_applier_status.cc @@ -166,7 +166,7 @@ void table_replication_applier_status::make_row(Master_info *mi) m_row.service_state= PS_RPL_NO; m_row.remaining_delay= 0; - if (slave_sql_running_state == Relay_log_info::state_delaying_string) + if (slave_sql_running_state == stage_sql_thd_waiting_until_delay.m_name) { time_t t= my_time(0), sql_delay_end= mi->rli.get_sql_delay_end(); m_row.remaining_delay= (uint)(t < sql_delay_end ? diff --git a/storage/perfschema/table_replication_applier_status.h b/storage/perfschema/table_replication_applier_status.h index 4da2087a32a..5e97dba5c45 100644 --- a/storage/perfschema/table_replication_applier_status.h +++ b/storage/perfschema/table_replication_applier_status.h @@ -59,7 +59,7 @@ struct st_row_applier_status { enum_rpl_yes_no service_state; uint remaining_delay; bool remaining_delay_is_set; - ulong count_transactions_retries; + ulonglong count_transactions_retries; }; /** Table PERFORMANCE_SCHEMA.replication_applier_status */ diff --git a/storage/perfschema/unittest/pfs_instr-t.cc b/storage/perfschema/unittest/pfs_instr-t.cc index 9667d7ff2be..55c4f61997b 100644 --- a/storage/perfschema/unittest/pfs_instr-t.cc +++ b/storage/perfschema/unittest/pfs_instr-t.cc @@ -86,6 +86,8 @@ void test_no_instruments() cleanup_instruments(); } +PRAGMA_DISABLE_CHECK_STACK_FRAME + void test_no_instances() { int rc; @@ -245,6 +247,7 @@ void test_no_instances() cleanup_file_hash(); cleanup_instruments(); } +PRAGMA_REENABLE_CHECK_STACK_FRAME void test_with_instances() { diff --git a/storage/perfschema/unittest/pfs_instr_class-t.cc b/storage/perfschema/unittest/pfs_instr_class-t.cc index 7651898d684..76e3668d378 100644 --- a/storage/perfschema/unittest/pfs_instr_class-t.cc +++ b/storage/perfschema/unittest/pfs_instr_class-t.cc @@ -743,6 +743,7 @@ void do_all_tests() int main(int argc, char **argv) { plan(209); + pfs_enabled= 1; MY_INIT(argv[0]); do_all_tests(); my_end(0); diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt index e86781ffdd4..0228703f990 100644 --- a/storage/rocksdb/CMakeLists.txt +++ b/storage/rocksdb/CMakeLists.txt @@ -204,7 +204,7 @@ ADD_CONVENIENCE_LIBRARY(rocksdb_aux_lib ADD_DEPENDENCIES(rocksdb_aux_lib GenError) # MARIAROCKS-TODO: how to properly depend on -lrt ? -TARGET_LINK_LIBRARIES(rocksdb_aux_lib rocksdblib ${ZLIB_LIBRARY}) +TARGET_LINK_LIBRARIES(rocksdb_aux_lib rocksdblib ${ZLIB_LIBRARIES}) if (UNIX AND NOT APPLE AND NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") TARGET_LINK_LIBRARIES(rocksdb_aux_lib -lrt) endif() diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake index 27a8616cfda..e89dbfc0627 100644 --- a/storage/rocksdb/build_rocksdb.cmake +++ b/storage/rocksdb/build_rocksdb.cmake @@ -79,7 +79,7 @@ check_lib(Snappy) check_lib(ZSTD ZDICT_trainFromBuffer) add_definitions(-DZLIB) -list(APPEND THIRDPARTY_LIBS ${ZLIB_LIBRARY}) +list(APPEND THIRDPARTY_LIBS ${ZLIB_LIBRARIES}) ADD_FEATURE_INFO(ROCKSDB_ZLIB "ON" "zlib Compression in the RocksDB storage engine") if(CMAKE_SYSTEM_NAME MATCHES "Cygwin") diff --git a/storage/rocksdb/ha_rocksdb.h b/storage/rocksdb/ha_rocksdb.h index d03c183873e..eeb2ddfe94f 100644 --- a/storage/rocksdb/ha_rocksdb.h +++ b/storage/rocksdb/ha_rocksdb.h @@ -397,7 +397,7 @@ class ha_rocksdb : public my_core::handler { current lookup to be covered. If the bitmap field is null, that means this index does not cover the current lookup for any record. */ - MY_BITMAP m_lookup_bitmap = {nullptr, nullptr, 0, 0}; + MY_BITMAP m_lookup_bitmap = {nullptr, nullptr, 0, 0, 0}; int alloc_key_buffers(const TABLE *const table_arg, const Rdb_tbl_def *const tbl_def_arg, diff --git a/storage/rocksdb/mysql-test/rocksdb/r/group_min_max.result b/storage/rocksdb/mysql-test/rocksdb/r/group_min_max.result index 5a1350fe0ff..dbf4d7d362e 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/group_min_max.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/group_min_max.result @@ -3517,7 +3517,7 @@ SHOW SESSION STATUS LIKE 'Handler_read%'; Variable_name Value Handler_read_first 0 Handler_read_key 3 -Handler_read_last 1 +Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_retry 0 diff --git a/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result b/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result index 68240d98533..4b8e3802c56 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/innodb_i_s_tables_disabled.result @@ -68,7 +68,6 @@ buffer_flush_n_to_flush_by_age buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NUL buffer_flush_adaptive_avg_time buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Avg time (ms) spent for adaptive flushing recently. buffer_flush_adaptive_avg_pass buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of adaptive flushes passed during the recent Avg period. buffer_LRU_get_free_loops buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Total loops in LRU get free. -buffer_LRU_get_free_waits buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Total sleep waits in LRU get free. buffer_flush_avg_page_rate buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Average number of pages at which flushing is happening buffer_flush_lsn_avg_rate buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Average redo generation rate buffer_flush_pct_for_dirty buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Percent of IO capacity used to avoid max dirty page limit @@ -88,7 +87,6 @@ buffer_LRU_batch_num_scan buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NUL buffer_LRU_batch_scanned_per_call buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Pages scanned per LRU batch call buffer_LRU_batch_flush_total_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Total pages flushed as part of LRU batches buffer_LRU_batch_evict_total_pages buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Total pages evicted as part of LRU batches -buffer_LRU_single_flush_failure_count Buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times attempt to flush a single page from LRU failed buffer_LRU_get_free_search Buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of searches performed for a clean page buffer_LRU_search_scanned buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_owner Total pages scanned as part of LRU search buffer_LRU_search_num_scan buffer 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 set_member Number of times LRU search is performed diff --git a/storage/rocksdb/mysql-test/rocksdb/r/partition.result b/storage/rocksdb/mysql-test/rocksdb/r/partition.result index a7f2a6112c1..1ba966e9e07 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/partition.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/partition.result @@ -46,7 +46,6 @@ CREATE TABLE t1 (i INT, j INT, k INT, PRIMARY KEY (i)) ENGINE = ROCKSDB PARTITIO Table Op Msg_type Msg_text test.t1 optimize status OK Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK Table Op Msg_type Msg_text test.t1 repair status OK diff --git a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def index 627d7da4171..c16c1021141 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def +++ b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def @@ -87,6 +87,10 @@ compact_deletes: MDEV-12663 : rocksdb.compact_deletes times out and causes other blind_delete_without_tx_api: MDEV-12286: rocksdb.blind_delete_without_tx_api test fails information_schema: MDEV-14372: unstable testcase +bloomfilter2: MDEV-33789: rocksdb.bloomfilter2 failed on amd64-debian-12-rocksdb +write_sync: MDEV-33866: rocksdb.write_sync fails on amd64-windows-packages +locking_issues_case5_rc: MDEV-33781: rocksdb.locking_issues_case5_rc fails on amd64-windows-packages + ## ## Tests that fail for some other reason ## diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 046567724d9..c2fbb77621d 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -268,19 +268,19 @@ int ha_spider::open( spider_bulk_malloc(spider_current_trx, 16, MYF(MY_WME | MY_ZEROFILL), &wide_handler, sizeof(SPIDER_WIDE_HANDLER), &searched_bitmap, - (uint) sizeof(uchar) * no_bytes_in_map(table->read_set), + (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set), &ft_discard_bitmap, - (uint) sizeof(uchar) * no_bytes_in_map(table->read_set), + (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set), &position_bitmap, - (uint) sizeof(uchar) * no_bytes_in_map(table->read_set), + (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set), &idx_read_bitmap, - (uint) sizeof(uchar) * no_bytes_in_map(table->read_set), + (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set), &idx_write_bitmap, - (uint) sizeof(uchar) * no_bytes_in_map(table->read_set), + (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set), &rnd_read_bitmap, - (uint) sizeof(uchar) * no_bytes_in_map(table->read_set), + (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set), &rnd_write_bitmap, - (uint) sizeof(uchar) * no_bytes_in_map(table->read_set), + (uint) sizeof(uchar) * my_bitmap_buffer_size(table->read_set), &partition_handler, (uint) sizeof(SPIDER_PARTITION_HANDLER), NullS) @@ -304,9 +304,9 @@ int ha_spider::open( wide_handler->top_share = table->s; owner->wide_handler_owner = TRUE; memset(wide_handler->ft_discard_bitmap, 0xFF, - no_bytes_in_map(table->read_set)); + my_bitmap_buffer_size(table->read_set)); memset(wide_handler->searched_bitmap, 0, - no_bytes_in_map(table->read_set)); + my_bitmap_buffer_size(table->read_set)); wide_handler_alloc = TRUE; if (!share && !spider_get_share(name, table, thd, this, &error_num)) @@ -346,12 +346,23 @@ int ha_spider::open( result_list.last = NULL; result_list.current = NULL; result_list.record_num = 0; - if ( - !(result_list.sqls = new spider_string[share->link_count]) || - !(result_list.insert_sqls = new spider_string[share->link_count]) || - !(result_list.update_sqls = new spider_string[share->link_count]) || - !(result_list.tmp_sqls = new spider_string[share->link_count]) - ) { + if (!(result_list.sqls = new spider_string[share->link_count])) + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_init_result_list; + } + if (!(result_list.insert_sqls = new spider_string[share->link_count])) + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_init_result_list; + } + if (!(result_list.update_sqls = new spider_string[share->link_count])) + { + error_num = HA_ERR_OUT_OF_MEM; + goto error_init_result_list; + } + if (!(result_list.tmp_sqls = new spider_string[share->link_count])) + { error_num = HA_ERR_OUT_OF_MEM; goto error_init_result_list; } @@ -984,9 +995,9 @@ int ha_spider::reset() if (!is_clone) { memset(wide_handler->ft_discard_bitmap, 0xFF, - no_bytes_in_map(table->read_set)); + my_bitmap_buffer_size(table->read_set)); memset(wide_handler->searched_bitmap, 0, - no_bytes_in_map(table->read_set)); + my_bitmap_buffer_size(table->read_set)); } while (wide_handler->condition) { @@ -1211,7 +1222,7 @@ int ha_spider::index_init( bitmap_set_all(table->read_set); if (is_clone) memset(wide_handler->searched_bitmap, 0xFF, - no_bytes_in_map(table->read_set)); + my_bitmap_buffer_size(table->read_set)); } } @@ -3107,7 +3118,7 @@ ha_rows ha_spider::multi_range_read_info_const( bitmap_set_all(table->read_set); if (is_clone) memset(wide_handler->searched_bitmap, 0xFF, - no_bytes_in_map(table->read_set)); + my_bitmap_buffer_size(table->read_set)); } } @@ -3161,7 +3172,7 @@ ha_rows ha_spider::multi_range_read_info( bitmap_set_all(table->read_set); if (is_clone) memset(wide_handler->searched_bitmap, 0xFF, - no_bytes_in_map(table->read_set)); + my_bitmap_buffer_size(table->read_set)); } } @@ -5420,7 +5431,7 @@ int ha_spider::rnd_init( bitmap_set_all(table->read_set); if (is_clone) memset(wide_handler->searched_bitmap, 0xFF, - no_bytes_in_map(table->read_set)); + my_bitmap_buffer_size(table->read_set)); } set_select_column_mode(); @@ -8969,27 +8980,35 @@ bool ha_spider::auto_repair() const } int ha_spider::disable_indexes( - uint mode + key_map map, bool persist ) { int error_num; backup_error_status(); DBUG_ENTER("ha_spider::disable_indexes"); DBUG_PRINT("info",("spider this=%p", this)); - if ((error_num = spider_db_disable_keys(this))) - DBUG_RETURN(check_error_mode(error_num)); - DBUG_RETURN(0); + if (persist) + { + if ((error_num = spider_db_disable_keys(this))) + DBUG_RETURN(check_error_mode(error_num)); + DBUG_RETURN(0); + } + DBUG_RETURN(HA_ERR_WRONG_COMMAND); } int ha_spider::enable_indexes( - uint mode + key_map map, bool persist ) { int error_num; backup_error_status(); DBUG_ENTER("ha_spider::enable_indexes"); DBUG_PRINT("info",("spider this=%p", this)); - if ((error_num = spider_db_enable_keys(this))) - DBUG_RETURN(check_error_mode(error_num)); - DBUG_RETURN(0); + if (persist) + { + if ((error_num = spider_db_enable_keys(this))) + DBUG_RETURN(check_error_mode(error_num)); + DBUG_RETURN(0); + } + DBUG_RETURN(HA_ERR_WRONG_COMMAND); } diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h index 50266739b63..2e638269ef9 100644 --- a/storage/spider/ha_spider.h +++ b/storage/spider/ha_spider.h @@ -482,10 +482,10 @@ public: bool auto_repair() const; #endif int disable_indexes( - uint mode + key_map map, bool persist ); int enable_indexes( - uint mode + key_map map, bool persist ); int check( THD* thd, @@ -791,3 +791,26 @@ public: int lock_tables(); int dml_init(); }; + + +/* This is a hack for ASAN + * Libraries such as libxml2 and libodbc do not like being unloaded before + * exit and will show as a leak in ASAN with no stack trace (as the plugin + * has been unloaded from memory). + * + * The below is designed to trick the compiler into adding a "UNIQUE" symbol + * which can be seen using: + * readelf -s storage/spider/ha_spider.so | grep UNIQUE + * + * Having this symbol means that the plugin remains in memory after dlclose() + * has been called. Thereby letting the libraries clean up properly. + */ +#if defined(__SANITIZE_ADDRESS__) +__attribute__((__used__)) +inline int dummy(void) +{ + static int d; + d++; + return d; +} +#endif diff --git a/storage/spider/mysql-test/spider/bg/r/spider3_fixes.result b/storage/spider/mysql-test/spider/bg/r/spider3_fixes.result index eacac93a8cf..17386c713aa 100644 --- a/storage/spider/mysql-test/spider/bg/r/spider3_fixes.result +++ b/storage/spider/mysql-test/spider/bg/r/spider3_fixes.result @@ -8,6 +8,7 @@ child3_1 child3_2 child3_3 for slave1_1 +include/start_slave.inc drop and create databases connection master_1; diff --git a/storage/spider/mysql-test/spider/bg/r/spider3_fixes_part.result b/storage/spider/mysql-test/spider/bg/r/spider3_fixes_part.result index c9dafa5fe6a..0074197df12 100644 --- a/storage/spider/mysql-test/spider/bg/r/spider3_fixes_part.result +++ b/storage/spider/mysql-test/spider/bg/r/spider3_fixes_part.result @@ -8,6 +8,7 @@ child3_1 child3_2 child3_3 for slave1_1 +include/start_slave.inc drop and create databases connection master_1; diff --git a/storage/spider/mysql-test/spider/bg/r/spider_fixes.result b/storage/spider/mysql-test/spider/bg/r/spider_fixes.result index 4c3dc0148a7..a1e503a0d78 100644 --- a/storage/spider/mysql-test/spider/bg/r/spider_fixes.result +++ b/storage/spider/mysql-test/spider/bg/r/spider_fixes.result @@ -8,6 +8,7 @@ child3_1 child3_2 child3_3 for slave1_1 +include/start_slave.inc drop and create databases connection master_1; diff --git a/storage/spider/mysql-test/spider/bg/r/spider_fixes_part.result b/storage/spider/mysql-test/spider/bg/r/spider_fixes_part.result index 245093413d5..2a2700efc77 100644 --- a/storage/spider/mysql-test/spider/bg/r/spider_fixes_part.result +++ b/storage/spider/mysql-test/spider/bg/r/spider_fixes_part.result @@ -8,6 +8,7 @@ child3_1 child3_2 child3_3 for slave1_1 +include/start_slave.inc drop and create databases connection master_1; diff --git a/storage/spider/mysql-test/spider/bg/t/slave_test_init.inc b/storage/spider/mysql-test/spider/bg/t/slave_test_init.inc index 323c9669a73..4f7a6bbae20 100644 --- a/storage/spider/mysql-test/spider/bg/t/slave_test_init.inc +++ b/storage/spider/mysql-test/spider/bg/t/slave_test_init.inc @@ -20,7 +20,7 @@ if (!$SLAVE1_1_SLAVE_STATUS) MASTER_SSL_VERIFY_SERVER_CERT=0 ; } -START SLAVE; +--source include/start_slave.inc --connection master_1 call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); --connection slave1_1 diff --git a/storage/spider/mysql-test/spider/bugfix/r/delete_with_float_column_default.result b/storage/spider/mysql-test/spider/bugfix/r/delete_with_float_column_default.result index 9701f859d1d..eae04ad0786 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/delete_with_float_column_default.result +++ b/storage/spider/mysql-test/spider/bugfix/r/delete_with_float_column_default.result @@ -5,6 +5,7 @@ child2_2 child2_3 for child3 for slave1_1 +include/start_slave.inc connection slave1_1; connection master_1; set @old_binlog_format= @@binlog_format; diff --git a/storage/spider/mysql-test/spider/bugfix/r/delete_with_float_column_mariadb.result b/storage/spider/mysql-test/spider/bugfix/r/delete_with_float_column_mariadb.result index 9701f859d1d..eae04ad0786 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/delete_with_float_column_mariadb.result +++ b/storage/spider/mysql-test/spider/bugfix/r/delete_with_float_column_mariadb.result @@ -5,6 +5,7 @@ child2_2 child2_3 for child3 for slave1_1 +include/start_slave.inc connection slave1_1; connection master_1; set @old_binlog_format= @@binlog_format; diff --git a/storage/spider/mysql-test/spider/bugfix/r/delete_with_float_column_mysql.result b/storage/spider/mysql-test/spider/bugfix/r/delete_with_float_column_mysql.result index aee11b0c6c7..e9b258a1c5f 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/delete_with_float_column_mysql.result +++ b/storage/spider/mysql-test/spider/bugfix/r/delete_with_float_column_mysql.result @@ -5,6 +5,7 @@ child2_2 child2_3 for child3 for slave1_1 +include/start_slave.inc connection slave1_1; connection master_1; set @old_binlog_format= @@binlog_format; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_19866.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_19866.result index d31ad7afba5..e52843d9837 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_19866.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_19866.result @@ -77,7 +77,6 @@ SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argum argument select `pkey`,`val` from `auto_test_remote`.`tbl_a` select `pkey`,`val` from `auto_test_remote`.`tbl_a` where `pkey` = 1 -select 1 from (select 1) t0 select `pkey`,`val` from `auto_test_remote`.`tbl_a` select `pkey`,`val` from `auto_test_remote`.`tbl_a` SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' @@ -91,7 +90,6 @@ argument select `pkey`,`val` from `auto_test_remote2`.`tbl_a` select `pkey`,`val` from `auto_test_remote2`.`tbl_a` select `pkey`,`val` from `auto_test_remote2`.`tbl_a` where `pkey` = 2 -select 1 from (select 1) t0 select `pkey`,`val` from `auto_test_remote2`.`tbl_a` SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT pkey, val FROM tbl_a ORDER BY pkey; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_27172.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27172.result index 2d4600dbf83..f824c787cfb 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_27172.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27172.result @@ -72,9 +72,6 @@ id greeting connection child2_1; SELECT argument FROM mysql.general_log WHERE argument LIKE 'select `id`,`greeting` from %'; argument -select `id`,`greeting` from `auto_test_remote`.`tbl_a` where `greeting` = 'Aloha!' and ((`greeting` = 'Aloha!')) -select `id`,`greeting` from `auto_test_remote`.`tbl_b` where `greeting` like 'Aloha%' and ((`greeting` = 'Aloha!')) -select `id`,`greeting` from `auto_test_remote`.`tbl_c` where `greeting` like 'Aloha%' and ((`greeting` = 'Aloha!')) connection child2_1; SET @@global.general_log = @general_log_backup; SET @@global.log_output = @log_output_backup; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_28856.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_28856.result index 7c66fa79f6c..9a79bceb8be 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_28856.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_28856.result @@ -5,6 +5,8 @@ for master_1 for child2 for child3 set spider_same_server_link=1; +set @old_spider_same_server_link=@@global.spider_same_server_link; +set global spider_same_server_link=1; CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); # testing monitoring_* @@ -207,6 +209,7 @@ max(d) 93 drop table t1, t2; drop server srv; +set global spider_same_server_link=@old_spider_same_server_link; for master_1 for child2 for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_30727.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_30727.result new file mode 100644 index 00000000000..79a383feb83 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_30727.result @@ -0,0 +1,24 @@ +CREATE FUNCTION spider_direct_sql RETURNS INT SONAME 'ha_spider.so'; +SELECT spider_direct_sql ('SELECT * FROM s','a','srv "b"'); +ERROR HY000: Can't initialize function 'spider_direct_sql'; Plugin 'SPIDER' is not loaded +CREATE FUNCTION spider_bg_direct_sql RETURNS INT SONAME 'ha_spider.so'; +SELECT spider_bg_direct_sql ('SELECT * FROM s','a','srv "b"'); +ERROR HY000: Can't initialize function 'spider_bg_direct_sql'; Plugin 'SPIDER' is not loaded +CREATE FUNCTION spider_copy_tables RETURNS INT SONAME 'ha_spider.so'; +SELECT spider_copy_tables ('t', '0', '0'); +ERROR HY000: Can't initialize function 'spider_copy_tables'; Plugin 'SPIDER' is not loaded +CREATE FUNCTION spider_flush_table_mon_cache RETURNS INT SONAME 'ha_spider.so'; +SELECT spider_flush_table_mon_cache (); +spider_flush_table_mon_cache () +1 +install soname 'ha_spider'; +SELECT spider_direct_sql ('SELECT * FROM s','a','srv "b"'); +ERROR HY000: The foreign server name you are trying to reference does not exist. Data source error: b +call mtr.add_suppression(".*\\[Error\\] (mysqld|mariadbd): Can't find record in 'spider_tables'"); +SELECT spider_copy_tables ('t', '0', '0'); +ERROR HY000: Can't find record in 'spider_tables' +SELECT spider_flush_table_mon_cache (); +spider_flush_table_mon_cache () +1 +Warnings: +Warning 1620 Plugin is busy and will be uninstalled on shutdown diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_33242.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_33242.result new file mode 100644 index 00000000000..1be8d48e778 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_33242.result @@ -0,0 +1,6 @@ +set @old_old_mode=@@global.old_mode; +set global old_mode=4; +Warnings: +Warning 1287 'ZERO_DATE_TIME_CAST' is deprecated and will be removed in a future release +INSTALL SONAME 'ha_spider.so'; +set global old_mode=@old_old_mode; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_33434.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_33434.result new file mode 100644 index 00000000000..2cbcff38752 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_33434.result @@ -0,0 +1,12 @@ +# +# MDEV-33434 MDEV-33434 UBSAN null pointer passed as argument 2, which is declared to never be null in spider_udf_direct_sql_create_conn +# +INSTALL SONAME 'ha_spider'; +SET character_set_connection=ucs2; +SELECT SPIDER_DIRECT_SQL('SELECT SLEEP(1)', '', 'srv "dummy", port "3307"'); +ERROR HY000: Unable to connect to foreign data source: localhost +Warnings: +Warning 1620 Plugin is busy and will be uninstalled on shutdown +# +# end of test mdev_33434 +# diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_33494.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_33494.result new file mode 100644 index 00000000000..3db28c0f08e --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_33494.result @@ -0,0 +1,4 @@ +set @old_sql_mode=@@global.sql_mode; +set global sql_mode=(SELECT CONCAT (@@sql_mode,',no_zero_date')); +install soname 'ha_spider'; +set global sql_mode=@old_sql_mode; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_33538.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_33538.result new file mode 100644 index 00000000000..a5ab3c1d836 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_33538.result @@ -0,0 +1,12 @@ +show create table information_schema.SPIDER_ALLOC_MEM; +Table Create Table +SPIDER_ALLOC_MEM CREATE TEMPORARY TABLE `SPIDER_ALLOC_MEM` ( + `ID` int(10) unsigned NOT NULL, + `FUNC_NAME` varchar(64), + `FILE_NAME` varchar(64), + `LINE_NO` int(10) unsigned, + `TOTAL_ALLOC_MEM` bigint(20) unsigned, + `CURRENT_ALLOC_MEM` bigint(20), + `ALLOC_MEM_COUNT` bigint(20) unsigned, + `FREE_MEM_COUNT` bigint(20) unsigned +) ENGINE=MEMORY DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_33538_fail_init.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_33538_fail_init.result new file mode 100644 index 00000000000..7535da830cc --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_33538_fail_init.result @@ -0,0 +1,10 @@ +call mtr.add_suppression("\\[ERROR\\] SPIDER plugin initialization failed"); +call mtr.add_suppression(".*\\[ERROR\\] Plugin 'SPIDER' registration as a STORAGE ENGINE failed."); +call mtr.add_suppression(".*\\[ERROR\\] Plugin 'SPIDER_WRAPPER_PROTOCOLS' registration as a INFORMATION SCHEMA failed."); +call mtr.add_suppression(".*\\[ERROR\\] Plugin 'SPIDER_ALLOC_MEM' registration as a INFORMATION SCHEMA failed."); +create table mysql.spider_tables (c int); +# restart: --plugin-load-add=ha_spider +SELECT * FROM information_schema.SPIDER_ALLOC_MEM; +ID FUNC_NAME FILE_NAME LINE_NO TOTAL_ALLOC_MEM CURRENT_ALLOC_MEM ALLOC_MEM_COUNT FREE_MEM_COUNT +SELECT * FROM information_schema.SPIDER_WRAPPER_PROTOCOLS; +WRAPPER_NAME WRAPPER_VERSION WRAPPER_DESCRIPTION WRAPPER_MATURITY diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_33584.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_33584.result new file mode 100644 index 00000000000..796c75cc560 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_33584.result @@ -0,0 +1,4 @@ +set @old_sql_mode=@@global.sql_mode; +set global sql_mode='traditional'; +install soname 'ha_spider'; +set global sql_mode=@old_sql_mode; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_33679.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_33679.result new file mode 100644 index 00000000000..0f7f2048d37 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_33679.result @@ -0,0 +1,29 @@ +# +# MDEV-33679 spider returns parsing failure on valid left join select by translating the on expression to () +# +for master_1 +for child2 +for child3 +CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +CREATE TABLE `t1` (`c` INT(10) UNSIGNED NOT NULL, `b` VARCHAR(255) NOT NULL , PRIMARY KEY (`c`) USING BTREE ) ENGINE=MYISAM; +CREATE TABLE `t2` (`a` INT(10) UNSIGNED NOT NULL, `c` INT(10) UNSIGNED NOT NULL ) ENGINE=MYISAM; +SET spider_same_server_link= on; +CREATE TABLE `t1_spider` (`c` INT(10) UNSIGNED NOT NULL, `b` VARCHAR(255) NOT NULL , PRIMARY KEY (`c`) USING BTREE ) COMMENT='wrapper "mysql",srv "srv", table "t1"' ENGINE=SPIDER; +Warnings: +Warning 138 Spider table params in COMMENT or CONNECTION strings have been deprecated and will be removed in a future release. Please use table options instead. +CREATE TABLE `t2_spider` (`a` INT(10) UNSIGNED NOT NULL, `c` INT(10) UNSIGNED NOT NULL +, PRIMARY KEY (`a`) USING BTREE +) COMMENT='wrapper "mysql",srv "srv",table "t2"' ENGINE=SPIDER; +Warnings: +Warning 138 Spider table params in COMMENT or CONNECTION strings have been deprecated and will be removed in a future release. Please use table options instead. +INSERT INTO t1_spider VALUES(1,'oooo'); +INSERT INTO t2_spider VALUES(1,1); +SELECT t2_spider.a,t1_spider.c FRoM t2_spider LEFT join t1_spider ON (t2_spider.c = t1_spider.c) WHERE t2_spider.a = 1; +a c +1 1 +drop table t1, t2, t1_spider, t2_spider; +drop server srv; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_33731.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_33731.result new file mode 100644 index 00000000000..a63830f194c --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_33731.result @@ -0,0 +1,10 @@ +for master_1 +for child2 +for child3 +CREATE TABLE t (a INT) ENGINE=Spider PARTITION BY LIST (a) PARTITIONS 2 (PARTITION p1 VALUES IN (0,1),PARTITION p2 VALUES IN (2,3)); +DELETE FROM t PARTITION (p2); +ERROR HY000: Unable to connect to foreign data source: localhost +drop table t; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_34003.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_34003.result new file mode 100644 index 00000000000..a661d5bcea7 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_34003.result @@ -0,0 +1,20 @@ +for master_1 +for child2 +for child3 +set spider_same_server_link= 1; +CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t2 (c INT KEY,c1 BLOB,c2 TEXT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (0,1,0),(1,0,0),(2,0,0); +create table t1 (c INT KEY,c1 BLOB,c2 TEXT) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; +Warnings: +Warning 138 Spider table params in COMMENT or CONNECTION strings have been deprecated and will be removed in a future release. Please use table options instead. +SELECT * FROM t1 WHERE c=0; +c c1 c2 +0 1 0 +drop table t1, t2; +drop server srv; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_all.result b/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_all.result index 04e5ed6da68..4d161a2f7fb 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_all.result +++ b/storage/spider/mysql-test/spider/bugfix/r/plugin_load_add_all.result @@ -3,5 +3,9 @@ # select * from mysql.plugin; name dl +select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = "information_schema" and TABLE_NAME like "SPIDER_%"; +TABLE_NAME +SPIDER_ALLOC_MEM +SPIDER_WRAPPER_PROTOCOLS create table t (c int) Engine=SPIDER; drop table t; diff --git a/storage/spider/mysql-test/spider/bugfix/r/slave_transaction_retry_errors_5digit.result b/storage/spider/mysql-test/spider/bugfix/r/slave_transaction_retry_errors_5digit.result index f2cab6b0a95..83dab07f622 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/slave_transaction_retry_errors_5digit.result +++ b/storage/spider/mysql-test/spider/bugfix/r/slave_transaction_retry_errors_5digit.result @@ -5,11 +5,12 @@ child2_2 child2_3 for child3 for slave1_1 +include/start_slave.inc connection slave1_1; SHOW VARIABLES LIKE 'slave_transaction_retry_errors'; Variable_name Value -slave_transaction_retry_errors 1158,1159,1160,1161,1205,1213,1429,2013,12701,10000,20000,30000 +slave_transaction_retry_errors 1158,1159,1160,1161,1205,1213,1020,1429,2013,12701,10000,20000,30000 connection slave1_1; for slave1_1 for master_1 diff --git a/storage/spider/mysql-test/spider/bugfix/r/slave_trx_isolation.result b/storage/spider/mysql-test/spider/bugfix/r/slave_trx_isolation.result index 968647d3887..2282eceeeaf 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/slave_trx_isolation.result +++ b/storage/spider/mysql-test/spider/bugfix/r/slave_trx_isolation.result @@ -5,6 +5,7 @@ child2_2 child2_3 for child3 for slave1_1 +include/start_slave.inc connection slave1_1; set @old_spider_slave_trx_isolation= @@spider_slave_trx_isolation; set global spider_slave_trx_isolation= 1; diff --git a/storage/spider/mysql-test/spider/bugfix/r/udf_mysql_func_early_init_file.result b/storage/spider/mysql-test/spider/bugfix/r/udf_mysql_func_early_init_file.result deleted file mode 120000 index 045ddc4372c..00000000000 --- a/storage/spider/mysql-test/spider/bugfix/r/udf_mysql_func_early_init_file.result +++ /dev/null @@ -1 +0,0 @@ -udf_mysql_func_early.result \ No newline at end of file diff --git a/storage/spider/mysql-test/spider/bugfix/r/udf_mysql_func_early_init_file.result b/storage/spider/mysql-test/spider/bugfix/r/udf_mysql_func_early_init_file.result new file mode 100644 index 00000000000..35bd8335b69 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/udf_mysql_func_early_init_file.result @@ -0,0 +1,45 @@ +# +# Test that udf created by inserting into mysql_func works as expected +# +CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS ( +HOST 'localhost', +DATABASE 'auto_test_local', +USER 'root', +PASSWORD '', +SOCKET '$MASTER_1_MYSOCK' + ); +CREATE SERVER s_2_1 FOREIGN DATA WRAPPER mysql OPTIONS ( +HOST 'localhost', +DATABASE 'auto_test_remote', +USER 'root', +PASSWORD '', +SOCKET '$CHILD2_1_MYSOCK' + ); +connect master_1, localhost, root, , , $MASTER_1_MYPORT, $MASTER_1_MYSOCK; +connect child2_1, localhost, root, , , $CHILD2_1_MYPORT, $CHILD2_1_MYSOCK; +connection child2_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a ( +a INT +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +insert into tbl_a values (42); +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE tbl_a ( +a INT +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"'; +Warnings: +Warning 138 Spider table params in COMMENT or CONNECTION strings have been deprecated and will be removed in a future release. Please use table options instead. +create temporary table results (a int); +SELECT SPIDER_DIRECT_SQL('select * from tbl_a', 'results', 'srv "s_2_1", database "auto_test_remote"'); +SPIDER_DIRECT_SQL('select * from tbl_a', 'results', 'srv "s_2_1", database "auto_test_remote"') +1 +select * from results; +a +42 +connection master_1; +DROP DATABASE IF EXISTS auto_test_local; +connection child2_1; +DROP DATABASE IF EXISTS auto_test_remote; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28856.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28856.test index 62f59766aae..b2781771ec7 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_28856.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28856.test @@ -10,6 +10,9 @@ # This test covers some table params under consideration for inclusion # in the engine-defined options to be implemented in MDEV-28856. set spider_same_server_link=1; +set @old_spider_same_server_link=@@global.spider_same_server_link; +set global spider_same_server_link=1; + evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); @@ -175,6 +178,7 @@ select max(d) from t1; drop table t1, t2; drop server srv; +set global spider_same_server_link=@old_spider_same_server_link; --disable_query_log --disable_result_log diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_30727.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_30727.test new file mode 100644 index 00000000000..ebd08edce24 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_30727.test @@ -0,0 +1,30 @@ +CREATE FUNCTION spider_direct_sql RETURNS INT SONAME 'ha_spider.so'; +--error ER_CANT_INITIALIZE_UDF +SELECT spider_direct_sql ('SELECT * FROM s','a','srv "b"'); + +CREATE FUNCTION spider_bg_direct_sql RETURNS INT SONAME 'ha_spider.so'; +--error ER_CANT_INITIALIZE_UDF +SELECT spider_bg_direct_sql ('SELECT * FROM s','a','srv "b"'); + +CREATE FUNCTION spider_copy_tables RETURNS INT SONAME 'ha_spider.so'; +--error ER_CANT_INITIALIZE_UDF +SELECT spider_copy_tables ('t', '0', '0'); + +# spider_flush_table_mon_cache does not require spider init to function +CREATE FUNCTION spider_flush_table_mon_cache RETURNS INT SONAME 'ha_spider.so'; +SELECT spider_flush_table_mon_cache (); + +# The function functions properly after the plugin is installed +install soname 'ha_spider'; + +--error ER_FOREIGN_SERVER_DOESNT_EXIST +SELECT spider_direct_sql ('SELECT * FROM s','a','srv "b"'); + +call mtr.add_suppression(".*\\[Error\\] (mysqld|mariadbd): Can't find record in 'spider_tables'"); +--error ER_KEY_NOT_FOUND +SELECT spider_copy_tables ('t', '0', '0'); + +SELECT spider_flush_table_mon_cache (); + +--disable_query_log +--source ../../include/clean_up_spider.inc diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_33242.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_33242.test new file mode 100644 index 00000000000..215dab25f09 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_33242.test @@ -0,0 +1,6 @@ +set @old_old_mode=@@global.old_mode; +set global old_mode=4; +INSTALL SONAME 'ha_spider.so'; +set global old_mode=@old_old_mode; +--disable_query_log +--source ../../include/clean_up_spider.inc diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_33434.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_33434.test new file mode 100644 index 00000000000..dd9f882f42e --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_33434.test @@ -0,0 +1,15 @@ +--echo # +--echo # MDEV-33434 MDEV-33434 UBSAN null pointer passed as argument 2, which is declared to never be null in spider_udf_direct_sql_create_conn +--echo # + +INSTALL SONAME 'ha_spider'; +SET character_set_connection=ucs2; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +SELECT SPIDER_DIRECT_SQL('SELECT SLEEP(1)', '', 'srv "dummy", port "3307"'); +--disable_query_log +--source ../../include/clean_up_spider.inc +--enable_query_log + +--echo # +--echo # end of test mdev_33434 +--echo # diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_33494.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_33494.test new file mode 100644 index 00000000000..30beca77f35 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_33494.test @@ -0,0 +1,11 @@ +# This test tests spider init with global no_zero_date sql mode +set @old_sql_mode=@@global.sql_mode; +set global sql_mode=(SELECT CONCAT (@@sql_mode,',no_zero_date')); +install soname 'ha_spider'; +set global sql_mode=@old_sql_mode; + +--disable_query_log +--disable_result_log +--source ../../include/clean_up_spider.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_33538.opt b/storage/spider/mysql-test/spider/bugfix/t/mdev_33538.opt new file mode 100644 index 00000000000..a90c3a39413 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_33538.opt @@ -0,0 +1,2 @@ +--plugin-load-add=ha_spider +--transaction-read-only=on diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_33538.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_33538.test new file mode 100644 index 00000000000..e2d4d8b46e4 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_33538.test @@ -0,0 +1,2 @@ +# we check that information_schema.SPIDER_ALLOC_MEM exists +show create table information_schema.SPIDER_ALLOC_MEM; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_33538_fail_init.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_33538_fail_init.test new file mode 100644 index 00000000000..fafc2fdb852 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_33538_fail_init.test @@ -0,0 +1,17 @@ +call mtr.add_suppression("\\[ERROR\\] SPIDER plugin initialization failed"); +call mtr.add_suppression(".*\\[ERROR\\] Plugin 'SPIDER' registration as a STORAGE ENGINE failed."); +call mtr.add_suppression(".*\\[ERROR\\] Plugin 'SPIDER_WRAPPER_PROTOCOLS' registration as a INFORMATION SCHEMA failed."); +call mtr.add_suppression(".*\\[ERROR\\] Plugin 'SPIDER_ALLOC_MEM' registration as a INFORMATION SCHEMA failed."); +# We create a table with identical name of the spider system table, to +# fail the spider init query ([ERROR] SPIDER plugin initialization +# failed at 'alter table mysql.spider_tables add column if not exists +# link_id int not null default 0 after table_name, drop primary key, +# add primary key (db_name, table_name, link_id), algorithm=copy, +# lock=shared;' by 'Unknown column 'table_name' in 'spider_tables'') +# This will cause the init of spider_alloc_mem to fail because it +# depends on the main spider plugin. +create table mysql.spider_tables (c int); +--let $restart_parameters= --plugin-load-add=ha_spider +--source include/restart_mysqld.inc +SELECT * FROM information_schema.SPIDER_ALLOC_MEM; +SELECT * FROM information_schema.SPIDER_WRAPPER_PROTOCOLS; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_33584.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_33584.test new file mode 100644 index 00000000000..886449716eb --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_33584.test @@ -0,0 +1,11 @@ +# This test tests spider init with global no_zero_date sql mode +set @old_sql_mode=@@global.sql_mode; +set global sql_mode='traditional'; +install soname 'ha_spider'; +set global sql_mode=@old_sql_mode; + +--disable_query_log +--disable_result_log +--source ../../include/clean_up_spider.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_33679.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_33679.test new file mode 100644 index 00000000000..eee47a21163 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_33679.test @@ -0,0 +1,29 @@ +--echo # +--echo # MDEV-33679 spider returns parsing failure on valid left join select by translating the on expression to () +--echo # +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); + +CREATE TABLE `t1` (`c` INT(10) UNSIGNED NOT NULL, `b` VARCHAR(255) NOT NULL , PRIMARY KEY (`c`) USING BTREE ) ENGINE=MYISAM; +CREATE TABLE `t2` (`a` INT(10) UNSIGNED NOT NULL, `c` INT(10) UNSIGNED NOT NULL ) ENGINE=MYISAM; +SET spider_same_server_link= on; +CREATE TABLE `t1_spider` (`c` INT(10) UNSIGNED NOT NULL, `b` VARCHAR(255) NOT NULL , PRIMARY KEY (`c`) USING BTREE ) COMMENT='wrapper "mysql",srv "srv", table "t1"' ENGINE=SPIDER; +CREATE TABLE `t2_spider` (`a` INT(10) UNSIGNED NOT NULL, `c` INT(10) UNSIGNED NOT NULL +, PRIMARY KEY (`a`) USING BTREE +) COMMENT='wrapper "mysql",srv "srv",table "t2"' ENGINE=SPIDER; +INSERT INTO t1_spider VALUES(1,'oooo'); +INSERT INTO t2_spider VALUES(1,1); +SELECT t2_spider.a,t1_spider.c FRoM t2_spider LEFT join t1_spider ON (t2_spider.c = t1_spider.c) WHERE t2_spider.a = 1; + +drop table t1, t2, t1_spider, t2_spider; +drop server srv; +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_33731.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_33731.test new file mode 100644 index 00000000000..b98c9620414 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_33731.test @@ -0,0 +1,16 @@ +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +CREATE TABLE t (a INT) ENGINE=Spider PARTITION BY LIST (a) PARTITIONS 2 (PARTITION p1 VALUES IN (0,1),PARTITION p2 VALUES IN (2,3)); +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +DELETE FROM t PARTITION (p2); +drop table t; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_34003.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_34003.test new file mode 100644 index 00000000000..f81259b99a9 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_34003.test @@ -0,0 +1,20 @@ +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log +set spider_same_server_link= 1; +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t2 (c INT KEY,c1 BLOB,c2 TEXT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (0,1,0),(1,0,0),(2,0,0); +create table t1 (c INT KEY,c1 BLOB,c2 TEXT) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; +SELECT * FROM t1 WHERE c=0; +drop table t1, t2; +drop server srv; +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.test b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.test index 396145fba2e..35242b2092b 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.test +++ b/storage/spider/mysql-test/spider/bugfix/t/plugin_load_add_all.test @@ -3,5 +3,6 @@ --echo # # A simple test that tests plugin-load-add=ha_spider select * from mysql.plugin; +select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = "information_schema" and TABLE_NAME like "SPIDER_%"; create table t (c int) Engine=SPIDER; drop table t; diff --git a/storage/spider/mysql-test/spider/bugfix/t/self_reference_multi.test b/storage/spider/mysql-test/spider/bugfix/t/self_reference_multi.test index 4263560baa1..de75f0eec3f 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/self_reference_multi.test +++ b/storage/spider/mysql-test/spider/bugfix/t/self_reference_multi.test @@ -19,8 +19,10 @@ eval create table t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "$srv", eval alter table t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "$srv",TABLE "t0"'; --error 12719 select * from t0; +--replace_result test.t1 test.t0 test.t2 test.t0 --error 12719 select * from t1; +--replace_result test.t1 test.t0 test.t2 test.t0 --error 12719 select * from t2; drop table t0, t1, t2; diff --git a/storage/spider/mysql-test/spider/feature/r/pushdown_case.result b/storage/spider/mysql-test/spider/feature/r/pushdown_case.result new file mode 100644 index 00000000000..bf373874b18 --- /dev/null +++ b/storage/spider/mysql-test/spider/feature/r/pushdown_case.result @@ -0,0 +1,59 @@ +# +# MDEV-28993 Spider: Push down CASE statement +# +for master_1 +for child2 +for child3 +set spider_same_server_link= 1; +CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t2 (c int); +create table t1 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; +Warnings: +Warning 138 Spider table params in COMMENT or CONNECTION strings have been deprecated and will be removed in a future release. Please use table options instead. +insert into t1 values (42), (3), (848), (100); +explain select case c when 3 then "three" when 42 then "answer" else "other" end from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY +select case c when 3 then "three" when 42 then "answer" else "other" end from t1; +case c when 3 then "three" when 42 then "answer" else "other" end +answer +three +other +other +explain select case c when 3 then "three" when 42 then "answer" end from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY +select case c when 3 then "three" when 42 then "answer" end from t1; +case c when 3 then "three" when 42 then "answer" end +answer +three +NULL +NULL +explain select case when c = 3 then "three" when c = 42 then "answer" else "other" end from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY +select case when c = 3 then "three" when c = 42 then "answer" else "other" end from t1; +case when c = 3 then "three" when c = 42 then "answer" else "other" end +answer +three +other +other +explain select case when c = 3 then "three" when c = 42 then "answer" end from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY +select case when c = 3 then "three" when c = 42 then "answer" end from t1; +case when c = 3 then "three" when c = 42 then "answer" end +answer +three +NULL +NULL +drop table t1, t2; +drop server srv; +for master_1 +for child2 +for child3 +# +# end of test pushdown_case +# diff --git a/storage/spider/mysql-test/spider/feature/r/pushdown_timestamp_diff.result b/storage/spider/mysql-test/spider/feature/r/pushdown_timestamp_diff.result new file mode 100644 index 00000000000..874297d5539 --- /dev/null +++ b/storage/spider/mysql-test/spider/feature/r/pushdown_timestamp_diff.result @@ -0,0 +1,113 @@ +# +# MDEV-28992 Spider: Push down TIMESTAMPDIFF function +# +for master_1 +for child2 +for child3 +set spider_same_server_link= 1; +CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t2 ( +a INT, +b CHAR(1), +c DATETIME, +PRIMARY KEY(a) +); +CREATE TABLE t1 ( +a INT, +b CHAR(1), +c DATETIME, +PRIMARY KEY(a) +) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; +Warnings: +Warning 138 Spider table params in COMMENT or CONNECTION strings have been deprecated and will be removed in a future release. Please use table options instead. +INSERT INTO t1 (a, b, c) VALUES +(1, 'a', '2018-11-01 10:21:39'), +(2, 'b', '2015-06-30 23:59:59'), +(3, 'c', '2013-11-01 01:01:01'); +interval year +explain select a, b, timestampdiff(year, '2000-01-01 00:00:00', c) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY +select a, b, timestampdiff(year, '2000-01-01 00:00:00', c) from t1; +a b timestampdiff(year, '2000-01-01 00:00:00', c) +1 a 18 +2 b 15 +3 c 13 +interval quarter +explain select a, b, timestampdiff(quarter, '2000-01-01 00:00:00', c) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY +select a, b, timestampdiff(quarter, '2000-01-01 00:00:00', c) from t1; +a b timestampdiff(quarter, '2000-01-01 00:00:00', c) +1 a 75 +2 b 61 +3 c 55 +interval month +explain select a, b, timestampdiff(month, '2000-01-01 00:00:00', c) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY +select a, b, timestampdiff(month, '2000-01-01 00:00:00', c) from t1; +a b timestampdiff(month, '2000-01-01 00:00:00', c) +1 a 226 +2 b 185 +3 c 166 +interval week +explain select a, b, timestampdiff(week, '2000-01-01 00:00:00', c) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY +select a, b, timestampdiff(week, '2000-01-01 00:00:00', c) from t1; +a b timestampdiff(week, '2000-01-01 00:00:00', c) +1 a 982 +2 b 808 +3 c 721 +interval day +explain select a, b, timestampdiff(day, '2000-01-01 00:00:00', c) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY +select a, b, timestampdiff(day, '2000-01-01 00:00:00', c) from t1; +a b timestampdiff(day, '2000-01-01 00:00:00', c) +1 a 6879 +2 b 5659 +3 c 5053 +internal hour +explain select a, b, timestampdiff(hour, '2000-01-01 00:00:00', c) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY +select a, b, timestampdiff(hour, '2000-01-01 00:00:00', c) from t1; +a b timestampdiff(hour, '2000-01-01 00:00:00', c) +1 a 165106 +2 b 135839 +3 c 121273 +internal minute +explain select a, b, timestampdiff(minute, '2000-01-01 00:00:00', c) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY +select a, b, timestampdiff(minute, '2000-01-01 00:00:00', c) from t1; +a b timestampdiff(minute, '2000-01-01 00:00:00', c) +1 a 9906381 +2 b 8150399 +3 c 7276381 +internal second +explain select a, b, timestampdiff(second, '2000-01-01 00:00:00', c) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY +select a, b, timestampdiff(second, '2000-01-01 00:00:00', c) from t1; +a b timestampdiff(second, '2000-01-01 00:00:00', c) +1 a 594382899 +2 b 489023999 +3 c 436582861 +internal microsecond +explain select a, b, timestampdiff(microsecond, '2000-01-01 00:00:00', c) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY +select a, b, timestampdiff(microsecond, '2000-01-01 00:00:00', c) from t1; +a b timestampdiff(microsecond, '2000-01-01 00:00:00', c) +1 a 594382899000000 +2 b 489023999000000 +3 c 436582861000000 +drop table t1, t2; +drop server srv; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/feature/r/slave_transaction_retry_errors.result b/storage/spider/mysql-test/spider/feature/r/slave_transaction_retry_errors.result index 0a147c0356a..f7d4341c5da 100644 --- a/storage/spider/mysql-test/spider/feature/r/slave_transaction_retry_errors.result +++ b/storage/spider/mysql-test/spider/feature/r/slave_transaction_retry_errors.result @@ -5,11 +5,12 @@ child2_2 child2_3 for child3 for slave1_1 +include/start_slave.inc connection slave1_1; SHOW VARIABLES LIKE 'slave_transaction_retry_errors'; Variable_name Value -slave_transaction_retry_errors 1158,1159,1160,1161,1205,1213,1429,2013,12701 +slave_transaction_retry_errors 1158,1159,1160,1161,1205,1213,1020,1429,2013,12701 connection slave1_1; for slave1_1 for master_1 diff --git a/storage/spider/mysql-test/spider/feature/t/pushdown_case.test b/storage/spider/mysql-test/spider/feature/t/pushdown_case.test new file mode 100644 index 00000000000..b86edceb615 --- /dev/null +++ b/storage/spider/mysql-test/spider/feature/t/pushdown_case.test @@ -0,0 +1,50 @@ +--echo # +--echo # MDEV-28993 Spider: Push down CASE statement +--echo # +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log +set spider_same_server_link= 1; +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t2 (c int); +create table t1 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; +insert into t1 values (42), (3), (848), (100); + +# everything +let $query= +select case c when 3 then "three" when 42 then "answer" else "other" end from t1; +eval explain $query; +eval $query; + +# no else +let $query= +select case c when 3 then "three" when 42 then "answer" end from t1; +eval explain $query; +eval $query; + +# no value +let $query= +select case when c = 3 then "three" when c = 42 then "answer" else "other" end from t1; +eval explain $query; +eval $query; + +# neither +let $query= +select case when c = 3 then "three" when c = 42 then "answer" end from t1; +eval explain $query; +eval $query; + +drop table t1, t2; +drop server srv; +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log +--echo # +--echo # end of test pushdown_case +--echo # diff --git a/storage/spider/mysql-test/spider/feature/t/pushdown_timestamp_diff.test b/storage/spider/mysql-test/spider/feature/t/pushdown_timestamp_diff.test new file mode 100644 index 00000000000..81251860f74 --- /dev/null +++ b/storage/spider/mysql-test/spider/feature/t/pushdown_timestamp_diff.test @@ -0,0 +1,93 @@ +--echo # +--echo # MDEV-28992 Spider: Push down TIMESTAMPDIFF function +--echo # +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +set spider_same_server_link= 1; +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); + +create table t2 ( + a INT, + b CHAR(1), + c DATETIME, + PRIMARY KEY(a) +); +CREATE TABLE t1 ( + a INT, + b CHAR(1), + c DATETIME, + PRIMARY KEY(a) +) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; + +INSERT INTO t1 (a, b, c) VALUES + (1, 'a', '2018-11-01 10:21:39'), + (2, 'b', '2015-06-30 23:59:59'), + (3, 'c', '2013-11-01 01:01:01'); + +--echo interval year +let $query= +select a, b, timestampdiff(year, '2000-01-01 00:00:00', c) from t1; +eval explain $query; +eval $query; + +--echo interval quarter +let $query= +select a, b, timestampdiff(quarter, '2000-01-01 00:00:00', c) from t1; +eval explain $query; +eval $query; + +--echo interval month +let $query= +select a, b, timestampdiff(month, '2000-01-01 00:00:00', c) from t1; +eval explain $query; +eval $query; + +--echo interval week +let $query= +select a, b, timestampdiff(week, '2000-01-01 00:00:00', c) from t1; +eval explain $query; +eval $query; + +--echo interval day +let $query= +select a, b, timestampdiff(day, '2000-01-01 00:00:00', c) from t1; +eval explain $query; +eval $query; + +--echo internal hour +let $query= +select a, b, timestampdiff(hour, '2000-01-01 00:00:00', c) from t1; +eval explain $query; +eval $query; + +--echo internal minute +let $query= +select a, b, timestampdiff(minute, '2000-01-01 00:00:00', c) from t1; +eval explain $query; +eval $query; + +--echo internal second +let $query= +select a, b, timestampdiff(second, '2000-01-01 00:00:00', c) from t1; +eval explain $query; +eval $query; + +--echo internal microsecond +let $query= +select a, b, timestampdiff(microsecond, '2000-01-01 00:00:00', c) from t1; +eval explain $query; +eval $query; + +drop table t1, t2; +drop server srv; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/mysql-test/spider/include/clean_up_spider.inc b/storage/spider/mysql-test/spider/include/clean_up_spider.inc index 1c977bfb66f..249606ec774 100644 --- a/storage/spider/mysql-test/spider/include/clean_up_spider.inc +++ b/storage/spider/mysql-test/spider/include/clean_up_spider.inc @@ -3,7 +3,6 @@ DROP FUNCTION spider_copy_tables; DROP FUNCTION spider_ping_table; DROP FUNCTION spider_bg_direct_sql; DROP FUNCTION spider_direct_sql; ---replace_regex /\.dll/.so/ UNINSTALL SONAME IF EXISTS 'ha_spider'; DROP TABLE IF EXISTS mysql.spider_xa; DROP TABLE IF EXISTS mysql.spider_xa_member; diff --git a/storage/spider/mysql-test/spider/r/partition_join_pushdown_for_single_partition.result b/storage/spider/mysql-test/spider/r/partition_join_pushdown_for_single_partition.result index 126aa7e2e5b..e7e34988229 100644 --- a/storage/spider/mysql-test/spider/r/partition_join_pushdown_for_single_partition.result +++ b/storage/spider/mysql-test/spider/r/partition_join_pushdown_for_single_partition.result @@ -100,10 +100,8 @@ SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argum argument select `value` from `auto_test_remote2`.`tbl_a` where `value` = 5 select `value2` from `auto_test_remote2`.`tbl_b` where `value2` = 5 -select sum('5') `sum(a.value)`,count('5') `count(b.value2)` from (select 1) t0 join (select 1) t1 select `value` from `auto_test_remote2`.`tbl_a` where `value` = 5 select `value2` from `auto_test_remote2`.`tbl_b` where `value2` = 5 -select sum('5') `sum(a.value)`,count('5') `count(b.value2)` from (select 1) t0 join (select 1) t1 SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT value FROM tbl_a ORDER BY value; value diff --git a/storage/spider/mysql-test/spider/r/slave_trx_isolation.result b/storage/spider/mysql-test/spider/r/slave_trx_isolation.result index 8aa7d5b4c77..c65a62e0108 100644 --- a/storage/spider/mysql-test/spider/r/slave_trx_isolation.result +++ b/storage/spider/mysql-test/spider/r/slave_trx_isolation.result @@ -8,6 +8,7 @@ child3_1 child3_2 child3_3 for slave1_1 +include/start_slave.inc connection slave1_1; set @old_spider_slave_trx_isolation= @@spider_slave_trx_isolation; set global spider_slave_trx_isolation= 1; diff --git a/storage/spider/mysql-test/spider/r/spider3_fixes.result b/storage/spider/mysql-test/spider/r/spider3_fixes.result index a977517efe8..9b0fc311c04 100644 --- a/storage/spider/mysql-test/spider/r/spider3_fixes.result +++ b/storage/spider/mysql-test/spider/r/spider3_fixes.result @@ -8,6 +8,7 @@ child3_1 child3_2 child3_3 for slave1_1 +include/start_slave.inc drop and create databases connection master_1; diff --git a/storage/spider/mysql-test/spider/r/spider3_fixes_part.result b/storage/spider/mysql-test/spider/r/spider3_fixes_part.result index f11f245a539..03bb6437028 100644 --- a/storage/spider/mysql-test/spider/r/spider3_fixes_part.result +++ b/storage/spider/mysql-test/spider/r/spider3_fixes_part.result @@ -8,6 +8,7 @@ child3_1 child3_2 child3_3 for slave1_1 +include/start_slave.inc drop and create databases connection master_1; diff --git a/storage/spider/mysql-test/spider/r/spider_fixes.result b/storage/spider/mysql-test/spider/r/spider_fixes.result index 185e8591cb2..e4c6826b525 100644 --- a/storage/spider/mysql-test/spider/r/spider_fixes.result +++ b/storage/spider/mysql-test/spider/r/spider_fixes.result @@ -8,6 +8,7 @@ child3_1 child3_2 child3_3 for slave1_1 +include/start_slave.inc drop and create databases connection master_1; diff --git a/storage/spider/mysql-test/spider/r/spider_fixes_part.result b/storage/spider/mysql-test/spider/r/spider_fixes_part.result index d1b98f40b3d..53e15609b0f 100644 --- a/storage/spider/mysql-test/spider/r/spider_fixes_part.result +++ b/storage/spider/mysql-test/spider/r/spider_fixes_part.result @@ -8,6 +8,7 @@ child3_1 child3_2 child3_3 for slave1_1 +include/start_slave.inc drop and create databases connection master_1; @@ -124,6 +125,7 @@ a b c 2.26 auto_increment with partition connection master_1; +include/save_master_pos.inc connection slave1_1; connection master_1; DROP TABLE IF EXISTS t1; diff --git a/storage/spider/mysql-test/spider/t/slave_test_init.inc b/storage/spider/mysql-test/spider/t/slave_test_init.inc index 323c9669a73..4f7a6bbae20 100644 --- a/storage/spider/mysql-test/spider/t/slave_test_init.inc +++ b/storage/spider/mysql-test/spider/t/slave_test_init.inc @@ -20,7 +20,7 @@ if (!$SLAVE1_1_SLAVE_STATUS) MASTER_SSL_VERIFY_SERVER_CERT=0 ; } -START SLAVE; +--source include/start_slave.inc --connection master_1 call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); --connection slave1_1 diff --git a/storage/spider/mysql-test/spider/t/spider_fixes_part.opt b/storage/spider/mysql-test/spider/t/spider_fixes_part.opt new file mode 100644 index 00000000000..1f24df45b33 --- /dev/null +++ b/storage/spider/mysql-test/spider/t/spider_fixes_part.opt @@ -0,0 +1 @@ +--log-warnings=3 diff --git a/storage/spider/mysql-test/spider/t/spider_fixes_part.test b/storage/spider/mysql-test/spider/t/spider_fixes_part.test index 49b2f2816e9..6c0c8a7ed34 100644 --- a/storage/spider/mysql-test/spider/t/spider_fixes_part.test +++ b/storage/spider/mysql-test/spider/t/spider_fixes_part.test @@ -494,7 +494,23 @@ if ($HAVE_PARTITION) if ($USE_REPLICATION) { save_master_pos; + --source include/save_master_pos.inc --connection slave1_1 + --let $rc= `select master_pos_wait('$_master_file', $_master_pos, 300, '')` + if (`select $rc is NULL OR $rc < 0`) + { + --vertical_results + show slave status; + --horizontal_results + show global status; + show global variables; + --let $MYSQLD_DATADIR= `select @@datadir` + --exec $MYSQL_BINLOG -v $MYSQLD_DATADIR/mysqld-relay-bin.000001; + # Check that the relay-log file is fully on disk. + --exec ls -l $MYSQLD_DATADIR; + # After that try to restart the slave SQL thread + start slave sql_thread; + } sync_with_master; --connection master_1 --disable_query_log diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc index b2079f5286f..fed6bc2728f 100644 --- a/storage/spider/spd_conn.cc +++ b/storage/spider/spd_conn.cc @@ -56,7 +56,7 @@ extern struct charset_info_st *spd_charset_utf8mb3_bin; extern LEX_CSTRING spider_unique_id; pthread_mutex_t spider_conn_id_mutex; pthread_mutex_t spider_ipport_conn_mutex; -ulonglong spider_conn_id = 1; +ulonglong spider_conn_id; extern pthread_attr_t spider_pt_attr; @@ -93,7 +93,7 @@ extern sql_mode_t pushdown_sql_mode; HASH spider_open_connections; uint spider_open_connections_id; HASH spider_ipport_conns; -long spider_conn_mutex_id = 0; +long spider_conn_mutex_id; const char *spider_open_connections_func_name; const char *spider_open_connections_file_name; diff --git a/storage/spider/spd_copy_tables.cc b/storage/spider/spd_copy_tables.cc index 44bf57e443a..1a6bd861c0a 100644 --- a/storage/spider/spd_copy_tables.cc +++ b/storage/spider/spd_copy_tables.cc @@ -298,7 +298,7 @@ int spider_udf_get_copy_tgt_tables( if ( (error_num = spider_get_sys_tables_connect_info( - table_tables, tmp_share, 0, mem_root)) || + table_tables, tmp_share, mem_root)) || (error_num = spider_get_sys_tables_link_status( table_tables, tmp_share->link_statuses, mem_root)) || (error_num = spider_get_sys_tables_link_idx( @@ -965,7 +965,12 @@ long long spider_copy_tables_body( all_link_cnt = copy_tables->link_idx_count[0] + copy_tables->link_idx_count[1]; if ( - !(tmp_sql = new spider_string[all_link_cnt]) || + !(tmp_sql = new spider_string[all_link_cnt]) + ) { + my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM); + goto error; + } + if ( !(spider = new ha_spider[all_link_cnt]) ) { my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM); @@ -994,13 +999,6 @@ long long spider_copy_tables_body( tmp_spider->share = table_conn->share; tmp_spider->wide_handler = wide_handler; wide_handler->trx = copy_tables->trx; -/* - if (spider_db_append_set_names(table_conn->share)) - { - my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM); - goto error_append_set_names; - } -*/ tmp_spider->conns = &table_conn->conn; tmp_sql[roop_count].init_calc_mem(SPD_MID_COPY_TABLES_BODY_3); tmp_sql[roop_count].set_charset(copy_tables->access_charset); @@ -1040,13 +1038,6 @@ long long spider_copy_tables_body( tmp_spider->share = table_conn->share; tmp_spider->wide_handler = wide_handler; wide_handler->trx = copy_tables->trx; -/* - if (spider_db_append_set_names(table_conn->share)) - { - my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM); - goto error_append_set_names; - } -*/ tmp_spider->conns = &table_conn->conn; tmp_sql[roop_count].init_calc_mem(SPD_MID_COPY_TABLES_BODY_5); tmp_sql[roop_count].set_charset(copy_tables->access_charset); @@ -1073,14 +1064,6 @@ long long spider_copy_tables_body( bulk_insert_rows))) goto error_db_udf_copy_tables; -/* - for (table_conn = copy_tables->table_conn[0]; - table_conn; table_conn = table_conn->next) - spider_db_free_set_names(table_conn->share); - for (table_conn = copy_tables->table_conn[1]; - table_conn; table_conn = table_conn->next) - spider_db_free_set_names(table_conn->share); -*/ if (table_list->table) { (thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd)); @@ -1101,8 +1084,7 @@ long long spider_copy_tables_body( } delete [] spider; } - if (tmp_sql) - delete [] tmp_sql; + delete [] tmp_sql; spider_udf_free_copy_tables_alloc(copy_tables); DBUG_RETURN(1); @@ -1110,17 +1092,6 @@ long long spider_copy_tables_body( error_db_udf_copy_tables: error_create_dbton_handler: error_init_dbton_handler: -/* -error_append_set_names: -*/ -/* - for (table_conn = copy_tables->table_conn[0]; - table_conn; table_conn = table_conn->next) - spider_db_free_set_names(table_conn->share); - for (table_conn = copy_tables->table_conn[1]; - table_conn; table_conn = table_conn->next) - spider_db_free_set_names(table_conn->share); -*/ error: if (spider) { @@ -1178,6 +1149,11 @@ my_bool spider_copy_tables_init_body( char *message ) { DBUG_ENTER("spider_copy_tables_init_body"); + if (!spider_hton_ptr) + { + strcpy(message, "Plugin 'SPIDER' is not loaded"); + goto error; + } if (args->arg_count != 3 && args->arg_count != 4) { strcpy(message, "spider_copy_tables() requires 3 or 4 arguments"); diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index c786bd42746..5f816d47b70 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -63,7 +63,7 @@ pthread_mutex_t spider_open_conn_mutex; const char spider_dig_upper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; /* UTC time zone for timestamp columns */ -Time_zone *UTC = 0; +Time_zone *UTC; int spider_db_connect( const SPIDER_SHARE *share, @@ -343,7 +343,6 @@ int spider_db_conn_queue_action( ) || ( conn->loop_check_queue.records && - conn->db_conn->set_loop_check_in_bulk_sql() && (error_num = spider_dbton[conn->dbton_id].db_util-> append_loop_check(&sql_str, conn)) ) || @@ -442,13 +441,6 @@ int spider_db_conn_queue_action( ) { DBUG_RETURN(error_num); } - if ( - conn->loop_check_queue.records && - !conn->db_conn->set_loop_check_in_bulk_sql() && - (error_num = conn->db_conn->set_loop_check((int *) conn->need_mon)) - ) { - DBUG_RETURN(error_num); - } if ( conn->queued_trx_isolation && !conn->queued_semi_trx_isolation && @@ -9123,6 +9115,9 @@ int spider_db_udf_ping_table_append_select( DBUG_RETURN(0); } +/* Stack size 33032 with clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + int spider_db_udf_ping_table_mon_next( THD *thd, SPIDER_TABLE_MON *table_mon, @@ -9269,6 +9264,7 @@ int spider_db_udf_ping_table_mon_next( delete res; DBUG_RETURN(error_num); } +PRAGMA_REENABLE_CHECK_STACK_FRAME int spider_db_udf_copy_key_row( spider_string *str, diff --git a/storage/spider/spd_db_include.cc b/storage/spider/spd_db_include.cc index a4d7d4b49a0..514470a2c80 100644 --- a/storage/spider/spd_db_include.cc +++ b/storage/spider/spd_db_include.cc @@ -64,22 +64,6 @@ spider_db_conn::spider_db_conn( DBUG_VOID_RETURN; } -bool spider_db_conn::set_loop_check_in_bulk_sql() -{ - DBUG_ENTER("spider_db_conn::set_loop_check_in_bulk_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(FALSE); -} - -int spider_db_conn::set_loop_check( - int *need_mon -) { - DBUG_ENTER("spider_db_conn::set_loop_check"); - DBUG_PRINT("info",("spider this=%p", this)); - /* nothing to do */ - DBUG_RETURN(0); -} - int spider_db_conn::fin_loop_check() { st_spider_conn_loop_check *lcptr; diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h index d384e54ff6f..87985584b60 100644 --- a/storage/spider/spd_db_include.h +++ b/storage/spider/spd_db_include.h @@ -86,7 +86,6 @@ typedef st_spider_result SPIDER_RESULT; #define SPIDER_SQL_HS_LTEQUAL_STR "<=" #define SPIDER_SQL_HS_LTEQUAL_LEN (sizeof(SPIDER_SQL_HS_LTEQUAL_STR) - 1) -#ifdef ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC #define SPIDER_SQL_CASE_STR "case " #define SPIDER_SQL_CASE_LEN (sizeof(SPIDER_SQL_CASE_STR) - 1) #define SPIDER_SQL_WHEN_STR " when " @@ -97,7 +96,6 @@ typedef st_spider_result SPIDER_RESULT; #define SPIDER_SQL_ELSE_LEN (sizeof(SPIDER_SQL_ELSE_STR) - 1) #define SPIDER_SQL_END_STR " end" #define SPIDER_SQL_END_LEN (sizeof(SPIDER_SQL_END_STR) - 1) -#endif #define SPIDER_SQL_USING_STR " using " #define SPIDER_SQL_USING_LEN (sizeof(SPIDER_SQL_USING_STR) - 1) @@ -1026,10 +1024,6 @@ public: Time_zone *time_zone, int *need_mon ) = 0; - virtual bool set_loop_check_in_bulk_sql(); - virtual int set_loop_check( - int *need_mon - ); virtual int fin_loop_check(); virtual int show_master_status( SPIDER_TRX *trx, diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 45ff1e1d480..8ff45022153 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -1193,7 +1193,7 @@ int spider_db_mbase_result::fetch_table_cardinality( uint num_fields = this->num_fields(); if (num_fields < 12 || num_fields > 14) { - DBUG_PRINT("info",("spider num_fields < 12 || num_fields > 13")); + DBUG_PRINT("info",("spider num_fields < 12 || num_fields > 14")); DBUG_RETURN(ER_SPIDER_INVALID_REMOTE_TABLE_INFO_NUM); } @@ -3266,110 +3266,6 @@ int spider_db_mbase::set_time_zone( DBUG_RETURN(0); } -bool spider_db_mbase::set_loop_check_in_bulk_sql() -{ - DBUG_ENTER("spider_db_mbase::set_loop_check_in_bulk_sql"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_RETURN(TRUE); -} - -int spider_db_mbase::set_loop_check( - int *need_mon -) { - SPIDER_CONN_LOOP_CHECK *lcptr; - char sql_buf[MAX_FIELD_WIDTH]; - spider_string sql_str(sql_buf, sizeof(sql_buf), &my_charset_bin); - DBUG_ENTER("spider_db_mbase::set_loop_check"); - DBUG_PRINT("info",("spider this=%p", this)); - sql_str.init_calc_mem(SPD_MID_DB_MBASE_SET_LOOP_CHECK_1); - while ((lcptr = (SPIDER_CONN_LOOP_CHECK *) my_hash_element( - &conn->loop_check_queue, 0))) - { - sql_str.length(0); - if (sql_str.reserve(SPIDER_SQL_SET_USER_VAL_LEN + - SPIDER_SQL_LOP_CHK_PRM_PRF_LEN + lcptr->to_name.length + - SPIDER_SQL_NAME_QUOTE_LEN + SPIDER_SQL_EQUAL_LEN + - SPIDER_SQL_VALUE_QUOTE_LEN + - lcptr->merged_value.length + SPIDER_SQL_VALUE_QUOTE_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - sql_str.q_append(SPIDER_SQL_SET_USER_VAL_STR, SPIDER_SQL_SET_USER_VAL_LEN); - sql_str.q_append(SPIDER_SQL_LOP_CHK_PRM_PRF_STR, - SPIDER_SQL_LOP_CHK_PRM_PRF_LEN); - sql_str.q_append(lcptr->to_name.str, lcptr->to_name.length); - sql_str.q_append(SPIDER_SQL_NAME_QUOTE_STR, SPIDER_SQL_NAME_QUOTE_LEN); - sql_str.q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); - sql_str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); - sql_str.q_append(lcptr->merged_value.str, lcptr->merged_value.length); - sql_str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); - - pthread_mutex_assert_not_owner(&conn->mta_conn_mutex); - pthread_mutex_lock(&conn->mta_conn_mutex); - SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos); - conn->need_mon = need_mon; - DBUG_ASSERT(!conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = TRUE; - conn->mta_conn_mutex_unlock_later = TRUE; - if (spider_db_query( - conn, - sql_str.ptr(), - sql_str.length(), - -1, - need_mon) - ) { - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - DBUG_RETURN(spider_db_errorno(conn)); - } - DBUG_ASSERT(conn->mta_conn_mutex_lock_already); - DBUG_ASSERT(conn->mta_conn_mutex_unlock_later); - conn->mta_conn_mutex_lock_already = FALSE; - conn->mta_conn_mutex_unlock_later = FALSE; - SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos); - pthread_mutex_unlock(&conn->mta_conn_mutex); - - my_hash_delete(&conn->loop_check_queue, (uchar*) lcptr); - } - DBUG_RETURN(0); -} - -int spider_db_mbase::fin_loop_check() -{ - st_spider_conn_loop_check *lcptr; - DBUG_ENTER("spider_db_mbase::fin_loop_check"); - DBUG_PRINT("info",("spider this=%p", this)); - if (conn->loop_check_queue.records) - { - uint l = 0; - while ((lcptr = (SPIDER_CONN_LOOP_CHECK *) my_hash_element( - &conn->loop_check_queue, l))) - { - lcptr->flag = 0; - ++l; - } - my_hash_reset(&conn->loop_check_queue); - } - lcptr = conn->loop_check_ignored_first; - while (lcptr) - { - lcptr->flag = 0; - lcptr = lcptr->next; - } - conn->loop_check_ignored_first = NULL; - lcptr = conn->loop_check_meraged_first; - while (lcptr) - { - lcptr->flag = 0; - lcptr = lcptr->next; - } - conn->loop_check_meraged_first = NULL; - DBUG_RETURN(0); -} - int spider_db_mbase::exec_simple_sql_with_result( SPIDER_TRX *trx, SPIDER_SHARE *share, @@ -5512,14 +5408,6 @@ int spider_db_mbase_util::open_item_func( alias_length, use_fields, fields)); } -static bool item_func_is_timestampdiff( - const char *func_name, - int func_name_length -) { - return func_name_length == 13 && - !strncasecmp("timestampdiff", func_name, func_name_length); -} - static bool not_func_should_be_skipped( Item_func *item_func ){ @@ -5589,16 +5477,10 @@ int spider_db_mbase_util::check_item_func( Item_func::Functype func_type = item_func->functype(); DBUG_PRINT("info",("spider functype = %d", func_type)); - const char *func_name = (char*) item_func->func_name(); - int func_name_length = strlen(func_name); - DBUG_PRINT("info",("spider func_name = %s", func_name)); - /* The blacklist of the functions that cannot be pushed down */ switch (func_type) { case Item_func::TRIG_COND_FUNC: - case Item_func::CASE_SEARCHED_FUNC: - case Item_func::CASE_SIMPLE_FUNC: DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); case Item_func::NOT_FUNC: /* Why the following check is necessary? */ @@ -5607,13 +5489,6 @@ int spider_db_mbase_util::check_item_func( break; case Item_func::FUNC_SP: case Item_func::UDF_FUNC: - /* Notes on merging regarding MDEV-29447: please refer to the - following commits for build error or merge conflicts: - 10.6: 1ed20b993b0dd4e95450cab2e8347e5bf4617a69 - 10.9: dd316b6e20265cfd832bb5585cb4c96e716387c8 - 10.10-11: 3f67f110ba1b23a89c5ede0fbeeb203cf5e164f4 - 11.0-1: 17ba6748afa8834df5658361088e6c8e65aca16f - Please remove this comment after merging. */ use_pushdown_udf= spider_param_use_pushdown_udf( spider->wide_handler->trx->thd, spider->share->use_pushdown_udf); if (!use_pushdown_udf) @@ -5623,12 +5498,18 @@ int spider_db_mbase_util::check_item_func( if (spider_db_check_ft_idx(item_func, spider) == MAX_KEY) DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); break; -#ifndef ITEM_FUNC_TIMESTAMPDIFF_ARE_PUBLIC - case Item_func::UNKNOWN_FUNC: - if (item_func_is_timestampdiff(func_name, func_name_length)) - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); - break; -#endif + case Item_func::MULT_EQUAL_FUNC: + /* If there is still Item_equal by the time of + JOIN::make_aggr_tables_info() where the spider group by handler + is created, it indicates a bug in the optimizer, because there + shouldn't be any. */ + push_warning_printf( + spider->wide_handler->trx->thd, SPIDER_WARN_LEVEL_WARN, + ER_INTERNAL_ERROR, + ER_THD(spider->wide_handler->trx->thd, ER_INTERNAL_ERROR), + "Spider group by handler: Encountered multiple equalities, likely " + "an optimizer bug"); + DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); default: break; } @@ -5670,7 +5551,7 @@ int spider_db_mbase_util::print_item_func( Item *item, **item_list = item_func->arguments(); Field *field; spider_string tmp_str; - uint roop_count, item_count = item_func->argument_count(), start_item = 0; + uint i, item_count = item_func->argument_count(), start_item = 0; LEX_CSTRING org_func_name= {SPIDER_SQL_NULL_CHAR_STR, SPIDER_SQL_NULL_CHAR_LEN}; const char *func_name = SPIDER_SQL_NULL_CHAR_STR, @@ -5679,8 +5560,8 @@ int spider_db_mbase_util::print_item_func( int func_name_length = SPIDER_SQL_NULL_CHAR_LEN, separator_str_length = SPIDER_SQL_NULL_CHAR_LEN, last_str_length = SPIDER_SQL_NULL_CHAR_LEN; - int use_pushdown_udf; - bool merge_func = FALSE; + int use_pushdown_udf, case_when_start, case_when_count; + bool merge_func = FALSE, case_with_else; DBUG_ENTER("spider_db_mbase_util::print_item_func"); DBUG_ASSERT(!check_item_func(item_func, spider, alias, alias_length, use_fields, fields)); @@ -5998,7 +5879,82 @@ int spider_db_mbase_util::print_item_func( alias, alias_length, dbton_id, use_fields, fields)); } else if (!strncasecmp("timestampdiff", func_name, func_name_length)) { - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); + Item_func_timestamp_diff *item_func_timestamp_diff = + (Item_func_timestamp_diff *) item_func; + const char *interval_str; + uint interval_len; + switch (item_func_timestamp_diff->get_int_type()) + { + case INTERVAL_YEAR: + interval_str = SPIDER_SQL_YEAR_STR; + interval_len = SPIDER_SQL_YEAR_LEN; + break; + case INTERVAL_QUARTER: + interval_str = SPIDER_SQL_QUARTER_STR; + interval_len = SPIDER_SQL_QUARTER_LEN; + break; + case INTERVAL_MONTH: + interval_str = SPIDER_SQL_MONTH_STR; + interval_len = SPIDER_SQL_MONTH_LEN; + break; + case INTERVAL_WEEK: + interval_str = SPIDER_SQL_WEEK_STR; + interval_len = SPIDER_SQL_WEEK_LEN; + break; + case INTERVAL_DAY: + interval_str = SPIDER_SQL_DAY_STR; + interval_len = SPIDER_SQL_DAY_LEN; + break; + case INTERVAL_HOUR: + interval_str = SPIDER_SQL_HOUR_STR; + interval_len = SPIDER_SQL_HOUR_LEN; + break; + case INTERVAL_MINUTE: + interval_str = SPIDER_SQL_MINUTE_STR; + interval_len = SPIDER_SQL_MINUTE_LEN; + break; + case INTERVAL_SECOND: + interval_str = SPIDER_SQL_SECOND_STR; + interval_len = SPIDER_SQL_SECOND_LEN; + break; + case INTERVAL_MICROSECOND: + interval_str = SPIDER_SQL_MICROSECOND_STR; + interval_len = SPIDER_SQL_MICROSECOND_LEN; + break; + default: + interval_str = ""; + interval_len = 0; + break; + } + str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); + if (str->reserve(func_name_length + SPIDER_SQL_OPEN_PAREN_LEN + + interval_len + SPIDER_SQL_COMMA_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(func_name, func_name_length); + str->q_append(SPIDER_SQL_OPEN_PAREN_STR, SPIDER_SQL_OPEN_PAREN_LEN); + str->q_append(interval_str, interval_len); + str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + + if ((error_num = spider_db_print_item_type(item_list[0], NULL, spider, + str, alias, alias_length, dbton_id, use_fields, fields))) + DBUG_RETURN(error_num); + if (str) + { + if (str->reserve(SPIDER_SQL_COMMA_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + } + if ((error_num = spider_db_print_item_type(item_list[1], NULL, spider, + str, alias, alias_length, dbton_id, use_fields, fields))) + DBUG_RETURN(error_num); + if (str) + { + if (str->reserve(SPIDER_SQL_CLOSE_PAREN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, + SPIDER_SQL_CLOSE_PAREN_LEN); + } + DBUG_RETURN(0); } } else if (func_name_length == 14) { @@ -6492,7 +6448,83 @@ int spider_db_mbase_util::print_item_func( DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); case Item_func::CASE_SEARCHED_FUNC: case Item_func::CASE_SIMPLE_FUNC: - DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); + /* + Arrangement of arguments: + - Item_func_case_searched: + when1 when2 ... whenk then1 then2 .. thenk [else] + - Item_func_case_simple: + value when1 when2 ... whenk then1 then2 .. thenk [else] + */ + if (item_func->functype() == Item_func::CASE_SEARCHED_FUNC) + { + case_when_start= 0; + case_when_count= item_count / 2; + case_with_else= item_count % 2; + } + else + { + case_when_start= 1; + case_when_count= (item_count - 1) / 2; + case_with_else= item_count % 2 == 0; + } + if (str) + { + if (str->reserve(SPIDER_SQL_CASE_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_CASE_STR, SPIDER_SQL_CASE_LEN); + } + if (case_when_start > 0) + { + if ((error_num = spider_db_print_item_type( + item_list[0], NULL, spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + DBUG_RETURN(error_num); + } + for (i = 0; i < (uint) case_when_count; i++) + { + if (str) + { + if (str->reserve(SPIDER_SQL_WHEN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_WHEN_STR, SPIDER_SQL_WHEN_LEN); + } + if ((error_num = spider_db_print_item_type( + item_list[i + case_when_start], NULL, spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + DBUG_RETURN(error_num); + if (str) + { + if (str->reserve(SPIDER_SQL_THEN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_THEN_STR, SPIDER_SQL_THEN_LEN); + } + if ((error_num = spider_db_print_item_type( + item_list[i + case_when_start + case_when_count], NULL, spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + DBUG_RETURN(error_num); + } + if (case_with_else) + { + if (str) + { + if (str->reserve(SPIDER_SQL_ELSE_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_ELSE_STR, SPIDER_SQL_ELSE_LEN); + } + if ((error_num = spider_db_print_item_type( + item_list[item_count - 1], NULL, spider, str, + alias, alias_length, dbton_id, use_fields, fields))) + DBUG_RETURN(error_num); + } + if (str) + { + if (str->reserve(SPIDER_SQL_END_LEN + SPIDER_SQL_CLOSE_PAREN_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + str->q_append(SPIDER_SQL_END_STR, SPIDER_SQL_END_LEN); + str->q_append(SPIDER_SQL_CLOSE_PAREN_STR, + SPIDER_SQL_CLOSE_PAREN_LEN); + } + DBUG_RETURN(0); case Item_func::JSON_EXTRACT_FUNC: func_name = (char*) item_func->func_name(); func_name_length = strlen(func_name); @@ -6507,6 +6539,18 @@ int spider_db_mbase_util::print_item_func( last_str = SPIDER_SQL_CLOSE_PAREN_STR; last_str_length = SPIDER_SQL_CLOSE_PAREN_LEN; break; + case Item_func::MULT_EQUAL_FUNC: + /* If there is still Item_equal by the time of + JOIN::make_aggr_tables_info() where the spider group by handler + is created, it indicates a bug in the optimizer, because there + shouldn't be any. */ + push_warning_printf( + spider->wide_handler->trx->thd, + SPIDER_WARN_LEVEL_WARN, ER_INTERNAL_ERROR, + ER_THD(spider->wide_handler->trx->thd, ER_INTERNAL_ERROR), + "Spider group by handler: Encountered multiple equalities, likely " + "an optimizer bug"); + DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); default: THD *thd = spider->wide_handler->trx->thd; SPIDER_SHARE *share = spider->share; @@ -6536,13 +6580,13 @@ int spider_db_mbase_util::print_item_func( Loop through the items of the current function expression to print its portion of the statement */ - for (roop_count = start_item; roop_count < item_count; roop_count++) + for (i = start_item; i < item_count; i++) { - item = item_list[roop_count]; + item = item_list[i]; if ((error_num = spider_db_print_item_type(item, field, spider, str, alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); - if (roop_count == 1) + if (i == 1) { /* Remaining operands need to be preceded by the separator */ func_name = separator_str; @@ -6556,7 +6600,7 @@ int spider_db_mbase_util::print_item_func( } /* Print the last operand value */ - item = item_list[roop_count]; + item = item_list[i]; if ((error_num = spider_db_print_item_type(item, field, spider, str, alias, alias_length, dbton_id, use_fields, fields))) DBUG_RETURN(error_num); @@ -7189,11 +7233,9 @@ int spider_mbase_share::init() DBUG_RETURN(HA_ERR_OUT_OF_MEM); } - if (keys > 0 && - !(key_hint = new spider_string[keys]) - ) { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } + if (keys > 0) + if (!(key_hint = new spider_string[keys])) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); for (roop_count = 0; roop_count < keys; roop_count++) { key_hint[roop_count].init_calc_mem(SPD_MID_MBASE_SHARE_INIT_2); @@ -7201,12 +7243,12 @@ int spider_mbase_share::init() } DBUG_PRINT("info",("spider key_hint=%p", key_hint)); - if ( - !(table_select = new spider_string[1]) || - (keys > 0 && - !(key_select = new spider_string[keys]) - ) || - (error_num = create_table_names_str()) || + if (!(table_select = new spider_string[1])) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + if (keys > 0) + if (!(key_select = new spider_string[keys])) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + if ((error_num = create_table_names_str()) || (table_share && ( (error_num = create_column_name_str()) || @@ -7357,11 +7399,18 @@ int spider_mbase_share::create_table_names_str() table_names_str = NULL; db_names_str = NULL; db_table_str = NULL; - if ( - !(table_names_str = new spider_string[spider_share->all_link_count]) || - !(db_names_str = new spider_string[spider_share->all_link_count]) || - !(db_table_str = new spider_string[spider_share->all_link_count]) - ) { + if (!(table_names_str = new spider_string[spider_share->all_link_count])) + { + error_num = HA_ERR_OUT_OF_MEM; + goto error; + } + if (!(db_names_str = new spider_string[spider_share->all_link_count])) + { + error_num = HA_ERR_OUT_OF_MEM; + goto error; + } + if (!(db_table_str = new spider_string[spider_share->all_link_count])) + { error_num = HA_ERR_OUT_OF_MEM; goto error; } @@ -7510,11 +7559,9 @@ int spider_mbase_share::create_column_name_str() Field **field; TABLE_SHARE *table_share = spider_share->table_share; DBUG_ENTER("spider_mbase_share::create_column_name_str"); - if ( - table_share->fields && - !(column_name_str = new spider_string[table_share->fields]) - ) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); + if (table_share->fields) + if (!(column_name_str = new spider_string[table_share->fields])) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); for (field = table_share->field, str = column_name_str; *field; field++, str++) { @@ -8290,7 +8337,7 @@ int spider_mbase_handler::init() &link_for_hash, sizeof(SPIDER_LINK_FOR_HASH) * share->link_count, &minimum_select_bitmap, - table ? sizeof(uchar) * no_bytes_in_map(table->read_set) : 0, + table ? sizeof(uchar) * my_bitmap_buffer_size(table->read_set) : 0, NullS)) ) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -14373,7 +14420,7 @@ void spider_mbase_handler::minimum_select_bitmap_create() Field **field_p; DBUG_ENTER("spider_mbase_handler::minimum_select_bitmap_create"); DBUG_PRINT("info",("spider this=%p", this)); - memset(minimum_select_bitmap, 0, no_bytes_in_map(table->read_set)); + memset(minimum_select_bitmap, 0, my_bitmap_buffer_size(table->read_set)); if ( spider->use_index_merge || spider->is_clone @@ -14384,7 +14431,7 @@ void spider_mbase_handler::minimum_select_bitmap_create() table_share->primary_key == MAX_KEY ) { /* need all columns */ - memset(minimum_select_bitmap, 0xFF, no_bytes_in_map(table->read_set)); + memset(minimum_select_bitmap, 0xFF, my_bitmap_buffer_size(table->read_set)); DBUG_VOID_RETURN; } else { /* need primary key columns */ diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h index bf94c94d4b4..a8fa33125e8 100644 --- a/storage/spider/spd_db_mysql.h +++ b/storage/spider/spd_db_mysql.h @@ -523,11 +523,6 @@ public: Time_zone *time_zone, int *need_mon ); - bool set_loop_check_in_bulk_sql(); - int set_loop_check( - int *need_mon - ); - int fin_loop_check(); int exec_simple_sql_with_result( SPIDER_TRX *trx, SPIDER_SHARE *share, diff --git a/storage/spider/spd_direct_sql.cc b/storage/spider/spd_direct_sql.cc index 3dd8e4293c1..6d0af8cc015 100644 --- a/storage/spider/spd_direct_sql.cc +++ b/storage/spider/spd_direct_sql.cc @@ -364,6 +364,23 @@ int spider_udf_direct_sql_create_conn_key( DBUG_RETURN(0); } +static inline void spider_maybe_memcpy_string( + char **dest, + char *src, + char *tmp, + uint *dest_len, + uint src_len) +{ + *dest_len= src_len; + if (src_len) + { + *dest= tmp; + memcpy(*dest, src, src_len); + } else + *dest= NULL; +} + + SPIDER_CONN *spider_udf_direct_sql_create_conn( const SPIDER_DIRECT_SQL *direct_sql, int *error_num @@ -433,105 +450,49 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn( conn->tgt_host = tmp_host; memcpy(conn->tgt_host, direct_sql->tgt_host, direct_sql->tgt_host_length); conn->tgt_port = direct_sql->tgt_port; - conn->tgt_socket_length = direct_sql->tgt_socket_length; - conn->tgt_socket = tmp_socket; - memcpy(conn->tgt_socket, direct_sql->tgt_socket, - direct_sql->tgt_socket_length); + spider_maybe_memcpy_string( + &conn->tgt_socket, direct_sql->tgt_socket, tmp_socket, + &conn->tgt_socket_length, direct_sql->tgt_socket_length); if (!tables_on_different_db_are_joinable) - { - conn->tgt_db_length = direct_sql->tgt_default_db_name_length; - conn->tgt_db = tmp_db; - memcpy(conn->tgt_db, direct_sql->tgt_default_db_name, - direct_sql->tgt_default_db_name_length); - } - conn->tgt_username_length = direct_sql->tgt_username_length; - conn->tgt_username = tmp_username; - memcpy(conn->tgt_username, direct_sql->tgt_username, - direct_sql->tgt_username_length); - conn->tgt_password_length = direct_sql->tgt_password_length; - conn->tgt_password = tmp_password; - memcpy(conn->tgt_password, direct_sql->tgt_password, - direct_sql->tgt_password_length); - conn->tgt_ssl_ca_length = direct_sql->tgt_ssl_ca_length; - if (conn->tgt_ssl_ca_length) - { - conn->tgt_ssl_ca = tmp_ssl_ca; - memcpy(conn->tgt_ssl_ca, direct_sql->tgt_ssl_ca, - direct_sql->tgt_ssl_ca_length); - } else - conn->tgt_ssl_ca = NULL; - conn->tgt_ssl_capath_length = direct_sql->tgt_ssl_capath_length; - if (conn->tgt_ssl_capath_length) - { - conn->tgt_ssl_capath = tmp_ssl_capath; - memcpy(conn->tgt_ssl_capath, direct_sql->tgt_ssl_capath, - direct_sql->tgt_ssl_capath_length); - } else - conn->tgt_ssl_capath = NULL; - conn->tgt_ssl_cert_length = direct_sql->tgt_ssl_cert_length; - if (conn->tgt_ssl_cert_length) - { - conn->tgt_ssl_cert = tmp_ssl_cert; - memcpy(conn->tgt_ssl_cert, direct_sql->tgt_ssl_cert, - direct_sql->tgt_ssl_cert_length); - } else - conn->tgt_ssl_cert = NULL; - conn->tgt_ssl_cipher_length = direct_sql->tgt_ssl_cipher_length; - if (conn->tgt_ssl_cipher_length) - { - conn->tgt_ssl_cipher = tmp_ssl_cipher; - memcpy(conn->tgt_ssl_cipher, direct_sql->tgt_ssl_cipher, - direct_sql->tgt_ssl_cipher_length); - } else - conn->tgt_ssl_cipher = NULL; - conn->tgt_ssl_key_length = direct_sql->tgt_ssl_key_length; - if (conn->tgt_ssl_key_length) - { - conn->tgt_ssl_key = tmp_ssl_key; - memcpy(conn->tgt_ssl_key, direct_sql->tgt_ssl_key, - direct_sql->tgt_ssl_key_length); - } else - conn->tgt_ssl_key = NULL; - conn->tgt_default_file_length = direct_sql->tgt_default_file_length; - if (conn->tgt_default_file_length) - { - conn->tgt_default_file = tmp_default_file; - memcpy(conn->tgt_default_file, direct_sql->tgt_default_file, - direct_sql->tgt_default_file_length); - } else - conn->tgt_default_file = NULL; - conn->tgt_default_group_length = direct_sql->tgt_default_group_length; - if (conn->tgt_default_group_length) - { - conn->tgt_default_group = tmp_default_group; - memcpy(conn->tgt_default_group, direct_sql->tgt_default_group, - direct_sql->tgt_default_group_length); - } else - conn->tgt_default_group = NULL; - conn->tgt_dsn_length = direct_sql->tgt_dsn_length; - if (conn->tgt_dsn_length) - { - conn->tgt_dsn = tmp_dsn; - memcpy(conn->tgt_dsn, direct_sql->tgt_dsn, - direct_sql->tgt_dsn_length); - } else - conn->tgt_dsn = NULL; - conn->tgt_filedsn_length = direct_sql->tgt_filedsn_length; - if (conn->tgt_filedsn_length) - { - conn->tgt_filedsn = tmp_filedsn; - memcpy(conn->tgt_filedsn, direct_sql->tgt_filedsn, - direct_sql->tgt_filedsn_length); - } else - conn->tgt_filedsn = NULL; - conn->tgt_driver_length = direct_sql->tgt_driver_length; - if (conn->tgt_driver_length) - { - conn->tgt_driver = tmp_driver; - memcpy(conn->tgt_driver, direct_sql->tgt_driver, - direct_sql->tgt_driver_length); - } else - conn->tgt_driver = NULL; + spider_maybe_memcpy_string( + &conn->tgt_db, direct_sql->tgt_default_db_name, tmp_db, + &conn->tgt_db_length, direct_sql->tgt_default_db_name_length); + spider_maybe_memcpy_string( + &conn->tgt_username, direct_sql->tgt_username, tmp_username, + &conn->tgt_username_length, direct_sql->tgt_username_length); + spider_maybe_memcpy_string( + &conn->tgt_password, direct_sql->tgt_password, tmp_password, + &conn->tgt_password_length, direct_sql->tgt_password_length); + spider_maybe_memcpy_string( + &conn->tgt_ssl_ca, direct_sql->tgt_ssl_ca, tmp_ssl_ca, + &conn->tgt_ssl_ca_length, direct_sql->tgt_ssl_ca_length); + spider_maybe_memcpy_string( + &conn->tgt_ssl_capath, direct_sql->tgt_ssl_capath, tmp_ssl_capath, + &conn->tgt_ssl_capath_length, direct_sql->tgt_ssl_capath_length); + spider_maybe_memcpy_string( + &conn->tgt_ssl_cert, direct_sql->tgt_ssl_cert, tmp_ssl_cert, + &conn->tgt_ssl_cert_length, direct_sql->tgt_ssl_cert_length); + spider_maybe_memcpy_string( + &conn->tgt_ssl_cipher, direct_sql->tgt_ssl_cipher, tmp_ssl_cipher, + &conn->tgt_ssl_cipher_length, direct_sql->tgt_ssl_cipher_length); + spider_maybe_memcpy_string( + &conn->tgt_ssl_key, direct_sql->tgt_ssl_key, tmp_ssl_key, + &conn->tgt_ssl_key_length, direct_sql->tgt_ssl_key_length); + spider_maybe_memcpy_string( + &conn->tgt_default_file, direct_sql->tgt_default_file, tmp_default_file, + &conn->tgt_default_file_length, direct_sql->tgt_default_file_length); + spider_maybe_memcpy_string( + &conn->tgt_default_group, direct_sql->tgt_default_group, tmp_default_group, + &conn->tgt_default_group_length, direct_sql->tgt_default_group_length); + spider_maybe_memcpy_string( + &conn->tgt_dsn, direct_sql->tgt_dsn, tmp_dsn, + &conn->tgt_dsn_length, direct_sql->tgt_dsn_length); + spider_maybe_memcpy_string( + &conn->tgt_filedsn, direct_sql->tgt_filedsn, tmp_filedsn, + &conn->tgt_filedsn_length, direct_sql->tgt_filedsn_length); + spider_maybe_memcpy_string( + &conn->tgt_driver, direct_sql->tgt_driver, tmp_driver, + &conn->tgt_driver_length, direct_sql->tgt_driver_length); conn->tgt_ssl_vsc = direct_sql->tgt_ssl_vsc; conn->dbton_id = direct_sql->dbton_id; conn->conn_need_mon = need_mon; @@ -1656,6 +1617,11 @@ my_bool spider_direct_sql_init_body( ) { SPIDER_BG_DIRECT_SQL *bg_direct_sql; DBUG_ENTER("spider_direct_sql_init_body"); + if (!spider_hton_ptr) + { + strcpy(message, "Plugin 'SPIDER' is not loaded"); + goto error; + } if (args->arg_count != 3) { strcpy(message, "spider_(bg)_direct_sql() requires 3 arguments"); diff --git a/storage/spider/spd_i_s.cc b/storage/spider/spd_i_s.cc index 7db9537136a..8ae88102e81 100644 --- a/storage/spider/spd_i_s.cc +++ b/storage/spider/spd_i_s.cc @@ -28,6 +28,7 @@ #include "spd_table.h" extern pthread_mutex_t spider_mem_calc_mutex; +extern handlerton *spider_hton_ptr; extern const char *spider_alloc_func_name[SPIDER_MEM_CALC_LIST_NUM]; extern const char *spider_alloc_file_name[SPIDER_MEM_CALC_LIST_NUM]; @@ -63,6 +64,8 @@ static int spider_i_s_alloc_mem_fill_table( uint roop_count; TABLE *table = tables->table; DBUG_ENTER("spider_i_s_alloc_mem_fill_table"); + if (!spider_hton_ptr) + DBUG_RETURN(0); for (roop_count = 0; roop_count < SPIDER_MEM_CALC_LIST_NUM; roop_count++) { table->field[0]->store(roop_count, TRUE); @@ -177,6 +180,8 @@ static int spider_i_s_wrapper_protocols_fill_table( SPIDER_DBTON *dbton; TABLE *table = tables->table; DBUG_ENTER("spider_i_s_wrapper_protocols_fill_table"); + if (!spider_hton_ptr) + DBUG_RETURN(0); for (roop_count = 0; roop_count < SPIDER_DBTON_SIZE; roop_count++) { dbton = &spider_dbton[roop_count]; diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index b46a593f391..33fd26af4b4 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -253,7 +253,6 @@ enum spider_malloc_id { SPD_MID_DB_MBASE_RESULT_FETCH_ROW_FROM_TMP_TABLE_3, SPD_MID_DB_MBASE_ROW_APPEND_ESCAPED_TO_STR_1, SPD_MID_DB_MBASE_ROW_CLONE_1, - SPD_MID_DB_MBASE_SET_LOOP_CHECK_1, SPD_MID_DB_MBASE_SET_SQL_MODE_1, SPD_MID_DB_MBASE_SET_TIME_ZONE_1, SPD_MID_DB_MBASE_SET_WAIT_TIMEOUT_1, @@ -1455,6 +1454,7 @@ typedef struct st_spider_table_mon st_spider_table_mon *next; } SPIDER_TABLE_MON; +/* List of `SPIDER_TABLE_MON's */ typedef struct st_spider_table_mon_list { char *key; diff --git a/storage/spider/spd_init_query.h b/storage/spider/spd_init_query.h index 35a250c7d3c..ced68e03d08 100644 --- a/storage/spider/spd_init_query.h +++ b/storage/spider/spd_init_query.h @@ -20,8 +20,16 @@ */ static LEX_STRING spider_init_queries[] = { + /* Use the default SQL_MODE for this connection. */ {C_STRING_WITH_LEN( - "SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'ORACLE', '');" + "SET @@SQL_MODE = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO," + "NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';" + )}, + {C_STRING_WITH_LEN( + "SET @@OLD_MODE = CONCAT(@@OLD_MODE, ',UTF8_IS_UTF8MB3');" + )}, + {C_STRING_WITH_LEN( + "SET tx_read_only = off;" )}, {C_STRING_WITH_LEN( "create table if not exists mysql.spider_xa(" diff --git a/storage/spider/spd_ping_table.cc b/storage/spider/spd_ping_table.cc index edad3163c0b..2597150d7aa 100644 --- a/storage/spider/spd_ping_table.cc +++ b/storage/spider/spd_ping_table.cc @@ -50,6 +50,8 @@ extern PSI_mutex_key spd_key_mutex_mon_list_update_status; extern PSI_mutex_key spd_key_mutex_mon_table_cache; #endif +/* Array (of size `spider_udf_table_mon_mutex_count') of hashes of +`SPIDER_TABLE_MON_LIST'. */ HASH *spider_udf_table_mon_list_hash; uint spider_udf_table_mon_list_hash_id; const char *spider_udf_table_mon_list_hash_func_name; @@ -59,23 +61,43 @@ pthread_mutex_t *spider_udf_table_mon_mutexes; pthread_cond_t *spider_udf_table_mon_conds; pthread_mutex_t spider_mon_table_cache_mutex; +/* A cache to store distinct SPIDER_MON_KEYs with db name, table name +and link id read from mysql.spider_link_mon_servers table. Initialised +and populated in spider_init_ping_table_mon_cache(), and used in +spider_ping_table_cache_compare(). The udf +spider_flush_table_mon_cache is used to flag a initialisation. */ DYNAMIC_ARRAY spider_mon_table_cache; uint spider_mon_table_cache_id; const char *spider_mon_table_cache_func_name; const char *spider_mon_table_cache_file_name; ulong spider_mon_table_cache_line_no; -volatile ulonglong spider_mon_table_cache_version = 0; -volatile ulonglong spider_mon_table_cache_version_req = 1; +/* The mon table cache version, initialised at 0, and always no +greater than spider_mon_table_cache_version_req. When the inequality +is strict, an initialisation of spider_mon_table_cache will be +triggered. */ +volatile ulonglong spider_mon_table_cache_version; +/* The required mon table cache version, incremented by one by the +udf spider_flush_table_mon_cache */ +volatile ulonglong spider_mon_table_cache_version_req; + /* Get or create a `SPIDER_TABLE_MON_LIST' for a key `str' */ SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list( SPIDER_TRX *trx, THD *thd, - spider_string *str, + spider_string *str, /* The key to search in + `spider_udf_table_mon_list_hash', + usually in the format of + "./$db_name/$table_name000000000$link_idx" */ uint conv_name_length, int link_idx, char *static_link_id, uint static_link_id_length, - uint32 server_id, + uint32 server_id, /* The server id of the monitor + server, used for creating a new + table mon list having a + `SPIDER_TABLE_MON' corresponding to + the server id as the `current' + field */ bool need_lock, int *error_num ) { @@ -85,6 +107,7 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list( ulonglong mon_table_cache_version; my_hash_value_type hash_value; DBUG_ENTER("spider_get_ping_table_mon_list"); + /* Reset the cache if the version does not match the requirement */ if (spider_mon_table_cache_version != spider_mon_table_cache_version_req) { SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME)); @@ -97,6 +120,9 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list( free_root(&mem_root, MYF(0)); } + /* Search for the table mon list in the hash, if one is not found or + if it is found but has the wrong cache version, create and + initialise a new one. */ mutex_hash= spider_udf_calc_hash(str->c_ptr(), spider_udf_table_mon_mutex_count); DBUG_PRINT("info",("spider hash key=%s", str->c_ptr())); @@ -113,12 +139,15 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list( table_mon_list->mon_table_cache_version != mon_table_cache_version ) { + /* If table_mon_list is found but the cache version does not + match, remove it from the hash and free it. */ if ( table_mon_list && table_mon_list->mon_table_cache_version != mon_table_cache_version ) spider_release_ping_table_mon_list_loop(mutex_hash, table_mon_list); - + /* create and initialise `table_mon_list' and insert it into the + hash */ if (!(table_mon_list = spider_get_ping_table_tgt(thd, str->c_ptr(), conv_name_length, link_idx, static_link_id, static_link_id_length, server_id, str, need_lock, error_num))) @@ -240,6 +269,14 @@ int spider_release_ping_table_mon_list( DBUG_RETURN(0); } +/* + Look for a `SPIDER_MON_KEY` in `spider_mon_table_cache' whose db and + table name and link_idx matching `name' and `link_idx' with wild + card matching. If a match is found, create `SPIDER_TABLE_MON's from + all rows in mysql.spider_link_mon_servers that match the info in the + `SPIDER_MON_KEY' and populate the `table_mon_list' with these + `SPIDER_TABLE_MON's. +*/ int spider_get_ping_table_mon( THD *thd, SPIDER_TABLE_MON_LIST *table_mon_list, @@ -316,6 +353,8 @@ int spider_get_ping_table_mon( goto error; create_table_mon: + /* Find the first row in mysql.spider_link_mon_servers matching the + db name, table name and link_idx */ if ((error_num = spider_get_sys_table_by_idx(table_link_mon, table_key, table_link_mon->s->primary_key, 3))) { @@ -323,6 +362,9 @@ create_table_mon: goto error; } + /* create one `SPIDER_TABLE_MON' per row in + mysql.spider_link_mon_servers with matching db name, table name and + link_idx, and add it to `table_mon_list'. */ do { if (!(table_mon = (SPIDER_TABLE_MON *) spider_bulk_malloc(spider_current_trx, SPD_MID_GET_PING_TABLE_MON_1, MYF(MY_WME | MY_ZEROFILL), @@ -356,7 +398,7 @@ create_table_mon: (error_num = spider_get_sys_link_mon_server_id( table_link_mon, &table_mon->server_id, mem_root)) || (error_num = spider_get_sys_link_mon_connect_info( - table_link_mon, tmp_share, 0, mem_root)) + table_link_mon, tmp_share, mem_root)) ) { table_link_mon->file->print_error(error_num, MYF(0)); spider_sys_index_end(table_link_mon); @@ -416,15 +458,21 @@ error: DBUG_RETURN(error_num); } +/* + creates and return table_mon_list associated with table with `name' + and `link_idx'th link. +*/ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt( THD *thd, - char *name, + char *name, /* The table name, usually fully qualified */ uint name_length, int link_idx, char *static_link_id, uint static_link_id_length, - uint32 server_id, - spider_string *str, + uint32 server_id, /* The server_id will determine the + `current' field of the returned + `SPIDER_TABLE_MON_LIST'. */ + spider_string *str, /* str->c_ptr() == name */ bool need_lock, int *error_num ) { @@ -469,6 +517,7 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt( memcpy(key_str, str->ptr(), table_mon_list->key_length); tmp_share->access_charset = thd->variables.character_set_client; + /* Open mysql.spider_tables */ if ( !(table_tables = spider_open_sys_table( thd, SPIDER_SYS_TABLES_TABLE_NAME_STR, @@ -478,6 +527,8 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt( my_error(*error_num, MYF(0)); goto error; } + /* store db and table names and link idx in mysql.spider_tables for + reading */ spider_store_tables_name(table_tables, name, name_length); if (static_link_id) { @@ -501,9 +552,10 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt( goto error; } } + /* Populate tmp_share with info read from mysql.spider_tables */ if ( (*error_num = spider_get_sys_tables_connect_info( - table_tables, tmp_share, 0, &mem_root)) || + table_tables, tmp_share, &mem_root)) || (*error_num = spider_get_sys_tables_link_status( table_tables, tmp_share->link_statuses, &mem_root)) ) { @@ -524,9 +576,8 @@ SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt( tmp_share, name, name_length )) || (*error_num = spider_create_conn_keys(tmp_share)) || -/* - (*error_num = spider_db_create_table_names_str(tmp_share)) || -*/ + /* Pinally, populate `table_mon_list' with newly created + `SPIDER_TABLE_MON's */ (*error_num = spider_get_ping_table_mon( thd, table_mon_list, name, name_length, link_idx, server_id, &mem_root, need_lock)) @@ -811,6 +862,11 @@ error_open_table_tables: DBUG_RETURN(error_num); } +/* + Initialise `spider_mon_table_cache' by scanning the + mysql.spider_link_mon_servers table, creating distinct + `SPIDER_MON_KEY's with the info and inserting them into the cache. +*/ int spider_init_ping_table_mon_cache( THD *thd, MEM_ROOT *mem_root, @@ -839,6 +895,7 @@ int spider_init_ping_table_mon_cache( /* reset */ spider_mon_table_cache.elements = 0; + /* start at the first row */ if ((error_num = spider_sys_index_first(table_link_mon, table_link_mon->s->primary_key))) { @@ -855,10 +912,16 @@ int spider_init_ping_table_mon_cache( mon_key.table_name_length = SPIDER_SYS_LINK_MON_TABLE_TABLE_NAME_SIZE + 1; mon_key.link_id_length = SPIDER_SYS_LINK_MON_TABLE_LINK_ID_SIZE + 1; do { + /* update content of `mon_key' */ if ((error_num = spider_get_sys_link_mon_key(table_link_mon, &mon_key, mem_root, &same))) goto error_get_sys_link_mon_key; + /* `mon_key' has changed content. since + mysql.spider_link_mon_servers is indexed by db_name, + table_name, link_idx, and server_id, it is possible that + different server_ids share the same mon_key which only has + db_name, table_name, link_idx */ if (!same) { mon_key.sort = spider_calc_for_sort(3, mon_key.db_name, @@ -929,6 +992,13 @@ error_open_sys_table: DBUG_RETURN(error_num); } +/* + Read from msyql.spider_link_mon_servers table fields the db name, + table name and link_id and search for them with wild card matching + in `spider_mon_table_cache'. store the db name, table name, and + link_id of the matching `SPIDER_MON_KEY' back to the table field on + success. +*/ int spider_ping_table_cache_compare( TABLE *table, MEM_ROOT *mem_root @@ -1205,9 +1275,6 @@ long long spider_ping_table_body( DBUG_PRINT("info",("spider mon_table_result->result_status=SPIDER_LINK_MON_NG 2")); if (table_mon_list->mon_status != SPIDER_LINK_MON_NG) { -/* - pthread_mutex_lock(&table_mon_list->update_status_mutex); -*/ pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); if (table_mon_list->mon_status != SPIDER_LINK_MON_NG) { @@ -1222,9 +1289,6 @@ long long spider_ping_table_body( conv_name.c_ptr(), conv_name_length, link_idx); status_changed_to_ng = TRUE; } -/* - pthread_mutex_unlock(&table_mon_list->update_status_mutex); -*/ pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); if (status_changed_to_ng) { @@ -1278,9 +1342,6 @@ long long spider_ping_table_body( DBUG_PRINT("info",("spider mon_table_result->result_status=SPIDER_LINK_MON_NG 3")); if (table_mon_list->mon_status != SPIDER_LINK_MON_NG) { -/* - pthread_mutex_lock(&table_mon_list->update_status_mutex); -*/ pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); if (table_mon_list->mon_status != SPIDER_LINK_MON_NG) { @@ -1295,9 +1356,6 @@ long long spider_ping_table_body( conv_name.c_ptr(), conv_name_length, link_idx); status_changed_to_ng = TRUE; } -/* - pthread_mutex_unlock(&table_mon_list->update_status_mutex); -*/ pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); if (status_changed_to_ng) { @@ -1341,9 +1399,6 @@ long long spider_ping_table_body( mon_table_result->result_status == SPIDER_LINK_MON_NG && table_mon_list->mon_status != SPIDER_LINK_MON_NG ) { -/* - pthread_mutex_lock(&table_mon_list->update_status_mutex); -*/ pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); if (table_mon_list->mon_status != SPIDER_LINK_MON_NG) { @@ -1358,9 +1413,6 @@ long long spider_ping_table_body( conv_name.c_ptr(), conv_name_length, link_idx); status_changed_to_ng = TRUE; } -/* - pthread_mutex_unlock(&table_mon_list->update_status_mutex); -*/ pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); if (status_changed_to_ng) { @@ -1531,9 +1583,9 @@ int spider_ping_table_mon_from_table( SPIDER_SHARE *share, int base_link_idx, uint32 server_id, - char *conv_name, + char *conv_name, /* Usually fully qualified table name */ uint conv_name_length, - int link_idx, + int link_idx, /* The link id to ping */ char *where_clause, uint where_clause_length, long monitoring_kind, @@ -1543,9 +1595,6 @@ int spider_ping_table_mon_from_table( ) { int error_num = 0, current_mon_count, flags; uint32 first_sid; -/* - THD *thd = trx->thd; -*/ SPIDER_TABLE_MON_LIST *table_mon_list; SPIDER_TABLE_MON *table_mon; SPIDER_MON_TABLE_RESULT mon_table_result; @@ -1614,6 +1663,7 @@ int spider_ping_table_mon_from_table( if (monitoring_flag & 1) flags |= SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES; + /* Get or create `table_mon_list' for `conv_name_str'. */ if (!(table_mon_list = spider_get_ping_table_mon_list(trx, thd, &conv_name_str, conv_name_length, link_idx, share->static_link_ids[link_idx], @@ -1645,6 +1695,8 @@ int spider_ping_table_mon_from_table( table_mon = table_mon_list->current; first_sid = table_mon->server_id; current_mon_count = 1; + /* Call spider_ping_table on each table_mon of `table_mon_list', + until one succeeds */ while (TRUE) { DBUG_PRINT("info",("spider thd->killed=%s", @@ -1689,16 +1741,13 @@ int spider_ping_table_mon_from_table( if (!spider_db_udf_ping_table_mon_next( thd, table_mon, mon_conn, &mon_table_result, conv_name, conv_name_length, link_idx, - where_clause, where_clause_length, -1, table_mon_list->list_size, + where_clause, where_clause_length, /*first_sid=*/-1, table_mon_list->list_size, 0, 0, 0, flags, monitoring_limit)) { if ( mon_table_result.result_status == SPIDER_LINK_MON_NG && table_mon_list->mon_status != SPIDER_LINK_MON_NG ) { -/* - pthread_mutex_lock(&table_mon_list->update_status_mutex); -*/ pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); if (table_mon_list->mon_status != SPIDER_LINK_MON_NG) { @@ -1713,9 +1762,6 @@ int spider_ping_table_mon_from_table( spider_sys_log_tables_link_failed(thd, conv_name, conv_name_length, link_idx); } -/* - pthread_mutex_unlock(&table_mon_list->update_status_mutex); -*/ pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); } table_mon_list->last_caller_result = mon_table_result.result_status; diff --git a/storage/spider/spd_sys_table.cc b/storage/spider/spd_sys_table.cc index 08eea15a76e..5cbae605ca5 100644 --- a/storage/spider/spd_sys_table.cc +++ b/storage/spider/spd_sys_table.cc @@ -562,6 +562,11 @@ int spider_check_sys_table_for_update_all_columns( HA_WHOLE_KEY, HA_READ_KEY_EXACT)); } +/* + Creates a key (`table_key') consisting of `col_count' key parts of + `idx'th index of the table, then positions an index cursor to that + key. +*/ int spider_get_sys_table_by_idx( TABLE *table, char *table_key, @@ -617,7 +622,7 @@ int spider_sys_index_next_same( int spider_sys_index_first( TABLE *table, - const int idx + const int idx /* which index to use */ ) { int error_num; DBUG_ENTER("spider_sys_index_first"); @@ -2147,14 +2152,16 @@ int spider_get_sys_tables( DBUG_RETURN(0); } +/* Read table info from mysql.spider_tables into a `SPIDER_SHARE' */ int spider_get_sys_tables_connect_info( - TABLE *table, - SPIDER_SHARE *share, - int link_idx, + TABLE *table, /* The mysql.spider_tables table */ + SPIDER_SHARE *share, /* The `SPIDER_SHARE' to + update info */ MEM_ROOT *mem_root ) { char *ptr; int error_num = 0; + const int link_idx= 0; DBUG_ENTER("spider_get_sys_tables_connect_info"); DBUG_PRINT("info",("spider link_idx:%d", link_idx)); if ((ptr = get_field(mem_root, table->field[SPIDER_TABLES_PRIORITY_POS]))) @@ -2588,11 +2595,17 @@ error: DBUG_RETURN(error_num); } +/* Populate `mon_key' from the current row in `table' */ int spider_get_sys_link_mon_key( - TABLE *table, - SPIDER_MON_KEY *mon_key, + TABLE *table, /* the mysql.spider_link_mon_servers + table */ + SPIDER_MON_KEY *mon_key, /* output, to be populated in this + function */ MEM_ROOT *mem_root, - int *same + int *same /* output, true if the data from the + current row in the table agrees with + existing data in `mon_key' and false + otherwise */ ) { char *db_name, *table_name, *link_id; uint db_name_length, table_name_length, link_id_length; @@ -2608,6 +2621,7 @@ int spider_get_sys_link_mon_key( DBUG_RETURN(ER_SPIDER_SYS_TABLE_VERSION_NUM); } + /* get data for `mon_key' from the table record */ if (!(db_name= get_field(mem_root, table->field[SPIDER_LINK_MON_SERVERS_DB_NAME_POS]))) @@ -2659,9 +2673,12 @@ int spider_get_sys_link_mon_key( DBUG_RETURN(0); } +/* Get the server id from the spider_link_mon_servers table field */ int spider_get_sys_link_mon_server_id( - TABLE *table, - uint32 *server_id, + TABLE *table, /* the + mysql.spider_link_mon_servers + table */ + uint32 *server_id, /* output to server_id */ MEM_ROOT *mem_root ) { char *ptr; @@ -2675,14 +2692,17 @@ int spider_get_sys_link_mon_server_id( DBUG_RETURN(error_num); } +/* Get connect info from the spider_link_mon_servers table fields */ int spider_get_sys_link_mon_connect_info( - TABLE *table, - SPIDER_SHARE *share, - int link_idx, + TABLE *table, /* The + mysql.spider_link_mon_servers + table */ + SPIDER_SHARE *share, /* The output spider_share */ MEM_ROOT *mem_root ) { char *ptr; int error_num = 0; + const int link_idx= 0; DBUG_ENTER("spider_get_sys_link_mon_connect_info"); if ( !table->field[SPIDER_LINK_MON_SERVERS_SERVER_POS]->is_null() && diff --git a/storage/spider/spd_sys_table.h b/storage/spider/spd_sys_table.h index a51d6914c71..cef44df9a93 100644 --- a/storage/spider/spd_sys_table.h +++ b/storage/spider/spd_sys_table.h @@ -56,6 +56,7 @@ #define SPIDER_SYS_LINK_MON_TABLE_TABLE_NAME_SIZE 64 #define SPIDER_SYS_LINK_MON_TABLE_LINK_ID_SIZE 64 +/* For insertion into `spider_mon_table_cache'. */ class SPIDER_MON_KEY: public SPIDER_SORT { public: @@ -393,7 +394,6 @@ int spider_get_sys_tables( int spider_get_sys_tables_connect_info( TABLE *table, SPIDER_SHARE *share, - int link_idx, MEM_ROOT *mem_root ); @@ -460,7 +460,6 @@ int spider_get_sys_link_mon_server_id( int spider_get_sys_link_mon_connect_info( TABLE *table, SPIDER_SHARE *share, - int link_idx, MEM_ROOT *mem_root ); diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index f2682e8b39d..bdc3a33a017 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -125,6 +125,11 @@ extern SPIDER_DBTON spider_dbton_mysql; extern SPIDER_DBTON spider_dbton_mariadb; SPIDER_THREAD *spider_table_sts_threads; SPIDER_THREAD *spider_table_crd_threads; +extern volatile ulonglong spider_mon_table_cache_version; +extern volatile ulonglong spider_mon_table_cache_version_req; +extern ulonglong spider_conn_id; +extern Time_zone *UTC; +extern ulonglong spider_thread_id; #ifdef HAVE_PSI_INTERFACE PSI_mutex_key spd_key_mutex_tbl; @@ -4019,11 +4024,13 @@ error_alloc_conn_string: DBUG_RETURN(error_num); } +/* Set default connect info of a SPIDER_SHARE if needed */ int spider_set_connect_info_default( - SPIDER_SHARE *share, - partition_element *part_elem, - partition_element *sub_elem, - TABLE_SHARE *table_share + SPIDER_SHARE *share, /* The `SPIDER_SHARE' to set + default connect info */ + partition_element *part_elem, /* partition info used as input */ + partition_element *sub_elem, /* subpartition info used as input */ + TABLE_SHARE *table_share /* table share info used as input */ ) { bool check_socket; bool check_database; @@ -4257,22 +4264,6 @@ int spider_set_connect_info_default( } } -/* - if (!share->static_link_ids[roop_count]) - { - DBUG_PRINT("info",("spider create default static_link_ids")); - share->static_link_ids_lengths[roop_count] = - SPIDER_DB_STATIC_LINK_ID_LEN; - if ( - !(share->static_link_ids[roop_count] = spider_create_string( - SPIDER_DB_STATIC_LINK_ID_STR, - share->static_link_ids_lengths[roop_count])) - ) { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - } -*/ - if (port_has_default_value) { share->tgt_ports[roop_count] = MYSQL_PORT; @@ -4362,7 +4353,11 @@ int spider_set_connect_info_default( DBUG_RETURN(0); } - +/* + This function is a no-op if all share->tgt_dbs and + share->tgt_table_names are non-null, otherwise it may assign them + with db_name and table_name +*/ int spider_set_connect_info_default_db_table( SPIDER_SHARE *share, const char *db_name, @@ -4448,6 +4443,11 @@ int spider_set_connect_info_default_db_table( DBUG_RETURN(0); } +/* + Parse `dbtable_name' into db name and table name, and call + spider_set_connect_info_default_db_table() to set the db/table name + values of `share' if needed +*/ int spider_set_connect_info_default_dbtable( SPIDER_SHARE *share, const char *dbtable_name, @@ -4817,12 +4817,12 @@ SPIDER_SHARE *spider_create_share( share->table.key_info = table_share->key_info; share->table.read_set = &table_share->all_set; - if (table_share->keys > 0 && - !(share->key_hint = new spider_string[table_share->keys]) - ) { - *error_num = HA_ERR_OUT_OF_MEM; - goto error_init_hint_string; - } + if (table_share->keys > 0) + if (!(share->key_hint = new spider_string[table_share->keys])) + { + *error_num = HA_ERR_OUT_OF_MEM; + goto error_init_hint_string; + } for (roop_count = 0; roop_count < (int) table_share->keys; roop_count++) share->key_hint[roop_count].init_calc_mem(SPD_MID_CREATE_SHARE_2); DBUG_PRINT("info",("spider share->key_hint=%p", share->key_hint)); @@ -6006,7 +6006,7 @@ int spider_open_all_tables( (error_num = spider_get_sys_tables( table_tables, &db_name, &table_name, &mem_root)) || (error_num = spider_get_sys_tables_connect_info( - table_tables, &tmp_share, 0, &mem_root)) || + table_tables, &tmp_share, &mem_root)) || (error_num = spider_set_connect_info_default( &tmp_share, NULL, @@ -6279,7 +6279,11 @@ int spider_close_connection( } spider_rollback(spider_hton_ptr, thd, TRUE); + + Dummy_error_handler deh; // suppress network errors at this stage + thd->push_internal_handler(&deh); spider_free_trx(trx, TRUE, false); + thd->pop_internal_handler(); DBUG_RETURN(0); } @@ -6450,6 +6454,7 @@ int spider_db_done( pthread_mutex_destroy(&spider_tbl_mutex); pthread_attr_destroy(&spider_pt_attr); + spider_hton_ptr= NULL; for (roop_count = 0; roop_count < SPIDER_MEM_CALC_LIST_NUM; roop_count++) { if (spider_alloc_func_name[roop_count]) @@ -6559,6 +6564,12 @@ int spider_db_init( handlerton *spider_hton = (handlerton *)p; DBUG_ENTER("spider_db_init"); + spider_mon_table_cache_version= 0; + spider_mon_table_cache_version_req= 1; + spider_conn_id= 1; + spider_conn_mutex_id= 0; + UTC = 0; + spider_thread_id = 1; const LEX_CSTRING aria_name={STRING_WITH_LEN("Aria")}; if (!plugin_is_ready(&aria_name, MYSQL_STORAGE_ENGINE_PLUGIN)) DBUG_RETURN(HA_ERR_RETRY_INIT); @@ -6793,11 +6804,6 @@ int spider_db_init( spider_udf_table_mon_list_hash[roop_count].array.size_of_element); } - if (spider_init_system_tables()) - { - goto error_system_table_creation; - } - if (!(spider_table_sts_threads = (SPIDER_THREAD *) spider_bulk_malloc(NULL, SPD_MID_DB_INIT_12, MYF(MY_WME | MY_ZEROFILL), &spider_table_sts_threads, (uint) (sizeof(SPIDER_THREAD) * @@ -6806,7 +6812,7 @@ int spider_db_init( spider_param_table_crd_thread_count()), NullS)) ) - goto error_alloc_mon_mutxes; + goto error_alloc_table_sts_crd_threads; for (roop_count = 0; roop_count < (int) spider_param_table_sts_thread_count(); @@ -6863,6 +6869,7 @@ error_init_table_sts_threads: { spider_free_sts_threads(&spider_table_sts_threads[roop_count]); } +error_alloc_table_sts_crd_threads: spider_free(NULL, spider_table_sts_threads, MYF(0)); roop_count= spider_udf_table_mon_mutex_count - 1; error_init_udf_table_mon_list_hash: @@ -6878,7 +6885,6 @@ error_init_udf_table_mon_list_hash: error_init_udf_table_mon_cond: for (; roop_count >= 0; roop_count--) pthread_cond_destroy(&spider_udf_table_mon_conds[roop_count]); -error_system_table_creation: roop_count= spider_udf_table_mon_mutex_count - 1; error_init_udf_table_mon_mutex: for (; roop_count >= 0; roop_count--) diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index b6a2bcd8494..124e47364e6 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -41,7 +41,7 @@ extern struct charset_info_st *spd_charset_utf8mb3_bin; extern handlerton *spider_hton_ptr; extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; pthread_mutex_t spider_thread_id_mutex; -ulonglong spider_thread_id = 1; +ulonglong spider_thread_id; #ifdef HAVE_PSI_INTERFACE extern PSI_mutex_key spd_key_mutex_udf_table; diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index aa4d366208f..a79a0764840 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -39437,18 +39437,24 @@ my_uca1400_collation_definition_init(MY_CHARSET_LOADER *loader, *dst= nopad ? my_charset_utf8mb4_unicode_520_nopad_ci : my_charset_utf8mb4_unicode_520_ci; break; +#ifdef HAVE_CHARSET_ucs2 case MY_CS_ENCODING_UCS2: *dst= nopad ? my_charset_ucs2_unicode_520_nopad_ci : my_charset_ucs2_unicode_520_ci; break; +#endif +#ifdef HAVE_CHARSET_utf16 case MY_CS_ENCODING_UTF16: *dst= nopad ? my_charset_utf16_unicode_520_nopad_ci : my_charset_utf16_unicode_520_ci; break; +#endif +#ifdef HAVE_CHARSET_utf32 case MY_CS_ENCODING_UTF32: *dst= nopad ? my_charset_utf32_unicode_520_nopad_ci : my_charset_utf32_unicode_520_ci; break; +#endif } dst->number= id; diff --git a/support-files/mariadb.service.in b/support-files/mariadb.service.in index 1af0106e929..79c8b9a8cca 100644 --- a/support-files/mariadb.service.in +++ b/support-files/mariadb.service.in @@ -51,7 +51,7 @@ Group=mysql # CAP_DAC_OVERRIDE To allow auth_pam_tool (which is SUID root) to read /etc/shadow when it's chmod 0 # does nothing for non-root, not needed if /etc/shadow is u+r # CAP_AUDIT_WRITE auth_pam_tool needs it on Debian for whatever reason -CapabilityBoundingSet=CAP_IPC_LOCK CAP_DAC_OVERRIDE CAP_AUDIT_WRITE +AmbientCapabilities=CAP_IPC_LOCK CAP_DAC_OVERRIDE CAP_AUDIT_WRITE # PrivateDevices=true implies NoNewPrivileges=true and # SUID auth_pam_tool suddenly doesn't do setuid anymore diff --git a/support-files/mariadb@.service.in b/support-files/mariadb@.service.in index 8cb3ab2a4d7..31f1586f1bf 100644 --- a/support-files/mariadb@.service.in +++ b/support-files/mariadb@.service.in @@ -181,7 +181,7 @@ PrivateNetwork=false # CAP_DAC_OVERRIDE To allow auth_pam_tool (which is SUID root) to read /etc/shadow when it's chmod 0 # does nothing for non-root, not needed if /etc/shadow is u+r # CAP_AUDIT_WRITE auth_pam_tool needs it on Debian for whatever reason -CapabilityBoundingSet=CAP_IPC_LOCK CAP_DAC_OVERRIDE CAP_AUDIT_WRITE +AmbientCapabilities=CAP_IPC_LOCK CAP_DAC_OVERRIDE CAP_AUDIT_WRITE # PrivateDevices=true implies NoNewPrivileges=true and # SUID auth_pam_tool suddenly doesn't do setuid anymore diff --git a/support-files/mini-benchmark.sh b/support-files/mini-benchmark.sh index 18de6dbec51..a405b6c469c 100755 --- a/support-files/mini-benchmark.sh +++ b/support-files/mini-benchmark.sh @@ -1,6 +1,6 @@ #!/bin/bash # Abort on errors -set -e +set -ex display_help() { echo "Usage: $(basename "$0") [-h] [--perf] [--perf-flamegraph]" @@ -10,13 +10,33 @@ display_help() { echo "regressions." echo echo "optional arguments:" + echo " --name STRING identifier for the benchmark, added to the " + echo " folder name and (if --log is set) the log file " + echo " --threads \"STRING\" quoted string of space-separated integers " + echo " representing the threads to run." + echo " example: --threads \"1 32 64 128\"" + echo " default: \"1 2 4 8 16\"" + echo " --duration INTEGER duration of each thread run in seconds" + echo " default: 60" + echo " --workload STRING sysbench workload to execute" + echo " default: oltp_read_write" + echo " --log logs the mini-benchmark stdout/stderr into the" + echo " benchmark folder." echo " --perf measure CPU cycles and instruction count in for " echo " sysbench runs" echo " --perf-flamegraph record performance counters in perf.data.* and" echo " generate flamegraphs automatically" + echo " --cpu-limit upper limit on the number of CPU cycles (in billions) used for the benchmark" + echo " default: 750" echo " -h, --help display this help and exit" } +# Default parameters +BENCHMARK_NAME='mini-benchmark' +THREADS='1 2 4 8 16' +DURATION=60 +WORKLOAD='oltp_read_write' + while : do case "$1" in @@ -28,6 +48,31 @@ do display_version exit 0 ;; + --name) + shift + BENCHMARK_NAME+='-' + BENCHMARK_NAME+=$1 + shift + ;; + --threads) + shift + THREADS=$1 + shift + ;; + --duration) + shift + DURATION=$1 + shift + ;; + --workload) + shift + WORKLOAD=$1 + shift + ;; + --log) + LOG=true + shift + ;; --perf) PERF=true shift @@ -36,6 +81,11 @@ do PERF_RECORD=true shift ;; + --cpu-limit) + shift + CPU_CYCLE_LIMIT=$1 + shift + ;; -*) echo "Error: Unknown option: $1" >&2 ## or call function display_help @@ -47,6 +97,13 @@ do esac done +# Save results of this run in a subdirectory so that they are not overwritten by +# the next run +TIMESTAMP="$(date -Iseconds)" +mkdir "$BENCHMARK_NAME-$TIMESTAMP" +cd "$BENCHMARK_NAME-$TIMESTAMP" || exit 1 + +( # Check that the dependencies of this script are available if [ ! -e /usr/bin/pgrep ] then @@ -62,6 +119,7 @@ fi # If there are multiple processes, assume the last one is the actual server and # any potential other ones were just part of the service wrapper chain +# shellcheck disable=SC2005 MARIADB_SERVER_PID="$(echo "$(pgrep -f mariadbd || pgrep -f mysqld)" | tail -n 1)" if [ -z "$MARIADB_SERVER_PID" ] @@ -70,6 +128,12 @@ then exit 1 fi +if [ "$PERF" == true ] && [ "$PERF_RECORD" == true ] +then + echo "ERROR: Cannot select both --perf and --perf-flamegraph options simultaneously. Please choose one or the other." + exit 1 +fi + if [ "$PERF" == true ] || [ "$PERF_RECORD" == true ] then if [ ! -e /usr/bin/perf ] @@ -102,31 +166,31 @@ then echo "Ensure the MariaDB Server debug symbols are installed" for x in $(ldd /usr/sbin/mariadbd | grep -oE " /.* ") do - rpm -q --whatprovides --qf '%{name}' $x | cut -d : -f 1 + rpm -q --whatprovides --qf '%{name}' "$x" | cut -d : -f 1 done | sort -u > mariadbd-dependencies.txt # shellcheck disable=SC2046 debuginfo-install -y mariadb-server $(cat mariadbd-dependencies.txt) - - if [ ! $(perf record echo "testing perf" > /dev/null 2>&1) ] + + if ! (perf record echo "testing perf") > /dev/null 2>&1 then echo "perf does not have permission to run on this system. Skipping." - PERF="" + PERF_COMMAND="" else echo "Using 'perf' to record performance counters in perf.data files" - PERF="perf record -g --freq=99 --output=perf.data --timestamp-filename --pid=$MARIADB_SERVER_PID --" + PERF_COMMAND="perf record -g --freq=99 --output=perf.data --timestamp-filename --pid=$MARIADB_SERVER_PID --" fi -elif [ -e /usr/bin/perf ] +elif [ "$PERF" == true ] then # If flamegraphs were not requested, log normal perf counters if possible - if [ ! $(perf stat echo "testing perf" > /dev/null 2>&1) ] + if ! (perf stat echo "testing perf") > /dev/null 2>&1 then echo "perf does not have permission to run on this system. Skipping." - PERF="" + PERF_COMMAND="" else echo "Using 'perf' to log basic performance counters for benchmark" - PERF="perf stat -p $MARIADB_SERVER_PID --" + PERF_COMMAND="perf stat -p $MARIADB_SERVER_PID --" fi fi @@ -156,28 +220,23 @@ mariadb -e " CREATE USER IF NOT EXISTS sbtest@localhost; GRANT ALL PRIVILEGES ON sbtest.* TO sbtest@localhost" -sysbench oltp_read_write prepare --tables=20 --table-size=100000 | tee sysbench-prepare.log +sysbench "$WORKLOAD" prepare --tables=20 --table-size=100000 | tee sysbench-prepare.log sync && sleep 1 # Ensure writes were propagated to disk -# Save results of this run in a subdirectory so that they are not overwritten by -# the next run -TIMESTAMP="$(date -Iseconds)" -mkdir "mini-benchmark-$TIMESTAMP" -cd "mini-benchmark-$TIMESTAMP" || exit 1 - # Run benchmark with increasing thread counts. The MariaDB Server will be using # around 300 MB of RAM and mostly reading and writing in RAM, so I/O usage is # also low. The benchmark will most likely be CPU bound to due to the load # profile, and also guaranteed to be CPU bound because of being limited to a # single CPU with 'tasksel'. -for t in 1 2 4 8 16 +for t in $THREADS do # Prepend command with perf if defined - # Output stderr to stdout as perf outpus everything in stderr - $PERF $TASKSET_SYSBENCH sysbench oltp_read_write run --threads=$t --time=60 --report-interval=10 2>&1 | tee sysbench-run-$t.log + # Output stderr to stdout as perf outputs everything in stderr + # shellcheck disable=SC2086 + $PERF_COMMAND $TASKSET_SYSBENCH sysbench "$WORKLOAD" run --threads=$t --time=$DURATION --report-interval=10 2>&1 | tee sysbench-run-$t.log done -sysbench oltp_read_write cleanup --tables=20 | tee sysbench-cleanup.log +sysbench "$WORKLOAD" cleanup --tables=20 | tee sysbench-cleanup.log # Store results from 4 thread run in a Gitlab-CI compatible metrics file grep -oE '[a-z]+:[ ]+[0-9.]+' sysbench-run-4.log | sed -r 's/\s+/ /g' | tail -n 15 > metrics.txt @@ -195,12 +254,21 @@ then echo "Total: $(grep -h -e instructions sysbench-run-*.log | sort -k 1 | awk '{s+=$1}END{print s}')" echo # Newline improves readability + if [ -z "$CPU_CYCLE_LIMIT" ] + then + # 04-04-2024: We found this to be an appropriate default limit after running a few benchmarks + # Configure the limit with --cpu-limit if needed + CPU_CYCLE_LIMIT=750 + fi + CPU_CYCLE_LIMIT_LONG="${CPU_CYCLE_LIMIT}000000000" + # Final verdict based on cpu cycle count RESULT="$(grep -h -e cycles sysbench-run-*.log | sort -k 1 | awk '{s+=$1}END{print s}')" - if [ "$RESULT" -gt 850000000000 ] + if [ "$RESULT" -gt "$CPU_CYCLE_LIMIT_LONG" ] then echo # Newline improves readability - echo "Benchmark exceeded 8.5 billion cpu cycles, performance most likely regressed!" + echo "Benchmark exceeded the allowed limit of ${CPU_CYCLE_LIMIT} billion CPU cycles" + echo "Performance most likely regressed!" exit 1 fi fi @@ -216,12 +284,12 @@ if [ "$PERF_RECORD" == true ] then for f in perf.data.* do - perf script -i $f | stackcollapse-perf.pl | flamegraph.pl --width 3000 > $f.svg + perf script -i "$f" | stackcollapse-perf.pl | flamegraph.pl --width 1800 > "$f".svg done - echo "Flamegraphs stored in folder mini-benchmark-$TIMESTAMP/" + echo "Flamegraphs stored in folder $BENCHMARK_NAME-$TIMESTAMP/" fi -# Fallback if CPU cycle count not availalbe: final verdict based on peak QPS +# Fallback if CPU cycle count not available: final verdict based on peak QPS RESULT="$(sort -k 9 -h sysbench-run-*.log | tail -n 1 | grep -oE "qps: [0-9]+" | grep -oE "[0-9]+")" case $RESULT in ''|*[!0-9]*) @@ -240,3 +308,6 @@ case $RESULT in fi ;; esac +# Record the output into the log file, if requested +) 2>&1 | ($LOG && tee "$BENCHMARK_NAME"-"$TIMESTAMP".log) +exit ${PIPESTATUS[0]} # Propagate errors in the sub-shell diff --git a/support-files/policy/apparmor/usr.sbin.mysqld b/support-files/policy/apparmor/usr.sbin.mysqld index c9b780bd413..c144fb2e777 100644 --- a/support-files/policy/apparmor/usr.sbin.mysqld +++ b/support-files/policy/apparmor/usr.sbin.mysqld @@ -14,6 +14,7 @@ capability chown, capability dac_override, + capability ipc_lock, capability setgid, capability setuid, capability sys_rawio, diff --git a/support-files/policy/selinux/mariadb-server.te b/support-files/policy/selinux/mariadb-server.te index 89846063506..ba53c97d4a8 100644 --- a/support-files/policy/selinux/mariadb-server.te +++ b/support-files/policy/selinux/mariadb-server.te @@ -25,7 +25,7 @@ require { class lnk_file read; class process { getattr signull }; class unix_stream_socket connectto; - class capability { sys_resource sys_nice }; + class capability { ipc_lock sys_resource sys_nice }; class tcp_socket { name_bind name_connect }; class file { execute setattr read create getattr execute_no_trans write ioctl open append unlink }; class sock_file { create unlink getattr }; @@ -87,6 +87,8 @@ allow mysqld_t bin_t:file { getattr read execute open execute_no_trans ioctl }; # MariaDB additions allow mysqld_t self:process setpgid; +allow mysqld_t self:capability { ipc_lock }; + # This rule allows port tcp/4444 allow mysqld_t kerberos_port_t:tcp_socket { name_bind name_connect }; # This rule allows port tcp/4567 (tram_port_t may not be available on diff --git a/tests/async_queries.c b/tests/async_queries.c index 8509b414f6e..f0b4fab870a 100644 --- a/tests/async_queries.c +++ b/tests/async_queries.c @@ -358,6 +358,7 @@ handle_option(const struct my_option *opt, const char *arg, return 0; } +PRAGMA_DISABLE_CHECK_STACK_FRAME int main(int argc, char *argv[]) @@ -433,3 +434,4 @@ main(int argc, char *argv[]) return 0; } +PRAGMA_REENABLE_CHECK_STACK_FRAME diff --git a/tests/mysql_client_fw.c b/tests/mysql_client_fw.c index e1b59410933..9f0faf85021 100644 --- a/tests/mysql_client_fw.c +++ b/tests/mysql_client_fw.c @@ -571,6 +571,9 @@ static int my_process_result(MYSQL *mysql_arg) #define MAX_RES_FIELDS 50 #define MAX_FIELD_DATA_SIZE 255 +/* Stack usage 18888 with clang */ +PRAGMA_DISABLE_CHECK_STACK_FRAME + static int my_process_stmt_result(MYSQL_STMT *stmt) { int field_count; @@ -659,6 +662,7 @@ static int my_process_stmt_result(MYSQL_STMT *stmt) mysql_free_result(result); return row_count; } +PRAGMA_REENABLE_CHECK_STACK_FRAME /* Prepare statement, execute, and process result set for given query */ @@ -1434,12 +1438,14 @@ int main(int argc, char **argv) tests_to_run[i]= NULL; } -#ifdef _WIN32 - /* must be the same in C/C and embedded, 1208 on 64bit, 968 on 32bit */ - compile_time_assert(sizeof(MYSQL) == 60*sizeof(void*)+728); -#else - /* must be the same in C/C and embedded, 1272 on 64bit, 964 on 32bit */ - compile_time_assert(sizeof(MYSQL) == 77*sizeof(void*)+656); +/* + this limited check is enough, if sizeof(MYSQL) changes, it changes + everywhere +*/ +#if defined __x86_64__ + compile_time_assert(sizeof(MYSQL) == 1272); +#elif defined __i386__ + compile_time_assert(sizeof(MYSQL) == 964); #endif if (mysql_server_init(embedded_server_arg_count, diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 3bab258d811..0033c5f5307 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -3842,7 +3842,7 @@ static void test_bind_result_ext1() short i_data; uchar b_data; int f_data; - long bData; + int bData; char d_data[20]; double szData; MYSQL_BIND my_bind[8]; @@ -3938,7 +3938,7 @@ static void test_bind_result_ext1() fprintf(stdout, "\n data (float) : %d(%lu)", f_data, length[4]); fprintf(stdout, "\n data (double) : %s(%lu)", d_data, length[5]); - fprintf(stdout, "\n data (bin) : %ld(%lu)", bData, length[6]); + fprintf(stdout, "\n data (bin) : %d(%lu)", bData, length[6]); fprintf(stdout, "\n data (str) : %g(%lu)", szData, length[7]); } @@ -20564,7 +20564,6 @@ typedef struct { #ifndef EMBEDDED_LIBRARY static void test_proxy_header_tcp(const char *ipaddr, int port) { - int rc; MYSQL_RES *result; int family = (strchr(ipaddr,':') == NULL)?AF_INET:AF_INET6; @@ -20639,6 +20638,11 @@ static void test_proxy_header_tcp(const char *ipaddr, int port) DIE_UNLESS(strncmp(row[0], normalized_addr, addrlen) == 0); DIE_UNLESS(atoi(row[0] + addrlen+1) == port); mysql_free_result(result); + if (i == 0 && !strcmp(ipaddr,"192.0.2.1")) + { + /* do "dirty" close, to get aborted message in error log.*/ + mariadb_cancel(m); + } mysql_close(m); } sprintf(query,"DROP USER 'u'@'%s'",normalized_addr); diff --git a/tests/upgrade_from/test_upgrade.sh b/tests/upgrade_from/test_upgrade.sh index e356231afc8..d26ff71f7a3 100755 --- a/tests/upgrade_from/test_upgrade.sh +++ b/tests/upgrade_from/test_upgrade.sh @@ -132,7 +132,7 @@ install_mariadb_from_archive() { [mariadb] name=MariaDB baseurl=$rpm_repository -gpgkey=https://ftp.osuosl.org/pub/mariadb/yum/RPM-GPG-KEY-MariaDB +gpgkey=https://archive.mariadb.org/PublicKey gpgcheck=1 EOF @@ -153,7 +153,7 @@ EOF [[ $latest_distro == 33 ]] && dnf install -y http://springdale.princeton.edu/data/springdale/7/x86_64/os/Computational/boost173-program-options-1.73.0-7.sdl7.x86_64.rpm [[ $latest_distro == 34 ]] && dnf install -y https://repo.almalinux.org/almalinux/9/AppStream/x86_64/os/Packages/boost-program-options-1.75.0-8.el9.x86_64.rpm \ https://vault.centos.org/centos/8/AppStream/x86_64/os/Packages/liburing-1.0.7-3.el8.x86_64.rpm - [[ $latest_distro == 35 ]] && dnf install -y https://download-ib01.fedoraproject.org/pub/fedora/linux/updates/36/Everything/x86_64/Packages/b/boost-program-options-1.76.0-12.fc36.x86_64.rpm + [[ $latest_distro == 35 ]] && dnf install -y https://archives.fedoraproject.org/pub/archive/fedora/linux/updates/36/Everything/x86_64/Packages/b/boost-program-options-1.76.0-12.fc36.x86_64.rpm if [[ $major_version == "10.4" ]] && [[ $minor_version -ge 24 ]]; then log RPMs not available for version 10.4.24+ from this repository. You may try testing by installing from the .tar.gz binaries. exit 1 diff --git a/tpool/tpool_generic.cc b/tpool/tpool_generic.cc index fd97b4464af..a4d6c405bdf 100644 --- a/tpool/tpool_generic.cc +++ b/tpool/tpool_generic.cc @@ -628,7 +628,7 @@ void thread_pool_generic::check_idle(std::chrono::system_clock::time_point now) } /* Switch timer off after 1 minute of idle time */ - if (now - idle_since > max_idle_time) + if (now - idle_since > max_idle_time && m_active_threads.empty()) { idle_since= invalid_timestamp; switch_timer(timer_state_t::OFF); @@ -722,13 +722,17 @@ static int throttling_interval_ms(size_t n_threads,size_t concurrency) /* Create a new worker.*/ bool thread_pool_generic::add_thread() { - if (m_thread_creation_pending.test_and_set()) - return false; - size_t n_threads = thread_count(); if (n_threads >= m_max_threads) return false; + + /* + Deadlock danger exists, so monitor pool health + with maintenance timer. + */ + switch_timer(timer_state_t::ON); + if (n_threads >= m_min_threads) { auto now = std::chrono::system_clock::now(); @@ -739,12 +743,18 @@ bool thread_pool_generic::add_thread() Throttle thread creation and wakeup deadlock detection timer, if is it off. */ - switch_timer(timer_state_t::ON); - return false; } } + /* Check and set "thread creation pending" flag before creating the thread. We + reset the flag in thread_pool_generic::worker_main in new thread created. The + flag must be reset back in case we fail to create the thread. If this flag is + not reset all future attempt to create thread for this pool would not work as + we would return from here. */ + if (m_thread_creation_pending.test_and_set()) + return false; + worker_data *thread_data = m_thread_data_cache.get(); m_active_threads.push_back(thread_data); try @@ -764,6 +774,7 @@ bool thread_pool_generic::add_thread() "current number of threads in pool %zu\n", e.what(), thread_count()); warning_written = true; } + m_thread_creation_pending.clear(); return false; } return true; @@ -801,6 +812,7 @@ thread_pool_generic::thread_pool_generic(int min_threads, int max_threads) : m_tasks_dequeued(), m_wakeups(), m_spurious_wakeups(), + m_timer_state(timer_state_t::ON), m_in_shutdown(), m_timestamp(), m_long_tasks_count(), @@ -813,6 +825,7 @@ thread_pool_generic::thread_pool_generic(int min_threads, int max_threads) : m_maintenance_timer(thread_pool_generic::maintenance_func, this, nullptr) { set_concurrency(); + // start the timer m_maintenance_timer.set_time(0, (int)m_timer_interval.count()); } diff --git a/unittest/mysys/CMakeLists.txt b/unittest/mysys/CMakeLists.txt index d292b7724e2..03c92e8b222 100644 --- a/unittest/mysys/CMakeLists.txt +++ b/unittest/mysys/CMakeLists.txt @@ -19,7 +19,7 @@ MY_ADD_TESTS(bitmap base64 my_atomic my_rdtsc lf my_malloc my_getopt dynstring MY_ADD_TESTS(my_vsnprintf LINK_LIBRARIES strings mysys) MY_ADD_TESTS(aes LINK_LIBRARIES mysys mysys_ssl) ADD_DEFINITIONS(${SSL_DEFINES}) -INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) +INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIRS}) MY_ADD_TESTS(ma_dyncol LINK_LIBRARIES mysys) IF(WIN32) diff --git a/unittest/mysys/bitmap-t.c b/unittest/mysys/bitmap-t.c index 22466355191..8e12b2b8ca7 100644 --- a/unittest/mysys/bitmap-t.c +++ b/unittest/mysys/bitmap-t.c @@ -29,6 +29,8 @@ uint get_rand_bit(uint bitsize) { + if (bitsize == 0) + return 0; return (rand() % bitsize); } @@ -121,6 +123,8 @@ error6: return TRUE; } +PRAGMA_DISABLE_CHECK_STACK_FRAME + my_bool test_compare_operators(MY_BITMAP *map, uint bitsize) { uint i, j, test_bit1, test_bit2, test_bit3,test_bit4; @@ -226,6 +230,8 @@ error5: test_bit1); return TRUE; } +PRAGMA_REENABLE_CHECK_STACK_FRAME + my_bool test_count_bits_set(MY_BITMAP *map, uint bitsize) { @@ -266,7 +272,7 @@ my_bool test_get_first_bit(MY_BITMAP *map, uint bitsize) bitmap_clear_all(map); for (i=0; i < bitsize; i++) bitmap_set_bit(map, i); - if (bitmap_get_first(map) != MY_BIT_NONE) + if (bitmap_get_first_clear(map) != MY_BIT_NONE) goto error2; bitmap_clear_all(map); @@ -278,7 +284,7 @@ my_bool test_get_first_bit(MY_BITMAP *map, uint bitsize) goto error1; bitmap_set_all(map); bitmap_clear_bit(map, test_bit); - if (bitmap_get_first(map) != test_bit) + if (bitmap_get_first_clear(map) != test_bit) goto error2; bitmap_clear_all(map); } @@ -297,14 +303,45 @@ my_bool test_get_next_bit(MY_BITMAP *map, uint bitsize) uint no_loops= bitsize > 128 ? 128 : bitsize; for (i=0; i < no_loops; i++) { + uint count= 0, bits_set= 0; + bitmap_clear_all(map); test_bit=get_rand_bit(bitsize); for (j=0; j < test_bit; j++) bitmap_set_next(map); if (!bitmap_is_prefix(map, test_bit)) goto error1; + j= bitmap_get_first_set(map); + if (j == MY_BIT_NONE) + { + if (test_bit != 0) + goto error1; + continue; + } + count= 1; + while ((j= bitmap_get_next_set(map,j)) != MY_BIT_NONE) + count++; + if (count != test_bit) + goto error1; + + if (test_bit < 3) + continue; bitmap_clear_all(map); + for (j=1; j < test_bit; j+=2) + { + bits_set++; + bitmap_set_bit(map, j); + } + if ((j= bitmap_get_first_set(map)) == MY_BIT_NONE) + goto error1; + count= 1; + while ((j= bitmap_get_next_set(map,j)) != MY_BIT_NONE) + count++; + if (count != bits_set) + goto error1; } + return FALSE; + error1: diag("get_next error bitsize= %u, prefix_size= %u", bitsize,test_bit); return TRUE; @@ -371,7 +408,7 @@ error5: my_bool test_compare(MY_BITMAP *map, uint bitsize) { MY_BITMAP map2; - uint32 map2buf[MAX_TESTED_BITMAP_SIZE]; + my_bitmap_map map2buf[MAX_TESTED_BITMAP_SIZE]; uint i, test_bit; uint no_loops= bitsize > 128 ? 128 : bitsize; if (my_bitmap_init(&map2, map2buf, bitsize)) @@ -431,7 +468,7 @@ my_bool test_intersect(MY_BITMAP *map, uint bitsize) { uint bitsize2 = 1 + get_rand_bit(MAX_TESTED_BITMAP_SIZE - 1); MY_BITMAP map2; - uint32 map2buf[MAX_TESTED_BITMAP_SIZE]; + my_bitmap_map map2buf[MAX_TESTED_BITMAP_SIZE]; uint i, test_bit1, test_bit2, test_bit3; if (my_bitmap_init(&map2, map2buf, bitsize2)) { @@ -477,6 +514,107 @@ error: return TRUE; } +my_bool test_copy(MY_BITMAP *map, uint bitsize) +{ + my_bitmap_map buff[16], buff2[16], buff3[16]; + MY_BITMAP map2, map3; + uint rnd_bit; + + my_bitmap_init(&map2, buff, sizeof(buff)*8); + my_bitmap_init(&map3, buff2, sizeof(buff)*8); + bitmap_set_all(&map2); + bitmap_set_all(&map3); + + bitsize= MY_MIN(bitsize, map2.n_bits); + bitmap_copy(map, &map2); + if (bitmap_bits_set(map) != bitsize) + { + diag("bitmap_copy failed on bitsize %d", bitsize); + return 1; + } + bitmap_set_prefix(&map2, rnd_bit= get_rand_bit(bitsize)+1); + bitmap_export((uchar*) buff3, &map2); + bitmap_import(&map3, (uchar*) buff3); + if (!bitmap_cmp(&map2, &map3)) + { + diag("bitmap_export/bitmap_import failed on bitsize %d rnd_bit: %d", + bitsize, rnd_bit); + return 1; + } + return 0; +} + +static my_bool exec_bitmap_exists_intersection(MY_BITMAP **maps, uint bitsize, + uint start, uint end, uint bit) +{ + bitmap_clear_all(maps[0]); + bitmap_clear_all(maps[1]); + bitmap_set_bit(maps[0], bit); + bitmap_set_bit(maps[1], bit); + return bitmap_exists_intersection(maps, 2, start, end); +} + +my_bool test_bitmap_exists_intersection(MY_BITMAP *map, uint bitsize) +{ + MY_BITMAP map2; + uint start_bit, end_bit, rnd_bit; + MY_BITMAP *maps[2]; + maps[0]= map; + maps[1]= &map2; + + my_bitmap_init(&map2, 0, bitsize); + bitmap_clear_all(map); + bitmap_clear_all(&map2); + + start_bit= get_rand_bit(bitsize); + end_bit= get_rand_bit(bitsize); + if (start_bit > end_bit) + swap_variables(uint, start_bit, end_bit); + rnd_bit= start_bit+get_rand_bit(end_bit-start_bit); + + if (!exec_bitmap_exists_intersection(maps, bitsize, start_bit, end_bit, + rnd_bit)) + goto err; + + start_bit= end_bit= rnd_bit= 0; + if (!exec_bitmap_exists_intersection(maps, bitsize, start_bit, end_bit, + rnd_bit)) + goto err; + + start_bit= rnd_bit= 0 ; end_bit= bitsize-1; + if (!exec_bitmap_exists_intersection(maps, bitsize, start_bit, end_bit, + rnd_bit)) + goto err; + + start_bit= rnd_bit= end_bit= bitsize-1; + if (!exec_bitmap_exists_intersection(maps, bitsize, start_bit, end_bit, + rnd_bit)) + goto err; + + if (bitsize > 1) + { + start_bit= end_bit= 1 ; rnd_bit= 0; + if (exec_bitmap_exists_intersection(maps, bitsize, start_bit, end_bit, + rnd_bit)) + goto err; + + start_bit= end_bit= bitsize-1 ; rnd_bit= bitsize-2; + if (exec_bitmap_exists_intersection(maps, bitsize, start_bit, end_bit, + rnd_bit)) + goto err; + } + + my_bitmap_free(&map2); + return 0; +err: + diag("bitmap_exist_intersection failed on bitsize: %d start_bit: %d " + "end_bit: %d rnd_bit: %d", + bitsize, start_bit, end_bit, rnd_bit); + my_bitmap_free(&map2); + return 1; +} + + my_bool do_test(uint bitsize) { MY_BITMAP map; @@ -515,6 +653,12 @@ my_bool do_test(uint bitsize) bitmap_clear_all(&map); if (test_intersect(&map,bitsize)) goto error; + bitmap_clear_all(&map); + if (test_copy(&map,bitsize)) + goto error; + bitmap_clear_all(&map); + if (test_bitmap_exists_intersection(&map, bitsize)) + goto error; return FALSE; error: return TRUE; diff --git a/unittest/mysys/crc32-t.c b/unittest/mysys/crc32-t.c index 9834d21769b..7079aeb614a 100644 --- a/unittest/mysys/crc32-t.c +++ b/unittest/mysys/crc32-t.c @@ -1,4 +1,4 @@ -/* Copyright (c) MariaDB 2020 +/* Copyright (c) MariaDB 2020, 2024 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -19,51 +19,127 @@ #include #include #include -#include /* - Check that optimized crc32 (ieee, or ethernet polynomical) returns the same - result as zlib (not so well optimized, yet, but trustworthy) + The following lookup table oriented computation of CRC-32 + is based on the Public Domain / Creative Commons CC0 Perl code from + http://billauer.co.il/blog/2011/05/perl-crc32-crc-xs-module/ */ -#define DO_TEST_CRC32(crc,str) \ - ok(crc32(crc,(const Bytef *)str,(uint)(sizeof(str)-1)) == my_checksum(crc, str, sizeof(str)-1), "crc32 '%s'",str) -/* Check that CRC32-C calculation returns correct result*/ -#define DO_TEST_CRC32C(crc,str,expected) \ - do { \ - unsigned int v = my_crc32c(crc, str, sizeof(str)-1); \ - printf("crc32(%u,'%s',%zu)=%u\n",crc,str,sizeof(str)-1,v); \ - ok(expected == my_crc32c(crc, str, sizeof(str)-1),"crc32c '%s'",str); \ - }while(0) +/** Lookup tables */ +static uint32 tab_3309[256], tab_castagnoli[256]; +/** Initialize a lookup table for a CRC-32 polynomial */ +static void init_lookup(uint32 *tab, uint32 polynomial) +{ + unsigned i; + for (i= 0; i < 256; i++) + { + uint32 x= i; + unsigned j; + for (j= 0; j < 8; j++) + if (x & 1) + x= (x >> 1) ^ polynomial; + else + x>>= 1; + tab[i]= x; + } +} -#define LONG_STR "1234567890234568900212345678901231213123321212123123123123123"\ - "............................................................................." \ - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ - "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" \ - "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" +/** Compute a CRC-32 one octet at a time based on a lookup table */ +static uint crc_(uint32 crc, const void *buf, size_t len, const uint32 *tab) +{ + const unsigned char *b= buf; + const unsigned char *const end = b + len; + crc^= 0xffffffff; + while (b != end) + crc= ((crc >> 8) & 0xffffff) ^ tab[(crc ^ *b++) & 0xff]; + crc^= 0xffffffff; + return crc; +} + +static uint crc32(uint32 crc, const void *buf, size_t len) +{ return crc_(crc, buf, len, tab_3309); } +static uint crc32c(uint32 crc, const void *buf, size_t len) +{ return crc_(crc, buf, len, tab_castagnoli); } + +static char buf[16384]; + +typedef uint (*check)(uint32, const void*, size_t); + +static size_t test_buf(check c1, check c2) +{ + size_t s; + for (s= sizeof buf; s; s--) + if (c1(0, buf, s) != c2(0, buf, s)) + break; + return s; +} + +#define DO_TEST_CRC32(crc,str,len) \ + ok(crc32(crc,str,len) == my_checksum(crc, str, len), \ + "crc32(%u,'%.*s')", crc, (int) len, str) + +/* Check that CRC-32C calculation returns correct result*/ +#define DO_TEST_CRC32C(crc,str,len) \ + ok(crc32c(crc,str,len) == my_crc32c(crc, str, len), \ + "crc32c(%u,'%.*s')", crc, (int) len, str) + +static const char STR[]= + "123456789012345678900212345678901231213123321212123123123123123" + "..........................................................................." + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" + "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"; int main(int argc __attribute__((unused)),char *argv[]) { MY_INIT(argv[0]); - plan(14); + init_lookup(tab_3309, 0xedb88320); + init_lookup(tab_castagnoli, 0x82f63b78); + + plan(36); printf("%s\n",my_crc32c_implementation()); - DO_TEST_CRC32(0,""); - DO_TEST_CRC32(1,""); - DO_TEST_CRC32(0,"12345"); - DO_TEST_CRC32(1,"12345"); - DO_TEST_CRC32(0,"1234567890123456789"); - DO_TEST_CRC32(0, LONG_STR); + DO_TEST_CRC32(0,STR,0); + DO_TEST_CRC32(1,STR,0); + DO_TEST_CRC32(0,STR,3); + DO_TEST_CRC32(0,STR,5); + DO_TEST_CRC32(1,STR,5); + DO_TEST_CRC32(0,STR,15); + DO_TEST_CRC32(0,STR,16); + DO_TEST_CRC32(0,STR,19); + DO_TEST_CRC32(0,STR,32); + DO_TEST_CRC32(0,STR,63); + DO_TEST_CRC32(0,STR,64); + DO_TEST_CRC32(0,STR,65); + DO_TEST_CRC32(0,STR,255); + DO_TEST_CRC32(0,STR,256); + DO_TEST_CRC32(0,STR,257); + DO_TEST_CRC32(0,STR,(sizeof(STR)-1)); ok(0 == my_checksum(0, NULL, 0) , "crc32 data = NULL, length = 0"); - DO_TEST_CRC32C(0,"", 0); - DO_TEST_CRC32C(1,"", 1); - DO_TEST_CRC32C(0, "12345", 416359221); - DO_TEST_CRC32C(1, "12345", 549473433); - DO_TEST_CRC32C(0, "1234567890123456789", 2366987449U); - DO_TEST_CRC32C(0, LONG_STR, 3009234172U); + DO_TEST_CRC32C(0,STR,0); + DO_TEST_CRC32C(1,STR,0); + DO_TEST_CRC32C(0,STR,3); + DO_TEST_CRC32C(0,STR,5); + DO_TEST_CRC32C(1,STR,5); + DO_TEST_CRC32C(0,STR,15); + DO_TEST_CRC32C(0,STR,16); + DO_TEST_CRC32C(0,STR,19); + DO_TEST_CRC32C(0,STR,32); + DO_TEST_CRC32C(0,STR,63); + DO_TEST_CRC32C(0,STR,64); + DO_TEST_CRC32C(0,STR,65); + DO_TEST_CRC32C(0,STR,255); + DO_TEST_CRC32C(0,STR,256); + DO_TEST_CRC32C(0,STR,257); + DO_TEST_CRC32C(0,STR,(sizeof(STR)-1)); ok(0 == my_crc32c(0, NULL, 0), "crc32c data = NULL, length = 0"); + memset(buf, 0x5a, sizeof buf); + ok(0 == test_buf(my_checksum, crc32), "crc32 with various lengths"); + ok(0 == test_buf(my_crc32c, crc32c), "crc32c with various lengths"); + my_end(0); return exit_status(); } diff --git a/unittest/mysys/my_getopt-t.c b/unittest/mysys/my_getopt-t.c index 6ffbfb20789..a71c4676d63 100644 --- a/unittest/mysys/my_getopt-t.c +++ b/unittest/mysys/my_getopt-t.c @@ -378,10 +378,10 @@ int main(int argc __attribute__((unused)), char **argv) "res:%d, argc:%d, opt_ull:%llu", res, arg_c, opt_ull); run("--ull=-100", NULL); - ok(res==9 && arg_c==1 && opt_ull==0ULL, + ok(res==13 && arg_c==0 && opt_ull==0ULL, "res:%d, argc:%d, opt_ull:%llu", res, arg_c, opt_ull); run("--ul=-100", NULL); - ok(res==9 && arg_c==1 && opt_ul==0UL, + ok(res==13 && arg_c==0 && opt_ul==0UL, "res:%d, argc:%d, opt_ul:%lu", res, arg_c, opt_ul); my_end(0); diff --git a/unittest/sql/mf_iocache-t.cc b/unittest/sql/mf_iocache-t.cc index cc97d3b221a..c72e6b7c7e2 100644 --- a/unittest/sql/mf_iocache-t.cc +++ b/unittest/sql/mf_iocache-t.cc @@ -96,6 +96,8 @@ void sql_print_error(const char *format, ...) /*** end of encryption tweaks and stubs ****************************/ +PRAGMA_DISABLE_CHECK_STACK_FRAME + static IO_CACHE info; #define CACHE_SIZE 16384 @@ -472,3 +474,4 @@ int main(int argc __attribute__((unused)),char *argv[]) return exit_status(); } +PRAGMA_REENABLE_CHECK_STACK_FRAME diff --git a/vio/vio.c b/vio/vio.c index 7a98eb2af7b..bf1e79ae36b 100644 --- a/vio/vio.c +++ b/vio/vio.c @@ -79,6 +79,7 @@ static my_bool has_no_data(Vio *vio __attribute__((unused))) int vio_pipe_shutdown(Vio *vio, int how) { vio->shutdown_flag= how; + vio->state= VIO_STATE_SHUTDOWN; return CancelIoEx(vio->hPipe, NULL); } #endif @@ -98,6 +99,7 @@ static void vio_init(Vio *vio, enum enum_vio_type type, #endif memset(vio, 0, sizeof(*vio)); vio->type= type; + vio->state= VIO_STATE_ACTIVE; vio->mysql_socket= MYSQL_INVALID_SOCKET; mysql_socket_setfd(&vio->mysql_socket, sd); vio->localhost= flags & VIO_LOCALHOST; diff --git a/vio/viosocket.c b/vio/viosocket.c index 002ff274b74..ffdc76a5deb 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -288,12 +288,18 @@ size_t vio_write(Vio *vio, const uchar* buf, size_t size) int vio_socket_shutdown(Vio *vio, int how) { - int ret= shutdown(mysql_socket_getfd(vio->mysql_socket), how); + int ret; + DBUG_ENTER("vio_socket_shutdown"); + DBUG_PRINT("enter", ("sd: %d", (int)mysql_socket_getfd(vio->mysql_socket))); + + vio->state= VIO_STATE_SHUTDOWN; + ret= shutdown(mysql_socket_getfd(vio->mysql_socket), how); + #ifdef _WIN32 /* Cancel possible IO in progress (shutdown does not do that on Windows). */ (void) CancelIoEx((HANDLE)mysql_socket_getfd(vio->mysql_socket), NULL); #endif - return ret; + DBUG_RETURN(ret); } @@ -552,7 +558,8 @@ my_bool vio_should_retry(Vio *vio) { DBUG_ENTER("vio_should_retry"); - DBUG_PRINT("info", ("vio_errno: %d", vio_errno(vio))); + DBUG_PRINT("info", ("vio_errno: %d state: %d", + vio_errno(vio), (int) vio->state)); DBUG_RETURN(vio_errno(vio) == SOCKET_EINTR); } @@ -576,28 +583,30 @@ vio_was_timeout(Vio *vio) int vio_close(Vio *vio) { - int r=0; DBUG_ENTER("vio_close"); DBUG_PRINT("enter", ("sd: %d", (int)mysql_socket_getfd(vio->mysql_socket))); if (vio->type != VIO_CLOSED) { + MYSQL_SOCKET mysql_socket= vio->mysql_socket; DBUG_ASSERT(vio->type == VIO_TYPE_TCPIP || - vio->type == VIO_TYPE_SOCKET || - vio->type == VIO_TYPE_SSL); + vio->type == VIO_TYPE_SOCKET || + vio->type == VIO_TYPE_SSL); - DBUG_ASSERT(mysql_socket_getfd(vio->mysql_socket) >= 0); - if (mysql_socket_close(vio->mysql_socket)) - r= -1; + + vio->type= VIO_CLOSED; + vio->state= VIO_STATE_CLOSED; + vio->mysql_socket= MYSQL_INVALID_SOCKET; + + DBUG_ASSERT(mysql_socket_getfd(mysql_socket) >= 0); + if (mysql_socket_close(mysql_socket)) + { + DBUG_PRINT("vio_error", ("close() failed, error: %d",socket_errno)); + /* FIXME: error handling (not critical for MySQL) */ + DBUG_RETURN(-1); + } } - if (r) - { - DBUG_PRINT("vio_error", ("close() failed, error: %d",socket_errno)); - /* FIXME: error handling (not critical for MySQL) */ - } - vio->type= VIO_CLOSED; - vio->mysql_socket= MYSQL_INVALID_SOCKET; - DBUG_RETURN(r); + DBUG_RETURN(0); } @@ -917,8 +926,11 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout) my_socket sd= mysql_socket_getfd(vio->mysql_socket); MYSQL_SOCKET_WAIT_VARIABLES(locker, state) /* no ';' */ DBUG_ENTER("vio_io_wait"); - DBUG_PRINT("enter", ("timeout: %d", timeout)); + DBUG_PRINT("enter", ("sd: %d timeout: %d", + (int) mysql_socket_getfd(vio->mysql_socket), + timeout)); + DBUG_ASSERT(vio->state != VIO_STATE_CLOSED); memset(&pfd, 0, sizeof(pfd)); pfd.fd= sd; @@ -948,7 +960,7 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout) switch ((ret= poll(&pfd, 1, timeout))) { case -1: - DBUG_PRINT("error", ("poll returned -1")); + DBUG_PRINT("error", ("poll returned -1 errno: %d", vio_errno(vio))); /* On error, -1 is returned. */ break; case 0: @@ -979,6 +991,7 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout) fd_set readfds, writefds, exceptfds; MYSQL_SOCKET_WAIT_VARIABLES(locker, state) /* no ';' */ DBUG_ENTER("vio_io_wait"); + DBUG_ASSERT(vio->state != VIO_STATE_CLOSED); /* Convert the timeout, in milliseconds, to seconds and microseconds. */ if (timeout >= 0) @@ -1152,6 +1165,7 @@ my_bool vio_is_connected(Vio *vio) { uint bytes= 0; DBUG_ENTER("vio_is_connected"); + DBUG_ASSERT(vio->state != VIO_STATE_CLOSED); /* The first step of detecting an EOF condition is verifying @@ -1159,6 +1173,7 @@ my_bool vio_is_connected(Vio *vio) the EOF. An exceptional condition event and/or errors are interpreted as if there is data to read. */ + if (!vio_io_wait(vio, VIO_IO_EVENT_READ, 0)) DBUG_RETURN(TRUE); diff --git a/win/packaging/CPackWixConfig.cmake b/win/packaging/CPackWixConfig.cmake index 79a638b9d5a..53449b51d92 100644 --- a/win/packaging/CPackWixConfig.cmake +++ b/win/packaging/CPackWixConfig.cmake @@ -53,11 +53,10 @@ add_component(Backup DESCRIPTION "Installs backup utilities(mariabackup and mbstream)") #Miscellaneous hidden components, part of server / or client programs -foreach(comp connect-engine connect-engine-jdbc ClientPlugins aws-key-management rocksdb-engine) +foreach(comp connect-engine connect-engine-jdbc ClientPlugins aws-key-management rocksdb-engine plugin-hashicorp-key-management) add_component(${comp} GROUP MySQLServer HIDDEN) endforeach() - add_component_group(Devel DISPLAY_NAME "Development components" DESCRIPTION "Installs C/C++ header files and libraries") diff --git a/wsrep-lib b/wsrep-lib index a5d95f0175f..dfc4bdb8a5d 160000 --- a/wsrep-lib +++ b/wsrep-lib @@ -1 +1 @@ -Subproject commit a5d95f0175f10b6127ea039c542725f6c4aa5cb9 +Subproject commit dfc4bdb8a5dcbd6fbea007ad3beff899a6b5b7bd diff --git a/zlib/ChangeLog b/zlib/ChangeLog index 8707988ac18..b801a1031ec 100644 --- a/zlib/ChangeLog +++ b/zlib/ChangeLog @@ -1,6 +1,16 @@ ChangeLog file for zlib +Changes in 1.3.1 (22 Jan 2024) +- Reject overflows of zip header fields in minizip +- Fix bug in inflateSync() for data held in bit buffer +- Add LIT_MEM define to use more memory for a small deflate speedup +- Fix decision on the emission of Zip64 end records in minizip +- Add bounds checking to ERR_MSG() macro, used by zError() +- Neutralize zip file traversal attacks in miniunz +- Fix a bug in ZLIB_DEBUG compiles in check_match() +- Various portability and appearance improvements + Changes in 1.3 (18 Aug 2023) - Remove K&R function definitions and zlib2ansi - Fix bug in deflateBound() for level 0 and memLevel 9 diff --git a/zlib/FAQ b/zlib/FAQ index 55f1cdc22f6..92f5d3e29fa 100644 --- a/zlib/FAQ +++ b/zlib/FAQ @@ -14,8 +14,7 @@ The latest zlib FAQ is at http://zlib.net/zlib_faq.html 2. Where can I get a Windows DLL version? The zlib sources can be compiled without change to produce a DLL. See the - file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the - precompiled DLL are found in the zlib web site at http://zlib.net/ . + file win32/DLL_FAQ.txt in the zlib distribution. 3. Where can I get a Visual Basic interface to zlib? diff --git a/zlib/README b/zlib/README index e02fc5aa206..c5f917540b6 100644 --- a/zlib/README +++ b/zlib/README @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.3 is a general purpose data compression library. All the code is +zlib 1.3.1 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and @@ -31,7 +31,7 @@ Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at https://marknelson.us/posts/1997/01/01/zlib-engine.html . -The changes made in version 1.3 are documented in the file ChangeLog. +The changes made in version 1.3.1 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . @@ -83,7 +83,7 @@ Acknowledgments: Copyright notice: - (C) 1995-2023 Jean-loup Gailly and Mark Adler + (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/zlib/contrib/nuget/nuget.csproj b/zlib/contrib/nuget/nuget.csproj new file mode 100644 index 00000000000..68627f034aa --- /dev/null +++ b/zlib/contrib/nuget/nuget.csproj @@ -0,0 +1,43 @@ + + + + net6.0 + madler.zlib.redist + $(PackageId).win + $(PackageId).linux + $(PackageId).osx + (C) 1995-2024 Jean-loup Gailly and Mark Adler + 1.3.1 + NuGet Package for consuming native builds of zlib into .NET without complexity. + + NU5128 + $(MSBuildProjectDirectory) + Jean-loup Gailly and Mark Adler + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zlib/contrib/nuget/nuget.sln b/zlib/contrib/nuget/nuget.sln new file mode 100644 index 00000000000..46ee8deab8f --- /dev/null +++ b/zlib/contrib/nuget/nuget.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nuget", "nuget.csproj", "{B1BD3984-EF8F-4E9D-9A94-EB784E5EB1E8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B1BD3984-EF8F-4E9D-9A94-EB784E5EB1E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B1BD3984-EF8F-4E9D-9A94-EB784E5EB1E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B1BD3984-EF8F-4E9D-9A94-EB784E5EB1E8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B1BD3984-EF8F-4E9D-9A94-EB784E5EB1E8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/zlib/contrib/vstudio/vc17/miniunz.vcxproj b/zlib/contrib/vstudio/vc17/miniunz.vcxproj new file mode 100644 index 00000000000..68ef16588b2 --- /dev/null +++ b/zlib/contrib/vstudio/vc17/miniunz.vcxproj @@ -0,0 +1,409 @@ + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694382A} + Win32Proj + 10.0 + + + + Application + MultiByte + v143 + + + Application + Unicode + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + true + false + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + false + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + true + true + true + false + false + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + false + false + false + false + false + false + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + arm64\MiniUnzip$(Configuration)\ + arm64\MiniUnzip$(Configuration)\Tmp\ + + + arm64\MiniUnzip$(Configuration)\ + arm64\MiniUnzip$(Configuration)\Tmp\ + + + arm\MiniUnzip$(Configuration)\ + arm\MiniUnzip$(Configuration)\Tmp\ + + + arm\MiniUnzip$(Configuration)\ + arm\MiniUnzip$(Configuration)\Tmp\ + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineX64 + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineX64 + + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/zlib/contrib/vstudio/vc17/minizip.vcxproj b/zlib/contrib/vstudio/vc17/minizip.vcxproj new file mode 100644 index 00000000000..dd3c52e70c9 --- /dev/null +++ b/zlib/contrib/vstudio/vc17/minizip.vcxproj @@ -0,0 +1,405 @@ + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B} + Win32Proj + 10.0 + + + + Application + MultiByte + v143 + + + Application + Unicode + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + true + false + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + false + x64\$(Configuration)\ + x64\$(Configuration)\ + true + true + true + false + false + false + x64\$(Configuration)\ + x64\$(Configuration)\ + false + false + false + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + arm64\MiniZip$(Configuration)\ + arm64\MiniZip$(Configuration)\Tmp\ + + + arm64\MiniZip$(Configuration)\ + arm64\MiniZip$(Configuration)\Tmp\ + + + arm\MiniZip$(Configuration)\ + arm\MiniZip$(Configuration)\Tmp\ + + + arm\MiniZip$(Configuration)\ + arm\MiniZip$(Configuration)\Tmp\ + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineX64 + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineX64 + + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/zlib/contrib/vstudio/vc17/testzlib.vcxproj b/zlib/contrib/vstudio/vc17/testzlib.vcxproj new file mode 100644 index 00000000000..4cc99b3ffe1 --- /dev/null +++ b/zlib/contrib/vstudio/vc17/testzlib.vcxproj @@ -0,0 +1,473 @@ + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + ARM + + + ReleaseWithoutAsm + ARM64 + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B} + testzlib + Win32Proj + 10.0 + + + + Application + MultiByte + true + v143 + + + Application + MultiByte + true + v143 + + + Application + Unicode + v143 + + + Application + true + v143 + + + Application + true + v143 + + + Application + true + v143 + + + Application + true + v143 + + + Application + true + v143 + + + Application + true + v143 + + + Application + v143 + + + Application + v143 + + + Application + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + true + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + false + false + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + arm64\TestZlib$(Configuration)\ + arm64\TestZlib$(Configuration)\Tmp\ + + + arm64\TestZlib$(Configuration)\ + arm64\TestZlib$(Configuration)\Tmp\ + + + arm64\TestZlib$(Configuration)\ + arm64\TestZlib$(Configuration)\Tmp\ + + + arm\TestZlib$(Configuration)\ + arm\TestZlib$(Configuration)\Tmp\ + + + arm\TestZlib$(Configuration)\ + arm\TestZlib$(Configuration)\Tmp\ + + + arm\TestZlib$(Configuration)\ + arm\TestZlib$(Configuration)\Tmp\ + + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + ProgramDatabase + + + %(AdditionalDependencies) + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + %(AdditionalDependencies) + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + false + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDebugDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDebugDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDebugDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/zlib/contrib/vstudio/vc17/testzlibdll.vcxproj b/zlib/contrib/vstudio/vc17/testzlibdll.vcxproj new file mode 100644 index 00000000000..73bba55da80 --- /dev/null +++ b/zlib/contrib/vstudio/vc17/testzlibdll.vcxproj @@ -0,0 +1,409 @@ + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694366A} + Win32Proj + 10.0 + + + + Application + MultiByte + v143 + + + Application + Unicode + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + true + false + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + false + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + true + true + true + false + false + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + false + false + false + false + false + false + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + arm64\TestZlibDll$(Configuration)\ + arm64\TestZlibDll$(Configuration)\Tmp\ + + + arm64\TestZlibDll$(Configuration)\ + arm64\TestZlibDll$(Configuration)\Tmp\ + + + arm\TestZlibDll$(Configuration)\ + arm\TestZlibDll$(Configuration)\Tmp\ + + + arm\TestZlibDll$(Configuration)\ + arm\TestZlibDll$(Configuration)\Tmp\ + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + MachineX64 + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + MachineX64 + + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/zlib/contrib/vstudio/vc17/zlib.rc b/zlib/contrib/vstudio/vc17/zlib.rc new file mode 100644 index 00000000000..a55f341c74c --- /dev/null +++ b/zlib/contrib/vstudio/vc17/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1, 3, 1, 0 + PRODUCTVERSION 1, 3, 1, 0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" + VALUE "FileVersion", "1.3.1\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlibwapi.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-2024 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/zlib/contrib/vstudio/vc17/zlibstat.vcxproj b/zlib/contrib/vstudio/vc17/zlibstat.vcxproj new file mode 100644 index 00000000000..b946ac2a90f --- /dev/null +++ b/zlib/contrib/vstudio/vc17/zlibstat.vcxproj @@ -0,0 +1,602 @@ + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + ARM + + + ReleaseWithoutAsm + ARM64 + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8} + 10.0 + + + + StaticLibrary + false + v143 + + + StaticLibrary + false + v143 + + + StaticLibrary + false + v143 + Unicode + + + StaticLibrary + false + v143 + + + StaticLibrary + false + v143 + + + StaticLibrary + false + v143 + + + StaticLibrary + false + v143 + + + StaticLibrary + false + v143 + + + StaticLibrary + false + v143 + + + StaticLibrary + false + v143 + + + StaticLibrary + false + v143 + + + StaticLibrary + false + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + arm64\ZlibStat$(Configuration)\ + arm64\ZlibStat$(Configuration)\Tmp\ + + + arm64\ZlibStat$(Configuration)\ + arm64\ZlibStat$(Configuration)\Tmp\ + + + arm64\ZlibStat$(Configuration)\ + arm64\ZlibStat$(Configuration)\Tmp\ + + + arm\ZlibStat$(Configuration)\ + arm\ZlibStat$(Configuration)\Tmp\ + + + arm\ZlibStat$(Configuration)\ + arm\ZlibStat$(Configuration)\Tmp\ + + + arm\ZlibStat$(Configuration)\ + arm\ZlibStat$(Configuration)\Tmp\ + + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + %(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:ARM64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:ARM /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + %(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:ARM64 /NODEFAULTLIB %(AdditionalOptions) + %(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:ARM /NODEFAULTLIB %(AdditionalOptions) + %(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:ARM64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:ARM /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/zlib/contrib/vstudio/vc17/zlibvc.def b/zlib/contrib/vstudio/vc17/zlibvc.def new file mode 100644 index 00000000000..53947cc31b7 --- /dev/null +++ b/zlib/contrib/vstudio/vc17/zlibvc.def @@ -0,0 +1,158 @@ +LIBRARY +; zlib data compression and ZIP file I/O library + +VERSION 1.3.1 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + inflateCopy @42 + inflateBackInit_ @43 + inflateBack @44 + inflateBackEnd @45 + compressBound @46 + deflateBound @47 + gzclearerr @48 + gzungetc @49 + zlibCompileFlags @50 + deflatePrime @51 + deflatePending @52 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unzOpenCurrentFile3 @69 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + unzOpen2 @77 + unzOpenCurrentFile2 @78 + unzOpenCurrentFilePassword @79 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 + zipOpenNewFileInZip2 @86 + zipCloseFileInZipRaw @87 + zipOpen2 @88 + zipOpenNewFileInZip3 @89 + + unzGetFilePos @100 + unzGoToFilePos @101 + + fill_win32_filefunc @110 + +; zlibwapi v1.2.4 added: + fill_win32_filefunc64 @111 + fill_win32_filefunc64A @112 + fill_win32_filefunc64W @113 + + unzOpen64 @120 + unzOpen2_64 @121 + unzGetGlobalInfo64 @122 + unzGetCurrentFileInfo64 @124 + unzGetCurrentFileZStreamPos64 @125 + unztell64 @126 + unzGetFilePos64 @127 + unzGoToFilePos64 @128 + + zipOpen64 @130 + zipOpen2_64 @131 + zipOpenNewFileInZip64 @132 + zipOpenNewFileInZip2_64 @133 + zipOpenNewFileInZip3_64 @134 + zipOpenNewFileInZip4_64 @135 + zipCloseFileInZipRaw64 @136 + +; zlib1 v1.2.4 added: + adler32_combine @140 + crc32_combine @142 + deflateSetHeader @144 + deflateTune @145 + gzbuffer @146 + gzclose_r @147 + gzclose_w @148 + gzdirect @149 + gzoffset @150 + inflateGetHeader @156 + inflateMark @157 + inflatePrime @158 + inflateReset2 @159 + inflateUndermine @160 + +; zlib1 v1.2.6 added: + gzgetc_ @161 + inflateResetKeep @163 + deflateResetKeep @164 + +; zlib1 v1.2.7 added: + gzopen_w @165 + +; zlib1 v1.2.8 added: + inflateGetDictionary @166 + gzvprintf @167 + +; zlib1 v1.2.9 added: + inflateCodesUsed @168 + inflateValidate @169 + uncompress2 @170 + gzfread @171 + gzfwrite @172 + deflateGetDictionary @173 + adler32_z @174 + crc32_z @175 + +; zlib1 v1.2.12 added: + crc32_combine_gen @176 + crc32_combine_gen64 @177 + crc32_combine_op @178 diff --git a/zlib/contrib/vstudio/vc17/zlibvc.sln b/zlib/contrib/vstudio/vc17/zlibvc.sln new file mode 100644 index 00000000000..67896b7470d --- /dev/null +++ b/zlib/contrib/vstudio/vc17/zlibvc.sln @@ -0,0 +1,179 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33015.44 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseWithoutAsm|ARM = ReleaseWithoutAsm|ARM + ReleaseWithoutAsm|ARM64 = ReleaseWithoutAsm|ARM64 + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 + ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|ARM.ActiveCfg = Debug|ARM + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|ARM.Build.0 = Debug|ARM + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|ARM64.Build.0 = Debug|ARM64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|ARM.ActiveCfg = Release|ARM + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|ARM.Build.0 = Release|ARM + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|ARM64.ActiveCfg = Release|ARM64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|ARM64.Build.0 = Release|ARM64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|ARM.ActiveCfg = ReleaseWithoutAsm|ARM + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|ARM.Build.0 = ReleaseWithoutAsm|ARM + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|ARM64.ActiveCfg = ReleaseWithoutAsm|ARM64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|ARM64.Build.0 = ReleaseWithoutAsm|ARM64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|ARM.ActiveCfg = Debug|ARM + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|ARM.Build.0 = Debug|ARM + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|ARM64.Build.0 = Debug|ARM64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|ARM.ActiveCfg = Release|ARM + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|ARM.Build.0 = Release|ARM + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|ARM64.ActiveCfg = Release|ARM64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|ARM64.Build.0 = Release|ARM64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|ARM.ActiveCfg = ReleaseWithoutAsm|ARM + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|ARM.Build.0 = ReleaseWithoutAsm|ARM + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|ARM64.ActiveCfg = ReleaseWithoutAsm|ARM64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|ARM64.Build.0 = ReleaseWithoutAsm|ARM64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|ARM.ActiveCfg = Debug|ARM + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|ARM.Build.0 = Debug|ARM + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|ARM64.Build.0 = Debug|ARM64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|ARM.ActiveCfg = Release|ARM + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|ARM.Build.0 = Release|ARM + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|ARM64.ActiveCfg = Release|ARM64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|ARM64.Build.0 = Release|ARM64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|ARM.ActiveCfg = ReleaseWithoutAsm|ARM + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|ARM.Build.0 = ReleaseWithoutAsm|ARM + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|ARM64.ActiveCfg = ReleaseWithoutAsm|ARM64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|ARM64.Build.0 = ReleaseWithoutAsm|ARM64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|ARM.ActiveCfg = Debug|ARM + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|ARM.Build.0 = Debug|ARM + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|ARM64.Build.0 = Debug|ARM64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|ARM.ActiveCfg = Release|ARM + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|ARM.Build.0 = Release|ARM + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|ARM64.ActiveCfg = Release|ARM64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|ARM64.Build.0 = Release|ARM64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|ARM.ActiveCfg = Release|ARM + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|ARM.Build.0 = Release|ARM + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|ARM64.ActiveCfg = Release|ARM64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|ARM64.Build.0 = Release|ARM64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|ARM.ActiveCfg = Debug|ARM + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|ARM.Build.0 = Debug|ARM + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|ARM64.Build.0 = Debug|ARM64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|ARM.ActiveCfg = Release|ARM + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|ARM.Build.0 = Release|ARM + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|ARM64.ActiveCfg = Release|ARM64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|ARM64.Build.0 = Release|ARM64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|ARM.ActiveCfg = Release|ARM + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|ARM.Build.0 = Release|ARM + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|ARM64.ActiveCfg = Release|ARM64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|ARM64.Build.0 = Release|ARM64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|ARM.ActiveCfg = Debug|ARM + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|ARM.Build.0 = Debug|ARM + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|ARM64.Build.0 = Debug|ARM64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|ARM.ActiveCfg = Release|ARM + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|ARM.Build.0 = Release|ARM + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|ARM64.ActiveCfg = Release|ARM64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|ARM64.Build.0 = Release|ARM64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|ARM.ActiveCfg = Release|ARM + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|ARM.Build.0 = Release|ARM + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|ARM64.ActiveCfg = Release|ARM64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|ARM64.Build.0 = Release|ARM64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {EAA58685-56D9-43F2-8703-FD2CB020745E} + EndGlobalSection +EndGlobal diff --git a/zlib/contrib/vstudio/vc17/zlibvc.vcxproj b/zlib/contrib/vstudio/vc17/zlibvc.vcxproj new file mode 100644 index 00000000000..10a7a901efe --- /dev/null +++ b/zlib/contrib/vstudio/vc17/zlibvc.vcxproj @@ -0,0 +1,875 @@ + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + ARM + + + ReleaseWithoutAsm + ARM64 + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {8FD826F8-3739-44E6-8CC8-997122E53B8D} + 10.0 + + + + DynamicLibrary + false + true + v143 + + + DynamicLibrary + false + true + v143 + + + DynamicLibrary + false + v143 + Unicode + + + DynamicLibrary + false + true + v143 + + + DynamicLibrary + false + true + v143 + + + DynamicLibrary + false + true + v143 + + + DynamicLibrary + false + true + v143 + + + DynamicLibrary + false + true + v143 + + + DynamicLibrary + false + true + v143 + + + DynamicLibrary + false + v143 + + + DynamicLibrary + false + v143 + + + DynamicLibrary + false + v143 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + true + false + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + true + true + true + false + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + false + false + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + false + false + false + false + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + zlibwapi + + + arm64\ZlibDll$(Configuration)\ + arm64\ZlibDll$(Configuration)\Tmp\ + + + arm\ZlibDll$(Configuration)\ + arm\ZlibDll$(Configuration)\Tmp\ + + + arm64\ZlibDll$(Configuration)\ + arm64\ZlibDll$(Configuration)\Tmp\ + + + arm64\ZlibDll$(Configuration)\ + arm64\ZlibDll$(Configuration)\Tmp\ + + + arm\ZlibDll$(Configuration)\ + arm\ZlibDll$(Configuration)\Tmp\ + + + arm\ZlibDll$(Configuration)\ + arm\ZlibDll$(Configuration)\Tmp\ + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + %(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + %(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + false + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + %(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + %(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + %(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + %(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + %(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN32;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + %(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + + + + + + + + + + + + + + + + + + + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/zlib/deflate.c b/zlib/deflate.c index bd011751920..012ea8148e8 100644 --- a/zlib/deflate.c +++ b/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.3 Copyright 1995-2023 Jean-loup Gailly and Mark Adler "; + " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -493,7 +493,7 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, * symbols from which it is being constructed. */ - s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4); + s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS); s->pending_buf_size = (ulg)s->lit_bufsize * 4; if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || @@ -503,8 +503,14 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, deflateEnd (strm); return Z_MEM_ERROR; } +#ifdef LIT_MEM + s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); + s->l_buf = s->pending_buf + (s->lit_bufsize << 2); + s->sym_end = s->lit_bufsize - 1; +#else s->sym_buf = s->pending_buf + s->lit_bufsize; s->sym_end = (s->lit_bufsize - 1) * 3; +#endif /* We avoid equality with lit_bufsize*3 because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. @@ -720,9 +726,15 @@ int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; +#ifdef LIT_MEM + if (bits < 0 || bits > 16 || + (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#else if (bits < 0 || bits > 16 || s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) return Z_BUF_ERROR; +#endif do { put = Buf_size - s->bi_valid; if (put > bits) @@ -1294,7 +1306,7 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4); + ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { @@ -1305,10 +1317,15 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); +#ifdef LIT_MEM + ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); + ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); +#else ds->sym_buf = ds->pending_buf + ds->lit_bufsize; +#endif ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; @@ -1539,13 +1556,21 @@ local uInt longest_match(deflate_state *s, IPos cur_match) { */ local void check_match(deflate_state *s, IPos start, IPos match, int length) { /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); + Bytef *back = s->window + (int)match, *here = s->window + start; + IPos len = length; + if (match == (IPos)-1) { + /* match starts one byte before the current window -- just compare the + subsequent length-1 bytes */ + back++; + here++; + len--; + } + if (zmemcmp(back, here, len) != EQUAL) { + fprintf(stderr, " start %u, match %d, length %d\n", + start, (int)match, length); do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); + fprintf(stderr, "(%02x %02x)", *back++, *here++); + } while (--len != 0); z_error("invalid match"); } if (z_verbose > 1) { diff --git a/zlib/deflate.h b/zlib/deflate.h index 8696791429f..300c6ada62b 100644 --- a/zlib/deflate.h +++ b/zlib/deflate.h @@ -1,5 +1,5 @@ /* deflate.h -- internal compression state - * Copyright (C) 1995-2018 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -23,6 +23,10 @@ # define GZIP #endif +/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at + the cost of a larger memory footprint */ +/* #define LIT_MEM */ + /* =========================================================================== * Internal compression state. */ @@ -217,7 +221,14 @@ typedef struct internal_state { /* Depth of each subtree used as tie breaker for trees of equal frequency */ +#ifdef LIT_MEM +# define LIT_BUFS 5 + ushf *d_buf; /* buffer for distances */ + uchf *l_buf; /* buffer for literals/lengths */ +#else +# define LIT_BUFS 4 uchf *sym_buf; /* buffer for distances and literals/lengths */ +#endif uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for @@ -239,7 +250,7 @@ typedef struct internal_state { * - I can't count above 4 */ - uInt sym_next; /* running index in sym_buf */ + uInt sym_next; /* running index in symbol buffer */ uInt sym_end; /* symbol table full when sym_next reaches this */ ulg opt_len; /* bit length of current block with optimal trees */ @@ -318,6 +329,25 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, extern const uch ZLIB_INTERNAL _dist_code[]; #endif +#ifdef LIT_MEM +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->sym_next] = 0; \ + s->l_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->d_buf[s->sym_next] = dist; \ + s->l_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#else # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->sym_buf[s->sym_next++] = 0; \ @@ -337,6 +367,7 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->sym_next == s->sym_end); \ } +#endif #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ diff --git a/zlib/gzguts.h b/zlib/gzguts.h index f9375047e8c..eba72085bb7 100644 --- a/zlib/gzguts.h +++ b/zlib/gzguts.h @@ -1,5 +1,5 @@ /* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -210,9 +210,5 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD error); /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t value -- needed when comparing unsigned to z_off64_t, which is signed (possible z_off64_t types off_t, off64_t, and long are all signed) */ -#ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) -#else unsigned ZLIB_INTERNAL gz_intmax(void); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) diff --git a/zlib/gzlib.c b/zlib/gzlib.c index 29fc4486fba..983153cc8e4 100644 --- a/zlib/gzlib.c +++ b/zlib/gzlib.c @@ -1,5 +1,5 @@ /* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -563,20 +563,20 @@ void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { #endif } -#ifndef INT_MAX /* portably return maximum value for an int (when limits.h presumed not available) -- we need to do this to cover cases where 2's complement not used, since C standard permits 1's complement and sign-bit representations, otherwise we could just use ((unsigned)-1) >> 1 */ unsigned ZLIB_INTERNAL gz_intmax(void) { - unsigned p, q; - - p = 1; +#ifdef INT_MAX + return INT_MAX; +#else + unsigned p = 1, q; do { q = p; p <<= 1; p++; } while (p > q); return q >> 1; -} #endif +} diff --git a/zlib/inflate.c b/zlib/inflate.c index b0757a9b249..94ecff015a9 100644 --- a/zlib/inflate.c +++ b/zlib/inflate.c @@ -1387,7 +1387,7 @@ int ZEXPORT inflateSync(z_streamp strm) { /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; - state->hold <<= state->bits & 7; + state->hold >>= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { diff --git a/zlib/inftrees.c b/zlib/inftrees.c index 8a208c2daa8..98cfe164458 100644 --- a/zlib/inftrees.c +++ b/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2023 Mark Adler + * Copyright (C) 1995-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.3 Copyright 1995-2023 Mark Adler "; + " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -57,7 +57,7 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 198, 203}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/zlib/inftrees.h b/zlib/inftrees.h index a10712d8cb5..396f74b5da7 100644 --- a/zlib/inftrees.h +++ b/zlib/inftrees.h @@ -41,8 +41,8 @@ typedef struct { examples/enough.c found in the zlib distribution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the + returns 852, and "enough 30 6 15" for distance codes returns 592. The + initial root table size (9 or 6) is found in the fifth argument of the inflate_table() calls in inflate.c and infback.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ diff --git a/zlib/qnx/package.qpg b/zlib/qnx/package.qpg index d882af2bfb3..4877e0ef013 100644 --- a/zlib/qnx/package.qpg +++ b/zlib/qnx/package.qpg @@ -25,10 +25,10 @@ - - - - + + + + @@ -63,7 +63,7 @@ - 1.3.0 + 1.3.1 Medium Stable diff --git a/zlib/treebuild.xml b/zlib/treebuild.xml index 1d1b007707c..930b00be4a8 100644 --- a/zlib/treebuild.xml +++ b/zlib/treebuild.xml @@ -1,6 +1,6 @@ - - + + zip compression library diff --git a/zlib/trees.c b/zlib/trees.c index 8dbdc40bacc..6a523ef34e3 100644 --- a/zlib/trees.c +++ b/zlib/trees.c @@ -1,5 +1,5 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2021 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -899,14 +899,19 @@ local void compress_block(deflate_state *s, const ct_data *ltree, const ct_data *dtree) { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in sym_buf */ + unsigned sx = 0; /* running index in symbol buffers */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->sym_next != 0) do { +#ifdef LIT_MEM + dist = s->d_buf[sx]; + lc = s->l_buf[sx++]; +#else dist = s->sym_buf[sx++] & 0xff; dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; lc = s->sym_buf[sx++]; +#endif if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); @@ -931,8 +936,12 @@ local void compress_block(deflate_state *s, const ct_data *ltree, } } /* literal or match pair ? */ - /* Check that the overlay between pending_buf and sym_buf is ok: */ + /* Check for no overlay of pending_buf on needed symbols */ +#ifdef LIT_MEM + Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow"); +#else Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); +#endif } while (sx < s->sym_next); @@ -1082,9 +1091,14 @@ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, * the current block must be flushed. */ int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { +#ifdef LIT_MEM + s->d_buf[s->sym_next] = (ush)dist; + s->l_buf[s->sym_next++] = (uch)lc; +#else s->sym_buf[s->sym_next++] = (uch)dist; s->sym_buf[s->sym_next++] = (uch)(dist >> 8); s->sym_buf[s->sym_next++] = (uch)lc; +#endif if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; diff --git a/zlib/win32/DLL_FAQ.txt b/zlib/win32/DLL_FAQ.txt index 12c009018c3..d8cf5f31e3d 100644 --- a/zlib/win32/DLL_FAQ.txt +++ b/zlib/win32/DLL_FAQ.txt @@ -3,7 +3,7 @@ This document describes the design, the rationale, and the usage -of the official DLL build of zlib, named ZLIB1.DLL. If you have +of the common DLL build of zlib, named ZLIB1.DLL. If you have general questions about zlib, you should see the file "FAQ" found in the zlib distribution, or at the following location: http://www.gzip.org/zlib/zlib_faq.html @@ -11,13 +11,9 @@ in the zlib distribution, or at the following location: 1. What is ZLIB1.DLL, and how can I get it? - - ZLIB1.DLL is the official build of zlib as a DLL. + - ZLIB1.DLL is the common build of zlib as a DLL. (Please remark the character '1' in the name.) - Pointers to a precompiled ZLIB1.DLL can be found in the zlib - web site at: - http://www.zlib.net/ - Applications that link to ZLIB1.DLL can rely on the following specification: @@ -379,18 +375,6 @@ in the zlib distribution, or at the following location: code. But you can make your own private DLL build, under a different file name, as suggested in the previous answer. - -17. I made my own ZLIB1.DLL build. Can I test it for compliance? - - - We prefer that you download the official DLL from the zlib - web site. If you need something peculiar from this DLL, you - can send your suggestion to the zlib mailing list. - - However, in case you do rebuild the DLL yourself, you can run - it with the test programs found in the DLL distribution. - Running these test programs is not a guarantee of compliance, - but a failure can imply a detected problem. - ** This document is written and maintained by diff --git a/zlib/win32/README-WIN32.txt b/zlib/win32/README-WIN32.txt index 384c988fa84..14e6398ef3a 100644 --- a/zlib/win32/README-WIN32.txt +++ b/zlib/win32/README-WIN32.txt @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.3.0 is a general purpose data compression library. All the code is +zlib 1.3.1 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) @@ -16,13 +16,13 @@ is http://zlib.net/ . Before reporting a problem, please check this site to verify that you have the latest version of zlib; otherwise get the latest version and check whether the problem still exists or not. -PLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html -before asking for help. +PLEASE read DLL_FAQ.txt, and the zlib FAQ http://zlib.net/zlib_faq.html before +asking for help. Manifest: -The package zlib-1.3.0-win32-x86.zip will contain the following files: +The package zlib-1.3.1-win32-x86.zip will contain the following files: README-WIN32.txt This document ChangeLog Changes since previous zlib packages diff --git a/zlib/zconf.h.cmakein b/zlib/zconf.h.cmakein index 310c43928a2..0abe3bc9d8f 100644 --- a/zlib/zconf.h.cmakein +++ b/zlib/zconf.h.cmakein @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -302,14 +302,6 @@ # endif #endif -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have diff --git a/zlib/zconf.h.in b/zlib/zconf.h.in index fb76ffe312a..62adc8d8431 100644 --- a/zlib/zconf.h.in +++ b/zlib/zconf.h.in @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -300,14 +300,6 @@ # endif #endif -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have diff --git a/zlib/zlib.3 b/zlib/zlib.3 index 4dd28967534..c716020ea9c 100644 --- a/zlib/zlib.3 +++ b/zlib/zlib.3 @@ -1,4 +1,4 @@ -.TH ZLIB 3 "18 Aug 2023" +.TH ZLIB 3 "22 Jan 2024" .SH NAME zlib \- compression/decompression library .SH SYNOPSIS @@ -105,9 +105,9 @@ before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). .SH AUTHORS AND LICENSE -Version 1.3 +Version 1.3.1 .LP -Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler +Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler .LP This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/zlib/zlib.h b/zlib/zlib.h index da09785ed1d..32dc34b6670 100644 --- a/zlib/zlib.h +++ b/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.3, August 18th, 2023 + version 1.3.1, January 22nd, 2024 - Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.3" -#define ZLIB_VERNUM 0x1300 +#define ZLIB_VERSION "1.3.1" +#define ZLIB_VERNUM 0x1310 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 3 -#define ZLIB_VER_REVISION 0 +#define ZLIB_VER_REVISION 1 #define ZLIB_VER_SUBREVISION 0 /* @@ -936,10 +936,10 @@ ZEXTERN int ZEXPORT inflateSync(z_streamp strm); inflateSync returns Z_OK if a possible full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. + In the success case, the application may save the current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, @@ -1758,14 +1758,14 @@ ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. + len2. len2 must be non-negative. */ /* ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); Return the operator corresponding to length len2, to be used with - crc32_combine_op(). + crc32_combine_op(). len2 must be non-negative. */ ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); diff --git a/zlib/zutil.h b/zlib/zutil.h index 902a304cc2d..48dd7febae6 100644 --- a/zlib/zutil.h +++ b/zlib/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -56,7 +56,7 @@ typedef unsigned long ulg; extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] +#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] #define ERR_RETURN(strm,err) \ return (strm->msg = ERR_MSG(err), (err)) @@ -137,17 +137,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # endif #endif -#if defined(MACOS) || defined(TARGET_OS_MAC) +#if defined(MACOS) # define OS_CODE 7 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif #endif #ifdef __acorn @@ -170,18 +161,6 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define OS_CODE 19 #endif -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - #if defined(__BORLANDC__) && !defined(MSDOS) #pragma warn -8004 #pragma warn -8008