1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

Merge branch '11.4' into 11.8

This commit is contained in:
Sergei Golubchik
2026-10-07 10:57:35 +02:00
305 changed files with 7780 additions and 1717 deletions

View File

@@ -22,7 +22,7 @@ TODO: fill description here
## Release Notes
TODO: What should the release notes say about this change?
Include any changed system variables, status variables or behaviour. Optionally list any https://mariadb.com/kb/ pages that need changing.
Include any changed system variables, status variables or behaviour. Optionally list any https://mariadb.com/docs/ pages that need changing.
## How can this PR be tested?

2
.gitignore vendored
View File

@@ -270,6 +270,8 @@ support-files/mariadb-extra.socket
support-files/mariadb@.service
support-files/mariadb@.socket
support-files/mariadb-extra@.socket
support-files/mariadb-plugin-config.cmake
support-files/mariadb-plugin-defines.cmake
support-files/mini-benchmark
support-files/my-huge.cnf
support-files/my-innodb-heavy-4G.cnf

View File

@@ -1,5 +1,5 @@
# Copyright (c) 2006, 2017, Oracle and/or its affiliates.
# Copyright (c) 2008, 2022, MariaDB Corporation.
# Copyright (c) 2008, 2026, 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
@@ -487,7 +487,18 @@ SET(PYTHON_SHEBANG "/usr/bin/env python3" CACHE STRING "python shebang")
MARK_AS_ADVANCED(PYTHON_SHEBANG)
# Add storage engines and plugins.
CONFIGURE_PLUGINS()
IF(NOT WITHOUT_SERVER)
FILE(GLOB dirs_storage ${CMAKE_SOURCE_DIR}/storage/*)
ENDIF()
FILE(GLOB dirs_plugin ${CMAKE_SOURCE_DIR}/plugin/*)
FOREACH(dir ${dirs_storage} ${dirs_plugin})
IF (EXISTS ${dir}/CMakeLists.txt)
ADD_SUBDIRECTORY(${dir})
ENDIF()
ENDFOREACH()
VERIFY_PLUGINS()
ADD_SUBDIRECTORY(include)
ADD_SUBDIRECTORY(dbug)

View File

@@ -57,7 +57,7 @@ build_script:
- set PATH=%OPENSSL_ROOT_DIR%;%PATH%
- set GENERATOR=-GNinja
- call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
- cmake -E time cmake %GENERATOR% .. -DWITH_SSL=system -DHAVE_OPENSSL_APPLINK_C=1 -DOPENSSL_ROOT_DIR=%OPENSSL_ROOT_DIR% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DMYSQL_MAINTAINER_MODE=ERR -DFAST_BUILD=1 -DBISON_EXECUTABLE=C:\cygwin64\bin\bison.exe -DPLUGIN_PERFSCHEMA=NO -DPLUGIN_FEEDBACK=NO
- cmake -E time cmake %GENERATOR% .. -DWITH_SSL=system -DHAVE_OPENSSL_APPLINK_C=1 -DOPENSSL_ROOT_DIR=%OPENSSL_ROOT_DIR% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DMYSQL_MAINTAINER_MODE=ERR -DFAST_BUILD=1 -DBISON_EXECUTABLE=C:\cygwin64\bin\bison.exe -DPLUGIN_PERFSCHEMA=NO -DPLUGIN_FEEDBACK=NO -DPLUGIN_ROCKSDB=NO
- set /A jobs=2*%NUMBER_OF_PROCESSORS%
- cmake -E time cmake --build . -j %jobs% --config %BUILD_TYPE% --target minbuild

View File

@@ -50,8 +50,6 @@ static bool sql_log_bin_off= false;
static uint opt_protocol=0;
static myf error_flags; /* flags to pass to my_printf_error, like ME_BELL */
static my_bool ex_status_printed = 0; /* First output is not relative. */
#include <sslopt-vars.h>
static void print_version(void);
@@ -928,7 +926,6 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
(*func)(res, row, rownr++);
print_top(res);
ex_status_printed = 1; /* From now on the output will be relative */
mysql_free_result(res);
break;
}

View File

@@ -127,7 +127,7 @@ static my_bool print_row_count_used= 0, print_row_event_positions_used= 0;
static my_bool debug_info_flag, debug_check_flag;
static my_bool force_if_open_opt= 1;
static my_bool opt_raw_mode= 0, opt_stop_never= 0;
my_bool opt_gtid_strict_mode= true;
my_bool opt_gtid_strict_mode= false;
static ulong opt_stop_never_slave_server_id= 0;
static my_bool opt_verify_binlog_checksum= 1;
static ulonglong offset = 0;
@@ -1645,7 +1645,7 @@ static struct my_option my_options[] =
"start < stop comparison condition. Sequence numbers of any gtid domain "
"must comprise monotically growing sequence",
&opt_gtid_strict_mode, &opt_gtid_strict_mode, 0,
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"stop-datetime", OPT_STOP_DATETIME,
"Stop reading the binlog at first event having a datetime equal or "
"posterior to the argument; the argument must be a date and time "

View File

@@ -300,36 +300,3 @@ ENDFUNCTION()
# For Makefile generators we default Debug build directory to ${buildroot}/../debug.
GET_FILENAME_COMPONENT(BINARY_PARENTDIR ${CMAKE_BINARY_DIR} PATH)
SET(DEBUGBUILDDIR "${BINARY_PARENTDIR}/debug" CACHE INTERNAL "Directory of debug build")
FUNCTION(INSTALL_MYSQL_TEST from to)
IF(INSTALL_MYSQLTESTDIR)
IF(NOT WITH_WSREP)
SET(EXCL_GALERA "(suite/(galera|wsrep|sys_vars/[rt]/(sysvars_)?wsrep).*|std_data/(galera|wsrep).*)")
ELSE()
SET(EXCL_GALERA "^DOES_NOT_EXIST$")
ENDIF()
INSTALL(
DIRECTORY ${from}
DESTINATION "${INSTALL_MYSQLTESTDIR}/${to}"
USE_SOURCE_PERMISSIONS
COMPONENT Test
PATTERN "var" EXCLUDE
PATTERN "lib/My/SafeProcess" EXCLUDE
PATTERN "lib/t*" EXCLUDE
PATTERN "CPack" EXCLUDE
PATTERN "CMake*" EXCLUDE
PATTERN "cmake_install.cmake" EXCLUDE
PATTERN "mtr.out*" EXCLUDE
PATTERN ".cvsignore" EXCLUDE
PATTERN "*.am" EXCLUDE
PATTERN "*.in" EXCLUDE
PATTERN "Makefile" EXCLUDE
PATTERN "*.vcxproj" EXCLUDE
PATTERN "*.vcxproj.filters" EXCLUDE
PATTERN "*.vcxproj.user" EXCLUDE
PATTERN "CTest*" EXCLUDE
PATTERN "*~" EXCLUDE
REGEX "${EXCL_GALERA}" EXCLUDE
)
ENDIF()
ENDFUNCTION()

View File

@@ -107,6 +107,13 @@ IF(NOT GIT_EXECUTABLE)
)
ENDIF()
# DuckDB uses these symbolic links only to test globbing behavior. They cause
# source package extraction failures with tar on Windows.
FILE(REMOVE
"${PACKAGE_DIR}/storage/duckdb/third_parties/duckdb/data/csv/glob/crawl/.symbolic_link/link_to_file"
"${PACKAGE_DIR}/storage/duckdb/third_parties/duckdb/data/csv/glob/crawl/.symbolic_link/mydir/link_to_upper_dir"
)
# Copy bison output
CONFIGURE_FILE(${CMAKE_BINARY_DIR}/sql/yy_mariadb.hh
${PACKAGE_DIR}/sql/yy_mariadb.hh COPYONLY)

View File

@@ -98,14 +98,11 @@ FUNCTION (MYSQL_ADD_EXECUTABLE)
IF(link)
IF(UNIX)
ADD_CUSTOM_COMMAND(TARGET ${target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink
${target} ${link}
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target} ${link}
COMMENT "Creating ${link} link"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})
INSTALL(PROGRAMS
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${link}
DESTINATION
${ARG_DESTINATION}
WORKING_DIRECTORY $<TARGET_FILE_DIR:${target}>/)
INSTALL(PROGRAMS $<TARGET_FILE_DIR:${target}>/${link}
DESTINATION ${ARG_DESTINATION}
COMPONENT ${COMP}Symlinks)
ELSE()
# Windows note:

View File

@@ -14,10 +14,46 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
IF(NOT EXTERNAL_PLUGIN)
STRING(CONCAT PARENT_SCOPE PARENT_SCOPE) # cannot use SET here
ENDIF()
FUNCTION(INSTALL_MYSQL_TEST from to)
IF(INSTALL_MYSQLTESTDIR)
IF(NOT WITH_WSREP)
SET(EXCL_GALERA "(suite/(galera|wsrep|sys_vars/[rt]/(sysvars_)?wsrep).*|std_data/(galera|wsrep).*)")
ELSE()
SET(EXCL_GALERA "^DOES_NOT_EXIST$")
ENDIF()
INSTALL(
DIRECTORY ${from}
DESTINATION "${INSTALL_MYSQLTESTDIR}/${to}"
USE_SOURCE_PERMISSIONS
COMPONENT Test
PATTERN "var" EXCLUDE
PATTERN "lib/My/SafeProcess" EXCLUDE
PATTERN "lib/t*" EXCLUDE
PATTERN "CPack" EXCLUDE
PATTERN "CMake*" EXCLUDE
PATTERN "cmake_install.cmake" EXCLUDE
PATTERN "mtr.out*" EXCLUDE
PATTERN ".cvsignore" EXCLUDE
PATTERN "*.am" EXCLUDE
PATTERN "*.in" EXCLUDE
PATTERN "Makefile" EXCLUDE
PATTERN "*.vcxproj" EXCLUDE
PATTERN "*.vcxproj.filters" EXCLUDE
PATTERN "*.vcxproj.user" EXCLUDE
PATTERN "CTest*" EXCLUDE
PATTERN "*~" EXCLUDE
REGEX "${EXCL_GALERA}" EXCLUDE
)
ENDIF()
ENDFUNCTION()
INCLUDE(CMakeParseArguments)
# MYSQL_ADD_PLUGIN(plugin_name source1...sourceN
# MARIADB_ADD_PLUGIN(plugin_name source1...sourceN
# [STORAGE_ENGINE]
# [STATIC_ONLY|MODULE_ONLY]
# [MANDATORY|DEFAULT]
@@ -32,10 +68,10 @@ INCLUDE(CMakeParseArguments)
# [LINK_LIBRARIES lib1...libN]
# [DEPENDS target1...targetN]
MACRO(MYSQL_ADD_PLUGIN)
MACRO(MARIADB_ADD_PLUGIN)
CMAKE_PARSE_ARGUMENTS(ARG
"STORAGE_ENGINE;STATIC_ONLY;MODULE_ONLY;MANDATORY;DEFAULT;DISABLED;NOT_EMBEDDED;RECOMPILE_FOR_EMBEDDED;CLIENT"
"MODULE_OUTPUT_NAME;STATIC_OUTPUT_NAME;COMPONENT;CONFIG;VERSION"
"MODULE_OUTPUT_NAME;STATIC_OUTPUT_NAME;COMPONENT;CONFIG;VERSION;AUTHOR;DESCRIPTION"
"LINK_LIBRARIES;DEPENDS"
${ARGN}
)
@@ -108,6 +144,10 @@ MACRO(MYSQL_ADD_PLUGIN)
MESSAGE(FATAL_ERROR "Invalid value for PLUGIN_${plugin}")
ENDIF()
IF(EXTERNAL_PLUGIN)
EXTERNAL_PLUGIN_PRE()
ENDIF()
# Validate that the requested build mode is compatible with what the
# plugin actually supports. STATIC_ONLY plugins cannot be built as
# dynamic modules, and MODULE_ONLY plugins cannot be linked statically.
@@ -129,9 +169,22 @@ MACRO(MYSQL_ADD_PLUGIN)
IF(NOT ARG_DEPENDS)
SET(ARG_DEPENDS)
ENDIF()
IF(NOT EXTERNAL_PLUGIN)
SET(ARG_DEPENDS GenError ${ARG_DEPENDS})
ENDIF()
SET(definitions ";PLUGIN_NAME=\"${target}\";PLUGIN_LICENSE=PLUGIN_LICENSE_GPL")
IF(ARG_VERSION)
SET(version_string ";PLUGIN_${plugin}_VERSION=\"${ARG_VERSION}\"")
IF(NOT ARG_VERSION MATCHES "^([0-9]+)\\.([0-9]+)" OR CMAKE_MATCH_2 GREATER 255)
MESSAGE(FATAL_ERROR "Plugin ${plugin} has invalid VERSION")
ENDIF()
SET(definitions "${definitions};PLUGIN_VERSION=\"${ARG_VERSION}\";PLUGIN_HEX_VERSION=${CMAKE_MATCH_1}*256+${CMAKE_MATCH_2}")
ENDIF()
IF(ARG_AUTHOR)
SET(definitions "${definitions};PLUGIN_AUTHOR=\"${ARG_AUTHOR}\"")
ENDIF()
IF(ARG_DESCRIPTION)
SET(definitions "${definitions};PLUGIN_DESCRIPTION=\"${ARG_DESCRIPTION}\"")
ENDIF()
IF(NOT ARG_MODULE_OUTPUT_NAME)
@@ -157,7 +210,7 @@ MACRO(MYSQL_ADD_PLUGIN)
ADD_LIBRARY(${target} STATIC ${SOURCES})
DTRACE_INSTRUMENT(${target})
ADD_DEPENDENCIES(${target} GenError ${ARG_DEPENDS})
ADD_DEPENDENCIES(${target} ${ARG_DEPENDS})
RESTRICT_SYMBOL_EXPORTS(${target})
IF(WITH_EMBEDDED_SERVER AND (NOT ARG_NOT_EMBEDDED))
# Embedded library should contain PIC code and be linkable
@@ -169,9 +222,9 @@ MACRO(MYSQL_ADD_PLUGIN)
DTRACE_INSTRUMENT(${target}_embedded)
IF(ARG_RECOMPILE_FOR_EMBEDDED)
SET_TARGET_PROPERTIES(${target}_embedded
PROPERTIES COMPILE_DEFINITIONS "EMBEDDED_LIBRARY${version_string}")
PROPERTIES COMPILE_DEFINITIONS "EMBEDDED_LIBRARY${definitions}")
ENDIF()
ADD_DEPENDENCIES(${target}_embedded GenError ${ARG_DEPENDS})
ADD_DEPENDENCIES(${target}_embedded ${ARG_DEPENDS})
IF(ARG_LINK_LIBRARIES)
TARGET_LINK_LIBRARIES (${target}_embedded ${ARG_LINK_LIBRARIES})
ENDIF()
@@ -207,11 +260,11 @@ MACRO(MYSQL_ADD_PLUGIN)
IF(ARG_MANDATORY)
SET (mysql_mandatory_plugins
"${mysql_mandatory_plugins}${builtin_entry}\n")
SET (mysql_mandatory_plugins ${mysql_mandatory_plugins} PARENT_SCOPE)
SET (mysql_mandatory_plugins ${mysql_mandatory_plugins} ${PARENT_SCOPE})
ELSE()
SET (mysql_optional_plugins
"${mysql_optional_plugins}${builtin_entry}\n")
SET (mysql_optional_plugins ${mysql_optional_plugins} PARENT_SCOPE)
SET (mysql_optional_plugins ${mysql_optional_plugins} ${PARENT_SCOPE})
ENDIF()
ELSEIF(PLUGIN_${plugin} MATCHES "(DYNAMIC|AUTO|YES)"
AND NOT ARG_STATIC_ONLY AND NOT WITHOUT_DYNAMIC_PLUGINS)
@@ -223,7 +276,7 @@ MACRO(MYSQL_ADD_PLUGIN)
SET_TARGET_PROPERTIES (${target} PROPERTIES PREFIX "")
IF (NOT ARG_CLIENT)
SET_TARGET_PROPERTIES (${target} PROPERTIES
COMPILE_DEFINITIONS "MYSQL_DYNAMIC_PLUGIN${version_string}")
COMPILE_DEFINITIONS "MYSQL_DYNAMIC_PLUGIN${definitions}")
ENDIF()
TARGET_LINK_LIBRARIES (${target} mysqlservices ${ARG_LINK_LIBRARIES})
@@ -254,7 +307,9 @@ MACRO(MYSQL_ADD_PLUGIN)
TARGET_LINK_LIBRARIES (${target} "-Wl,--no-undefined")
ENDIF()
ADD_DEPENDENCIES(${target} GenError ${ARG_DEPENDS})
IF (ARG_DEPENDS)
ADD_DEPENDENCIES(${target} ${ARG_DEPENDS})
ENDIF()
SET_TARGET_PROPERTIES(${target} PROPERTIES
OUTPUT_NAME "${ARG_MODULE_OUTPUT_NAME}")
@@ -263,24 +318,29 @@ MACRO(MYSQL_ADD_PLUGIN)
IF(CPACK_COMPONENTS_ALL AND
NOT CPACK_COMPONENTS_ALL MATCHES ${ARG_COMPONENT}
AND INSTALL_SYSCONF2DIR)
IF (ARG_STORAGE_ENGINE)
IF (ARG_STORAGE_ENGINE OR ARG_RECOMPILE_FOR_EMBEDDED)
IF(RPM)
STRING(REPLACE "-" "_" ver ${SERVER_VERSION})
SET(ver " = ${ver}-%{release}")
ELSE() # DEB
SET(ver " (= 1:${SERVER_VERSION}+maria~${DEBIAN_ABBR})")
ENDIF()
ELSE()
SET(ver "")
ENDIF()
STRING(TOUPPER ${ARG_COMPONENT} ARG_COMPONENT_UPPER)
SET(CPACK_COMPONENT_${ARG_COMPONENT_UPPER}SYMLINKS_GROUP ${ARG_COMPONENT} PARENT_SCOPE)
SET(CPACK_COMPONENT_${ARG_COMPONENT_UPPER}_GROUP ${ARG_COMPONENT} PARENT_SCOPE)
SET(CPACK_COMPONENT_${ARG_COMPONENT_UPPER}SYMLINKS_GROUP ${ARG_COMPONENT} ${PARENT_SCOPE})
SET(CPACK_COMPONENT_${ARG_COMPONENT_UPPER}_GROUP ${ARG_COMPONENT} ${PARENT_SCOPE})
SET(CPACK_COMPONENTS_ALL ${CPACK_COMPONENTS_ALL} ${ARG_COMPONENT} ${ARG_COMPONENT}Symlinks)
SET(CPACK_COMPONENTS_ALL ${CPACK_COMPONENTS_ALL} PARENT_SCOPE)
SET(CPACK_COMPONENTS_ALL ${CPACK_COMPONENTS_ALL} ${PARENT_SCOPE})
IF (NOT ARG_CLIENT)
SET(CPACK_RPM_${ARG_COMPONENT}_PACKAGE_REQUIRES "MariaDB-server${ver}" PARENT_SCOPE)
SET(CPACK_RPM_${ARG_COMPONENT}_PACKAGE_REQUIRES "MariaDB-server${ver}" ${PARENT_SCOPE})
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "mariadb-server${ver}")
ENDIF()
SET(CPACK_RPM_${ARG_COMPONENT}_USER_FILELIST ${ignored} PARENT_SCOPE)
SET(CPACK_RPM_${ARG_COMPONENT}_USER_FILELIST ${ignored} ${PARENT_SCOPE})
IF (ARG_VERSION)
SET(CPACK_RPM_${ARG_COMPONENT}_PACKAGE_VERSION ${SERVER_VERSION}_${ARG_VERSION} PARENT_SCOPE)
SET(CPACK_RPM_${ARG_COMPONENT}_PACKAGE_VERSION ${SERVER_VERSION}_${ARG_VERSION} ${PARENT_SCOPE})
SET_PLUGIN_DEB_VERSION(${target} ${SERVER_VERSION}-${ARG_VERSION})
ENDIF()
IF(NOT ARG_CLIENT AND UNIX)
@@ -288,9 +348,9 @@ MACRO(MYSQL_ADD_PLUGIN)
SET(ARG_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}.cnf")
FILE(WRITE ${ARG_CONFIG} "[mariadb]\nplugin-load-add=${ARG_MODULE_OUTPUT_NAME}.so\n")
ENDIF()
SET(CPACK_RPM_${ARG_COMPONENT}_USER_FILELIST ${ignored} "%config(noreplace) ${INSTALL_SYSCONF2DIR}/*" PARENT_SCOPE)
SET(CPACK_RPM_${ARG_COMPONENT}_POST_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/plugin-postin.sh PARENT_SCOPE)
SET(CPACK_RPM_${ARG_COMPONENT}_POST_TRANS_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-posttrans.sh PARENT_SCOPE)
SET(CPACK_RPM_${ARG_COMPONENT}_USER_FILELIST ${ignored} "%config(noreplace) ${INSTALL_SYSCONF2DIR}/*" ${PARENT_SCOPE})
SET(CPACK_RPM_${ARG_COMPONENT}_POST_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/plugin-postin.sh ${PARENT_SCOPE})
SET(CPACK_RPM_${ARG_COMPONENT}_POST_TRANS_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-posttrans.sh ${PARENT_SCOPE})
ENDIF()
ENDIF()
ELSE()
@@ -307,9 +367,8 @@ MACRO(MYSQL_ADD_PLUGIN)
ENDIF()
ENDIF()
GET_FILENAME_COMPONENT(subpath ${CMAKE_CURRENT_SOURCE_DIR} NAME)
IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/mysql-test")
INSTALL_MYSQL_TEST("${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/" "plugin/${subpath}")
INSTALL_MYSQL_TEST("${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/" "plugin/${target}")
ENDIF()
IF(TARGET ${target})
@@ -327,24 +386,18 @@ MACRO(MYSQL_ADD_PLUGIN)
ELSE()
ADD_FEATURE_INFO(${plugin} ${have_target} "Server plugin ${plugin_type}")
ENDIF()
IF (EXTERNAL_PLUGIN)
EXTERNAL_PLUGIN_POST()
ENDIF()
ENDIF(NOT WITHOUT_SERVER OR ARG_CLIENT)
ENDMACRO()
MACRO(MYSQL_ADD_PLUGIN)
MARIADB_ADD_PLUGIN(${ARGV})
ENDMACRO()
# Add all CMake projects under storage and plugin
# subdirectories, configure sql_builtins.cc
MACRO(CONFIGURE_PLUGINS)
IF(NOT WITHOUT_SERVER)
FILE(GLOB dirs_storage ${CMAKE_SOURCE_DIR}/storage/*)
ENDIF()
FILE(GLOB dirs_plugin ${CMAKE_SOURCE_DIR}/plugin/*)
FOREACH(dir ${dirs_storage} ${dirs_plugin})
IF (EXISTS ${dir}/CMakeLists.txt)
ADD_SUBDIRECTORY(${dir})
ENDIF()
ENDFOREACH()
# verify that all -DPLUGIN_xxx=YES plugins are being built
MACRO(VERIFY_PLUGINS)
GET_CMAKE_PROPERTY(ALL_VARS VARIABLES)
FOREACH (V ${ALL_VARS})
IF (V MATCHES "^PLUGIN_")

View File

@@ -590,6 +590,8 @@ CHECK_C_SOURCE_COMPILES("
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
/* macOS declares select() here and nowhere else that this test includes */
#include <sys/select.h>
#endif
int main()
{

View File

@@ -4,8 +4,7 @@ usr/include/mariadb/errmsg.h
usr/include/mariadb/ma_list.h
usr/include/mariadb/ma_pvio.h
usr/include/mariadb/ma_tls.h
usr/include/mariadb/mariadb/
usr/include/mariadb/mariadb/ma_io.h
usr/include/mariadb/mariadb
usr/include/mariadb/mariadb_com.h
usr/include/mariadb/mariadb_ctype.h
usr/include/mariadb/mariadb_dyncol.h
@@ -16,13 +15,12 @@ usr/include/mariadb/my_alloca.h
usr/include/mariadb/my_config.h
usr/include/mariadb/my_global.h
usr/include/mariadb/my_sys.h
usr/include/mariadb/mysql
usr/include/mariadb/mysql.h
usr/include/mariadb/mysql/
usr/include/mariadb/mysql/client_plugin.h
usr/include/mariadb/mysql/plugin_auth.h
usr/include/mariadb/mysql_com.h
usr/include/mariadb/mysql_version.h
usr/include/mariadb/mysqld_error.h
usr/include/mariadb/server
usr/lib/*/libmariadb.a
usr/lib/*/libmariadb.so
usr/lib/*/libmariadbclient.a
@@ -30,6 +28,7 @@ usr/lib/*/libmariadbclient.so
usr/lib/*/libmysqlservices.a
usr/lib/*/pkgconfig/libmariadb.pc
usr/share/aclocal/mysql.m4
usr/share/cmake/mariadb-plugin
usr/share/man/man1/mariadb_config.1
usr/share/man/man1/mysql_config.1
usr/share/man/man3/*.3

View File

@@ -1,4 +1,3 @@
usr/include/mariadb/server
usr/lib/*/libmariadbd.a
usr/lib/*/libmariadbd.so
usr/lib/*/libmysqld.a

View File

@@ -1,4 +1,5 @@
# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2026, 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
@@ -28,7 +29,16 @@ ENDIF()
# mysqld_error.h results in rebuild of the almost whole server)
# To preserve timestamp, first generate a temp header file, then copy it
# to mysqld_error.h using cmake -E copy_if_different
ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp
SET(GENERATED_ERROR_HEADERS
${CMAKE_BINARY_DIR}/include/mysqld_error.h
${CMAKE_BINARY_DIR}/include/mysqld_ername.h
${CMAKE_BINARY_DIR}/include/sql_state.h)
ADD_CUSTOM_COMMAND(OUTPUT ${GENERATED_ERROR_HEADERS}
BYPRODUCTS
${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp
${CMAKE_BINARY_DIR}/include/mysqld_ername.h.tmp
${CMAKE_BINARY_DIR}/include/sql_state.h.tmp
COMMAND comp_err
--charset=${PROJECT_SOURCE_DIR}/sql/share/charsets
--out-dir=${CMAKE_BINARY_DIR}/sql/share/
@@ -44,7 +54,7 @@ ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp
ADD_CUSTOM_TARGET(GenError
ALL
DEPENDS
${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
${GENERATED_ERROR_HEADERS})
# this approach doesn't work with cross-compiing (runs mariadbd)
# and doesn't work with ASAN, because LSAN complains about RocksDB (MDEV-36345).

View File

@@ -241,6 +241,10 @@ datadir_iter_new(const char *path, bool skip_first_level = true)
return(it);
error:
if (it) {
pthread_mutex_destroy(&it->mutex);
free(it->datadir_path);
}
free(it);
return(NULL);

View File

@@ -89,12 +89,23 @@ xb_write_galera_info(bool incremental_prepare)
*/
if (my_stat(MB_GALERA_INFO_FILENAME, &statinfo, MYF(0))) {
FILE* fp_in = fopen(MB_GALERA_INFO_FILENAME, "r");
if (!fp_in) {
die("could not open " MB_GALERA_INFO_FILENAME
", errno = %d\n", errno);
}
FILE* fp_out = fopen(MB_GALERA_INFO_FILENAME_SST, "w");
if (!fp_out) {
fclose(fp_in);
die("could not open " MB_GALERA_INFO_FILENAME_SST
", errno = %d\n", errno);
}
char buf[BUFSIZ] = {'\0'};
size_t size;
while ((size = fread(buf, 1, BUFSIZ, fp_in))) {
if (fwrite(buf, 1, size, fp_out) != strlen(buf)) {
fclose(fp_out);
fclose(fp_in);
die(
"could not write to "
MB_GALERA_INFO_FILENAME_SST
@@ -103,6 +114,8 @@ xb_write_galera_info(bool incremental_prepare)
}
}
if (!feof(fp_in)) {
fclose(fp_out);
fclose(fp_in);
die(
MB_GALERA_INFO_FILENAME_SST
" not fully copied\n"

View File

@@ -4847,6 +4847,7 @@ xb_load_list_file(
if (p) {
*p = '\0';
} else {
fclose(fp);
die("`%s...` name is too long", name_buf);
}
@@ -6735,7 +6736,7 @@ next_file_item_1:
/* single table tablespaces */
dir = os_file_opendir(path);
if (UNIV_UNLIKELY(dbdir == IF_WIN(INVALID_HANDLE_VALUE, nullptr))) {
if (UNIV_UNLIKELY(dir == IF_WIN(INVALID_HANDLE_VALUE, nullptr))) {
msg("Can't open dir %s", path);
return TRUE;
}

View File

@@ -83,7 +83,7 @@ INSTALL(DIRECTORY mysql/
PATTERN "${EXCL_SERVICE_WSREP}" EXCLUDE
)
STRING(REPLACE "." "\\." EXCL_RE "${HEADERS};${HEADERS_GEN_CONFIGURE}")
STRING(REPLACE "." "\\." EXCL_RE "${HEADERS};${HEADERS_GEN_CONFIGURE};config.h")
STRING(REPLACE ";" "|" EXCL_RE "${EXCL_RE}")
MACRO(INSTALL_PRIVATE DIR)

View File

@@ -48,4 +48,10 @@ SET(MYSQLSERVICES_SOURCES
)
ADD_CONVENIENCE_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
IF(MSVC)
# thin C API, no CRT state crosses it - don't force a CRT match on plugins
TARGET_COMPILE_OPTIONS(mysqlservices PRIVATE /Zl)
ENDIF()
INSTALL(TARGETS mysqlservices EXPORT mariadb-plugin-targets
DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)

View File

@@ -0,0 +1,55 @@
# Skip the test unless the filesystem holding $sparse_file_dir stores files
# with holes. The caller sets $sparse_file_dir to a directory on the
# filesystem where it builds its own sparse file, because vardir and datadir
# can be on different filesystems.
#
# A test that builds a large file by seeking past its end and writing a
# single byte relies on the skipped range staying unallocated. HFS on
# macOS allocates every block of that range, so the file consumes its full
# apparent size and the write fails with ENOSPC once the range exceeds the
# free space on the volume.
#
# The probe writes one byte 64MB past the start of an empty file and compares
# the allocated block count against that offset. A filesystem that leaves a
# hole allocates only the block holding the byte. The offset has to stay well
# above 16MB, since APFS fills the range of a file smaller than that rather
# than recording a hole.
if (!$sparse_file_dir)
{
--die have_sparse_files.inc requires the caller to set sparse_file_dir
}
# The probe cannot tell a directory it may not write from a filesystem
# without holes, thus a missing directory ends the test rather than skipping
# it.
--file_exists $sparse_file_dir
# mysqltest keeps variables in a case insensitive hash and exports a value
# under whichever spelling created the entry, so the exported name has to
# differ from $sparse_file_dir by more than case.
--let SPARSE_PROBE_DIR= $sparse_file_dir
--error 0,1
perl;
use strict;
use warnings;
my $probe= "$ENV{SPARSE_PROBE_DIR}/sparse_probe";
my $offset= 64 * 1024 * 1024;
my $sparse= 0;
if (open(my $fh, '>', $probe))
{
binmode $fh;
if (seek($fh, $offset, 0) and print($fh chr(0)) and close($fh))
{
my $blocks= (stat $probe)[12];
$sparse= 1 if defined($blocks) and $blocks * 512 < $offset;
}
}
unlink $probe;
exit($sparse ? 0 : 1);
EOF
if ($errno)
{
--skip Requires a filesystem that stores files with holes
}

View File

@@ -148,6 +148,7 @@ INSERT INTO global_suppressions VALUES
("Slave: .*Duplicate entry"),
("Statement may not be safe to log in statement format"),
("slave_connections_needed_for_purge"),
/* innodb foreign key tests that fail in ALTER or RENAME produce this */
("InnoDB: Error: in ALTER TABLE `test`.`t[123]`"),

View File

@@ -0,0 +1,4 @@
#
# suite.pm will make sure that all tests including this file
# will be skipped if run under macOS
#

View File

@@ -1,8 +0,0 @@
# This file should only be used with test that finds bugs in ASan that can not
# be overcome. In normal cases one should fix the bug server/test case or in
# the worst case add a (temporary?) suppression in asan.supp or lsan.supp
if (`select count(*) from information_schema.system_variables where variable_name='have_sanitizer' and global_value LIKE "%UBSAN"`)
{
--skip Can't be run with UBSAN
}

View File

@@ -1277,6 +1277,8 @@ ALTER TABLE t1
DROP i,
ADD i INT UNSIGNED NOT NULL AUTO_INCREMENT,
AUTO_INCREMENT = 1;
Warnings:
Note 4190 ALTER TABLE is implicitly changing the value of 'AUTO_INCREMENT' from '1' to '4'
DROP TABLE t1;
CREATE TABLE t1 (a CHAR(1), PRIMARY KEY (a(255)));
ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys
@@ -3215,6 +3217,29 @@ Tp4 CREATE TABLE `Tp4`-ok (
drop table Another.Tp4;
drop database Another;
#
# MDEV-35732: Failed ALTER TABLE causes inconsistency, changes behavior of the next statement
#
# It should be impossible for a failed rename index to affect
# a subsequent duplicate name check for a foreign key.
#
create table t1 (f1 int, f2 int, key(f1), key(f2)) engine=innodb;
create table t2 (pk int primary key, a int, b int, key ind1(a),
foreign key fk1 (b) references t1 (f1)) engine=innodb;
alter table t2 rename index fk1 to fk, algorithm=instant, order by a;
ERROR 0A000: ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=COPY
alter table t2 add foreign key ind1 (b) references t1 (f2);
ERROR 42000: Duplicate key name 'ind1'
drop table t2, t1;
#
# It should be impossible to add a foreign key with a duplicate name.
#
create table t1 (f1 int, f2 int, key(f1), key(f2)) engine=innodb;
create table t2 (pk int primary key, a int, b int, key ind1(a),
foreign key fk1 (b) references t1 (f1)) engine=innodb;
alter table t2 add foreign key ind1 (b) references t1 (f2);
ERROR 42000: Duplicate key name 'ind1'
drop table t2, t1;
#
# End of 11.4 tests
#
#

View File

@@ -2512,6 +2512,36 @@ show create table Another.Tp4;
drop table Another.Tp4;
drop database Another;
--echo #
--echo # MDEV-35732: Failed ALTER TABLE causes inconsistency, changes behavior of the next statement
--echo #
--echo # It should be impossible for a failed rename index to affect
--echo # a subsequent duplicate name check for a foreign key.
--echo #
create table t1 (f1 int, f2 int, key(f1), key(f2)) engine=innodb;
create table t2 (pk int primary key, a int, b int, key ind1(a),
foreign key fk1 (b) references t1 (f1)) engine=innodb;
--error ER_ALTER_OPERATION_NOT_SUPPORTED
alter table t2 rename index fk1 to fk, algorithm=instant, order by a;
--error ER_DUP_KEYNAME
alter table t2 add foreign key ind1 (b) references t1 (f2);
drop table t2, t1;
--echo #
--echo # It should be impossible to add a foreign key with a duplicate name.
--echo #
create table t1 (f1 int, f2 int, key(f1), key(f2)) engine=innodb;
create table t2 (pk int primary key, a int, b int, key ind1(a),
foreign key fk1 (b) references t1 (f1)) engine=innodb;
--error ER_DUP_KEYNAME
alter table t2 add foreign key ind1 (b) references t1 (f2);
drop table t2, t1;
--echo #
--echo # End of 11.4 tests
--echo #

View File

@@ -2,6 +2,8 @@ create table t1(a int(10)unsigned not null auto_increment primary key,
b varchar(255) not null) engine=innodb default charset=utf8;
insert into t1 values(1,'aaa'),(2,'bbb');
alter table t1 auto_increment=1;
Warnings:
Note 4190 ALTER TABLE is implicitly changing the value of 'AUTO_INCREMENT' from '1' to '3'
insert into t1 values(NULL, 'ccc');
select * from t1;
a b

View File

@@ -5789,6 +5789,13 @@ SELECT JSON_SCHEMA_VALID(@schema, @value);
JSON_SCHEMA_VALID(@schema, @value)
1
#
# MDEV-41181: ASAN heap-buffer-overflow after SELECT JSON_SCHEMA_VALID
#
SELECT JSON_SCHEMA_VALID( '{"enum": ["x"]}', CONVERT(CONCAT('"', REPEAT('e', 100000), '"') USING ucs2)) AS r;
r
0
# End of 11.4 tests
#
# MDEV-38702 Behaviour of IF() with boolean JSON_EXTRACT as expression is wrong
#
SELECT JSON_TYPE(JSON_EXTRACT(x.val, '$.booleanValue')) AS json_type,

View File

@@ -4454,6 +4454,14 @@ SET @value= '
SELECT JSON_SCHEMA_VALID(@schema, @value);
--echo #
--echo # MDEV-41181: ASAN heap-buffer-overflow after SELECT JSON_SCHEMA_VALID
--echo #
SELECT JSON_SCHEMA_VALID( '{"enum": ["x"]}', CONVERT(CONCAT('"', REPEAT('e', 100000), '"') USING ucs2)) AS r;
--echo # End of 11.4 tests
--echo #
--echo # MDEV-38702 Behaviour of IF() with boolean JSON_EXTRACT as expression is wrong
--echo #

View File

@@ -161,3 +161,64 @@ ERROR 42000: Incorrect parameter count in the call to native function 'kdf'
#
# End of 11.3 tests
#
#
# MDEV-40385 use-of-uninitialized-value in Binary_string::c_ptr()
#
SELECT KDF('','',1000,256);
KDF('','',1000,256)
NULL
Warnings:
Warning 3047 Invalid argument error: '256' in function kdf.
SELECT KDF('secret','salt',1000,999);
KDF('secret','salt',1000,999)
NULL
Warnings:
Warning 3047 Invalid argument error: '999' in function kdf.
SELECT KDF('secret','salt',1000,'pbkdf2_hmac') IS NOT NULL;
KDF('secret','salt',1000,'pbkdf2_hmac') IS NOT NULL
1
SELECT KDF('secret','salt') IS NOT NULL;
KDF('secret','salt') IS NOT NULL
1
#
# MDEV-41094 KDF() silently reduces large PBKDF2 iteration counts
# and key widths to weak 32-bit aliases
#
SET @@block_encryption_mode=DEFAULT;
SELECT HEX(KDF('foo', 'bar', 1000, 'pbkdf2_hmac'));
HEX(KDF('foo', 'bar', 1000, 'pbkdf2_hmac'))
76BA6DEC5C3F6A60704D730A2A4BAA1C
SELECT KDF('foo', 'bar', 4294968296, 'pbkdf2_hmac');
KDF('foo', 'bar', 4294968296, 'pbkdf2_hmac')
NULL
Warnings:
Warning 3047 Invalid argument error: 4294968296 in function kdf.
SELECT KDF('foo', 'bar', 2147483648, 'pbkdf2_hmac');
KDF('foo', 'bar', 2147483648, 'pbkdf2_hmac')
NULL
Warnings:
Warning 3047 Invalid argument error: 2147483648 in function kdf.
SELECT HEX(KDF('foo', 'bar', 1000, 'pbkdf2_hmac', 256));
HEX(KDF('foo', 'bar', 1000, 'pbkdf2_hmac', 256))
76BA6DEC5C3F6A60704D730A2A4BAA1C596F278AE35408EE5D67ECE0942C14F4
SELECT KDF('foo', 'bar', 1000, 'pbkdf2_hmac', 4294967552);
KDF('foo', 'bar', 1000, 'pbkdf2_hmac', 4294967552)
NULL
Warnings:
Warning 3047 Invalid argument error: 4294967552 in function kdf.
SELECT KDF('foo', 'bar', 1000, 'pbkdf2_hmac', -4294967040);
KDF('foo', 'bar', 1000, 'pbkdf2_hmac', -4294967040)
NULL
Warnings:
Warning 3047 Invalid argument error: -4294967040 in function kdf.
CREATE TABLE t1 (w BIGINT);
INSERT INTO t1 VALUES (4294967552);
SELECT KDF('foo', 'bar', 1000, 'pbkdf2_hmac', w) FROM t1;
KDF('foo', 'bar', 1000, 'pbkdf2_hmac', w)
NULL
Warnings:
Warning 3047 Invalid argument error: 4294967552 in function kdf.
DROP TABLE t1;
#
# End of 11.4 tests
#

View File

@@ -62,3 +62,33 @@ select kdf();
--echo # End of 11.3 tests
--echo #
--echo #
--echo # MDEV-40385 use-of-uninitialized-value in Binary_string::c_ptr()
--echo #
# MSAN only: this test verifies the fix behaviorally (warning + NULL); the
# uninitialized read itself is only observable under an MSAN build.
SELECT KDF('','',1000,256);
SELECT KDF('secret','salt',1000,999);
SELECT KDF('secret','salt',1000,'pbkdf2_hmac') IS NOT NULL;
SELECT KDF('secret','salt') IS NOT NULL;
--echo #
--echo # MDEV-41094 KDF() silently reduces large PBKDF2 iteration counts
--echo # and key widths to weak 32-bit aliases
--echo #
SET @@block_encryption_mode=DEFAULT;
SELECT HEX(KDF('foo', 'bar', 1000, 'pbkdf2_hmac'));
SELECT KDF('foo', 'bar', 4294968296, 'pbkdf2_hmac');
SELECT KDF('foo', 'bar', 2147483648, 'pbkdf2_hmac');
SELECT HEX(KDF('foo', 'bar', 1000, 'pbkdf2_hmac', 256));
SELECT KDF('foo', 'bar', 1000, 'pbkdf2_hmac', 4294967552);
SELECT KDF('foo', 'bar', 1000, 'pbkdf2_hmac', -4294967040);
CREATE TABLE t1 (w BIGINT);
INSERT INTO t1 VALUES (4294967552);
SELECT KDF('foo', 'bar', 1000, 'pbkdf2_hmac', w) FROM t1;
DROP TABLE t1;
--echo #
--echo # End of 11.4 tests
--echo #

View File

@@ -1,5 +1,5 @@
--- ./main/innodb_ext_key.result
+++ ./main/innodb_ext_key.reject
--- ./innodb_ext_key.result
+++ innodb_ext_key,covering,on.result
@@ -244,7 +244,7 @@
Variable_name Value
Handler_read_first 0

View File

@@ -1,5 +1,5 @@
--- main/innodb_ext_key.result
+++ main/innodb_ext_key,off.reject
--- ./innodb_ext_key.result
+++ innodb_ext_key,on.result
@@ -9,7 +9,7 @@
explain
select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01';

View File

@@ -1,5 +1,5 @@
--- ./main/innodb_ext_key.result
+++ ./main/innodb_ext_key.reject
--- ./innodb_ext_key.result
+++ innodb_ext_key,on,unoptimized.result
@@ -244,7 +244,7 @@
Variable_name Value
Handler_read_first 0

View File

@@ -5,11 +5,15 @@
# making writing tests that depend on reaching
# the depth hard.
#
source include/not_asan.inc;
source include/not_embedded.inc;
source include/not_ubsan.inc;
# MSAN with debug exceeds the stack early.
source include/not_msan_with_debug.inc;
if (`select count(*) from information_schema.system_variables
where variable_name='have_sanitizer'
and global_value REGEXP '(A|UB)SAN'`)
{
--skip Can't be run in UBSAN/ASAN (stack size predictability)
}
#
# Bug#10100 function (and stored procedure?) recursivity problem

View File

@@ -0,0 +1 @@
--lower-case-table-names=2

View File

@@ -0,0 +1,46 @@
#
# MDEV-33616 Routines of a mixed case database are not listed when
# lower_case_table_names is 2
#
CREATE DATABASE Db1;
USE Db1;
CREATE FUNCTION f1(a INT) RETURNS INT RETURN a;
CREATE PROCEDURE p1(b INT) BEGIN END;
SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='Db1';
SCHEMA_NAME
Db1
SELECT db, name FROM mysql.proc WHERE name IN ('f1','p1');
db name
db1 f1
db1 p1
SELECT ROUTINE_NAME FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA='Db1';
ROUTINE_NAME
f1
p1
SELECT SPECIFIC_NAME, ORDINAL_POSITION, PARAMETER_NAME
FROM information_schema.PARAMETERS WHERE SPECIFIC_SCHEMA='Db1';
SPECIFIC_NAME ORDINAL_POSITION PARAMETER_NAME
f1 0 NULL
f1 1 a
p1 1 b
SHOW FUNCTION STATUS WHERE Db='Db1';
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
db1 f1 FUNCTION root@localhost # # DEFINER latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
SHOW PROCEDURE STATUS WHERE Db='Db1';
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
db1 p1 PROCEDURE root@localhost # # DEFINER latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci
SELECT ROUTINE_NAME FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA='Db1' ORDER BY ROUTINE_NAME;
ROUTINE_NAME
f1
p1
SELECT SPECIFIC_NAME, ORDINAL_POSITION, PARAMETER_NAME
FROM information_schema.PARAMETERS WHERE SPECIFIC_SCHEMA='Db1'
ORDER BY SPECIFIC_NAME, ORDINAL_POSITION;
SPECIFIC_NAME ORDINAL_POSITION PARAMETER_NAME
f1 0 NULL
f1 1 a
p1 1 b
USE test;
DROP DATABASE Db1;

View File

@@ -0,0 +1,47 @@
#
# Tests that require lower_case_table_names to be 2
# (the default when the data directory is on a case insensitive file system)
#
--source include/have_lowercase2.inc
--echo #
--echo # MDEV-33616 Routines of a mixed case database are not listed when
--echo # lower_case_table_names is 2
--echo #
CREATE DATABASE Db1;
USE Db1;
CREATE FUNCTION f1(a INT) RETURNS INT RETURN a;
CREATE PROCEDURE p1(b INT) BEGIN END;
# The database keeps the case it was created with, mysql.proc does not.
SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='Db1';
--sorted_result
SELECT db, name FROM mysql.proc WHERE name IN ('f1','p1');
# The name from the WHERE clause becomes the key of an index read on
# mysql.proc. mysql.proc.db is utf8mb3_bin and holds the folded name, so
# an unfolded key finds nothing.
--sorted_result
SELECT ROUTINE_NAME FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA='Db1';
--sorted_result
SELECT SPECIFIC_NAME, ORDINAL_POSITION, PARAMETER_NAME
FROM information_schema.PARAMETERS WHERE SPECIFIC_SCHEMA='Db1';
--replace_column 5 # 6 #
SHOW FUNCTION STATUS WHERE Db='Db1';
--replace_column 5 # 6 #
SHOW PROCEDURE STATUS WHERE Db='Db1';
# ORDER BY keeps the condition from reaching the routine that fills the
# table, so mysql.proc is read in full and the WHERE is applied afterwards
# over a utf8mb3_general_ci column. That shape returned the rows even
# while the queries above returned none.
SELECT ROUTINE_NAME FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA='Db1' ORDER BY ROUTINE_NAME;
SELECT SPECIFIC_NAME, ORDINAL_POSITION, PARAMETER_NAME
FROM information_schema.PARAMETERS WHERE SPECIFIC_SCHEMA='Db1'
ORDER BY SPECIFIC_NAME, ORDINAL_POSITION;
USE test;
DROP DATABASE Db1;

View File

@@ -0,0 +1,46 @@
#
# MDEV-33616 A statement cannot reference two routines whose databases
# differ only in case
#
CREATE DATABASE Db1;
CREATE DATABASE db1;
CREATE FUNCTION Db1.f1() RETURNS INT RETURN 1;
CREATE FUNCTION db1.f1() RETURNS INT RETURN 2;
CREATE PROCEDURE test.p1() SELECT Db1.f1(), db1.f1();
SELECT Db1.f1();
Db1.f1()
1
SELECT db1.f1();
db1.f1()
2
connect con1,localhost,root,,test;
SELECT Db1.f1(), db1.f1();
Db1.f1() db1.f1()
1 2
disconnect con1;
connect con2,localhost,root,,test;
SELECT db1.f1(), Db1.f1();
db1.f1() Db1.f1()
2 1
disconnect con2;
connect con3,localhost,root,,test;
CALL test.p1();
Db1.f1() db1.f1()
1 2
disconnect con3;
connect con4,localhost,root,,test;
SELECT db1.f1();
db1.f1()
2
connection default;
DROP FUNCTION db1.f1;
CREATE FUNCTION db1.f1() RETURNS INT RETURN 99;
connection con4;
SELECT Db1.f1(), db1.f1();
Db1.f1() db1.f1()
1 99
disconnect con4;
connection default;
DROP PROCEDURE test.p1;
DROP DATABASE Db1;
DROP DATABASE db1;

View File

@@ -0,0 +1,65 @@
#
# Tests that require lower_case_table_names to be 0
# (the default when the data directory is on a case sensitive file system)
#
--source include/have_lowercase0.inc
--source include/have_case_sensitive_file_system.inc
--echo #
--echo # MDEV-33616 A statement cannot reference two routines whose databases
--echo # differ only in case
--echo #
CREATE DATABASE Db1;
CREATE DATABASE db1;
CREATE FUNCTION Db1.f1() RETURNS INT RETURN 1;
CREATE FUNCTION db1.f1() RETURNS INT RETURN 2;
CREATE PROCEDURE test.p1() SELECT Db1.f1(), db1.f1();
SELECT Db1.f1();
SELECT db1.f1();
# Every routine a statement names joins one set, keyed by the database and
# the routine name. The database name is case sensitive here, so the two
# routines have to stay apart and each reference has to reach its own. A
# connection that already holds one of them in its routine cache resolves
# both either way, so every check below starts from a connection that holds
# neither.
connect (con1,localhost,root,,test);
# A view compares its column names without regard to case, so under the
# view protocol the second column of a query like this one is given a
# generated name.
--disable_view_protocol
SELECT Db1.f1(), db1.f1();
--enable_view_protocol
disconnect con1;
connect (con2,localhost,root,,test);
--disable_view_protocol
SELECT db1.f1(), Db1.f1();
--enable_view_protocol
disconnect con2;
# A statement inside a routine body builds the same set.
connect (con3,localhost,root,,test);
CALL test.p1();
disconnect con3;
# A routine missing from the set is neither locked nor checked against the
# version of the routine cache, so it could execute a definition that
# another connection had already replaced.
connect (con4,localhost,root,,test);
SELECT db1.f1();
connection default;
DROP FUNCTION db1.f1;
CREATE FUNCTION db1.f1() RETURNS INT RETURN 99;
connection con4;
--disable_view_protocol
SELECT Db1.f1(), db1.f1();
--enable_view_protocol
disconnect con4;
connection default;
DROP PROCEDURE test.p1;
DROP DATABASE Db1;
DROP DATABASE db1;

View File

@@ -114,7 +114,7 @@ mysql.help_topic: Records: 839 Deleted: 0 Skipped: 0 Warnings: 0
Loading data from LOCAL file: vardir/tmp/dump/mysql/time_zone_transition.txt into time_zone_transition
mysql.time_zone_transition: Records: 394 Deleted: 0 Skipped: 0 Warnings: 0
Loading data from LOCAL file: vardir/tmp/dump/mtr/global_suppressions.txt into global_suppressions
mtr.global_suppressions: Records: 99 Deleted: 0 Skipped: 0 Warnings: 0
mtr.global_suppressions: Records: 100 Deleted: 0 Skipped: 0 Warnings: 0
Loading data from LOCAL file: vardir/tmp/dump/mysql/help_keyword.txt into help_keyword
mysql.help_keyword: Records: 106 Deleted: 0 Skipped: 0 Warnings: 0
Loading data from LOCAL file: vardir/tmp/dump/mysql/help_relation.txt into help_relation

View File

@@ -0,0 +1,207 @@
#
# MDEV-39993 mariadb-upgrade Drops Existing EXECUTE Grants on sys
# Stored Routines During Upgrade
#
CREATE USER mdev39993_user@localhost;
GRANT EXECUTE ON PROCEDURE sys.table_exists TO mdev39993_user@localhost;
GRANT EXECUTE ON FUNCTION sys.quote_identifier TO mdev39993_user@localhost;
SHOW GRANTS FOR mdev39993_user@localhost;
Grants for mdev39993_user@localhost
GRANT USAGE ON *.* TO `mdev39993_user`@`localhost`
GRANT EXECUTE ON PROCEDURE `sys`.`table_exists` TO `mdev39993_user`@`localhost`
GRANT EXECUTE ON FUNCTION `sys`.`quote_identifier` TO `mdev39993_user`@`localhost`
# Overwrite the routine bodies with a marker so that a passing test
# below actually proves the routines were reinstalled by the
# upgrade, rather than merely left untouched (i.e. sys schema
# install skipped).
CREATE OR REPLACE DEFINER='mariadb.sys'@'localhost' FUNCTION sys.quote_identifier(in_identifier TEXT)
RETURNS TEXT
SQL SECURITY INVOKER
DETERMINISTIC
BEGIN
RETURN 'stale_body_marker';
END|
CREATE OR REPLACE DEFINER='mariadb.sys'@'localhost' PROCEDURE sys.table_exists (
IN in_db VARCHAR(64), IN in_table VARCHAR(64),
OUT out_exists ENUM('', 'BASE TABLE', 'VIEW', 'TEMPORARY', 'SEQUENCE', 'SYSTEM VIEW', 'TEMPORARY SEQUENCE')
)
SQL SECURITY INVOKER
BEGIN
SET out_exists = '';
END|
SELECT sys.quote_identifier('abc') AS qi;
qi
stale_body_marker
CALL sys.table_exists('mysql', 'user', @exists);
SELECT @exists;
@exists
Phase 1/8: Checking and upgrading mysql database
Processing databases
mysql
mysql.column_stats OK
mysql.columns_priv OK
mysql.db OK
mysql.event OK
mysql.func OK
mysql.global_priv OK
mysql.gtid_slave_pos OK
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
mysql.help_topic OK
mysql.index_stats OK
mysql.innodb_index_stats OK
mysql.innodb_table_stats OK
mysql.plugin OK
mysql.proc OK
mysql.procs_priv OK
mysql.proxies_priv OK
mysql.roles_mapping OK
mysql.servers OK
mysql.table_stats OK
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.transaction_registry OK
Phase 2/8: Installing used storage engines... Skipped
Phase 3/8: Running 'mysql_fix_privilege_tables'
Phase 4/8: Fixing views
mysql.user OK
sys.host_summary OK
sys.host_summary_by_file_io OK
sys.host_summary_by_file_io_type OK
sys.host_summary_by_stages OK
sys.host_summary_by_statement_latency OK
sys.host_summary_by_statement_type OK
sys.innodb_buffer_stats_by_schema OK
sys.innodb_buffer_stats_by_table OK
sys.innodb_lock_waits OK
sys.io_by_thread_by_latency OK
sys.io_global_by_file_by_bytes OK
sys.io_global_by_file_by_latency OK
sys.io_global_by_wait_by_bytes OK
sys.io_global_by_wait_by_latency OK
sys.latest_file_io OK
sys.memory_by_host_by_current_bytes OK
sys.memory_by_thread_by_current_bytes OK
sys.memory_by_user_by_current_bytes OK
sys.memory_global_by_current_bytes OK
sys.memory_global_total OK
sys.metrics OK
sys.privileges_by_table_by_level OK
sys.processlist OK
sys.ps_check_lost_instrumentation OK
sys.schema_auto_increment_columns OK
sys.schema_index_statistics OK
sys.schema_object_overview OK
sys.schema_redundant_indexes OK
sys.schema_table_lock_waits OK
sys.schema_table_statistics OK
sys.schema_table_statistics_with_buffer OK
sys.schema_tables_with_full_table_scans OK
sys.schema_unused_indexes OK
sys.session OK
sys.session_ssl_status OK
sys.statement_analysis OK
sys.statements_with_errors_or_warnings OK
sys.statements_with_full_table_scans OK
sys.statements_with_runtimes_in_95th_percentile OK
sys.statements_with_sorting OK
sys.statements_with_temp_tables OK
sys.user_summary OK
sys.user_summary_by_file_io OK
sys.user_summary_by_file_io_type OK
sys.user_summary_by_stages OK
sys.user_summary_by_statement_latency OK
sys.user_summary_by_statement_type OK
sys.version OK
sys.wait_classes_global_by_avg_latency OK
sys.wait_classes_global_by_latency OK
sys.waits_by_host_by_latency OK
sys.waits_by_user_by_latency OK
sys.waits_global_by_latency OK
sys.x$host_summary OK
sys.x$host_summary_by_file_io OK
sys.x$host_summary_by_file_io_type OK
sys.x$host_summary_by_stages OK
sys.x$host_summary_by_statement_latency OK
sys.x$host_summary_by_statement_type OK
sys.x$innodb_buffer_stats_by_schema OK
sys.x$innodb_buffer_stats_by_table OK
sys.x$innodb_lock_waits OK
sys.x$io_by_thread_by_latency OK
sys.x$io_global_by_file_by_bytes OK
sys.x$io_global_by_file_by_latency OK
sys.x$io_global_by_wait_by_bytes OK
sys.x$io_global_by_wait_by_latency OK
sys.x$latest_file_io OK
sys.x$memory_by_host_by_current_bytes OK
sys.x$memory_by_thread_by_current_bytes OK
sys.x$memory_by_user_by_current_bytes OK
sys.x$memory_global_by_current_bytes OK
sys.x$memory_global_total OK
sys.x$processlist OK
sys.x$ps_digest_95th_percentile_by_avg_us OK
sys.x$ps_digest_avg_latency_distribution OK
sys.x$ps_schema_table_statistics_io OK
sys.x$schema_flattened_keys OK
sys.x$schema_index_statistics OK
sys.x$schema_table_lock_waits OK
sys.x$schema_table_statistics OK
sys.x$schema_table_statistics_with_buffer OK
sys.x$schema_tables_with_full_table_scans OK
sys.x$session OK
sys.x$statement_analysis OK
sys.x$statements_with_errors_or_warnings OK
sys.x$statements_with_full_table_scans OK
sys.x$statements_with_runtimes_in_95th_percentile OK
sys.x$statements_with_sorting OK
sys.x$statements_with_temp_tables OK
sys.x$user_summary OK
sys.x$user_summary_by_file_io OK
sys.x$user_summary_by_file_io_type OK
sys.x$user_summary_by_stages OK
sys.x$user_summary_by_statement_latency OK
sys.x$user_summary_by_statement_type OK
sys.x$wait_classes_global_by_avg_latency OK
sys.x$wait_classes_global_by_latency OK
sys.x$waits_by_host_by_latency OK
sys.x$waits_by_user_by_latency OK
sys.x$waits_global_by_latency OK
Phase 5/8: Fixing table and database names
Phase 6/8: Checking and upgrading tables
Processing databases
information_schema
mtr
mtr.global_suppressions OK
mtr.test_suppressions OK
performance_schema
sys
sys.sys_config OK
test
Phase 7/8: uninstalling plugins
Phase 8/8: Running 'FLUSH PRIVILEGES'
OK
# The EXECUTE grants on sys.table_exists and sys.quote_identifier
# must survive the reinstall of the sys schema.
SHOW GRANTS FOR mdev39993_user@localhost;
Grants for mdev39993_user@localhost
GRANT USAGE ON *.* TO `mdev39993_user`@`localhost`
GRANT EXECUTE ON PROCEDURE `sys`.`table_exists` TO `mdev39993_user`@`localhost`
GRANT EXECUTE ON FUNCTION `sys`.`quote_identifier` TO `mdev39993_user`@`localhost`
# The routine bodies must have been replaced back to their real
# definitions (proves the sys schema was actually reinstalled by
# the upgrade, not merely skipped).
SELECT sys.quote_identifier('abc') AS qi;
qi
`abc`
CALL sys.table_exists('mysql', 'user', @exists);
SELECT @exists;
@exists
VIEW
DROP USER mdev39993_user@localhost;
# End of 11.4 tests

View File

@@ -0,0 +1,61 @@
--source include/mysql_upgrade_preparation.inc
--source include/have_innodb.inc
--echo #
--echo # MDEV-39993 mariadb-upgrade Drops Existing EXECUTE Grants on sys
--echo # Stored Routines During Upgrade
--echo #
CREATE USER mdev39993_user@localhost;
GRANT EXECUTE ON PROCEDURE sys.table_exists TO mdev39993_user@localhost;
GRANT EXECUTE ON FUNCTION sys.quote_identifier TO mdev39993_user@localhost;
SHOW GRANTS FOR mdev39993_user@localhost;
--echo # Overwrite the routine bodies with a marker so that a passing test
--echo # below actually proves the routines were reinstalled by the
--echo # upgrade, rather than merely left untouched (i.e. sys schema
--echo # install skipped).
DELIMITER |;
CREATE OR REPLACE DEFINER='mariadb.sys'@'localhost' FUNCTION sys.quote_identifier(in_identifier TEXT)
RETURNS TEXT
SQL SECURITY INVOKER
DETERMINISTIC
BEGIN
RETURN 'stale_body_marker';
END|
CREATE OR REPLACE DEFINER='mariadb.sys'@'localhost' PROCEDURE sys.table_exists (
IN in_db VARCHAR(64), IN in_table VARCHAR(64),
OUT out_exists ENUM('', 'BASE TABLE', 'VIEW', 'TEMPORARY', 'SEQUENCE', 'SYSTEM VIEW', 'TEMPORARY SEQUENCE')
)
SQL SECURITY INVOKER
BEGIN
SET out_exists = '';
END|
DELIMITER ;|
SELECT sys.quote_identifier('abc') AS qi;
CALL sys.table_exists('mysql', 'user', @exists);
SELECT @exists;
--exec $MYSQL_UPGRADE --force 2>&1
let $MYSQLD_DATADIR= `select @@datadir`;
--file_exists $MYSQLD_DATADIR/mariadb_upgrade_info
--remove_file $MYSQLD_DATADIR/mariadb_upgrade_info
--echo # The EXECUTE grants on sys.table_exists and sys.quote_identifier
--echo # must survive the reinstall of the sys schema.
SHOW GRANTS FOR mdev39993_user@localhost;
--echo # The routine bodies must have been replaced back to their real
--echo # definitions (proves the sys schema was actually reinstalled by
--echo # the upgrade, not merely skipped).
SELECT sys.quote_identifier('abc') AS qi;
CALL sys.table_exists('mysql', 'user', @exists);
SELECT @exists;
DROP USER mdev39993_user@localhost;
--echo # End of 11.4 tests

View File

@@ -1358,8 +1358,7 @@ The following specify which files/extra groups are read (specified before remain
--slave-connections-needed-for-purge=#
Minimum number of connected slaves required for automatic
binary log purge with max_binlog_total_size,
binlog_expire_logs_seconds or binlog_expire_logs_days.
Default is 0 when Galera is enabled and 1 otherwise
binlog_expire_logs_seconds or binlog_expire_logs_days
--slave-ddl-exec-mode=name
How replication events should be executed. Legal values
are STRICT and IDEMPOTENT (default). In IDEMPOTENT mode,
@@ -2006,7 +2005,7 @@ skip-show-database FALSE
skip-slave-start FALSE
slave-abort-blocking-timeout 31536000
slave-compressed-protocol FALSE
slave-connections-needed-for-purge 1
slave-connections-needed-for-purge 0
slave-ddl-exec-mode IDEMPOTENT
slave-domain-parallel-threads 0
slave-exec-mode STRICT

View File

@@ -129,6 +129,8 @@ REPLACE INTO `innodb_index_stats` VALUES
('test','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx01',5,1,'Time_zone_id'),
('test','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx02',394,1,'Time_zone_id,Transition_time'),
('test','tz','PRIMARY','2019-12-31 21:00:00','n_leaf_pages',1,NULL,'Number of leaf pages in the index'),
('test','tz','PRIMARY','2019-12-31 21:00:00','n_nonnull_fld01',394,1,'Time_zone_id'),
('test','tz','PRIMARY','2019-12-31 21:00:00','n_nonnull_fld02',394,1,'Transition_time'),
('test','tz','PRIMARY','2019-12-31 21:00:00','size',1,NULL,'Number of pages in the index');
/*!40000 ALTER TABLE `innodb_index_stats` ENABLE KEYS */;
UNLOCK TABLES;
@@ -753,6 +755,8 @@ REPLACE INTO `innodb_index_stats` VALUES
('test','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx01',5,1,'Time_zone_id'),
('test','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx02',394,1,'Time_zone_id,Transition_time'),
('test','tz','PRIMARY','2019-12-31 21:00:00','n_leaf_pages',1,NULL,'Number of leaf pages in the index'),
('test','tz','PRIMARY','2019-12-31 21:00:00','n_nonnull_fld01',394,1,'Time_zone_id'),
('test','tz','PRIMARY','2019-12-31 21:00:00','n_nonnull_fld02',394,1,'Transition_time'),
('test','tz','PRIMARY','2019-12-31 21:00:00','size',1,NULL,'Number of pages in the index');
/*!40000 ALTER TABLE `innodb_index_stats` ENABLE KEYS */;
UNLOCK TABLES;
@@ -1353,6 +1357,8 @@ INSERT IGNORE INTO `innodb_index_stats` VALUES
('test','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx01',5,1,'Time_zone_id'),
('test','tz','PRIMARY','2019-12-31 21:00:00','n_diff_pfx02',394,1,'Time_zone_id,Transition_time'),
('test','tz','PRIMARY','2019-12-31 21:00:00','n_leaf_pages',1,NULL,'Number of leaf pages in the index'),
('test','tz','PRIMARY','2019-12-31 21:00:00','n_nonnull_fld01',394,1,'Time_zone_id'),
('test','tz','PRIMARY','2019-12-31 21:00:00','n_nonnull_fld02',394,1,'Transition_time'),
('test','tz','PRIMARY','2019-12-31 21:00:00','size',1,NULL,'Number of pages in the index');
/*!40000 ALTER TABLE `innodb_index_stats` ENABLE KEYS */;
UNLOCK TABLES;

View File

@@ -71,3 +71,27 @@ DROP TABLE t1, t2;
#
# End of 11.0 tests
#
#
# MDEV-36096: Assertion partial_join_cost >= 0.0 failed when
# sql_select_limit=1, and
# optimizer_join_limit_pref_ratio=1
#
CREATE TABLE t (c INT NOT NULL UNIQUE) ENGINE=InnoDB;
INSERT INTO t VALUES (0),(1),(2),(3),(4),(5);
SET @save_sql_select_limit= @@sql_select_limit;
SET sql_select_limit=1,optimizer_join_limit_pref_ratio=1;
EXPLAIN
SELECT * FROM t ORDER BY c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t index NULL c 4 NULL 1
SET sql_select_limit= @save_sql_select_limit;
# similar issue with LIMIT 1 clause query
EXPLAIN
SELECT * FROM t ORDER BY c LIMIT 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t index NULL c 4 NULL 1
SET optimizer_join_limit_pref_ratio= default;
DROP table t;
#
# End of 11.4 tests
#

View File

@@ -80,3 +80,31 @@ DROP TABLE t1, t2;
--echo #
--echo # End of 11.0 tests
--echo #
--echo #
--echo # MDEV-36096: Assertion partial_join_cost >= 0.0 failed when
--echo # sql_select_limit=1, and
--echo # optimizer_join_limit_pref_ratio=1
--echo #
CREATE TABLE t (c INT NOT NULL UNIQUE) ENGINE=InnoDB;
INSERT INTO t VALUES (0),(1),(2),(3),(4),(5);
SET @save_sql_select_limit= @@sql_select_limit;
SET sql_select_limit=1,optimizer_join_limit_pref_ratio=1;
EXPLAIN
SELECT * FROM t ORDER BY c;
SET sql_select_limit= @save_sql_select_limit;
--echo # similar issue with LIMIT 1 clause query
EXPLAIN
SELECT * FROM t ORDER BY c LIMIT 1;
SET optimizer_join_limit_pref_ratio= default;
DROP table t;
--echo #
--echo # End of 11.4 tests
--echo #

View File

@@ -400,6 +400,69 @@ DROP FUNCTION f;
# End of 10.5 tests
#
#
# MDEV-38861 heap-use-after-free in Prepared_statement::execute()
#
# A routine must not be removed from the SP cache while it is executing.
#
# DROP of the running routine
create procedure p0()
begin
prepare stmt from "drop procedure p0";
execute stmt;
end$$
call p0();
call p0();
ERROR 42000: PROCEDURE test.p0 does not exist
deallocate prepare stmt;
# CREATE OR REPLACE of the running routine
create procedure p0()
begin
prepare stmt from "create or replace procedure p0() begin select 1 as replaced; end";
execute stmt;
end$$
call p0();
call p0();
replaced
1
deallocate prepare stmt;
drop procedure p0;
# Recursive call after the self-DROP, with the default recursion depth
set @save_depth=@@max_sp_recursion_depth;
set @@max_sp_recursion_depth=0;
create procedure p0()
begin
prepare stmt from "drop procedure p0";
execute stmt;
call p0();
end$$
call p0();
ERROR HY000: Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine p0
call p0();
ERROR 42000: PROCEDURE test.p0 does not exist
deallocate prepare stmt;
set @@max_sp_recursion_depth=@save_depth;
# DROP of the caller, which then keeps running
create procedure outer_p()
begin
call inner_p();
select 'outer survived' as state;
end$$
create procedure inner_p()
begin
prepare stmt from "drop procedure outer_p";
execute stmt;
end$$
call outer_p();
state
outer survived
call outer_p();
ERROR 42000: PROCEDURE test.outer_p does not exist
deallocate prepare stmt;
drop procedure inner_p;
#
# End of 11.4 tests
#
#
# MDEV-36876 Crash during the Item_subselect::init - outer_select is NULL
#
# Vectors are not allowed for SOME/ANY

View File

@@ -438,6 +438,79 @@ DROP FUNCTION f;
--echo # End of 10.5 tests
--echo #
--echo #
--echo # MDEV-38861 heap-use-after-free in Prepared_statement::execute()
--echo #
--echo # A routine must not be removed from the SP cache while it is executing.
--echo #
--echo # DROP of the running routine
delimiter $$;
create procedure p0()
begin
prepare stmt from "drop procedure p0";
execute stmt;
end$$
delimiter ;$$
call p0();
--error ER_SP_DOES_NOT_EXIST
call p0();
deallocate prepare stmt;
--echo # CREATE OR REPLACE of the running routine
delimiter $$;
create procedure p0()
begin
prepare stmt from "create or replace procedure p0() begin select 1 as replaced; end";
execute stmt;
end$$
delimiter ;$$
call p0();
call p0();
deallocate prepare stmt;
drop procedure p0;
--echo # Recursive call after the self-DROP, with the default recursion depth
set @save_depth=@@max_sp_recursion_depth;
set @@max_sp_recursion_depth=0;
delimiter $$;
create procedure p0()
begin
prepare stmt from "drop procedure p0";
execute stmt;
call p0();
end$$
delimiter ;$$
--error ER_SP_RECURSION_LIMIT
call p0();
--error ER_SP_DOES_NOT_EXIST
call p0();
deallocate prepare stmt;
set @@max_sp_recursion_depth=@save_depth;
--echo # DROP of the caller, which then keeps running
delimiter $$;
create procedure outer_p()
begin
call inner_p();
select 'outer survived' as state;
end$$
create procedure inner_p()
begin
prepare stmt from "drop procedure outer_p";
execute stmt;
end$$
delimiter ;$$
call outer_p();
--error ER_SP_DOES_NOT_EXIST
call outer_p();
deallocate prepare stmt;
drop procedure inner_p;
--echo #
--echo # End of 11.4 tests
--echo #
--echo #
--echo # MDEV-36876 Crash during the Item_subselect::init - outer_select is NULL
--echo #

View File

@@ -2756,6 +2756,46 @@ c
0
DROP TABLE t1;
# end of 10.11 tests
#
# MDEV-41303 rand() in a semi-join subquery is checked on outer rows
#
create table t1 (a int);
insert into t1 values (1),(2),(3),(100);
create table t2 (c int, d int);
insert into t2 select 1, 1 from seq_1_to_80;
set @save_optimizer_switch= @@optimizer_switch;
set optimizer_switch='firstmatch=off';
# The subquery must check rand(1) < 0.09 on the 80 rows of t2.
# Must produce count(*)=1, not 0.
select count(*) from t1
where t1.a in (select c from t2 where rand(1) < 0.09);
count(*)
1
# Warning must have "<materialize>(...) JOIN..." and not
# "`test`.`t1` semi join (`test`.`t2`)"
explain extended
select count(*) from t1
where t1.a in (select c from t2 where rand(1) < 0.09);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 80 100.00 Using where
Warnings:
Note 1003 /* select#1 */ select count(0) AS `count(*)` from <materialize> (/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where rand(1) < 0.09) join `test`.`t1` where `<subquery2>`.`c` = `test`.`t1`.`a`
# rand() in the outer WHERE does not prevent the conversion to a
# semi-join.
explain extended
select count(*) from t1
where rand(1) < 2 and t1.a in (select c from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 80 100.00
Warnings:
Note 1003 select count(0) AS `count(*)` from `test`.`t1` semi join (`test`.`t2`) where rand(1) < 2
set optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
# end of 11.4 tests
set @subselect_mat_test_optimizer_switch_value=null;
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';

View File

@@ -2782,3 +2782,43 @@ c
0
DROP TABLE t1;
# end of 10.11 tests
#
# MDEV-41303 rand() in a semi-join subquery is checked on outer rows
#
create table t1 (a int);
insert into t1 values (1),(2),(3),(100);
create table t2 (c int, d int);
insert into t2 select 1, 1 from seq_1_to_80;
set @save_optimizer_switch= @@optimizer_switch;
set optimizer_switch='firstmatch=off';
# The subquery must check rand(1) < 0.09 on the 80 rows of t2.
# Must produce count(*)=1, not 0.
select count(*) from t1
where t1.a in (select c from t2 where rand(1) < 0.09);
count(*)
1
# Warning must have "<materialize>(...) JOIN..." and not
# "`test`.`t1` semi join (`test`.`t2`)"
explain extended
select count(*) from t1
where t1.a in (select c from t2 where rand(1) < 0.09);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 80 100.00 Using where
Warnings:
Note 1003 /* select#1 */ select count(0) AS `count(*)` from <materialize> (/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where rand(1) < 0.09) join `test`.`t1` where `<subquery2>`.`c` = `test`.`t1`.`a`
# rand() in the outer WHERE does not prevent the conversion to a
# semi-join.
explain extended
select count(*) from t1
where rand(1) < 2 and t1.a in (select c from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 80 100.00
Warnings:
Note 1003 select count(0) AS `count(*)` from `test`.`t1` semi join (`test`.`t2`) where rand(1) < 2
set optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
# end of 11.4 tests

View File

@@ -2480,3 +2480,36 @@ SELECT * FROM t1 WHERE (0,0) IN (SELECT MAX(c),MIN(c) FROM t1);
DROP TABLE t1;
--echo # end of 10.11 tests
--echo #
--echo # MDEV-41303 rand() in a semi-join subquery is checked on outer rows
--echo #
create table t1 (a int);
insert into t1 values (1),(2),(3),(100);
create table t2 (c int, d int);
insert into t2 select 1, 1 from seq_1_to_80;
set @save_optimizer_switch= @@optimizer_switch;
set optimizer_switch='firstmatch=off';
--echo # The subquery must check rand(1) < 0.09 on the 80 rows of t2.
--echo # Must produce count(*)=1, not 0.
select count(*) from t1
where t1.a in (select c from t2 where rand(1) < 0.09);
--echo # Warning must have "<materialize>(...) JOIN..." and not
--echo # "`test`.`t1` semi join (`test`.`t2`)"
explain extended
select count(*) from t1
where t1.a in (select c from t2 where rand(1) < 0.09);
--echo # rand() in the outer WHERE does not prevent the conversion to a
--echo # semi-join.
explain extended
select count(*) from t1
where rand(1) < 2 and t1.a in (select c from t2);
set optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
--echo # end of 11.4 tests

View File

@@ -4841,5 +4841,36 @@ c1 c2
2 2
DROP TABLE t1;
#
# MDEV-28509: Access null pointer during add_key_field call
#
CREATE TABLE t1 (i INT);
INSERT INTO t1 VALUES (1),(5),(7),(1);
WITH cte AS (SELECT i FROM (SELECT i FROM t1 GROUP BY i) dt WINDOW w AS (PARTITION BY i))
SELECT a.i FROM cte a JOIN cte b ON a.i=b.i WHERE a.i != 5;
i
1
7
# The same crash occurs when the WHERE uses < instead of !=.
WITH cte AS (SELECT i FROM (SELECT i FROM t1 GROUP BY i) dt WINDOW w AS (PARTITION BY i))
SELECT a.i FROM cte a JOIN cte b ON a.i=b.i WHERE a.i < 5;
i
1
SET @save_sql_mode= @@sql_mode;
SET sql_mode= ONLY_FULL_GROUP_BY;
WITH cte AS (SELECT i FROM (SELECT i FROM t1 GROUP BY i) dt WINDOW w AS (PARTITION BY i))
SELECT a.i FROM cte a JOIN cte b ON a.i=b.i WHERE a.i != 5;
i
1
7
WITH cte AS (SELECT i FROM (SELECT i FROM t1 GROUP BY i) dt WINDOW w AS (PARTITION BY i))
SELECT a.i FROM cte a JOIN cte b ON a.i=b.i WHERE a.i < 5;
i
1
# An unreferenced WINDOW does not exempt b.i from ONLY_FULL_GROUP_BY.
SELECT b.i FROM t1 a, t1 b GROUP BY a.i WINDOW w AS (PARTITION BY a.i);
ERROR 42000: 'test.b.i' isn't in GROUP BY
SET @@sql_mode= @save_sql_mode;
DROP TABLE t1;
#
# End of 10.11 tests
#

View File

@@ -3120,6 +3120,33 @@ from t1;
DROP TABLE t1;
--echo #
--echo # MDEV-28509: Access null pointer during add_key_field call
--echo #
CREATE TABLE t1 (i INT);
INSERT INTO t1 VALUES (1),(5),(7),(1);
WITH cte AS (SELECT i FROM (SELECT i FROM t1 GROUP BY i) dt WINDOW w AS (PARTITION BY i))
SELECT a.i FROM cte a JOIN cte b ON a.i=b.i WHERE a.i != 5;
--echo # The same crash occurs when the WHERE uses < instead of !=.
WITH cte AS (SELECT i FROM (SELECT i FROM t1 GROUP BY i) dt WINDOW w AS (PARTITION BY i))
SELECT a.i FROM cte a JOIN cte b ON a.i=b.i WHERE a.i < 5;
SET @save_sql_mode= @@sql_mode;
SET sql_mode= ONLY_FULL_GROUP_BY;
WITH cte AS (SELECT i FROM (SELECT i FROM t1 GROUP BY i) dt WINDOW w AS (PARTITION BY i))
SELECT a.i FROM cte a JOIN cte b ON a.i=b.i WHERE a.i != 5;
WITH cte AS (SELECT i FROM (SELECT i FROM t1 GROUP BY i) dt WINDOW w AS (PARTITION BY i))
SELECT a.i FROM cte a JOIN cte b ON a.i=b.i WHERE a.i < 5;
--echo # An unreferenced WINDOW does not exempt b.i from ONLY_FULL_GROUP_BY.
--error ER_WRONG_FIELD_WITH_GROUP
SELECT b.i FROM t1 a, t1 b GROUP BY a.i WINDOW w AS (PARTITION BY a.i);
SET @@sql_mode= @save_sql_mode;
DROP TABLE t1;
--echo #
--echo # End of 10.11 tests
--echo #

View File

@@ -115,3 +115,24 @@ pk a b bit_or bit_and bit_xor
8 2 16 208 0 192
drop table t1;
drop table t2;
#
# MDEV-40689: Sliding bit aggregates with NULL inputs
#
CREATE TABLE t1 (pk INT PRIMARY KEY,a INT,b INT);
INSERT INTO t1 VALUES (1,0,NULL),(2,0,1),(3,0,2),(4,0,NULL),(5,0,3),(6,1,7),(7,1,NULL),(8,1,6),(9,1,0),(10,1,5),(11,1,NULL),(12,1,NULL);
SELECT pk,b,BIT_AND(b) OVER w AS bit_and,BIT_OR(b) OVER w AS bit_or,BIT_XOR(b) OVER w AS bit_xor FROM t1 WINDOW w AS (ORDER BY pk ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) ORDER BY pk;
pk b bit_and bit_or bit_xor
1 NULL 18446744073709551615 0 0
2 1 1 1 1
3 2 0 3 3
4 NULL 2 2 2
5 3 3 3 3
6 7 3 7 4
7 NULL 7 7 7
8 6 6 6 6
9 0 0 6 6
10 5 0 5 5
11 NULL 5 5 5
12 NULL 18446744073709551615 0 0
DROP TABLE t1;
# End of 11.4 tests

View File

@@ -87,3 +87,12 @@ from t2;
drop table t1;
drop table t2;
--echo #
--echo # MDEV-40689: Sliding bit aggregates with NULL inputs
--echo #
CREATE TABLE t1 (pk INT PRIMARY KEY,a INT,b INT);
INSERT INTO t1 VALUES (1,0,NULL),(2,0,1),(3,0,2),(4,0,NULL),(5,0,3),(6,1,7),(7,1,NULL),(8,1,6),(9,1,0),(10,1,5),(11,1,NULL),(12,1,NULL);
SELECT pk,b,BIT_AND(b) OVER w AS bit_and,BIT_OR(b) OVER w AS bit_or,BIT_XOR(b) OVER w AS bit_xor FROM t1 WINDOW w AS (ORDER BY pk ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) ORDER BY pk;
DROP TABLE t1;
--echo # End of 11.4 tests

View File

@@ -49,6 +49,7 @@ sub skip_combinations {
$skip{'include/not_windows.inc'} = 'Requires not Windows' if IS_WINDOWS;
$skip{'include/not_aix.inc'} = 'Requires not AIX' if IS_AIX;
$skip{'include/not_mac.inc'} = 'Requires not macOS' if IS_MAC;
$skip{'include/not_ssl.inc'} = 'Skipped if --ssl' if $::opt_ssl;
$skip{'main/plugin_loaderr.test'} = 'needs compiled-in innodb'

View File

@@ -1,11 +1,11 @@
RESET MASTER;
"engine: aria crash point: ddl_log_drop_after_drop_tables position: 1"
master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `tABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB`,`tACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC`,`tADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD`,`tAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE`,`tAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF`,`tAGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG`,`tAHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH`,`tAIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII`,`tAJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ`,`tAKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK`,`tALLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL` /* generated by ddl recovery */
master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `tABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBv`,`tACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCv`,`tADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDv`,`tAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEv`,`tAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFv`,`tAGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGv`,`tAHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHv`,`tAIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIv`,`tAJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJv`,`tAKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKv` /* generated by ddl recovery */
master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `tAMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM`,`tANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN`,`tAOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO`,`tAPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP`,`tAQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ`,`tARRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR`,`tASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS`,`tATTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT`,`tAUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU`,`tAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV`,`tAWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW` /* generated by ddl recovery */
master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `tALLLLLLLLLLLLLLLLLLLLLLLLLLLLLLv`,`tAMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMv`,`tANNNNNNNNNNNNNNNNNNNNNNNNNNNNNNv`,`tAOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOv`,`tAPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPv`,`tAQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQv`,`tARRRRRRRRRRRRRRRRRRRRRRRRRRRRRRv`,`tASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSv`,`tATTTTTTTTTTTTTTTTTTTTTTTTTTTTTTv`,`tAUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUv`,`tAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVv` /* generated by ddl recovery */
master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `tAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`,`tAYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY`,`tAZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ`,`tBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`,`tBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB`,`tBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC`,`tBDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD`,`tBEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE` /* generated by ddl recovery */
master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `tAWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWv`,`tAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXv`,`tAYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYv`,`tAZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZv`,`tBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv`,`tBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBv`,`tBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCv`,`tBDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDv`,`tBEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEv` /* generated by ddl recovery */
master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `tabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb`,`tacccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc`,`tadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd`,`taeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee`,`taffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`,`tagggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg`,`tahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh`,`taiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii`,`tajjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj`,`takkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk`,`tallllllllllllllllllllllllllllllllllllllllllllllllllllllllllll` /* generated by ddl recovery */
master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `tabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbv`,`taccccccccccccccccccccccccccccccv`,`taddddddddddddddddddddddddddddddv`,`taeeeeeeeeeeeeeeeeeeeeeeeeeeeeeev`,`taffffffffffffffffffffffffffffffv`,`taggggggggggggggggggggggggggggggv`,`tahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhv`,`taiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiv`,`tajjjjjjjjjjjjjjjjjjjjjjjjjjjjjjv`,`takkkkkkkkkkkkkkkkkkkkkkkkkkkkkkv` /* generated by ddl recovery */
master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `tammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm`,`tannnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn`,`taoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo`,`tapppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp`,`taqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq`,`tarrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr`,`tassssssssssssssssssssssssssssssssssssssssssssssssssssssssssss`,`tatttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt`,`tauuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu`,`tavvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv`,`tawwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww` /* generated by ddl recovery */
master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `tallllllllllllllllllllllllllllllv`,`tammmmmmmmmmmmmmmmmmmmmmmmmmmmmmv`,`tannnnnnnnnnnnnnnnnnnnnnnnnnnnnnv`,`taoooooooooooooooooooooooooooooov`,`tappppppppppppppppppppppppppppppv`,`taqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqv`,`tarrrrrrrrrrrrrrrrrrrrrrrrrrrrrrv`,`tassssssssssssssssssssssssssssssv`,`tattttttttttttttttttttttttttttttv`,`tauuuuuuuuuuuuuuuuuuuuuuuuuuuuuuv`,`tavvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv`,`tawwwwwwwwwwwwwwwwwwwwwwwwwwwwwwv` /* generated by ddl recovery */
master-bin.000002 # Query # # use `test2`; DROP TABLE IF EXISTS `taxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`,`tayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy`,`tazzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz`,`tbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,`tbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb`,`tbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc`,`tbdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd`,`tbeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee` /* generated by ddl recovery */
master-bin.000002 # Query # # use `test2`; DROP VIEW IF EXISTS `taxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxv`,`tayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyv`,`tazzzzzzzzzzzzzzzzzzzzzzzzzzzzzzv`,`tbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaav`,`tbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbv`,`tbccccccccccccccccccccccccccccccv`,`tbddddddddddddddddddddddddddddddv`,`tbeeeeeeeeeeeeeeeeeeeeeeeeeeeeeev` /* generated by ddl recovery */
"engine: aria crash point: ddl_log_drop_before_binlog position: 1"
master-bin.000002 # Query # # DROP DATABASE IF EXISTS `test2` /* generated by ddl recovery */
Warnings:

View File

@@ -58,8 +58,10 @@ while ($e < $engine_count)
while ($t < $max_tables)
{
inc $t;
let $name=`select concat("t",char(floor(65+$t/26)),repeat(char(65+mod($t,26)),60))`;
let $view=`select concat("t",char(floor(65+$t/26)),repeat(char(65+mod($t,26)),30),'v')`;
# Generate the names in lower case so that they are unchanged by a
# lower_case_table_names setting of 1 or 2.
let $name=`select concat("t",char(floor(ascii('a')+$t/26)),repeat(char(ascii('a')+mod($t,26)),60))`;
let $view=`select concat("t",char(floor(ascii('a')+$t/26)),repeat(char(ascii('a')+mod($t,26)),30),'v')`;
--eval create table $name (a int not null) $extra_option
--eval create view $view as select * from $name
}

View File

@@ -577,9 +577,9 @@ if ($is_remote == 0)
--echo # Error Case 3:
--echo # A GTID --start-position with any sequence numbers that are not
--echo # eventually processed results in error
--echo # MYSQL_BINLOG BINLOG_FILE_PARAM2 --start-position=0-1-8,1-2-6 > tmp_out_ 2> err_out_
--echo # MYSQL_BINLOG BINLOG_FILE_PARAM2 --start-position=0-1-8,1-2-6 --gtid-strict-mode > tmp_out_ 2> err_out_
--error 1
--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM2 --start-position=0-1-8,1-2-6 > $tmp_out_ 2> $err_out_
--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM2 --start-position=0-1-8,1-2-6 --gtid-strict-mode > $tmp_out_ 2> $err_out_
if ($is_remote == 1)
{
--let SEARCH_PATTERN=ERROR: Got error reading packet from server

View File

@@ -1,4 +0,0 @@
!include include/default_my.cnf
[mariadbd]
slave_connections_needed_for_purge=0

View File

@@ -208,7 +208,7 @@ FOUND 1 /ERROR: Binary logs are missing data for domain 0/ in err.out
# Error Case 3:
# A GTID --start-position with any sequence numbers that are not
# eventually processed results in error
# MYSQL_BINLOG BINLOG_FILE_PARAM2 --start-position=0-1-8,1-2-6 > tmp_out_ 2> err_out_
# MYSQL_BINLOG BINLOG_FILE_PARAM2 --start-position=0-1-8,1-2-6 --gtid-strict-mode > tmp_out_ 2> err_out_
FOUND 2 /ERROR: Binary logs never reached expected GTID state/ in err.out
######################################
# Test Group 2
@@ -440,7 +440,7 @@ FOUND 1 /ERROR: Got error reading packet from server/ in err.out
# Error Case 3:
# A GTID --start-position with any sequence numbers that are not
# eventually processed results in error
# MYSQL_BINLOG BINLOG_FILE_PARAM2 --start-position=0-1-8,1-2-6 > tmp_out_ 2> err_out_
# MYSQL_BINLOG BINLOG_FILE_PARAM2 --start-position=0-1-8,1-2-6 --gtid-strict-mode > tmp_out_ 2> err_out_
FOUND 1 /ERROR: Got error reading packet from server/ in err.out
#
# Remote-only cleanup from error cases

View File

@@ -0,0 +1,9 @@
reset master;
create table t1 (a int);
create table t2 (a int);
drop table t1, t2;
flush binary logs;
drop table if exists t1, t2;
Warnings:
Note 1051 Unknown table 'test.t1,test.t2'
flush binary logs;

View File

@@ -120,6 +120,17 @@ use warnings;
use Fcntl qw(:DEFAULT :seek);
sysopen F, $ENV{FILE_TO_CORRUPT}, O_RDWR
or die "Cannot open file $ENV{FILE_TO_CORRUPT}: $!\n";
# Wait for the index file to be written (this happens asynchronously).
my @s;
for (1 .. 500) {
@s= stat F;
last if $s[7] >= 17; # Check file size
select(undef, undef, undef, 0.1); # Portable sub-second sleep
}
die "Index file $ENV{FILE_TO_CORRUPT} never grew past $s[7] bytes\n"
unless $s[7] >= 17;
# Corrupt the flag byte with an unused flag.
sysseek(F, 16, SEEK_SET)
or die "Cannot seek file: $!\n";

View File

@@ -0,0 +1,36 @@
--source include/have_log_bin.inc
#
# MDEV-29803: Unexpected ERROR: Found out of order GTID after replaying
# binlog read from remote server, then reading the resulting local binlog.
#
# When mysqlbinlog replays a remote binlog into a server, and we then
# read back the local binlog files, the replayed events reset the GTID
# sequence, which causes a "Found out of order GTID" error if
# --gtid-strict-mode is enabled.
#
# The fix is to change the default of --gtid-strict-mode to OFF so that
# mysqlbinlog does not refuse to display events by default.
#
reset master;
create table t1 (a int);
create table t2 (a int);
drop table t1, t2;
flush binary logs;
# Replay remote binlog into this server
--exec $MYSQL_BINLOG --read-from-remote-server -uroot --protocol=tcp --port=$MASTER_MYPORT master-bin.000001 | $MYSQL test 2>&1
drop table if exists t1, t2;
flush binary logs;
--let $datadir= `select @@datadir`
# With the fix, the default --gtid-strict-mode=OFF allows reading both binlog
# files without error, even though replayed events create out-of-order GTIDs.
--exec $MYSQL_BINLOG $datadir/master-bin.000001 $datadir/master-bin.000002 > /dev/null 2>&1
# Explicitly enabling --gtid-strict-mode should still produce an error
--error 1
--exec $MYSQL_BINLOG --gtid-strict-mode $datadir/master-bin.000001 $datadir/master-bin.000002 > /dev/null 2>&1

View File

@@ -1 +0,0 @@
--slave_connections_needed_for_purge=0

View File

@@ -3376,8 +3376,44 @@ DROP FUNCTION f1_deterministic;
DROP FUNCTION f2_not_deterministic;
DROP PACKAGE pkg1;
#
# Start of 11.7 tests
# MDEV-38861 heap-use-after-free in Prepared_statement::execute()
#
SET sql_mode=ORACLE;
# DROP PACKAGE BODY of the running package
CREATE PACKAGE pkg AS
PROCEDURE p1;
END$$
CREATE PACKAGE BODY pkg AS
PROCEDURE p1 AS
BEGIN
EXECUTE IMMEDIATE 'DROP PACKAGE BODY pkg';
SELECT 'body survived' AS state;
END;
END$$
CALL pkg.p1();
state
body survived
CALL pkg.p1();
ERROR 42000: PROCEDURE test.pkg.p1 does not exist
DROP PACKAGE pkg;
# CREATE OR REPLACE PACKAGE BODY of the running package
CREATE PACKAGE pkg AS
PROCEDURE p1;
END$$
CREATE PACKAGE BODY pkg AS
PROCEDURE p1 AS
BEGIN
EXECUTE IMMEDIATE 'CREATE OR REPLACE PACKAGE BODY pkg AS PROCEDURE p1 AS BEGIN SELECT ''replaced'' AS state; END; END';
SELECT 'body survived' AS state;
END;
END$$
CALL pkg.p1();
state
body survived
CALL pkg.p1();
state
replaced
DROP PACKAGE pkg;
#
# MDEV-12252 ROW data type for stored function return values
#
@@ -3452,6 +3488,4 @@ r.a || ' ' || r.b
1 b1
DROP PACKAGE pkg;
DROP TABLE t1;
#
# End of 11.7 tests
#

View File

@@ -3111,9 +3111,46 @@ DROP FUNCTION f2_not_deterministic;
DROP PACKAGE pkg1;
--echo #
--echo # Start of 11.7 tests
--echo # MDEV-38861 heap-use-after-free in Prepared_statement::execute()
--echo #
SET sql_mode=ORACLE;
--echo # DROP PACKAGE BODY of the running package
DELIMITER $$;
CREATE PACKAGE pkg AS
PROCEDURE p1;
END$$
CREATE PACKAGE BODY pkg AS
PROCEDURE p1 AS
BEGIN
EXECUTE IMMEDIATE 'DROP PACKAGE BODY pkg';
SELECT 'body survived' AS state;
END;
END$$
DELIMITER ;$$
CALL pkg.p1();
--error ER_SP_DOES_NOT_EXIST
CALL pkg.p1();
DROP PACKAGE pkg;
--echo # CREATE OR REPLACE PACKAGE BODY of the running package
DELIMITER $$;
CREATE PACKAGE pkg AS
PROCEDURE p1;
END$$
CREATE PACKAGE BODY pkg AS
PROCEDURE p1 AS
BEGIN
EXECUTE IMMEDIATE 'CREATE OR REPLACE PACKAGE BODY pkg AS PROCEDURE p1 AS BEGIN SELECT ''replaced'' AS state; END; END';
SELECT 'body survived' AS state;
END;
END$$
DELIMITER ;$$
CALL pkg.p1();
CALL pkg.p1();
DROP PACKAGE pkg;
--echo #
--echo # MDEV-12252 ROW data type for stored function return values
--echo #
@@ -3190,6 +3227,4 @@ CALL pkg.p2;
DROP PACKAGE pkg;
DROP TABLE t1;
--echo #
--echo # End of 11.7 tests
--echo #

View File

@@ -110,3 +110,19 @@ f1 f2
5 6
7 8
drop table t1,t2;
#
# MDEV 39795 : Assertion `n_reserved > 0' failed
#
SET GLOBAL innodb_encrypt_tables = ON;
CREATE TABLE t1 (
id INT NOT NULL AUTO_INCREMENT,
col1 INT,
col2 INT,
PRIMARY KEY (id)
) ENGINE=InnoDB ROW_FORMAT = Compact PAGE_COMPRESSED=1;
INSERT INTO t1 (col1, col2) VALUES (10, 100);
SET STATEMENT debug_dbug = 'd,inode_page_decryption_failed' FOR
ALTER TABLE t1 ADD INDEX idx_col1 (col1);
ERROR HY000: Got error 63 'Table is compressed or encrypted but uncompress or decrypt failed.' from InnoDB
SET GLOBAL innodb_encrypt_tables = OFF;
DROP TABLE t1;

View File

@@ -1,3 +1,17 @@
#
# MDEV 39795 : Assertion `n_reserved > 0' failed
#
SET GLOBAL innodb_encrypt_tables = ON;
SET GLOBAL innodb_compression_algorithm = 'none';
CREATE TABLE t1 (
id INT AUTO_INCREMENT PRIMARY KEY,
col1 INT,
col2 INT,
col3 INT
) ENGINE=InnoDB ROW_FORMAT = Compact PAGE_COMPRESSED=1;
INSERT INTO t1 (col1, col2, col3) VALUES (1, 10, 100);
FLUSH TABLES t1 FOR EXPORT;
UNLOCK TABLES;
set global innodb_compression_algorithm = 1;
create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb page_compressed=1;
show warnings;
@@ -86,3 +100,8 @@ drop procedure innodb_insert_proc;
drop table innodb_normal;
drop table innodb_compact;
drop table innodb_dynamic;
ALTER TABLE t1 ADD INDEX idx_col1 (col1);
# restart: --innodb-encrypt-tables=OFF
ALTER TABLE t1 ADD INDEX idx_col2_col3 (col2, col3);
# Cleanup
DROP TABLE t1;

View File

@@ -4847,6 +4847,37 @@ c1 c2
2 2
DROP TABLE t1;
#
# MDEV-28509: Access null pointer during add_key_field call
#
CREATE TABLE t1 (i INT);
INSERT INTO t1 VALUES (1),(5),(7),(1);
WITH cte AS (SELECT i FROM (SELECT i FROM t1 GROUP BY i) dt WINDOW w AS (PARTITION BY i))
SELECT a.i FROM cte a JOIN cte b ON a.i=b.i WHERE a.i != 5;
i
1
7
# The same crash occurs when the WHERE uses < instead of !=.
WITH cte AS (SELECT i FROM (SELECT i FROM t1 GROUP BY i) dt WINDOW w AS (PARTITION BY i))
SELECT a.i FROM cte a JOIN cte b ON a.i=b.i WHERE a.i < 5;
i
1
SET @save_sql_mode= @@sql_mode;
SET sql_mode= ONLY_FULL_GROUP_BY;
WITH cte AS (SELECT i FROM (SELECT i FROM t1 GROUP BY i) dt WINDOW w AS (PARTITION BY i))
SELECT a.i FROM cte a JOIN cte b ON a.i=b.i WHERE a.i != 5;
i
1
7
WITH cte AS (SELECT i FROM (SELECT i FROM t1 GROUP BY i) dt WINDOW w AS (PARTITION BY i))
SELECT a.i FROM cte a JOIN cte b ON a.i=b.i WHERE a.i < 5;
i
1
# An unreferenced WINDOW does not exempt b.i from ONLY_FULL_GROUP_BY.
SELECT b.i FROM t1 a, t1 b GROUP BY a.i WINDOW w AS (PARTITION BY a.i);
ERROR 42000: 'test.b.i' isn't in GROUP BY
SET @@sql_mode= @save_sql_mode;
DROP TABLE t1;
#
# End of 10.11 tests
#
#

View File

@@ -131,3 +131,22 @@ disconnect con1;
select * from t1;
drop table t1,t2;
--echo #
--echo # MDEV 39795 : Assertion `n_reserved > 0' failed
--echo #
SET GLOBAL innodb_encrypt_tables = ON;
CREATE TABLE t1 (
id INT NOT NULL AUTO_INCREMENT,
col1 INT,
col2 INT,
PRIMARY KEY (id)
) ENGINE=InnoDB ROW_FORMAT = Compact PAGE_COMPRESSED=1;
INSERT INTO t1 (col1, col2) VALUES (10, 100);
--error ER_GET_ERRMSG
SET STATEMENT debug_dbug = 'd,inode_page_decryption_failed' FOR
ALTER TABLE t1 ADD INDEX idx_col1 (col1);
# Cleanup
SET GLOBAL innodb_encrypt_tables = OFF;
DROP TABLE t1;

View File

@@ -3,7 +3,29 @@
-- source include/have_file_key_management_plugin.inc
let $innodb_compression_algorithm_orig=`SELECT @@innodb_compression_algorithm`;
let $innodb_encrypt_tables_orig=`SELECT @@innodb_encrypt_tables`;
--echo #
--echo # MDEV 39795 : Assertion `n_reserved > 0' failed
--echo #
SET GLOBAL innodb_encrypt_tables = ON;
SET GLOBAL innodb_compression_algorithm = 'none';
CREATE TABLE t1 (
id INT AUTO_INCREMENT PRIMARY KEY,
col1 INT,
col2 INT,
col3 INT
) ENGINE=InnoDB ROW_FORMAT = Compact PAGE_COMPRESSED=1;
INSERT INTO t1 (col1, col2, col3) VALUES (1, 10, 100);
FLUSH TABLES t1 FOR EXPORT; UNLOCK TABLES;
# continue further test after restart
# reset system
--disable_query_log
EVAL SET GLOBAL innodb_encrypt_tables = $innodb_encrypt_tables_orig;
--enable_query_log
# zlib
set global innodb_compression_algorithm = 1;
@@ -71,3 +93,12 @@ drop table innodb_dynamic;
--disable_query_log
EVAL SET GLOBAL innodb_compression_algorithm = $innodb_compression_algorithm_orig;
--enable_query_log
# Continuing test for MDEV-39795
ALTER TABLE t1 ADD INDEX idx_col1 (col1);
--source include/restart_mysqld.inc
ALTER TABLE t1 ADD INDEX idx_col2_col3 (col2, col3);
--echo # Cleanup
DROP TABLE t1;

View File

@@ -18,6 +18,59 @@ drop table t1;
select * from fed;
Got one of the listed errors
drop table fed;
#
# MDEV-41211 Federated multi_delete skips some records
#
connection slave;
CREATE TABLE federated.t1 (pk INT NOT NULL PRIMARY KEY, a INT);
INSERT INTO federated.t1 VALUES (1,1),(5,5),(9,9);
connection master;
CREATE TABLE federated.t1 (pk INT NOT NULL PRIMARY KEY, a INT)
ENGINE=FEDERATED
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
EXPLAIN DELETE a FROM federated.t1 a, federated.t1 b WHERE a.pk = 5 AND b.pk > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a const PRIMARY PRIMARY 4 const 1
1 SIMPLE b range PRIMARY PRIMARY 4 NULL 2 Using where
DELETE a FROM federated.t1 a, federated.t1 b WHERE a.pk = 5 AND b.pk > 0;
SELECT * FROM federated.t1 ORDER BY pk;
pk a
1 1
9 9
# Both tables are const
EXPLAIN DELETE a FROM federated.t1 a, federated.t1 b WHERE a.pk = 1 AND b.pk = 9;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a const PRIMARY PRIMARY 4 const 1
1 SIMPLE b const PRIMARY PRIMARY 4 const 1
DELETE a FROM federated.t1 a, federated.t1 b WHERE a.pk = 1 AND b.pk = 9;
SELECT * FROM federated.t1 ORDER BY pk;
pk a
9 9
# Multi-table UPDATE with a const target
INSERT INTO federated.t1 VALUES (1,1),(5,5);
EXPLAIN UPDATE federated.t1 a, federated.t1 b SET a.a = 0
WHERE a.pk = 5 AND b.pk > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a const PRIMARY PRIMARY 4 const 1
1 SIMPLE b range PRIMARY PRIMARY 4 NULL 2 Using where
UPDATE federated.t1 a, federated.t1 b SET a.a = 0 WHERE a.pk = 5 AND b.pk > 0;
SELECT * FROM federated.t1 ORDER BY pk;
pk a
1 1
5 0
9 9
connection slave;
SELECT * FROM federated.t1 ORDER BY pk;
pk a
1 1
5 0
9 9
connection master;
DROP TABLE federated.t1;
connection slave;
DROP TABLE federated.t1;
connection master;
# End of 11.4 tests
connection master;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;

View File

@@ -21,5 +21,46 @@ drop table t1;
select * from fed;
drop table fed;
--echo #
--echo # MDEV-41211 Federated multi_delete skips some records
--echo #
connection slave;
CREATE TABLE federated.t1 (pk INT NOT NULL PRIMARY KEY, a INT);
INSERT INTO federated.t1 VALUES (1,1),(5,5),(9,9);
connection master;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE federated.t1 (pk INT NOT NULL PRIMARY KEY, a INT)
ENGINE=FEDERATED
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
EXPLAIN DELETE a FROM federated.t1 a, federated.t1 b WHERE a.pk = 5 AND b.pk > 0;
DELETE a FROM federated.t1 a, federated.t1 b WHERE a.pk = 5 AND b.pk > 0;
SELECT * FROM federated.t1 ORDER BY pk;
--echo # Both tables are const
EXPLAIN DELETE a FROM federated.t1 a, federated.t1 b WHERE a.pk = 1 AND b.pk = 9;
DELETE a FROM federated.t1 a, federated.t1 b WHERE a.pk = 1 AND b.pk = 9;
SELECT * FROM federated.t1 ORDER BY pk;
--echo # Multi-table UPDATE with a const target
INSERT INTO federated.t1 VALUES (1,1),(5,5);
EXPLAIN UPDATE federated.t1 a, federated.t1 b SET a.a = 0
WHERE a.pk = 5 AND b.pk > 0;
UPDATE federated.t1 a, federated.t1 b SET a.a = 0 WHERE a.pk = 5 AND b.pk > 0;
SELECT * FROM federated.t1 ORDER BY pk;
connection slave;
SELECT * FROM federated.t1 ORDER BY pk;
connection master;
DROP TABLE federated.t1;
connection slave;
DROP TABLE federated.t1;
connection master;
--echo # End of 11.4 tests
source include/federated_cleanup.inc;

View File

@@ -1,11 +1,5 @@
connection node_2;
connection node_1;
select @@slave_connections_needed_for_purge;
@@slave_connections_needed_for_purge
0
select VARIABLE_NAME, GLOBAL_VALUE, GLOBAL_VALUE_ORIGIN from information_schema.system_variables where variable_name="slave_connections_needed_for_purge";
VARIABLE_NAME GLOBAL_VALUE GLOBAL_VALUE_ORIGIN
SLAVE_CONNECTIONS_NEEDED_FOR_PURGE 0 AUTO
USE test;
CREATE TABLE t1(c1 INT PRIMARY KEY) ENGINE=INNODB;
INSERT INTO t1 VALUES (1), (2), (3), (4), (5);

View File

@@ -0,0 +1,216 @@
connection node_2;
connection node_1;
connection node_1;
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY, f2 INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1, 0), (3, 0);
connection node_1;
START TRANSACTION;
INSERT INTO t1 VALUES (4, 0);
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
SET SESSION wsrep_sync_wait=0;
# The transaction above must have replicated a fragment, otherwise
# this test degenerates into galera_sequences_bf_kill
SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.wsrep_streaming_log;
EXPECT_1
1
# Block the applier on node #1 and issue a conflicting insert on node #2
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
INSERT INTO t1 VALUES (2, next value for s);
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
# Block the commit monitor and let the local transaction reserve a
# new range of sequence values, which conflicts with the applier
SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_master_enter_sync';
connection node_1;
INSERT INTO t1 VALUES (5, next value for s);
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
# Release the applier
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
# Release the local transaction
SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_master_enter_sync';
connection node_1;
COMMIT;
# Both nodes must have the same table contents. The sequence values
# are node specific, each node adjusts them to its own
# auto_increment_offset
connection node_1;
SELECT * FROM t1;
f1 f2
1 0
2 2
3 0
4 0
5 1
SELECT LASTVAL(s);
LASTVAL(s)
1
SELECT next_not_cached_value FROM s;
next_not_cached_value
11
connection node_2;
SELECT * FROM t1;
f1 f2
1 0
2 2
3 0
4 0
5 1
SELECT LASTVAL(s);
LASTVAL(s)
2
SELECT next_not_cached_value FROM s;
next_not_cached_value
12
# All fragments must have been removed on commit
connection node_1a;
SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log;
EXPECT_0
0
connection node_1;
DROP SEQUENCE s;
DROP TABLE t1;
connection node_1;
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY, f2 INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1, 0), (3, 0);
connection node_1;
START TRANSACTION;
INSERT INTO t1 VALUES (4, 0);
SELECT * FROM t1 WHERE f1 > 0 FOR UPDATE;
f1 f2
1 0
3 0
4 0
# Block the applier on node #1 and issue a conflicting insert on node #2
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
INSERT INTO t1 VALUES (2, next value for s);
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
# Block the commit monitor and let the local transaction reserve a
# new range of sequence values, which conflicts with the applier
SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_master_enter_sync';
connection node_1;
INSERT INTO t1 VALUES (5, next value for s);
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,abort_trx_end';
# Release the applier
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
# Wait until the applier has BF aborted the local transaction
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
# Release the applier and the local transaction
SET GLOBAL wsrep_provider_options = 'signal=abort_trx_end';
SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_master_enter_sync';
# The streaming transaction is BF aborted and rolled back
connection node_1;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
ROLLBACK;
# The rollback must have removed the already replicated fragments
# from both nodes, so neither node has row 4
connection node_1;
SELECT * FROM t1;
f1 f2
1 0
2 2
3 0
connection node_2;
SELECT * FROM t1;
f1 f2
1 0
2 2
3 0
connection node_1a;
SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log;
EXPECT_0
0
connection node_1;
DROP SEQUENCE s;
DROP TABLE t1;
connection node_1;
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY, f2 BIGINT) ENGINE=InnoDB;
connection node_1;
SET SESSION wsrep_trx_fragment_unit='rows';
SET SESSION wsrep_trx_fragment_size=3;
START TRANSACTION;
INSERT INTO t1 VALUES (100, NULL);
# Block the applier on node #1 and let node #2 reserve several
# ranges of its own
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
INSERT INTO t1 VALUES (201,NEXT VALUE FOR s),(202,NEXT VALUE FOR s),(203,NEXT VALUE FOR s),(204,NEXT VALUE FOR s),(205,NEXT VALUE FOR s),(206,NEXT VALUE FOR s),(207,NEXT VALUE FOR s),(208,NEXT VALUE FOR s),(209,NEXT VALUE FOR s),(210,NEXT VALUE FOR s),(211,NEXT VALUE FOR s),(212,NEXT VALUE FOR s);
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
# Block the commit monitor and let the local transaction reserve
# several ranges of its own, spread over several fragments
SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_master_enter_sync';
connection node_1;
INSERT INTO t1 VALUES (101,NEXT VALUE FOR s),(102,NEXT VALUE FOR s),(103,NEXT VALUE FOR s),(104,NEXT VALUE FOR s),(105,NEXT VALUE FOR s),(106,NEXT VALUE FOR s),(107,NEXT VALUE FOR s),(108,NEXT VALUE FOR s),(109,NEXT VALUE FOR s),(110,NEXT VALUE FOR s),(111,NEXT VALUE FOR s),(112,NEXT VALUE FOR s);
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
# Release the applier
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
# Release the local transaction
SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_master_enter_sync';
connection node_1;
COMMIT;
# Both nodes reserved more than one cache range
connection node_1;
SELECT next_not_cached_value > 21 AS EXPECT_1 FROM s;
EXPECT_1
1
# No value was handed out twice, and the two nodes used disjoint
# value spaces
SELECT COUNT(*) AS EXPECT_25 FROM t1;
EXPECT_25
25
SELECT COUNT(f2) = COUNT(DISTINCT f2) AS EXPECT_1 FROM t1;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_0 FROM t1 WHERE f1 < 200 AND MOD(f2, 2) != 1;
EXPECT_0
0
SELECT COUNT(*) AS EXPECT_0 FROM t1 WHERE f1 > 200 AND MOD(f2, 2) != 0;
EXPECT_0
0
connection node_2;
SELECT COUNT(*) AS EXPECT_25 FROM t1;
EXPECT_25
25
SELECT COUNT(f2) = COUNT(DISTINCT f2) AS EXPECT_1 FROM t1;
EXPECT_1
1
# All fragments must have been removed on commit
connection node_1a;
SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log;
EXPECT_0
0
connection node_1;
SET SESSION wsrep_trx_fragment_size=DEFAULT;
SET SESSION wsrep_trx_fragment_unit=DEFAULT;
DROP SEQUENCE s;
DROP TABLE t1;
connection node_1;
wsrep_local_replays
1
disconnect node_1a;

View File

@@ -31,6 +31,8 @@ SELECT LASTVAL(s);
LASTVAL(s)
12
SET GLOBAL innodb_log_checkpoint_now=1;
connection node_1_ctrl;
# Wait for the next_not_cached_value = 21 FROM s (1_ctrl)
connection node_1;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);

View File

@@ -1,9 +1,6 @@
--source include/galera_cluster.inc
--source include/have_innodb.inc
select @@slave_connections_needed_for_purge;
select VARIABLE_NAME, GLOBAL_VALUE, GLOBAL_VALUE_ORIGIN from information_schema.system_variables where variable_name="slave_connections_needed_for_purge";
USE test;
CREATE TABLE t1(c1 INT PRIMARY KEY) ENGINE=INNODB;
INSERT INTO t1 VALUES (1), (2), (3), (4), (5);

View File

@@ -0,0 +1,12 @@
!include ../galera_2nodes.cnf
[mysqld.1]
wsrep-auto-increment-control=OFF
auto-increment-increment=2
auto-increment-offset=1
wsrep_trx_fragment_size=1
[mysqld.2]
wsrep-auto-increment-control=OFF
auto-increment-increment=2
auto-increment-offset=2

View File

@@ -0,0 +1,5 @@
[binlogon]
log-bin
log-slave-updates
[binlogoff]

View File

@@ -0,0 +1,308 @@
#
# Test a conflict on an InnoDB sequence between a streaming replication
# transaction and an applier.
#
# The local transaction reserves a new range of sequence values, which
# writes the sequence table while holding SEQUENCE::mutex. At the same
# time an applier applies a sequence update originating from the other
# node, and needs the same mutex in SEQUENCE::set_value().
#
# If the sequence table write replicates a streaming fragment while the
# mutex is held, that fragment waits for commit order behind the applier's
# write set, while the applier waits for the mutex. The node deadlocks and
# the BF abort of the local transaction can never be delivered.
#
# This is specific to streaming replication. Without it the write set is
# replicated at COMMIT, after SEQUENCE::mutex has been released.
#
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_sequence.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/galera_have_debug_sync.inc
--disable_ps2_protocol
#
# We create an InnoDB sequence with a small cache that is then used as
# value for a column in the table. The cache is exhausted immediately, so
# that the first NEXTVAL on each node has to write the sequence table.
#
--connection node_1
--let $wsrep_local_replays_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'`
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY, f2 INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1, 0), (3, 0);
--connection node_1
START TRANSACTION;
INSERT INTO t1 VALUES (4, 0); # No conflict in cert
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
SET SESSION wsrep_sync_wait=0;
--echo # The transaction above must have replicated a fragment, otherwise
--echo # this test degenerates into galera_sequences_bf_kill
SELECT COUNT(*) > 0 AS EXPECT_1 FROM mysql.wsrep_streaming_log;
--echo # Block the applier on node #1 and issue a conflicting insert on node #2
--let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_set_sync_point.inc
#
# Send conflicting INSERT. This updates the sequence table on node #2,
# and the applier on node #1 will have to apply that update.
#
--connection node_2
INSERT INTO t1 VALUES (2, next value for s);
--connection node_1a
--source include/galera_wait_sync_point.inc
--source include/galera_clear_sync_point.inc
--echo # Block the commit monitor and let the local transaction reserve a
--echo # new range of sequence values, which conflicts with the applier
--let $galera_sync_point = commit_monitor_master_enter_sync
--source include/galera_set_sync_point.inc
--connection node_1
--send INSERT INTO t1 VALUES (5, next value for s)
--connection node_1a
--let $galera_sync_point = apply_monitor_slave_enter_sync commit_monitor_master_enter_sync
--source include/galera_wait_sync_point.inc
--source include/galera_clear_sync_point.inc
--echo # Release the applier
--let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_signal_sync_point.inc
--echo # Release the local transaction
--let $galera_sync_point = commit_monitor_master_enter_sync
--source include/galera_signal_sync_point.inc
--connection node_1
--reap
COMMIT;
--echo # Both nodes must have the same table contents. The sequence values
--echo # are node specific, each node adjusts them to its own
--echo # auto_increment_offset
--connection node_1
SELECT * FROM t1;
SELECT LASTVAL(s);
SELECT next_not_cached_value FROM s;
--connection node_2
SELECT * FROM t1;
SELECT LASTVAL(s);
SELECT next_not_cached_value FROM s;
--echo # All fragments must have been removed on commit
--connection node_1a
--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log;
--connection node_1
DROP SEQUENCE s;
DROP TABLE t1;
#
# Case 2: the same sequence conflict, but this time the applier also has
# to BF abort the local transaction over a gap lock. A streaming
# transaction cannot be replayed, so it is rolled back and the client
# gets ER_LOCK_DEADLOCK.
#
--connection node_1
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY, f2 INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1, 0), (3, 0);
--connection node_1
START TRANSACTION;
INSERT INTO t1 VALUES (4, 0);
SELECT * FROM t1 WHERE f1 > 0 FOR UPDATE; # Should cause GAP lock between 1 and 3
--echo # Block the applier on node #1 and issue a conflicting insert on node #2
--connection node_1a
--let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_set_sync_point.inc
--connection node_2
INSERT INTO t1 VALUES (2, next value for s); # BF aborts on the GAP lock
--connection node_1a
--source include/galera_wait_sync_point.inc
--source include/galera_clear_sync_point.inc
--echo # Block the commit monitor and let the local transaction reserve a
--echo # new range of sequence values, which conflicts with the applier
--let $galera_sync_point = commit_monitor_master_enter_sync
--source include/galera_set_sync_point.inc
--connection node_1
--send INSERT INTO t1 VALUES (5, next value for s)
--connection node_1a
--let $galera_sync_point = apply_monitor_slave_enter_sync commit_monitor_master_enter_sync
--source include/galera_wait_sync_point.inc
--source include/galera_clear_sync_point.inc
#
# Arm a sync point in the BF abort path before releasing the applier.
# Otherwise the local transaction could be released from the commit
# monitor and finish its fragment before the applier has reached the gap
# lock conflict, and no BF abort would be delivered at all. The sibling
# test galera_sequences_bf_kill.test uses the same handshake.
#
--let $galera_sync_point = abort_trx_end
--source include/galera_set_sync_point.inc
--echo # Release the applier
--let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_signal_sync_point.inc
--echo # Wait until the applier has BF aborted the local transaction
--let $galera_sync_point = abort_trx_end commit_monitor_master_enter_sync
--source include/galera_wait_sync_point.inc
--source include/galera_clear_sync_point.inc
--echo # Release the applier and the local transaction
--let $galera_sync_point = abort_trx_end
--source include/galera_signal_sync_point.inc
--let $galera_sync_point = commit_monitor_master_enter_sync
--source include/galera_signal_sync_point.inc
--echo # The streaming transaction is BF aborted and rolled back
--connection node_1
--error ER_LOCK_DEADLOCK
--reap
ROLLBACK;
--echo # The rollback must have removed the already replicated fragments
--echo # from both nodes, so neither node has row 4
--connection node_1
SELECT * FROM t1;
--connection node_2
SELECT * FROM t1;
--connection node_1a
--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log;
--connection node_1
DROP SEQUENCE s;
DROP TABLE t1;
#
# Case 3: several rows per fragment and several cache range reservations
# inside one streaming transaction, on both nodes at the same time.
#
# The cases above stream one row per fragment and reserve a single cache
# range on each side. Here both nodes insert twelve rows, so with CACHE=5
# each of them exhausts its cache three times and writes the sequence
# table three times, every time under SEQUENCE::mutex. On node #1 the
# fragment unit is rows and the fragment size is three, so those writes
# land inside fragments that carry several rows.
#
# The choreography is the one from case 1: the applier on node #1 is held
# back until the local transaction has reserved its ranges and is parked
# in the commit monitor, which is the state the deadlock needed. Both
# transactions must commit, and the values the two nodes handed out must
# be disjoint - each node reserves whole cache ranges and picks values
# from them by its own auto_increment_offset, node #1 the odd ones and
# node #2 the even ones.
#
--connection node_1
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY, f2 BIGINT) ENGINE=InnoDB;
--connection node_1
SET SESSION wsrep_trx_fragment_unit='rows';
SET SESSION wsrep_trx_fragment_size=3;
START TRANSACTION;
INSERT INTO t1 VALUES (100, NULL); # No conflict in cert
--echo # Block the applier on node #1 and let node #2 reserve several
--echo # ranges of its own
--connection node_1a
--let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_set_sync_point.inc
--connection node_2
INSERT INTO t1 VALUES (201,NEXT VALUE FOR s),(202,NEXT VALUE FOR s),(203,NEXT VALUE FOR s),(204,NEXT VALUE FOR s),(205,NEXT VALUE FOR s),(206,NEXT VALUE FOR s),(207,NEXT VALUE FOR s),(208,NEXT VALUE FOR s),(209,NEXT VALUE FOR s),(210,NEXT VALUE FOR s),(211,NEXT VALUE FOR s),(212,NEXT VALUE FOR s);
--connection node_1a
--source include/galera_wait_sync_point.inc
--source include/galera_clear_sync_point.inc
--echo # Block the commit monitor and let the local transaction reserve
--echo # several ranges of its own, spread over several fragments
--let $galera_sync_point = commit_monitor_master_enter_sync
--source include/galera_set_sync_point.inc
--connection node_1
--send INSERT INTO t1 VALUES (101,NEXT VALUE FOR s),(102,NEXT VALUE FOR s),(103,NEXT VALUE FOR s),(104,NEXT VALUE FOR s),(105,NEXT VALUE FOR s),(106,NEXT VALUE FOR s),(107,NEXT VALUE FOR s),(108,NEXT VALUE FOR s),(109,NEXT VALUE FOR s),(110,NEXT VALUE FOR s),(111,NEXT VALUE FOR s),(112,NEXT VALUE FOR s)
--connection node_1a
--let $galera_sync_point = apply_monitor_slave_enter_sync commit_monitor_master_enter_sync
--source include/galera_wait_sync_point.inc
--source include/galera_clear_sync_point.inc
--echo # Release the applier
--let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_signal_sync_point.inc
--echo # Release the local transaction
--let $galera_sync_point = commit_monitor_master_enter_sync
--source include/galera_signal_sync_point.inc
--connection node_1
--reap
COMMIT;
--echo # Both nodes reserved more than one cache range
--connection node_1
--let $wait_condition = SELECT COUNT(*) = 25 FROM t1
--source include/wait_condition.inc
SELECT next_not_cached_value > 21 AS EXPECT_1 FROM s;
--echo # No value was handed out twice, and the two nodes used disjoint
--echo # value spaces
SELECT COUNT(*) AS EXPECT_25 FROM t1;
SELECT COUNT(f2) = COUNT(DISTINCT f2) AS EXPECT_1 FROM t1;
SELECT COUNT(*) AS EXPECT_0 FROM t1 WHERE f1 < 200 AND MOD(f2, 2) != 1;
SELECT COUNT(*) AS EXPECT_0 FROM t1 WHERE f1 > 200 AND MOD(f2, 2) != 0;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 25 FROM t1
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_25 FROM t1;
SELECT COUNT(f2) = COUNT(DISTINCT f2) AS EXPECT_1 FROM t1;
--echo # All fragments must have been removed on commit
--connection node_1a
--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log;
--connection node_1
SET SESSION wsrep_trx_fragment_size=DEFAULT;
SET SESSION wsrep_trx_fragment_unit=DEFAULT;
DROP SEQUENCE s;
DROP TABLE t1;
# Streaming transactions are rolled back rather than replayed, so no
# replay happened in any of the cases above
--connection node_1
--let $wsrep_local_replays_new = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'`
--disable_query_log
--eval SELECT $wsrep_local_replays_new - $wsrep_local_replays_old = 0 AS wsrep_local_replays;
--enable_query_log
--disconnect node_1a

View File

@@ -57,6 +57,16 @@ SELECT NEXTVAL(s);
SELECT LASTVAL(s);
SET GLOBAL innodb_log_checkpoint_now=1;
# Node 1 has an open transaction and wsrep_sync_wait is not effective
# inside a transaction. Wait here until node 1 has applied the sequence
# update replicated by NEXTVAL above, otherwise node 1 may still consume
# its own cached value before the update arrives.
--connection node_1_ctrl
--echo # Wait for the next_not_cached_value = 21 FROM s (1_ctrl)
--let $wait_condition = SELECT next_not_cached_value = 21 FROM s
--let $wait_condition_on_error_output = SELECT next_not_cached_value FROM s
--source include/wait_condition_with_debug.inc
--connection node_1
# Update the sequence value further
INSERT INTO t1(f2) values (1);

View File

@@ -0,0 +1,25 @@
connection node_2;
connection node_1;
connection node_1;
connection node_2;
connection node_3;
# Precondition: Galera GTID mode is OFF
SELECT @@global.wsrep_gtid_mode AS wsrep_gtid_mode;
wsrep_gtid_mode
0
connection node_1;
CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
connection node_3;
connection node_3;
connection node_1;
connection node_1;
connection node_3;
SELECT COUNT(*) AS rows_on_joiner FROM t1;
rows_on_joiner
5
include/assert_grep.inc [joiner did not seed binlog GTID state in wsrep_gtid_mode=OFF]
connection node_1;
DROP TABLE t1;
disconnect node_2;
disconnect node_1;

View File

@@ -0,0 +1,91 @@
connection node_2;
connection node_1;
connection node_1;
connection node_2;
connection node_3;
connection node_1;
connection node_2;
connection node_3;
connection node_1;
CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB;
SET AUTOCOMMIT=OFF;
START TRANSACTION;
INSERT INTO t1 VALUES (1,'node1_committed_at_start');
INSERT INTO t1 VALUES (2,'node1_committed_at_start');
INSERT INTO t1 VALUES (3,'node1_committed_at_start');
INSERT INTO t1 VALUES (4,'node1_committed_at_start');
INSERT INTO t1 VALUES (5,'node1_committed_at_start');
COMMIT;
connection node_2;
connection node_3;
connection node_2;
SET AUTOCOMMIT=OFF;
START TRANSACTION;
INSERT INTO t1 VALUES (6,'node2_committed_when_node3_down');
INSERT INTO t1 VALUES (7,'node2_committed_when_node3_down');
INSERT INTO t1 VALUES (8,'node2_committed_when_node3_down');
INSERT INTO t1 VALUES (9,'node2_committed_when_node3_down');
INSERT INTO t1 VALUES (10,'node2_committed_when_node3_down');
COMMIT;
connection node_3;
# restart: --wsrep_sst_donor=node2
SET AUTOCOMMIT=ON;
SET SESSION wsrep_sync_wait=15;
SELECT COUNT(*) AS EXPECT_10 FROM t1;
EXPECT_10
10
SELECT * from t1;
id f1
1 node1_committed_at_start
2 node1_committed_at_start
3 node1_committed_at_start
4 node1_committed_at_start
5 node1_committed_at_start
6 node2_committed_when_node3_down
7 node2_committed_when_node3_down
8 node2_committed_when_node3_down
9 node2_committed_when_node3_down
10 node2_committed_when_node3_down
SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1;
COUNT(*) = 0
1
connection node_2;
connection node_3;
SET AUTOCOMMIT=OFF;
START TRANSACTION;
INSERT INTO t1 VALUES (11,'node2_committed_when_node2_down');
INSERT INTO t1 VALUES (12,'node2_committed_when_node2_down');
INSERT INTO t1 VALUES (13,'node2_committed_when_node2_down');
INSERT INTO t1 VALUES (14,'node2_committed_when_node2_down');
INSERT INTO t1 VALUES (15,'node2_committed_when_node2_down');
COMMIT;
connection node_2;
# restart: --wsrep_sst_donor=node3
SET AUTOCOMMIT=ON;
SET SESSION wsrep_sync_wait=15;
SELECT COUNT(*) AS EXPECT_15 FROM t1;
EXPECT_15
15
SELECT * from t1;
id f1
1 node1_committed_at_start
2 node1_committed_at_start
3 node1_committed_at_start
4 node1_committed_at_start
5 node1_committed_at_start
6 node2_committed_when_node3_down
7 node2_committed_when_node3_down
8 node2_committed_when_node3_down
9 node2_committed_when_node3_down
10 node2_committed_when_node3_down
11 node2_committed_when_node2_down
12 node2_committed_when_node2_down
13 node2_committed_when_node2_down
14 node2_committed_when_node2_down
15 node2_committed_when_node2_down
SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (10, 15)) AS a1;
COUNT(*) = 0
0
connection node_1;
DROP TABLE t1;
COMMIT;

View File

@@ -0,0 +1,16 @@
!include ../galera_3nodes.cnf
[mysqld]
wsrep_sst_method=rsync
[mysqld.1]
wsrep_provider_options='pc.ignore_sb=true;repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.wait_prim_timeout=PT60S;gcache.size=10M'
[mysqld.2]
wsrep_provider_options='pc.ignore_sb=true;repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.wait_prim_timeout=PT60S;gcache.size=10M'
innodb_log_group_home_dir=@ENV.MYSQL_TMP_DIR/mysqld.2/mdev_36677_log_dir
aria_log_dir_path=@ENV.MYSQL_TMP_DIR/mysqld.2/mdev_36677_aria_log_dir
[mysqld.3]
wsrep_provider_options='pc.ignore_sb=true;repl.causal_read_timeout=PT90S;base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.wait_prim_timeout=PT60S;gcache.size=10M'

View File

@@ -0,0 +1,126 @@
#
# MDEV-36677
#
# This test checks the rsync SST works also when InnoDB log files
# reside in a dedicated directory other than the data directory.
# The test comprises of two parts: in Part A the SST donor has InnoDB
# log files outside the data dictionary and in Part B the SST joiner
# has log files outside the data dictionary.
#
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/big_test.inc
# Set up a 3-node cluster where node_2 has log files outside data dictionary
--let $galera_connection_name = node_3
--let $galera_server_number = 3
--source include/galera_connect.inc
--let $node_1=node_1
--let $node_2=node_2
--let $node_3=node_3
--source ../galera/include/auto_increment_offset_save.inc
--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_size'
--connection node_1
--source include/wait_condition.inc
--connection node_2
--source include/wait_condition.inc
--connection node_3
--source include/wait_condition.inc
--connection node_1
CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB;
SET AUTOCOMMIT=OFF;
START TRANSACTION;
INSERT INTO t1 VALUES (1,'node1_committed_at_start');
INSERT INTO t1 VALUES (2,'node1_committed_at_start');
INSERT INTO t1 VALUES (3,'node1_committed_at_start');
INSERT INTO t1 VALUES (4,'node1_committed_at_start');
INSERT INTO t1 VALUES (5,'node1_committed_at_start');
COMMIT;
--connection node_2
--source include/galera_wait_ready.inc
let $MYSQLD2_DATADIR= `SELECT @@datadir`;
let $MYSQLD2_INNODB_LOGDIR= `SELECT @@innodb_log_group_home_dir`;
let $MYSQLD2_ARIA_LOGDIR= `SELECT @@aria_log_dir_path`;
# Part A: SST from node_2 to node_3
--connection node_3
--source include/shutdown_mysqld.inc
--remove_file $MYSQLTEST_VARDIR/mysqld.3/data/grastate.dat
--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.3/data
--connection node_2
SET AUTOCOMMIT=OFF;
START TRANSACTION;
INSERT INTO t1 VALUES (6,'node2_committed_when_node3_down');
INSERT INTO t1 VALUES (7,'node2_committed_when_node3_down');
INSERT INTO t1 VALUES (8,'node2_committed_when_node3_down');
INSERT INTO t1 VALUES (9,'node2_committed_when_node3_down');
INSERT INTO t1 VALUES (10,'node2_committed_when_node3_down');
COMMIT;
--connection node_3
--let $restart_parameters = --wsrep_sst_donor=node2
--source include/start_mysqld.inc
--source include/galera_wait_ready.inc
--let $wait_condition = SELECT COUNT(*)=10 FROM t1
--source include/wait_condition.inc
SET AUTOCOMMIT=ON;
SET SESSION wsrep_sync_wait=15;
SELECT COUNT(*) AS EXPECT_10 FROM t1;
SELECT * from t1;
SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1;
# Part B: SST from node_3 to node_2
--connection node_2
--source include/shutdown_mysqld.inc
--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data
--remove_files_wildcard $MYSQL_TMP_DIR/mysqld.2/mdev_36677_log_dir
--remove_files_wildcard $MYSQL_TMP_DIR/mysqld.2/mdev_36677_aria_log_dir
--connection node_3
SET AUTOCOMMIT=OFF;
START TRANSACTION;
INSERT INTO t1 VALUES (11,'node2_committed_when_node2_down');
INSERT INTO t1 VALUES (12,'node2_committed_when_node2_down');
INSERT INTO t1 VALUES (13,'node2_committed_when_node2_down');
INSERT INTO t1 VALUES (14,'node2_committed_when_node2_down');
INSERT INTO t1 VALUES (15,'node2_committed_when_node2_down');
COMMIT;
--connection node_2
--let $restart_parameters = --wsrep_sst_donor=node3
--source include/start_mysqld.inc
--source include/galera_wait_ready.inc
--let $wait_condition = SELECT COUNT(*)=15 FROM t1
--source include/wait_condition.inc
# check that InnoDB log file was not copied to a data directory, but to a dedicated directory
--exec if [ -f $MYSQLD2_DATADIR/ib_logfile0 ]; then false; fi
--exec if [ ! -f $MYSQLD2_INNODB_LOGDIR/ib_logfile0 ]; then false; fi
# check that Aria log file was not copied to a data directory, but to a dedicated directory
--exec if [ -f $MYSQLD2_DATADIR/aria_log.00000001 ]; then false; fi
--exec if [ ! -f $MYSQLD2_ARIA_LOGDIR/aria_log.00000001 ]; then false; fi
SET AUTOCOMMIT=ON;
SET SESSION wsrep_sync_wait=15;
SELECT COUNT(*) AS EXPECT_15 FROM t1;
SELECT * from t1;
SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (10, 15)) AS a1;
# cleanup
--connection node_1
--source ../galera/include/auto_increment_offset_restore.inc
DROP TABLE t1;
COMMIT;

View File

@@ -13,15 +13,21 @@ WHERE database_name = 'test' AND table_name = 't';
index_name stat_name stat_description
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
GEN_CLUST_INDEX n_nonnull_fld01 DB_ROW_ID
GEN_CLUST_INDEX size Number of pages in the index
idxa n_diff_pfx01 a
idxa n_diff_pfx02 a,DB_ROW_ID
idxa n_leaf_pages Number of leaf pages in the index
idxa n_nonnull_fld01 a
idxa n_nonnull_fld02 DB_ROW_ID
idxa size Number of pages in the index
vidxcd n_diff_pfx01 c
vidxcd n_diff_pfx02 c,d
vidxcd n_diff_pfx03 c,d,DB_ROW_ID
vidxcd n_leaf_pages Number of leaf pages in the index
vidxcd n_nonnull_fld01 c
vidxcd n_nonnull_fld02 d
vidxcd n_nonnull_fld03 DB_ROW_ID
vidxcd size Number of pages in the index
ALTER TABLE t ADD COLUMN e INT GENERATED ALWAYS AS(a+a+b), ADD INDEX idxb (b), ALGORITHM=INPLACE;
select count(*) from t;
@@ -33,19 +39,27 @@ WHERE database_name = 'test' AND table_name = 't';
index_name stat_name stat_description
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
GEN_CLUST_INDEX n_nonnull_fld01 DB_ROW_ID
GEN_CLUST_INDEX size Number of pages in the index
idxa n_diff_pfx01 a
idxa n_diff_pfx02 a,DB_ROW_ID
idxa n_leaf_pages Number of leaf pages in the index
idxa n_nonnull_fld01 a
idxa n_nonnull_fld02 DB_ROW_ID
idxa size Number of pages in the index
idxb n_diff_pfx01 b
idxb n_diff_pfx02 b,DB_ROW_ID
idxb n_leaf_pages Number of leaf pages in the index
idxb n_nonnull_fld01 b
idxb n_nonnull_fld02 DB_ROW_ID
idxb size Number of pages in the index
vidxcd n_diff_pfx01 c
vidxcd n_diff_pfx02 c,d
vidxcd n_diff_pfx03 c,d,DB_ROW_ID
vidxcd n_leaf_pages Number of leaf pages in the index
vidxcd n_nonnull_fld01 c
vidxcd n_nonnull_fld02 d
vidxcd n_nonnull_fld03 DB_ROW_ID
vidxcd size Number of pages in the index
ALTER TABLE t DROP COLUMN c, DROP INDEX idxa, ALGORITHM=INPLACE;
select count(*) from t;
@@ -57,14 +71,19 @@ WHERE database_name = 'test' AND table_name = 't';
index_name stat_name stat_description
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
GEN_CLUST_INDEX n_nonnull_fld01 DB_ROW_ID
GEN_CLUST_INDEX size Number of pages in the index
idxb n_diff_pfx01 b
idxb n_diff_pfx02 b,DB_ROW_ID
idxb n_leaf_pages Number of leaf pages in the index
idxb n_nonnull_fld01 b
idxb n_nonnull_fld02 DB_ROW_ID
idxb size Number of pages in the index
vidxcd n_diff_pfx01 d
vidxcd n_diff_pfx02 d,DB_ROW_ID
vidxcd n_leaf_pages Number of leaf pages in the index
vidxcd n_nonnull_fld01 d
vidxcd n_nonnull_fld02 DB_ROW_ID
vidxcd size Number of pages in the index
ALTER TABLE t ADD INDEX vidxe (e), ALGORITHM=INPLACE;
select count(*) from t;
@@ -76,18 +95,25 @@ WHERE database_name = 'test' AND table_name = 't';
index_name stat_name stat_description
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
GEN_CLUST_INDEX n_nonnull_fld01 DB_ROW_ID
GEN_CLUST_INDEX size Number of pages in the index
idxb n_diff_pfx01 b
idxb n_diff_pfx02 b,DB_ROW_ID
idxb n_leaf_pages Number of leaf pages in the index
idxb n_nonnull_fld01 b
idxb n_nonnull_fld02 DB_ROW_ID
idxb size Number of pages in the index
vidxcd n_diff_pfx01 d
vidxcd n_diff_pfx02 d,DB_ROW_ID
vidxcd n_leaf_pages Number of leaf pages in the index
vidxcd n_nonnull_fld01 d
vidxcd n_nonnull_fld02 DB_ROW_ID
vidxcd size Number of pages in the index
vidxe n_diff_pfx01 e
vidxe n_diff_pfx02 e,DB_ROW_ID
vidxe n_leaf_pages Number of leaf pages in the index
vidxe n_nonnull_fld01 e
vidxe n_nonnull_fld02 DB_ROW_ID
vidxe size Number of pages in the index
ALTER TABLE t ADD COLUMN f INT GENERATED ALWAYS AS(a + a), ADD INDEX vidxf (f), ALGORITHM=INPLACE;
select count(*) from t;
@@ -99,22 +125,31 @@ WHERE database_name = 'test' AND table_name = 't';
index_name stat_name stat_description
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
GEN_CLUST_INDEX n_nonnull_fld01 DB_ROW_ID
GEN_CLUST_INDEX size Number of pages in the index
idxb n_diff_pfx01 b
idxb n_diff_pfx02 b,DB_ROW_ID
idxb n_leaf_pages Number of leaf pages in the index
idxb n_nonnull_fld01 b
idxb n_nonnull_fld02 DB_ROW_ID
idxb size Number of pages in the index
vidxcd n_diff_pfx01 d
vidxcd n_diff_pfx02 d,DB_ROW_ID
vidxcd n_leaf_pages Number of leaf pages in the index
vidxcd n_nonnull_fld01 d
vidxcd n_nonnull_fld02 DB_ROW_ID
vidxcd size Number of pages in the index
vidxe n_diff_pfx01 e
vidxe n_diff_pfx02 e,DB_ROW_ID
vidxe n_leaf_pages Number of leaf pages in the index
vidxe n_nonnull_fld01 e
vidxe n_nonnull_fld02 DB_ROW_ID
vidxe size Number of pages in the index
vidxf n_diff_pfx01 f
vidxf n_diff_pfx02 f,DB_ROW_ID
vidxf n_leaf_pages Number of leaf pages in the index
vidxf n_nonnull_fld01 f
vidxf n_nonnull_fld02 DB_ROW_ID
vidxf size Number of pages in the index
ALTER TABLE t DROP INDEX vidxcd;
SELECT index_name, stat_name, stat_description
@@ -123,17 +158,24 @@ WHERE database_name = 'test' AND table_name = 't';
index_name stat_name stat_description
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
GEN_CLUST_INDEX n_nonnull_fld01 DB_ROW_ID
GEN_CLUST_INDEX size Number of pages in the index
idxb n_diff_pfx01 b
idxb n_diff_pfx02 b,DB_ROW_ID
idxb n_leaf_pages Number of leaf pages in the index
idxb n_nonnull_fld01 b
idxb n_nonnull_fld02 DB_ROW_ID
idxb size Number of pages in the index
vidxe n_diff_pfx01 e
vidxe n_diff_pfx02 e,DB_ROW_ID
vidxe n_leaf_pages Number of leaf pages in the index
vidxe n_nonnull_fld01 e
vidxe n_nonnull_fld02 DB_ROW_ID
vidxe size Number of pages in the index
vidxf n_diff_pfx01 f
vidxf n_diff_pfx02 f,DB_ROW_ID
vidxf n_leaf_pages Number of leaf pages in the index
vidxf n_nonnull_fld01 f
vidxf n_nonnull_fld02 DB_ROW_ID
vidxf size Number of pages in the index
DROP TABLE t;

View File

@@ -589,6 +589,8 @@ Expect 200
# This will not change the counter to 150, but to 201, which is the next
# of current max counter in the table
ALTER TABLE t3 AUTO_INCREMENT = 150;
Warnings:
Note 4190 ALTER TABLE is implicitly changing the value of 'AUTO_INCREMENT' from '150' to '201'
SHOW CREATE TABLE t3;
Table Create Table
t3 CREATE TABLE `t3` (
@@ -630,6 +632,8 @@ UPDATE t3 SET a = 200 WHERE a = 150;
INSERT INTO t3 VALUES(220);
# This still fails to set to 120, but just 221
ALTER TABLE t3 AUTO_INCREMENT = 120;
Warnings:
Note 4190 ALTER TABLE is implicitly changing the value of 'AUTO_INCREMENT' from '120' to '221'
SHOW CREATE TABLE t3;
Table Create Table
t3 CREATE TABLE `t3` (
@@ -752,6 +756,8 @@ t_inplace CREATE TABLE `t_inplace` (
# current max counter in the table, since the specified value
# is smaller than the existing biggest value(50 < 123)
ALTER TABLE t_inplace DROP COLUMN b, AUTO_INCREMENT = 50, ALGORITHM = INPLACE;
Warnings:
Note 4190 ALTER TABLE is implicitly changing the value of 'AUTO_INCREMENT' from '50' to '123'
# We expect the counter to be 123
SHOW CREATE TABLE t_inplace;
Table Create Table
@@ -840,6 +846,8 @@ t_copy CREATE TABLE `t_copy` (
# current max counter in the table, since the specified value
# is smaller than the existing biggest value(50 < 123)
ALTER TABLE t_copy DROP COLUMN b, AUTO_INCREMENT = 50, ALGORITHM = COPY;
Warnings:
Note 4190 ALTER TABLE is implicitly changing the value of 'AUTO_INCREMENT' from '50' to '123'
# We expect the counter to be 123
SHOW CREATE TABLE t_copy;
Table Create Table

View File

@@ -135,10 +135,6 @@ DROP TABLE t1;
#
set @old_sql_mode = @@sql_mode;
SET @@sql_mode='';
CREATE TABLE t1(pk INT,c CHAR(255),c2 CHAR(255),c3 CHAR(255),
c4 char(255), c5 char(255), c6 char(255),
c7 char(255), c8 char(255), primary key(pk)
)Engine=InnoDB character set utf32 ROW_FORMAT=REDUNDANT;
INSERT INTO t1(pk, c) VALUES (1, repeat('a', 255));
ALTER TABLE t1 FORCE;
CHECK TABLE t1;
@@ -150,4 +146,20 @@ LENGTH(c)
DROP TABLE t1;
set @@sql_mode = @old_sql_mode;
# End of 10.4 tests
#
# MDEV-39792 InnoDB: ALTER TABLE FORCE triggers assertion "s"
# in buf_page_get_gen() when converting an externally stored
# CHAR column to ROW_FORMAT=REDUNDANT
#
SET @a=REPEAT(_utf8mb4 0xF09F9880,254);
SET GLOBAL innodb_default_row_format = @row_format;
ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
SELECT c1=@a FROM t1;
c1=@a
1
DROP TABLE t1;
# End of 11.4 tests
SET GLOBAL innodb_default_row_format = @row_format;

View File

@@ -16,7 +16,7 @@ END REPEAT;
END
$
connection default;
ALTER TABLE t NOWAIT ADD INDEX (c);
ALTER TABLE t NOWAIT ADD INDEX (c(20));
connection con1;
connection default;
FLUSH TABLE t FOR EXPORT;

View File

@@ -22,6 +22,8 @@ a id
SET AUTO_INCREMENT_INCREMENT = 5, AUTO_INCREMENT_OFFSET = 30;
ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
DROP COLUMN id, AUTO_INCREMENT = 42, ALGORITHM=COPY;
Warnings:
Note 4190 ALTER TABLE is implicitly changing the value of 'AUTO_INCREMENT' from '42' to '70'
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -54,6 +56,8 @@ DROP COLUMN id, AUTO_INCREMENT = 42, ALGORITHM=INPLACE, LOCK=NONE;
ERROR 0A000: LOCK=NONE is not supported. Reason: Adding an auto-increment column requires a lock. Try LOCK=SHARED
ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
DROP COLUMN id, AUTO_INCREMENT = 42, ALGORITHM=INPLACE;
Warnings:
Note 4190 ALTER TABLE is implicitly changing the value of 'AUTO_INCREMENT' from '42' to '70'
SELECT * FROM t1;
a id
6 45
@@ -134,6 +138,8 @@ t1 CREATE TABLE `t1` (
) ENGINE=InnoDB AUTO_INCREMENT=75 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
ALTER TABLE t1 DROP PRIMARY KEY, ADD id INT AUTO_INCREMENT PRIMARY KEY,
DROP COLUMN id, AUTO_INCREMENT = 42, ALGORITHM=COPY;
Warnings:
Note 4190 ALTER TABLE is implicitly changing the value of 'AUTO_INCREMENT' from '42' to '70'
SELECT * FROM t1;
a id
6 45

View File

@@ -24,7 +24,9 @@ d1
3
ALTER TABLE t1 AUTO_INCREMENT = 3;
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
info: Records: 0 Duplicates: 0 Warnings: 1
Warnings:
Note 4190 ALTER TABLE is implicitly changing the value of 'AUTO_INCREMENT' from '3' to '4'
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (

View File

@@ -132,9 +132,11 @@ SELECT * FROM mysql.innodb_index_stats WHERE table_name IN ('t1');
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
test t1 PRIMARY LAST_UPDATE n_diff_pfx01 5 1 c1
test t1 PRIMARY LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index
test t1 PRIMARY LAST_UPDATE n_nonnull_fld01 5 1 c1
test t1 PRIMARY LAST_UPDATE size 1 NULL Number of pages in the index
test t1 c2 LAST_UPDATE n_diff_pfx01 5 1 c2
test t1 c2 LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index
test t1 c2 LAST_UPDATE n_nonnull_fld01 5 1 c2
test t1 c2 LAST_UPDATE size 1 NULL Number of pages in the index
CREATE TABLE t1_c2_stats SELECT * FROM mysql.innodb_index_stats
WHERE database_name = 'test' AND table_name = 't1' and index_name = 'c2';
@@ -148,9 +150,11 @@ SELECT * FROM mysql.innodb_index_stats WHERE table_name IN ('t1', 't1_c2_stats')
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
test t1 PRIMARY LAST_UPDATE n_diff_pfx01 5 1 c1
test t1 PRIMARY LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index
test t1 PRIMARY LAST_UPDATE n_nonnull_fld01 5 1 c1
test t1 PRIMARY LAST_UPDATE size 1 NULL Number of pages in the index
test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE n_diff_pfx01 3 1 DB_ROW_ID
test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE n_diff_pfx01 4 1 DB_ROW_ID
test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE n_leaf_pages 1 NULL Number of leaf pages in the index
test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE n_nonnull_fld01 4 1 DB_ROW_ID
test t1_c2_stats GEN_CLUST_INDEX LAST_UPDATE size 1 NULL Number of pages in the index
connection con1;
KILL QUERY @id;

View File

@@ -16,3 +16,28 @@ disconnect con1;
connection default;
SET debug_sync= "RESET";
DROP TABLE t1;
#
# MDEV-26057 Assertion `!vcol->v_indexes.empty() in trx_undo_log_v_idx
#
CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL,
f3 INT AS (f2) VIRTUAL) ENGINE=InnoDB;
INSERT INTO t1(f1, f2) VALUES(1, 1);
SET DEBUG_SYNC="alter_rollback_complete SIGNAL dml_start WAIT_FOR default_resume";
set STATEMENT DEBUG_DBUG="d,innodb_OOM_inplace_alter" FOR alter table t1 add index(f3), algorithm=inplace;
connect con1,localhost,root,,,;
SET DEBUG_SYNC="now WAIT_FOR dml_start";
INSERT INTO t1(f1, f2) VALUES(2, 2);
SET DEBUG_SYNC="now SIGNAL default_resume";
connection default;
ERROR HY000: Out of memory.
connection default;
disconnect con1;
SET DEBUG_SYNC="RESET";
SELECT * FROM t1;
f1 f2 f3
1 1 1
2 2 2
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;

View File

@@ -10,6 +10,9 @@ index_name PRIMARY
stat_name n_leaf_pages
stat_value 1
index_name PRIMARY
stat_name n_nonnull_fld01
stat_value 0
index_name PRIMARY
stat_name size
stat_value 1
INSERT INTO autorecalc VALUES (1);
@@ -25,6 +28,9 @@ index_name PRIMARY
stat_name n_leaf_pages
stat_value 1
index_name PRIMARY
stat_name n_nonnull_fld01
stat_value 2
index_name PRIMARY
stat_name size
stat_value 1
DELETE FROM autorecalc;
@@ -39,6 +45,9 @@ index_name PRIMARY
stat_name n_leaf_pages
stat_value 1
index_name PRIMARY
stat_name n_nonnull_fld01
stat_value 0
index_name PRIMARY
stat_name size
stat_value 1
DROP TABLE autorecalc;

View File

@@ -12,6 +12,9 @@ index_name PRIMARY
stat_name n_leaf_pages
stat_value 1
index_name PRIMARY
stat_name n_nonnull_fld01
stat_value 2
index_name PRIMARY
stat_name size
stat_value 1
DROP TABLE arddl;
@@ -29,6 +32,9 @@ index_name PRIMARY
stat_name n_leaf_pages
stat_value 1
index_name PRIMARY
stat_name n_nonnull_fld01
stat_value 2
index_name PRIMARY
stat_name size
stat_value 1
DROP TABLE arddl;

View File

@@ -3,7 +3,7 @@ CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB;
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't';
COUNT(*) 1
SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't';
COUNT(*) 3
COUNT(*) 4
SELECT * FROM t;
DELETE FROM mysql.innodb_index_stats WHERE table_name = 't';
DELETE FROM mysql.innodb_table_stats WHERE table_name = 't';
@@ -16,14 +16,14 @@ SELECT * FROM t;
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't';
COUNT(*) 1
SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't';
COUNT(*) 3
COUNT(*) 4
DROP TABLE t;
Test with explicit enable
CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=1;
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't';
COUNT(*) 1
SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't';
COUNT(*) 3
COUNT(*) 4
SELECT * FROM t;
DELETE FROM mysql.innodb_index_stats WHERE table_name = 't';
DELETE FROM mysql.innodb_table_stats WHERE table_name = 't';
@@ -36,14 +36,14 @@ SELECT * FROM t;
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't';
COUNT(*) 1
SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't';
COUNT(*) 3
COUNT(*) 4
DROP TABLE t;
Test with explicit disable
CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=0;
SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't';
COUNT(*) 1
SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't';
COUNT(*) 3
COUNT(*) 4
SELECT * FROM t;
DELETE FROM mysql.innodb_index_stats WHERE table_name = 't';
DELETE FROM mysql.innodb_table_stats WHERE table_name = 't';

View File

@@ -25,6 +25,9 @@ innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
connect con1,localhost,root,,;
SET innodb_lock_wait_timeout=1;
ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key;
@@ -58,6 +61,9 @@ innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key;
SELECT table_name FROM mysql.innodb_index_stats
WHERE table_name='innodb_stats_drop_locked';
@@ -65,6 +71,7 @@ table_name
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
DROP TABLE innodb_stats_drop_locked;
SELECT table_name FROM mysql.innodb_table_stats
WHERE table_name='innodb_stats_drop_locked';

View File

@@ -36,6 +36,16 @@ stat_value 1
sample_size NULL
stat_description Number of leaf pages in the index
index_name PRIMARY
stat_name n_nonnull_fld01
stat_value 0
sample_size 1
stat_description a
index_name PRIMARY
stat_name n_nonnull_fld02
stat_value 0
sample_size 1
stat_description b
index_name PRIMARY
stat_name size
stat_value 1
sample_size NULL
@@ -66,6 +76,26 @@ stat_value 1
sample_size NULL
stat_description Number of leaf pages in the index
index_name idx
stat_name n_nonnull_fld01
stat_value 0
sample_size 1
stat_description c
index_name idx
stat_name n_nonnull_fld02
stat_value 0
sample_size 1
stat_description d
index_name idx
stat_name n_nonnull_fld03
stat_value 0
sample_size 1
stat_description a
index_name idx
stat_name n_nonnull_fld04
stat_value 0
sample_size 1
stat_description b
index_name idx
stat_name size
stat_value 1
sample_size NULL

View File

@@ -24,6 +24,10 @@ stat_name n_leaf_pages
stat_value 1
table_name stats_rename_old
index_name PRIMARY
stat_name n_nonnull_fld01
stat_value 0
table_name stats_rename_old
index_name PRIMARY
stat_name size
stat_value 1
RENAME TABLE stats_rename_old TO stats_rename_new;
@@ -45,6 +49,10 @@ stat_name n_leaf_pages
stat_value 1
table_name stats_rename_new
index_name PRIMARY
stat_name n_nonnull_fld01
stat_value 0
table_name stats_rename_new
index_name PRIMARY
stat_name size
stat_value 1
DROP TABLE stats_rename_new;

Some files were not shown because too many files have changed in this diff Show More