mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
Merge 10.6 into 10.11
This commit is contained in:
@@ -1273,8 +1273,9 @@ static int get_options(int *argc, char ***argv)
|
||||
if (opt_slave_data)
|
||||
{
|
||||
opt_lock_all_tables= !opt_single_transaction;
|
||||
opt_master_data= 0;
|
||||
opt_delete_master_logs= 0;
|
||||
if (opt_slave_data != MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL)
|
||||
opt_master_data= 0;
|
||||
}
|
||||
|
||||
/* Ensure consistency of the set of binlog & locking options */
|
||||
@@ -1287,10 +1288,7 @@ static int get_options(int *argc, char ***argv)
|
||||
return(EX_USAGE);
|
||||
}
|
||||
if (opt_master_data)
|
||||
{
|
||||
opt_lock_all_tables= !opt_single_transaction;
|
||||
opt_slave_data= 0;
|
||||
}
|
||||
if (opt_single_transaction || opt_lock_all_tables)
|
||||
lock_tables= 0;
|
||||
if (enclosed && opt_enclosed)
|
||||
@@ -6227,17 +6225,12 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos,
|
||||
|
||||
}
|
||||
|
||||
/* SHOW MASTER STATUS reports file and position */
|
||||
print_comment(md_result_file, 0,
|
||||
"\n--\n-- Position to start replication or point-in-time "
|
||||
"recovery from\n--\n\n");
|
||||
fprintf(md_result_file,
|
||||
"%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
|
||||
(use_gtid ? "-- " : comment_prefix), file, offset);
|
||||
/* gtid */
|
||||
if (have_mariadb_gtid)
|
||||
{
|
||||
print_comment(md_result_file, 0,
|
||||
"\n--\n-- GTID to start replication from\n--\n\n");
|
||||
"\n-- Preferably use GTID to start replication from GTID "
|
||||
"position:\n\n");
|
||||
if (use_gtid)
|
||||
fprintf(md_result_file,
|
||||
"%sCHANGE MASTER TO MASTER_USE_GTID=slave_pos;\n",
|
||||
@@ -6246,6 +6239,19 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos,
|
||||
"%sSET GLOBAL gtid_slave_pos='%s';\n",
|
||||
(!use_gtid ? "-- " : comment_prefix), gtid_pos);
|
||||
}
|
||||
|
||||
/* SHOW MASTER STATUS reports file and position */
|
||||
print_comment(md_result_file, 0,
|
||||
"\n--\n-- Alternately, following is the position of the binary "
|
||||
"logging from SHOW MASTER STATUS at point of backup."
|
||||
"\n-- Use this when creating a replica of the primary server "
|
||||
"where the backup was made."
|
||||
"\n-- The new server will be connecting to the primary server "
|
||||
"where the backup was taken."
|
||||
"\n--\n\n");
|
||||
fprintf(md_result_file,
|
||||
"%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
|
||||
(use_gtid ? "-- " : comment_prefix), file, offset);
|
||||
check_io(md_result_file);
|
||||
|
||||
if (!consistent_binlog_pos)
|
||||
@@ -6324,7 +6330,6 @@ static int do_show_slave_status(MYSQL *mysql_con, int use_gtid,
|
||||
(opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
|
||||
const char *gtid_comment_prefix= (use_gtid ? comment_prefix : "-- ");
|
||||
const char *nogtid_comment_prefix= (!use_gtid ? comment_prefix : "-- ");
|
||||
int set_gtid_done= 0;
|
||||
|
||||
if (mysql_query_with_error_report(mysql_con, &slave,
|
||||
multi_source ?
|
||||
@@ -6340,23 +6345,36 @@ static int do_show_slave_status(MYSQL *mysql_con, int use_gtid,
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_comment(md_result_file, 0,
|
||||
"\n--\n-- The following is the SQL position of the replication "
|
||||
"taken from SHOW SLAVE STATUS at the time of backup.\n"
|
||||
"-- Use this position when creating a clone of, or replacement "
|
||||
"server, from where the backup was taken."
|
||||
"\n-- This new server will connects to the same primary "
|
||||
"server%s.\n--\n",
|
||||
multi_source ? "(s)" : "");
|
||||
|
||||
if (multi_source)
|
||||
{
|
||||
char gtid_pos[MAX_GTID_LENGTH];
|
||||
if (have_mariadb_gtid && get_gtid_pos(gtid_pos, 0))
|
||||
{
|
||||
mysql_free_result(slave);
|
||||
return 1;
|
||||
}
|
||||
print_comment(md_result_file, 0,
|
||||
"-- GTID position to start replication:\n");
|
||||
fprintf(md_result_file, "%sSET GLOBAL gtid_slave_pos='%s';\n",
|
||||
gtid_comment_prefix, gtid_pos);
|
||||
}
|
||||
if (use_gtid)
|
||||
print_comment(md_result_file, 0,
|
||||
"\n-- Use only the MASTER_USE_GTID=slave_pos or "
|
||||
"MASTER_LOG_FILE/MASTER_LOG_POS in the statements below."
|
||||
"\n\n");
|
||||
|
||||
while ((row= mysql_fetch_row(slave)))
|
||||
{
|
||||
if (multi_source && !set_gtid_done)
|
||||
{
|
||||
char gtid_pos[MAX_GTID_LENGTH];
|
||||
if (have_mariadb_gtid && get_gtid_pos(gtid_pos, 0))
|
||||
{
|
||||
mysql_free_result(slave);
|
||||
return 1;
|
||||
}
|
||||
if (opt_comments)
|
||||
fprintf(md_result_file, "\n--\n-- Gtid position to start replication "
|
||||
"from\n--\n\n");
|
||||
fprintf(md_result_file, "%sSET GLOBAL gtid_slave_pos='%s';\n",
|
||||
gtid_comment_prefix, gtid_pos);
|
||||
set_gtid_done= 1;
|
||||
}
|
||||
if (row[9 + multi_source] && row[21 + multi_source])
|
||||
{
|
||||
if (use_gtid)
|
||||
@@ -6370,11 +6388,6 @@ static int do_show_slave_status(MYSQL *mysql_con, int use_gtid,
|
||||
}
|
||||
|
||||
/* SHOW MASTER STATUS reports file and position */
|
||||
if (opt_comments)
|
||||
fprintf(md_result_file,
|
||||
"\n--\n-- Position to start replication or point-in-time "
|
||||
"recovery from (the master of this slave)\n--\n\n");
|
||||
|
||||
if (multi_source)
|
||||
fprintf(md_result_file, "%sCHANGE MASTER '%.80s' TO ",
|
||||
nogtid_comment_prefix, row[0]);
|
||||
@@ -6395,6 +6408,7 @@ static int do_show_slave_status(MYSQL *mysql_con, int use_gtid,
|
||||
check_io(md_result_file);
|
||||
}
|
||||
}
|
||||
fprintf(md_result_file, "\n");
|
||||
mysql_free_result(slave);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ SET(WITH_PCRE "auto" CACHE STRING
|
||||
"Which pcre to use (possible values are 'bundled', 'system', or 'auto')")
|
||||
|
||||
MACRO(BUNDLE_PCRE2)
|
||||
SET(WITH_PCRE "bundled" CACHE STRING
|
||||
"Which pcre to use (possible values are 'bundled', 'system', or 'auto')")
|
||||
|
||||
SET(dir "${CMAKE_BINARY_DIR}/extra/pcre2")
|
||||
SET(PCRE_INCLUDE_DIRS ${dir}/src/pcre2-build ${dir}/src/pcre2/src)
|
||||
MESSAGE(STATUS "Will download and bundle pcre2")
|
||||
|
||||
2
debian/mariadb-server.mariadb.init
vendored
2
debian/mariadb-server.mariadb.init
vendored
@@ -88,7 +88,7 @@ sanity_checks() {
|
||||
# If datadir location is not changed int configuration
|
||||
# then it's not printed with /usr/sbin/mariadbd --print-defaults
|
||||
# then we use 'sane' default.
|
||||
if [ -z "$datadir"]
|
||||
if [ -z "$datadir" ]
|
||||
then
|
||||
datadir="/var/lib/mysql"
|
||||
fi
|
||||
|
||||
1
debian/rules
vendored
1
debian/rules
vendored
@@ -98,7 +98,6 @@ endif
|
||||
-DCOMPILATION_COMMENT="mariadb.org binary distribution" \
|
||||
-DMYSQL_SERVER_SUFFIX="-$(DEB_VERSION_REVISION)" \
|
||||
-DSYSTEM_TYPE="debian-$(DEB_HOST_GNU_SYSTEM)" \
|
||||
-DCMAKE_SYSTEM_PROCESSOR=$(DEB_HOST_ARCH) \
|
||||
-DBUILD_CONFIG=mysql_release \
|
||||
-DCONC_DEFAULT_CHARSET=utf8mb4 \
|
||||
-DPLUGIN_AWS_KEY_MANAGEMENT=NO \
|
||||
|
||||
@@ -47,6 +47,12 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits>
|
||||
#ifdef HAVE_PWD_H
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#include "common.h"
|
||||
#include "xtrabackup.h"
|
||||
#include "srv0srv.h"
|
||||
@@ -92,11 +98,54 @@ MYSQL *mysql_connection;
|
||||
|
||||
extern my_bool opt_ssl_verify_server_cert, opt_use_ssl;
|
||||
|
||||
|
||||
/*
|
||||
get_os_user()
|
||||
Ressemles read_user_name() from libmariadb/libmariadb/mariadb_lib.c.
|
||||
*/
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
||||
#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL)
|
||||
struct passwd *getpwuid(uid_t);
|
||||
char* getlogin(void);
|
||||
#endif
|
||||
|
||||
static const char *get_os_user() // Posix
|
||||
{
|
||||
if (!geteuid())
|
||||
return "root";
|
||||
#ifdef HAVE_GETPWUID
|
||||
struct passwd *pw;
|
||||
const char *str;
|
||||
if ((pw= getpwuid(geteuid())) != NULL)
|
||||
return pw->pw_name;
|
||||
if ((str= getlogin()) != NULL)
|
||||
return str;
|
||||
#endif
|
||||
if ((str= getenv("USER")) ||
|
||||
(str= getenv("LOGNAME")) ||
|
||||
(str= getenv("LOGIN")))
|
||||
return str;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static const char *get_os_user() // Windows
|
||||
{
|
||||
return getenv("USERNAME");
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
MYSQL *
|
||||
xb_mysql_connect()
|
||||
{
|
||||
MYSQL *connection = mysql_init(NULL);
|
||||
char mysql_port_str[std::numeric_limits<int>::digits10 + 3];
|
||||
const char *user= opt_user ? opt_user : get_os_user();
|
||||
|
||||
sprintf(mysql_port_str, "%d", opt_port);
|
||||
|
||||
@@ -126,7 +175,7 @@ xb_mysql_connect()
|
||||
|
||||
msg("Connecting to MariaDB server host: %s, user: %s, password: %s, "
|
||||
"port: %s, socket: %s", opt_host ? opt_host : "localhost",
|
||||
opt_user ? opt_user : "not set",
|
||||
user ? user : "not set",
|
||||
opt_password ? "set" : "not set",
|
||||
opt_port != 0 ? mysql_port_str : "not set",
|
||||
opt_socket ? opt_socket : "not set");
|
||||
@@ -147,7 +196,7 @@ xb_mysql_connect()
|
||||
|
||||
if (!mysql_real_connect(connection,
|
||||
opt_host ? opt_host : "localhost",
|
||||
opt_user,
|
||||
user,
|
||||
opt_password,
|
||||
"" /*database*/, opt_port,
|
||||
opt_socket, 0)) {
|
||||
|
||||
44
include/mysql/service_print_check_msg.h
Normal file
44
include/mysql/service_print_check_msg.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* Copyright (c) 2019, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
@file include/mysql/service_print_check_msg.h
|
||||
This service provides functions to write messages for check or repair
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
extern struct print_check_msg_service_st {
|
||||
void (*print_check_msg)(MYSQL_THD, const char *db_name, const char *table_name,
|
||||
const char *op, const char *msg_type, const char *message,
|
||||
my_bool print_to_log);
|
||||
} *print_check_msg_service;
|
||||
|
||||
#ifdef MYSQL_DYNAMIC_PLUGIN
|
||||
# define print_check_msg_context(_THD) print_check_msg_service->print_check_msg
|
||||
#else
|
||||
extern void print_check_msg(MYSQL_THD, const char *db_name, const char *table_name,
|
||||
const char *op, const char *msg_type, const char *message,
|
||||
my_bool print_to_log);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -44,6 +44,7 @@
|
||||
#define VERSION_wsrep 0x0500
|
||||
#define VERSION_json 0x0100
|
||||
#define VERSION_thd_mdl 0x0100
|
||||
#define VERSION_print_check_msg 0x0100
|
||||
#define VERSION_sql_service 0x0101
|
||||
|
||||
#define VERSION_provider_bzip2 0x0100
|
||||
|
||||
@@ -25,6 +25,7 @@ SET(MYSQLSERVICES_SOURCES
|
||||
my_crypt_service.c
|
||||
my_md5_service.c
|
||||
my_print_error_service.c
|
||||
print_check_msg_service.c
|
||||
my_sha1_service.c
|
||||
my_sha2_service.c
|
||||
my_snprintf_service.c
|
||||
|
||||
18
libservices/print_check_msg_service.c
Normal file
18
libservices/print_check_msg_service.c
Normal file
@@ -0,0 +1,18 @@
|
||||
/* Copyright (c) 2024, MariaDB Plc
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <service_versions.h>
|
||||
SERVICE_VERSION print_check_msg_context= (void*) VERSION_print_check_msg;
|
||||
297
mysql-test/include/rpl_clone_slave_using_mariadb-backup.inc
Normal file
297
mysql-test/include/rpl_clone_slave_using_mariadb-backup.inc
Normal file
@@ -0,0 +1,297 @@
|
||||
if ($cnf == "galera2_to_mariadb")
|
||||
{
|
||||
--let MASTER_MYPORT= $NODE_MYPORT_1
|
||||
--connect master, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
--connect slave, 127.0.0.1, root, , test, $NODE_MYPORT_3
|
||||
--disable_query_log
|
||||
--replace_result $MASTER_MYPORT ###
|
||||
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$MASTER_MYPORT, MASTER_USE_GTID=NO;
|
||||
--enable_query_log
|
||||
START SLAVE;
|
||||
--source include/wait_for_slave_to_start.inc
|
||||
|
||||
--let XTRABACKUP_BACKUP_OPTIONS=--no-defaults --user=root --host='127.0.0.1' --port=$NODE_MYPORT_3
|
||||
--let XTRABACKUP_COPY_BACK_OPTIONS= --no-defaults
|
||||
}
|
||||
|
||||
if ($cnf == "mariadb_to_mariadb")
|
||||
{
|
||||
--let XTRABACKUP_BACKUP_OPTIONS=--defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group-suffix=.2
|
||||
--let XTRABACKUP_COPY_BACK_OPTIONS=--defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group-suffix=.2
|
||||
}
|
||||
|
||||
--connection master
|
||||
--let $MYSQLD_DATADIR_MASTER= `select @@datadir`
|
||||
--connection slave
|
||||
--let $MYSQLD_DATADIR_SLAVE= `select @@datadir`
|
||||
|
||||
# This test covers the filename:pos based synchronization
|
||||
# between the master and the slave.
|
||||
# If we ever need to test a GTID based synchronization,
|
||||
# it should be done in a separate test.
|
||||
|
||||
|
||||
--echo ##############################################################
|
||||
--echo ### Initial block with some transactions
|
||||
|
||||
--echo ### Slave: Make sure replication is not using GTID
|
||||
--connection slave
|
||||
--let $value= query_get_value(SHOW SLAVE STATUS, "Using_Gtid", 1)
|
||||
--echo # Using_Gtid=$value
|
||||
|
||||
--echo ### Master: Create and populate t1
|
||||
--connection master
|
||||
CREATE TABLE t1(a TEXT) ENGINE=InnoDB;
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#00:stmt#00 - slave run#0, before backup');
|
||||
INSERT INTO t1 VALUES ('tr#00:stmt#01 - slave run#0, before backup');
|
||||
INSERT INTO t1 VALUES ('tr#00:stmt#02 - slave run#0, before backup');
|
||||
COMMIT;
|
||||
--sync_slave_with_master
|
||||
|
||||
|
||||
|
||||
--echo ##############################################################
|
||||
--echo ### Run the last transaction before mariadb-backup --backup
|
||||
--echo ### Remember SHOW MASTER STATUS and @@gtid_binlog_pos
|
||||
--echo ### before and after the transaction.
|
||||
|
||||
--echo ### Master: Rember MASTER STATUS and @@gtid_binlog_pos before tr#01
|
||||
--connection master
|
||||
--let $master_before_tr01_show_master_status_file=query_get_value(SHOW MASTER STATUS, File, 1)
|
||||
--let $master_before_tr01_show_master_status_position=query_get_value(SHOW MASTER STATUS, Position, 1)
|
||||
--let $master_before_tr01_gtid_binlog_pos=`SELECT @@global.gtid_binlog_pos`
|
||||
|
||||
--echo ### Slave: Remember MASTER STATUS and @@gtid_binlog_pos before tr#01
|
||||
--connection slave
|
||||
--let $slave_before_tr01_show_master_status_file=query_get_value(SHOW MASTER STATUS, File, 1)
|
||||
--let $slave_before_tr01_show_master_status_position=query_get_value(SHOW MASTER STATUS, Position, 1)
|
||||
--let $slave_before_tr01_gtid_binlog_pos=`SELECT @@global.gtid_binlog_pos`
|
||||
|
||||
--echo ### Master: Run the actual last transaction before the backup
|
||||
--connection master
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#01:stmt#00 - slave run#0, before backup');
|
||||
INSERT INTO t1 VALUES ('tr#01:stmt#01 - slave run#0, before backup');
|
||||
INSERT INTO t1 VALUES ('tr#01:stmt#02 - slave run#0, before backup');
|
||||
COMMIT;
|
||||
--sync_slave_with_master
|
||||
|
||||
--echo ### Master: Remember MASTER STATUS and @@gtid_binlog_pos after tr#01
|
||||
--connection master
|
||||
--let $master_after_tr01_show_master_status_file=query_get_value(SHOW MASTER STATUS, File, 1)
|
||||
--let $master_after_tr01_show_master_status_position=query_get_value(SHOW MASTER STATUS, Position, 1)
|
||||
--let $master_after_tr01_gtid_binlog_pos=`SELECT @@global.gtid_binlog_pos`
|
||||
|
||||
--echo ### Slave: Remember MASTER STATUS and @@gtid_binlog_pos after tr#01
|
||||
--connection slave
|
||||
--let $slave_after_tr01_show_master_status_file=query_get_value(SHOW MASTER STATUS, File, 1)
|
||||
--let $slave_after_tr01_show_master_status_position=query_get_value(SHOW MASTER STATUS, Position, 1)
|
||||
--let $slave_after_tr01_gtid_binlog_pos=`SELECT @@global.gtid_binlog_pos`
|
||||
|
||||
|
||||
--echo ##############################################################
|
||||
--echo ### Running `mariadb-backup --backup,--prepare` and checking
|
||||
--echo ### that xtrabackup_slave_info and xtrabackup_binlog_info are OK
|
||||
|
||||
--echo ### Slave: Create a backup
|
||||
--let $backup_slave=$MYSQLTEST_VARDIR/tmp/backup-slave
|
||||
--disable_result_log
|
||||
--exec $XTRABACKUP $XTRABACKUP_BACKUP_OPTIONS --slave-info --backup --target-dir=$backup_slave
|
||||
--enable_result_log
|
||||
|
||||
--echo ### Slave: Prepare the backup
|
||||
--exec $XTRABACKUP --prepare --target-dir=$backup_slave
|
||||
|
||||
--echo ### Slave: xtrabackup files:
|
||||
--echo ############################ xtrabackup_slave_info
|
||||
--replace_result $master_after_tr01_show_master_status_file master_after_tr01_show_master_status_file $master_after_tr01_show_master_status_position master_after_tr01_show_master_status_position
|
||||
--cat_file $backup_slave/xtrabackup_slave_info
|
||||
--echo ############################ xtrabackup_binlog_info
|
||||
--replace_result $slave_after_tr01_show_master_status_file slave_after_tr01_show_master_status_file $slave_after_tr01_show_master_status_position slave_after_tr01_show_master_status_position $slave_after_tr01_gtid_binlog_pos slave_after_tr01_gtid_binlog_pos
|
||||
--cat_file $backup_slave/xtrabackup_binlog_info
|
||||
--echo ############################
|
||||
|
||||
|
||||
--echo ##############################################################
|
||||
--echo ### Run more transactions after the backup:
|
||||
--echo ### - while the slave is still running, then
|
||||
--echo ### - while the slave is shut down
|
||||
|
||||
--echo ### Master: Run another transaction while the slave is still running
|
||||
--connection master
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup');
|
||||
INSERT INTO t1 VALUES ('tr#02:stmt#01 - slave run#0, after backup');
|
||||
INSERT INTO t1 VALUES ('tr#02:stmt@02 - slave run#0, after backup');
|
||||
COMMIT;
|
||||
--sync_slave_with_master
|
||||
|
||||
--echo ### Master: Remember MASTER STATUS and @@gtid_binlog_pos after tr#02
|
||||
--connection master
|
||||
--let $master_after_tr02_show_master_status_file=query_get_value(SHOW MASTER STATUS, File, 1)
|
||||
--let $master_after_tr02_show_master_status_position=query_get_value(SHOW MASTER STATUS, Position, 1)
|
||||
--let $master_after_tr02_gtid_binlog_pos=`SELECT @@global.gtid_binlog_pos`
|
||||
|
||||
--echo ### Slave: Remember MASTER STATUS and @@gtid_binlog_pos after tr#02
|
||||
--connection slave
|
||||
--let $slave_after_tr02_show_master_status_file=query_get_value(SHOW MASTER STATUS, File, 1)
|
||||
--let $slave_after_tr02_show_master_status_position=query_get_value(SHOW MASTER STATUS, Position, 1)
|
||||
--let $slave_after_tr02_gtid_binlog_pos=`SELECT @@global.gtid_binlog_pos`
|
||||
|
||||
|
||||
--echo ### Master: Checking SHOW BINLOG EVENTS
|
||||
|
||||
--connection master
|
||||
--vertical_results
|
||||
### The BEGIN event
|
||||
--replace_column 4 # 5 #
|
||||
--replace_result $master_after_tr01_show_master_status_file master_after_tr01_show_master_status_file $master_after_tr01_show_master_status_position master_after_tr01_show_master_status_position $master_after_tr02_gtid_binlog_pos master_after_tr02_gtid_binlog_pos
|
||||
--eval SHOW BINLOG EVENTS IN '$master_after_tr01_show_master_status_file' FROM $master_after_tr01_show_master_status_position LIMIT 0,1
|
||||
### The INSERT event
|
||||
--replace_column 2 # 4 # 5 #
|
||||
--replace_result $master_after_tr01_show_master_status_file master_after_tr01_show_master_status_file $master_after_tr01_show_master_status_position master_after_tr01_show_master_status_position
|
||||
# Hide the difference between row and stmt binary logging
|
||||
--replace_regex /use `test`; // /(Query|Annotate_rows)/Query_or_Annotate_rows/
|
||||
--eval SHOW BINLOG EVENTS IN '$master_after_tr01_show_master_status_file' FROM $master_after_tr01_show_master_status_position LIMIT 1,1
|
||||
--horizontal_results
|
||||
|
||||
--echo ### Slave: Checking SHOW BINLOG EVENTS
|
||||
--connection slave
|
||||
--vertical_results
|
||||
### The BEGIN event
|
||||
--replace_column 2 # 5 #
|
||||
--replace_result $slave_after_tr01_show_master_status_file slave_after_tr01_show_master_status_file $slave_after_tr01_show_master_status_position slave_after_tr01_show_master_status_position $slave_after_tr02_gtid_binlog_pos slave_after_tr02_gtid_binlog_pos
|
||||
--eval SHOW BINLOG EVENTS IN '$slave_after_tr01_show_master_status_file' FROM $slave_after_tr01_show_master_status_position LIMIT 0,1
|
||||
### The INSERT event
|
||||
--replace_column 2 # 4 # 5 #
|
||||
--replace_result $slave_after_tr01_show_master_status_file slave_after_tr01_show_master_status_file $slave_after_tr01_show_master_status_position slave_after_tr01_show_master_status_position $slave_after_tr02_gtid_binlog_pos slave_after_tr02_gtid_binlog_pos
|
||||
# Hide the difference between row and stmt binary logging
|
||||
--replace_regex /use `test`; // /(Query|Annotate_rows)/Query_or_Annotate_rows/
|
||||
--eval SHOW BINLOG EVENTS IN '$slave_after_tr01_show_master_status_file' FROM $slave_after_tr01_show_master_status_position LIMIT 1,1
|
||||
--horizontal_results
|
||||
|
||||
--echo ### Slave: Stop replication
|
||||
--connection slave
|
||||
STOP SLAVE;
|
||||
--source include/wait_for_slave_to_stop.inc
|
||||
RESET SLAVE;
|
||||
|
||||
--echo ### Slave: Shutdown the server
|
||||
|
||||
if ($cnf == "mariadb_to_mariadb")
|
||||
{
|
||||
--let $rpl_server_number= 2
|
||||
--source include/rpl_stop_server.inc
|
||||
}
|
||||
|
||||
if ($cnf == "galera2_to_mariadb")
|
||||
{
|
||||
--connection slave
|
||||
--source $MYSQL_TEST_DIR/include/shutdown_mysqld.inc
|
||||
}
|
||||
|
||||
--echo ### Master: Run a transaction while the slave is shut down
|
||||
--connection master
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#03:stmt#00 - after slave run#0, slave is shut down, after backup');
|
||||
INSERT INTO t1 VALUES ('tr#03:stmt#01 - after slave run#0, slave is shut down, after backup');
|
||||
INSERT INTO t1 VALUES ('tr#03:stmt#02 - after slave run#0, slave is shut down, after backup');
|
||||
COMMIT;
|
||||
|
||||
|
||||
--echo ##############################################################
|
||||
--echo ### Emulate starting a new virgin slave
|
||||
|
||||
--echo ### Slave: Remove the data directory
|
||||
--rmdir $MYSQLD_DATADIR_SLAVE
|
||||
|
||||
--echo ### Slave: Copy back the backup
|
||||
--exec $XTRABACKUP $XTRABACKUP_COPY_BACK_OPTIONS --copy-back --datadir=$MYSQLD_DATADIR_SLAVE --target-dir=$backup_slave
|
||||
|
||||
--echo ### Slave: Restart the server
|
||||
if ($cnf == "mariadb_to_mariadb")
|
||||
{
|
||||
--let $rpl_server_number= 2
|
||||
--source include/rpl_start_server.inc
|
||||
--source include/wait_until_connected_again.inc
|
||||
}
|
||||
|
||||
if ($cnf == "galera2_to_mariadb")
|
||||
{
|
||||
--connection slave
|
||||
--source $MYSQL_TEST_DIR/include/start_mysqld.inc
|
||||
}
|
||||
|
||||
--echo ### Slave: Display the restored data before START SLAVE
|
||||
--connection slave
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
--echo ### Slave: Execute the CHANGE MASTER statement to set up the host and port
|
||||
--replace_result $MASTER_MYPORT ###
|
||||
--eval CHANGE MASTER '' TO MASTER_USER='root', MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_CONNECT_RETRY=1
|
||||
|
||||
--echo ### Slave: Execute the CHANGE MASTER statement from xtrabackup_slave_info
|
||||
--replace_result $master_after_tr01_show_master_status_file master_after_tr01_show_master_status_file $master_after_tr01_show_master_status_position master_after_tr01_show_master_status_position
|
||||
--source $backup_slave/xtrabackup_slave_info
|
||||
|
||||
--echo ### Slave: Execute START SLAVE
|
||||
--source include/start_slave.inc
|
||||
|
||||
--echo ### Master: Wait for the slave to apply all master events
|
||||
--connection master
|
||||
--sync_slave_with_master slave
|
||||
|
||||
--echo ### Slave: Make sure replication is not using GTID after the slave restart
|
||||
--connection slave
|
||||
--let $value= query_get_value(SHOW SLAVE STATUS, "Using_Gtid", 1)
|
||||
--echo # Using_Gtid=$value
|
||||
|
||||
--echo ### Slave: Display the restored data after START SLAVE
|
||||
--connection slave
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
|
||||
--echo ##############################################################
|
||||
--echo ### Continue master transactions, check the new slave replicates well.
|
||||
|
||||
--echo ### Master: Run a transaction after restarting replication
|
||||
--connection master
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#04:stmt#00 - slave run#1');
|
||||
INSERT INTO t1 VALUES ('tr#04:stmt#01 - slave run#1');
|
||||
INSERT INTO t1 VALUES ('tr#04:stmt#02 - slave run#1');
|
||||
COMMIT;
|
||||
--sync_slave_with_master
|
||||
|
||||
--echo ### Slave: Display the restored data + new transactions
|
||||
--connection slave
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
|
||||
--echo ##############################################################
|
||||
--echo ### Cleanup
|
||||
|
||||
--echo ### Removing the backup directory
|
||||
--rmdir $backup_slave
|
||||
|
||||
--connection master
|
||||
DROP TABLE t1;
|
||||
--sync_slave_with_master
|
||||
|
||||
if ($cnf == "mariadb_to_mariadb")
|
||||
{
|
||||
--source include/rpl_end.inc
|
||||
}
|
||||
|
||||
if ($cnf == "galera2_to_mariadb")
|
||||
{
|
||||
STOP SLAVE;
|
||||
--source include/wait_for_slave_to_stop.inc
|
||||
RESET SLAVE ALL;
|
||||
|
||||
--connection master
|
||||
set global wsrep_on=OFF;
|
||||
RESET MASTER;
|
||||
set global wsrep_on=ON;
|
||||
}
|
||||
@@ -87,12 +87,16 @@ sub flush_out {
|
||||
$out_line = "";
|
||||
}
|
||||
|
||||
use if $^O eq "MSWin32", "threads::shared";
|
||||
my $flush_lock :shared;
|
||||
|
||||
# Print to stdout
|
||||
sub print_out {
|
||||
if(IS_WIN32PERL) {
|
||||
$out_line .= $_[0];
|
||||
# Flush buffered output on new lines.
|
||||
if (rindex($_[0], "\n") != -1) {
|
||||
lock($flush_lock);
|
||||
flush_out();
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
--source include/innodb_prefix_index_cluster_optimization.inc
|
||||
--source include/no_valgrind_without_big.inc
|
||||
|
||||
--source include/innodb_stable_estimates.inc
|
||||
|
||||
SET SESSION DEFAULT_STORAGE_ENGINE='InnoDB';
|
||||
|
||||
set @innodb_stats_persistent_save= @@innodb_stats_persistent;
|
||||
|
||||
@@ -9,23 +9,27 @@ use test;
|
||||
connection slave;
|
||||
-- SET GLOBAL gtid_slave_pos='';
|
||||
CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
STOP ALL SLAVES;
|
||||
-- SET GLOBAL gtid_slave_pos='';
|
||||
CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
START ALL SLAVES;
|
||||
STOP ALL SLAVES;
|
||||
-- SET GLOBAL gtid_slave_pos='';
|
||||
CHANGE MASTER '' TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_MYPORT, MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
START ALL SLAVES;
|
||||
start slave;
|
||||
Warnings:
|
||||
Note 1254 Slave is already running
|
||||
-- SET GLOBAL gtid_slave_pos='';
|
||||
CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
start slave;
|
||||
Warnings:
|
||||
Note 1254 Slave is already running
|
||||
*** Test mysqldump --dump-slave GTID functionality.
|
||||
*** Test mysqldump --dump-slave GTID/non-gtid functionality.
|
||||
connection master;
|
||||
SET gtid_seq_no = 1000;
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||
@@ -35,36 +39,170 @@ connection slave;
|
||||
CREATE TABLE t2 (a INT PRIMARY KEY);
|
||||
DROP TABLE t2;
|
||||
|
||||
1. --dump-slave=1
|
||||
1. --dump-slave=1 --gtid
|
||||
|
||||
SET GLOBAL gtid_slave_pos='0-1-1001';
|
||||
CHANGE MASTER '' TO MASTER_USE_GTID=slave_pos;
|
||||
-- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
2. --dump-slave=2
|
||||
|
||||
1a. --dump-slave=1
|
||||
|
||||
-- SET GLOBAL gtid_slave_pos='0-1-1001';
|
||||
CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
|
||||
2. --dump-slave=2 --gtid
|
||||
|
||||
-- SET GLOBAL gtid_slave_pos='0-1-1001';
|
||||
-- CHANGE MASTER '' TO MASTER_USE_GTID=slave_pos;
|
||||
-- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
*** Test mysqldump --master-data GTID functionality.
|
||||
|
||||
1. --master-data=1
|
||||
|
||||
-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
2. --dump-slave=2
|
||||
|
||||
-- SET GLOBAL gtid_slave_pos='0-1-1001';
|
||||
-- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
*** Test mysqldump --master-data GTID/non-gtid functionality.
|
||||
|
||||
1. --master-data=1 --gtid
|
||||
|
||||
CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
|
||||
SET GLOBAL gtid_slave_pos='0-2-1003';
|
||||
|
||||
2. --master-data=2
|
||||
|
||||
-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
1a. --master-data=1
|
||||
|
||||
-- SET GLOBAL gtid_slave_pos='0-2-1003';
|
||||
CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
2. --master-data=2 --gtid
|
||||
|
||||
-- CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
|
||||
-- SET GLOBAL gtid_slave_pos='0-2-1003';
|
||||
-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
2a. --master-data=2
|
||||
|
||||
-- SET GLOBAL gtid_slave_pos='0-2-1003';
|
||||
-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
3. --master-data --single-transaction --gtid
|
||||
|
||||
CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
|
||||
SET GLOBAL gtid_slave_pos='0-2-1003';
|
||||
-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
3a. --master-data --single-transaction
|
||||
|
||||
-- SET GLOBAL gtid_slave_pos='0-2-1003';
|
||||
CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
4. --master-data=2 --dump-slave=2 --single-transaction --gtid (MDEV-4827)
|
||||
|
||||
-- MariaDB dump--
|
||||
-- Host: localhost Database: test
|
||||
-- ------------------------------------------------------
|
||||
-- Server version
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
-- Preferably use GTID to start replication from GTID position:
|
||||
|
||||
-- CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
|
||||
-- SET GLOBAL gtid_slave_pos='0-2-1003';
|
||||
|
||||
3. --master-data --single-transaction
|
||||
--
|
||||
-- Alternately, following is the position of the binary logging from SHOW MASTER STATUS at point of backup.
|
||||
-- Use this when creating a replica of the primary server where the backup was made.
|
||||
-- The new server will be connecting to the primary server where the backup was taken.
|
||||
--
|
||||
|
||||
-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
|
||||
SET GLOBAL gtid_slave_pos='0-2-1003';
|
||||
|
||||
--
|
||||
-- The following is the SQL position of the replication taken from SHOW SLAVE STATUS at the time of backup.
|
||||
-- Use this position when creating a clone of, or replacement server, from where the backup was taken.
|
||||
-- This new server will connects to the same primary server(s).
|
||||
--
|
||||
-- GTID position to start replication:
|
||||
-- SET GLOBAL gtid_slave_pos='0-1-1001';
|
||||
|
||||
-- Use only the MASTER_USE_GTID=slave_pos or MASTER_LOG_FILE/MASTER_LOG_POS in the statements below.
|
||||
|
||||
-- CHANGE MASTER '' TO MASTER_USE_GTID=slave_pos;
|
||||
-- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
-- Dump completed
|
||||
|
||||
4a. --master-data=2 --dump-slave=2 --single-transaction (MDEV-4827)
|
||||
|
||||
-- MariaDB dump--
|
||||
-- Host: localhost Database: test
|
||||
-- ------------------------------------------------------
|
||||
-- Server version
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
-- Preferably use GTID to start replication from GTID position:
|
||||
|
||||
-- SET GLOBAL gtid_slave_pos='0-2-1003';
|
||||
|
||||
--
|
||||
-- Alternately, following is the position of the binary logging from SHOW MASTER STATUS at point of backup.
|
||||
-- Use this when creating a replica of the primary server where the backup was made.
|
||||
-- The new server will be connecting to the primary server where the backup was taken.
|
||||
--
|
||||
|
||||
-- CHANGE MASTER TO MASTER_LOG_FILE='slave-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
--
|
||||
-- The following is the SQL position of the replication taken from SHOW SLAVE STATUS at the time of backup.
|
||||
-- Use this position when creating a clone of, or replacement server, from where the backup was taken.
|
||||
-- This new server will connects to the same primary server(s).
|
||||
--
|
||||
-- GTID position to start replication:
|
||||
-- SET GLOBAL gtid_slave_pos='0-1-1001';
|
||||
-- CHANGE MASTER '' TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=BINLOG_START;
|
||||
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
-- Dump completed
|
||||
connection master;
|
||||
CREATE TABLE t (
|
||||
id int
|
||||
@@ -77,8 +215,8 @@ include/stop_slave.inc
|
||||
change master to master_use_gtid=slave_pos;
|
||||
connection master;
|
||||
# Ensuring the binlog dump thread is killed on primary...
|
||||
-- CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000002', MASTER_LOG_POS=BINLOG_START;
|
||||
-- SET GLOBAL gtid_slave_pos='0-1-1005';
|
||||
-- CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000002', MASTER_LOG_POS=BINLOG_START;
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/rpl_end.inc
|
||||
|
||||
@@ -37,7 +37,7 @@ start slave;
|
||||
start slave;
|
||||
|
||||
|
||||
--echo *** Test mysqldump --dump-slave GTID functionality.
|
||||
--echo *** Test mysqldump --dump-slave GTID/non-gtid functionality.
|
||||
|
||||
--connection master
|
||||
SET gtid_seq_no = 1000;
|
||||
@@ -52,37 +52,80 @@ CREATE TABLE t2 (a INT PRIMARY KEY);
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo
|
||||
--echo 1. --dump-slave=1
|
||||
--echo 1. --dump-slave=1 --gtid
|
||||
--echo
|
||||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/
|
||||
--exec $MYSQL_DUMP_SLAVE --compact --dump-slave=1 --gtid test
|
||||
|
||||
--echo
|
||||
--echo 2. --dump-slave=2
|
||||
--echo 1a. --dump-slave=1
|
||||
--echo
|
||||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/
|
||||
--exec $MYSQL_DUMP_SLAVE --compact --dump-slave=1 test
|
||||
|
||||
--echo
|
||||
--echo 2. --dump-slave=2 --gtid
|
||||
--echo
|
||||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/
|
||||
--exec $MYSQL_DUMP_SLAVE --compact --dump-slave=2 --gtid test
|
||||
|
||||
|
||||
--echo *** Test mysqldump --master-data GTID functionality.
|
||||
--echo
|
||||
--echo 1. --master-data=1
|
||||
--echo 2. --dump-slave=2
|
||||
--echo
|
||||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/
|
||||
--exec $MYSQL_DUMP_SLAVE --compact --dump-slave=2 test
|
||||
|
||||
|
||||
--echo *** Test mysqldump --master-data GTID/non-gtid functionality.
|
||||
--echo
|
||||
--echo 1. --master-data=1 --gtid
|
||||
--echo
|
||||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/
|
||||
--exec $MYSQL_DUMP_SLAVE --compact --master-data=1 --gtid test
|
||||
|
||||
--echo
|
||||
--echo 2. --master-data=2
|
||||
--echo 1a. --master-data=1
|
||||
--echo
|
||||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/
|
||||
--exec $MYSQL_DUMP_SLAVE --compact --master-data=1 test
|
||||
|
||||
--echo
|
||||
--echo 2. --master-data=2 --gtid
|
||||
--echo
|
||||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/
|
||||
--exec $MYSQL_DUMP_SLAVE --compact --master-data=2 --gtid test
|
||||
|
||||
--echo
|
||||
--echo 3. --master-data --single-transaction
|
||||
--echo 2a. --master-data=2
|
||||
--echo
|
||||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/
|
||||
--exec $MYSQL_DUMP_SLAVE --compact --master-data=2 test
|
||||
|
||||
--echo
|
||||
--echo 3. --master-data --single-transaction --gtid
|
||||
--echo
|
||||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/
|
||||
--exec $MYSQL_DUMP_SLAVE --compact --master-data --single-transaction --gtid test
|
||||
|
||||
--echo
|
||||
--echo 3a. --master-data --single-transaction
|
||||
--echo
|
||||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/
|
||||
--exec $MYSQL_DUMP_SLAVE --compact --master-data --single-transaction test
|
||||
|
||||
--echo
|
||||
--echo 4. --master-data=2 --dump-slave=2 --single-transaction --gtid (MDEV-4827)
|
||||
--echo
|
||||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ /MariaDB dump.*/MariaDB dump/ /Dump completed.*/Dump completed/ /Server version.*/Server version/
|
||||
--exec $MYSQL_DUMP_SLAVE --master-data=2 --dump-slave=2 --single-transaction --gtid test
|
||||
--echo
|
||||
|
||||
--echo
|
||||
--echo 4a. --master-data=2 --dump-slave=2 --single-transaction (MDEV-4827)
|
||||
--echo
|
||||
--replace_regex /MASTER_LOG_POS=[0-9]+/MASTER_LOG_POS=BINLOG_START/ /MariaDB dump.*/MariaDB dump/ /Dump completed.*/Dump completed/ /Server version.*/Server version/
|
||||
--exec $MYSQL_DUMP_SLAVE --master-data=2 --dump-slave=2 --single-transaction test
|
||||
--echo
|
||||
#
|
||||
# MDEV-32611 Added test for mysqldump --delete-master-logs option.
|
||||
# This options is alias of
|
||||
|
||||
@@ -88,15 +88,142 @@ sel
|
||||
]
|
||||
set optimizer_trace=@tmp;
|
||||
drop table t0,t1,t10;
|
||||
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
|
||||
set histogram_size=@save_histogram_size;
|
||||
set use_stat_tables= @save_use_stat_tables;
|
||||
#
|
||||
# End of 10.4 tests
|
||||
#
|
||||
#
|
||||
# MDEV-33314: Crash inside calculate_cond_selectivity_for_table() with many columns
|
||||
#
|
||||
set optimizer_use_condition_selectivity= 4;
|
||||
set use_stat_tables= preferably;
|
||||
#
|
||||
# create table t1 (col0 int, col1 int, col2 int, ...);
|
||||
#
|
||||
$create_tbl;
|
||||
#
|
||||
# insert into t1 select seq, ... seq from seq_1_to_10;
|
||||
#
|
||||
$insert_cmd;
|
||||
analyze table t1 persistent for all;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status Engine-independent statistics collected
|
||||
test.t1 analyze status OK
|
||||
set @trace_tmp=@@optimizer_trace;
|
||||
set optimizer_trace=1;
|
||||
#
|
||||
# Basic testcase: don't crash for many-column selectivity
|
||||
# explain extended select * from t1 where col0>1 and col1>1 and col2>1 and ...
|
||||
#
|
||||
$query_tbl;
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 1,
|
||||
"nested_loop": [
|
||||
{
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ALL",
|
||||
"rows": 100,
|
||||
"filtered": 53.32928848,
|
||||
"attached_condition": "t1.col0 > 1 and t1.col1 > 1 and t1.col2 > 1 and t1.col3 > 1 and t1.col4 > 1 and t1.col5 > 1 and t1.col6 > 1 and t1.col7 > 1 and t1.col8 > 1 and t1.col9 > 1 and t1.col10 > 1 and t1.col11 > 1 and t1.col12 > 1 and t1.col13 > 1 and t1.col14 > 1 and t1.col15 > 1 and t1.col16 > 1 and t1.col17 > 1 and t1.col18 > 1 and t1.col19 > 1 and t1.col20 > 1 and t1.col21 > 1 and t1.col22 > 1 and t1.col23 > 1 and t1.col24 > 1 and t1.col25 > 1 and t1.col26 > 1 and t1.col27 > 1 and t1.col28 > 1 and t1.col29 > 1 and t1.col30 > 1 and t1.col31 > 1 and t1.col32 > 1 and t1.col33 > 1 and t1.col34 > 1 and t1.col35 > 1 and t1.col36 > 1 and t1.col37 > 1 and t1.col38 > 1 and t1.col39 > 1 and t1.col40 > 1 and t1.col41 > 1 and t1.col42 > 1 and t1.col43 > 1 and t1.col44 > 1 and t1.col45 > 1 and t1.col46 > 1 and t1.col47 > 1 and t1.col48 > 1 and t1.col49 > 1 and t1.col50 > 1 and t1.col51 > 1 and t1.col52 > 1 and t1.col53 > 1 and t1.col54 > 1 and t1.col55 > 1 and t1.col56 > 1 and t1.col57 > 1 and t1.col58 > 1 and t1.col59 > 1 and t1.col60 > 1 and t1.col61 > 1 and t1.col62 > 1 and t1.col63 > 1 and t1.col64 > 1 and t1.col65 > 1 and t1.col66 > 1 and t1.col67 > 1 and t1.col68 > 1 and t1.col69 > 1 and t1.col70 > 1 and t1.col71 > 1 and t1.col72 > 1 and t1.col73 > 1 and t1.col74 > 1 and t1.col75 > 1 and t1.col76 > 1 and t1.col77 > 1 and t1.col78 > 1 and t1.col79 > 1 and t1.col80 > 1 and t1.col81 > 1 and t1.col82 > 1 and t1.col83 > 1 and t1.col84 > 1 and t1.col85 > 1 and t1.col86 > 1 and t1.col87 > 1 and t1.col88 > 1 and t1.col89 > 1 and t1.col90 > 1 and t1.col91 > 1 and t1.col92 > 1 and t1.col93 > 1 and t1.col94 > 1 and t1.col95 > 1 and t1.col96 > 1 and t1.col97 > 1 and t1.col98 > 1 and t1.col99 > 1 and t1.col100 > 1 and t1.col101 > 1 and t1.col102 > 1 and t1.col103 > 1 and t1.col104 > 1 and t1.col105 > 1 and t1.col106 > 1 and t1.col107 > 1 and t1.col108 > 1 and t1.col109 > 1 and t1.col110 > 1 and t1.col111 > 1 and t1.col112 > 1 and t1.col113 > 1 and t1.col114 > 1 and t1.col115 > 1 and t1.col116 > 1 and t1.col117 > 1 and t1.col118 > 1 and t1.col119 > 1 and t1.col120 > 1 and t1.col121 > 1 and t1.col122 > 1 and t1.col123 > 1 and t1.col124 > 1 and t1.col125 > 1 and t1.col126 > 1 and t1.col127 > 1 and t1.col128 > 1 and t1.col129 > 1 and t1.col130 > 1 and t1.col131 > 1 and t1.col132 > 1 and t1.col133 > 1 and t1.col134 > 1 and t1.col135 > 1 and t1.col136 > 1 and t1.col137 > 1 and t1.col138 > 1 and t1.col139 > 1 and t1.col140 > 1 and t1.col141 > 1 and t1.col142 > 1 and t1.col143 > 1 and t1.col144 > 1 and t1.col145 > 1 and t1.col146 > 1 and t1.col147 > 1 and t1.col148 > 1 and t1.col149 > 1 and t1.col150 > 1 and t1.col151 > 1 and t1.col152 > 1 and t1.col153 > 1 and t1.col154 > 1 and t1.col155 > 1 and t1.col156 > 1 and t1.col157 > 1 and t1.col158 > 1 and t1.col159 > 1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
select
|
||||
json_detailed(json_extract(trace,'$**.selectivity_for_columns[0]')) as JS
|
||||
from
|
||||
information_schema.optimizer_trace;
|
||||
JS
|
||||
[
|
||||
{
|
||||
"column_name": "col0",
|
||||
"ranges":
|
||||
["1 < col0"],
|
||||
"selectivity_from_histogram": 0.996078431
|
||||
}
|
||||
]
|
||||
$query_tbl;
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 1,
|
||||
"nested_loop": [
|
||||
{
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ALL",
|
||||
"rows": 100,
|
||||
"filtered": 53.32928848,
|
||||
"attached_condition": "t1.col0 > 1 and t1.col1 > 1 and t1.col2 > 1 and t1.col3 > 1 and t1.col4 > 1 and t1.col5 > 1 and t1.col6 > 1 and t1.col7 > 1 and t1.col8 > 1 and t1.col9 > 1 and t1.col10 > 1 and t1.col11 > 1 and t1.col12 > 1 and t1.col13 > 1 and t1.col14 > 1 and t1.col15 > 1 and t1.col16 > 1 and t1.col17 > 1 and t1.col18 > 1 and t1.col19 > 1 and t1.col20 > 1 and t1.col21 > 1 and t1.col22 > 1 and t1.col23 > 1 and t1.col24 > 1 and t1.col25 > 1 and t1.col26 > 1 and t1.col27 > 1 and t1.col28 > 1 and t1.col29 > 1 and t1.col30 > 1 and t1.col31 > 1 and t1.col32 > 1 and t1.col33 > 1 and t1.col34 > 1 and t1.col35 > 1 and t1.col36 > 1 and t1.col37 > 1 and t1.col38 > 1 and t1.col39 > 1 and t1.col40 > 1 and t1.col41 > 1 and t1.col42 > 1 and t1.col43 > 1 and t1.col44 > 1 and t1.col45 > 1 and t1.col46 > 1 and t1.col47 > 1 and t1.col48 > 1 and t1.col49 > 1 and t1.col50 > 1 and t1.col51 > 1 and t1.col52 > 1 and t1.col53 > 1 and t1.col54 > 1 and t1.col55 > 1 and t1.col56 > 1 and t1.col57 > 1 and t1.col58 > 1 and t1.col59 > 1 and t1.col60 > 1 and t1.col61 > 1 and t1.col62 > 1 and t1.col63 > 1 and t1.col64 > 1 and t1.col65 > 1 and t1.col66 > 1 and t1.col67 > 1 and t1.col68 > 1 and t1.col69 > 1 and t1.col70 > 1 and t1.col71 > 1 and t1.col72 > 1 and t1.col73 > 1 and t1.col74 > 1 and t1.col75 > 1 and t1.col76 > 1 and t1.col77 > 1 and t1.col78 > 1 and t1.col79 > 1 and t1.col80 > 1 and t1.col81 > 1 and t1.col82 > 1 and t1.col83 > 1 and t1.col84 > 1 and t1.col85 > 1 and t1.col86 > 1 and t1.col87 > 1 and t1.col88 > 1 and t1.col89 > 1 and t1.col90 > 1 and t1.col91 > 1 and t1.col92 > 1 and t1.col93 > 1 and t1.col94 > 1 and t1.col95 > 1 and t1.col96 > 1 and t1.col97 > 1 and t1.col98 > 1 and t1.col99 > 1 and t1.col100 > 1 and t1.col101 > 1 and t1.col102 > 1 and t1.col103 > 1 and t1.col104 > 1 and t1.col105 > 1 and t1.col106 > 1 and t1.col107 > 1 and t1.col108 > 1 and t1.col109 > 1 and t1.col110 > 1 and t1.col111 > 1 and t1.col112 > 1 and t1.col113 > 1 and t1.col114 > 1 and t1.col115 > 1 and t1.col116 > 1 and t1.col117 > 1 and t1.col118 > 1 and t1.col119 > 1 and t1.col120 > 1 and t1.col121 > 1 and t1.col122 > 1 and t1.col123 > 1 and t1.col124 > 1 and t1.col125 > 1 and t1.col126 > 1 and t1.col127 > 1 and t1.col128 > 1 and t1.col129 > 1 and t1.col130 > 1 and t1.col131 > 1 and t1.col132 > 1 and t1.col133 > 1 and t1.col134 > 1 and t1.col135 > 1 and t1.col136 > 1 and t1.col137 > 1 and t1.col138 > 1 and t1.col139 > 1 and t1.col140 > 1 and t1.col141 > 1 and t1.col142 > 1 and t1.col143 > 1 and t1.col144 > 1 and t1.col145 > 1 and t1.col146 > 1 and t1.col147 > 1 and t1.col148 > 1 and t1.col149 > 1 and t1.col150 > 1 and t1.col151 > 1 and t1.col152 > 1 and t1.col153 > 1 and t1.col154 > 1 and t1.col155 > 1 and t1.col156 > 1 and t1.col157 > 1 and t1.col158 > 1 and t1.col159 > 1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
select
|
||||
json_detailed(json_extract(trace,'$**.selectivity_for_columns[159]')) as JS
|
||||
from
|
||||
information_schema.optimizer_trace;
|
||||
JS
|
||||
[
|
||||
{
|
||||
"column_name": "col159",
|
||||
"ranges":
|
||||
["1 < col159"],
|
||||
"selectivity_from_histogram": 0.996078431
|
||||
}
|
||||
]
|
||||
#
|
||||
# Check if not being able to infer anything for the first MAX_KEY
|
||||
# columns doesn't prevent further inferences.
|
||||
#
|
||||
# explain extended select * from t1
|
||||
# where (1>2 or col0>1 or col1>1 or ...) and col99>1
|
||||
#
|
||||
$query_tbl;
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 1,
|
||||
"nested_loop": [
|
||||
{
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ALL",
|
||||
"rows": 100,
|
||||
"filtered": 99.60784149,
|
||||
"attached_condition": "(t1.col1 > 1 or t1.col2 > 1 or t1.col3 > 1 or t1.col4 > 1 or t1.col5 > 1 or t1.col6 > 1 or t1.col7 > 1 or t1.col8 > 1 or t1.col9 > 1 or t1.col10 > 1 or t1.col11 > 1 or t1.col12 > 1 or t1.col13 > 1 or t1.col14 > 1 or t1.col15 > 1 or t1.col16 > 1 or t1.col17 > 1 or t1.col18 > 1 or t1.col19 > 1 or t1.col20 > 1 or t1.col21 > 1 or t1.col22 > 1 or t1.col23 > 1 or t1.col24 > 1 or t1.col25 > 1 or t1.col26 > 1 or t1.col27 > 1 or t1.col28 > 1 or t1.col29 > 1 or t1.col30 > 1 or t1.col31 > 1 or t1.col32 > 1 or t1.col33 > 1 or t1.col34 > 1 or t1.col35 > 1 or t1.col36 > 1 or t1.col37 > 1 or t1.col38 > 1 or t1.col39 > 1 or t1.col40 > 1 or t1.col41 > 1 or t1.col42 > 1 or t1.col43 > 1 or t1.col44 > 1 or t1.col45 > 1 or t1.col46 > 1 or t1.col47 > 1 or t1.col48 > 1 or t1.col49 > 1 or t1.col50 > 1 or t1.col51 > 1 or t1.col52 > 1 or t1.col53 > 1 or t1.col54 > 1 or t1.col55 > 1 or t1.col56 > 1 or t1.col57 > 1 or t1.col58 > 1 or t1.col59 > 1 or t1.col60 > 1 or t1.col61 > 1 or t1.col62 > 1 or t1.col63 > 1 or t1.col64 > 1 or t1.col65 > 1 or t1.col66 > 1 or t1.col67 > 1 or t1.col68 > 1 or t1.col69 > 1 or t1.col70 > 1 or t1.col71 > 1 or t1.col72 > 1 or t1.col73 > 1 or t1.col74 > 1 or t1.col75 > 1 or t1.col76 > 1 or t1.col77 > 1 or t1.col78 > 1 or t1.col79 > 1 or t1.col80 > 1 or t1.col81 > 1 or t1.col82 > 1 or t1.col83 > 1 or t1.col84 > 1 or t1.col85 > 1 or t1.col86 > 1 or t1.col87 > 1 or t1.col88 > 1 or t1.col89 > 1 or t1.col90 > 1 or t1.col91 > 1 or t1.col92 > 1 or t1.col93 > 1 or t1.col94 > 1 or t1.col95 > 1 or t1.col96 > 1 or t1.col97 > 1 or t1.col98 > 1 or t1.col99 > 1 or t1.col100 > 1 or t1.col101 > 1 or t1.col102 > 1 or t1.col103 > 1 or t1.col104 > 1 or t1.col105 > 1 or t1.col106 > 1 or t1.col107 > 1 or t1.col108 > 1 or t1.col109 > 1 or t1.col110 > 1 or t1.col111 > 1 or t1.col112 > 1 or t1.col113 > 1 or t1.col114 > 1 or t1.col115 > 1 or t1.col116 > 1 or t1.col117 > 1 or t1.col118 > 1 or t1.col119 > 1 or t1.col120 > 1 or t1.col121 > 1 or t1.col122 > 1 or t1.col123 > 1 or t1.col124 > 1 or t1.col125 > 1 or t1.col126 > 1 or t1.col127 > 1 or t1.col128 > 1 or t1.col129 > 1 or t1.col130 > 1 or t1.col131 > 1 or t1.col132 > 1 or t1.col133 > 1 or t1.col134 > 1 or t1.col135 > 1 or t1.col136 > 1 or t1.col137 > 1 or t1.col138 > 1 or t1.col139 > 1 or t1.col140 > 1 or t1.col141 > 1 or t1.col142 > 1 or t1.col143 > 1 or t1.col144 > 1 or t1.col145 > 1 or t1.col146 > 1 or t1.col147 > 1 or t1.col148 > 1 or t1.col149 > 1 or t1.col150 > 1 or t1.col151 > 1 or t1.col152 > 1 or t1.col153 > 1 or t1.col154 > 1 or t1.col155 > 1 or t1.col156 > 1 or t1.col157 > 1 or t1.col158 > 1) and t1.col159 > 1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
select
|
||||
json_detailed(json_extract(trace,'$**.selectivity_for_columns')) as JS
|
||||
from
|
||||
information_schema.optimizer_trace;
|
||||
JS
|
||||
[
|
||||
[
|
||||
{
|
||||
"column_name": "col159",
|
||||
"ranges":
|
||||
["1 < col159"],
|
||||
"selectivity_from_histogram": 0.996078431
|
||||
}
|
||||
]
|
||||
]
|
||||
set optimizer_trace=@trace_tmp;
|
||||
drop table t1;
|
||||
#
|
||||
# Clean up
|
||||
#
|
||||
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
|
||||
set use_stat_tables= @save_use_stat_tables;
|
||||
set @@global.histogram_size=@save_histogram_size;
|
||||
set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
|
||||
SET SESSION STORAGE_ENGINE=DEFAULT;
|
||||
|
||||
@@ -83,13 +83,140 @@ sel
|
||||
]
|
||||
set optimizer_trace=@tmp;
|
||||
drop table t0,t1,t10;
|
||||
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
|
||||
set histogram_size=@save_histogram_size;
|
||||
set use_stat_tables= @save_use_stat_tables;
|
||||
#
|
||||
# End of 10.4 tests
|
||||
#
|
||||
#
|
||||
# MDEV-33314: Crash inside calculate_cond_selectivity_for_table() with many columns
|
||||
#
|
||||
set optimizer_use_condition_selectivity= 4;
|
||||
set use_stat_tables= preferably;
|
||||
#
|
||||
# create table t1 (col0 int, col1 int, col2 int, ...);
|
||||
#
|
||||
$create_tbl;
|
||||
#
|
||||
# insert into t1 select seq, ... seq from seq_1_to_10;
|
||||
#
|
||||
$insert_cmd;
|
||||
analyze table t1 persistent for all;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status Engine-independent statistics collected
|
||||
test.t1 analyze status OK
|
||||
set @trace_tmp=@@optimizer_trace;
|
||||
set optimizer_trace=1;
|
||||
#
|
||||
# Basic testcase: don't crash for many-column selectivity
|
||||
# explain extended select * from t1 where col0>1 and col1>1 and col2>1 and ...
|
||||
#
|
||||
$query_tbl;
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 1,
|
||||
"nested_loop": [
|
||||
{
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ALL",
|
||||
"rows": 100,
|
||||
"filtered": 53.32928848,
|
||||
"attached_condition": "t1.col0 > 1 and t1.col1 > 1 and t1.col2 > 1 and t1.col3 > 1 and t1.col4 > 1 and t1.col5 > 1 and t1.col6 > 1 and t1.col7 > 1 and t1.col8 > 1 and t1.col9 > 1 and t1.col10 > 1 and t1.col11 > 1 and t1.col12 > 1 and t1.col13 > 1 and t1.col14 > 1 and t1.col15 > 1 and t1.col16 > 1 and t1.col17 > 1 and t1.col18 > 1 and t1.col19 > 1 and t1.col20 > 1 and t1.col21 > 1 and t1.col22 > 1 and t1.col23 > 1 and t1.col24 > 1 and t1.col25 > 1 and t1.col26 > 1 and t1.col27 > 1 and t1.col28 > 1 and t1.col29 > 1 and t1.col30 > 1 and t1.col31 > 1 and t1.col32 > 1 and t1.col33 > 1 and t1.col34 > 1 and t1.col35 > 1 and t1.col36 > 1 and t1.col37 > 1 and t1.col38 > 1 and t1.col39 > 1 and t1.col40 > 1 and t1.col41 > 1 and t1.col42 > 1 and t1.col43 > 1 and t1.col44 > 1 and t1.col45 > 1 and t1.col46 > 1 and t1.col47 > 1 and t1.col48 > 1 and t1.col49 > 1 and t1.col50 > 1 and t1.col51 > 1 and t1.col52 > 1 and t1.col53 > 1 and t1.col54 > 1 and t1.col55 > 1 and t1.col56 > 1 and t1.col57 > 1 and t1.col58 > 1 and t1.col59 > 1 and t1.col60 > 1 and t1.col61 > 1 and t1.col62 > 1 and t1.col63 > 1 and t1.col64 > 1 and t1.col65 > 1 and t1.col66 > 1 and t1.col67 > 1 and t1.col68 > 1 and t1.col69 > 1 and t1.col70 > 1 and t1.col71 > 1 and t1.col72 > 1 and t1.col73 > 1 and t1.col74 > 1 and t1.col75 > 1 and t1.col76 > 1 and t1.col77 > 1 and t1.col78 > 1 and t1.col79 > 1 and t1.col80 > 1 and t1.col81 > 1 and t1.col82 > 1 and t1.col83 > 1 and t1.col84 > 1 and t1.col85 > 1 and t1.col86 > 1 and t1.col87 > 1 and t1.col88 > 1 and t1.col89 > 1 and t1.col90 > 1 and t1.col91 > 1 and t1.col92 > 1 and t1.col93 > 1 and t1.col94 > 1 and t1.col95 > 1 and t1.col96 > 1 and t1.col97 > 1 and t1.col98 > 1 and t1.col99 > 1 and t1.col100 > 1 and t1.col101 > 1 and t1.col102 > 1 and t1.col103 > 1 and t1.col104 > 1 and t1.col105 > 1 and t1.col106 > 1 and t1.col107 > 1 and t1.col108 > 1 and t1.col109 > 1 and t1.col110 > 1 and t1.col111 > 1 and t1.col112 > 1 and t1.col113 > 1 and t1.col114 > 1 and t1.col115 > 1 and t1.col116 > 1 and t1.col117 > 1 and t1.col118 > 1 and t1.col119 > 1 and t1.col120 > 1 and t1.col121 > 1 and t1.col122 > 1 and t1.col123 > 1 and t1.col124 > 1 and t1.col125 > 1 and t1.col126 > 1 and t1.col127 > 1 and t1.col128 > 1 and t1.col129 > 1 and t1.col130 > 1 and t1.col131 > 1 and t1.col132 > 1 and t1.col133 > 1 and t1.col134 > 1 and t1.col135 > 1 and t1.col136 > 1 and t1.col137 > 1 and t1.col138 > 1 and t1.col139 > 1 and t1.col140 > 1 and t1.col141 > 1 and t1.col142 > 1 and t1.col143 > 1 and t1.col144 > 1 and t1.col145 > 1 and t1.col146 > 1 and t1.col147 > 1 and t1.col148 > 1 and t1.col149 > 1 and t1.col150 > 1 and t1.col151 > 1 and t1.col152 > 1 and t1.col153 > 1 and t1.col154 > 1 and t1.col155 > 1 and t1.col156 > 1 and t1.col157 > 1 and t1.col158 > 1 and t1.col159 > 1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
select
|
||||
json_detailed(json_extract(trace,'$**.selectivity_for_columns[0]')) as JS
|
||||
from
|
||||
information_schema.optimizer_trace;
|
||||
JS
|
||||
[
|
||||
{
|
||||
"column_name": "col0",
|
||||
"ranges":
|
||||
["1 < col0"],
|
||||
"selectivity_from_histogram": 0.996078431
|
||||
}
|
||||
]
|
||||
$query_tbl;
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 1,
|
||||
"nested_loop": [
|
||||
{
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ALL",
|
||||
"rows": 100,
|
||||
"filtered": 53.32928848,
|
||||
"attached_condition": "t1.col0 > 1 and t1.col1 > 1 and t1.col2 > 1 and t1.col3 > 1 and t1.col4 > 1 and t1.col5 > 1 and t1.col6 > 1 and t1.col7 > 1 and t1.col8 > 1 and t1.col9 > 1 and t1.col10 > 1 and t1.col11 > 1 and t1.col12 > 1 and t1.col13 > 1 and t1.col14 > 1 and t1.col15 > 1 and t1.col16 > 1 and t1.col17 > 1 and t1.col18 > 1 and t1.col19 > 1 and t1.col20 > 1 and t1.col21 > 1 and t1.col22 > 1 and t1.col23 > 1 and t1.col24 > 1 and t1.col25 > 1 and t1.col26 > 1 and t1.col27 > 1 and t1.col28 > 1 and t1.col29 > 1 and t1.col30 > 1 and t1.col31 > 1 and t1.col32 > 1 and t1.col33 > 1 and t1.col34 > 1 and t1.col35 > 1 and t1.col36 > 1 and t1.col37 > 1 and t1.col38 > 1 and t1.col39 > 1 and t1.col40 > 1 and t1.col41 > 1 and t1.col42 > 1 and t1.col43 > 1 and t1.col44 > 1 and t1.col45 > 1 and t1.col46 > 1 and t1.col47 > 1 and t1.col48 > 1 and t1.col49 > 1 and t1.col50 > 1 and t1.col51 > 1 and t1.col52 > 1 and t1.col53 > 1 and t1.col54 > 1 and t1.col55 > 1 and t1.col56 > 1 and t1.col57 > 1 and t1.col58 > 1 and t1.col59 > 1 and t1.col60 > 1 and t1.col61 > 1 and t1.col62 > 1 and t1.col63 > 1 and t1.col64 > 1 and t1.col65 > 1 and t1.col66 > 1 and t1.col67 > 1 and t1.col68 > 1 and t1.col69 > 1 and t1.col70 > 1 and t1.col71 > 1 and t1.col72 > 1 and t1.col73 > 1 and t1.col74 > 1 and t1.col75 > 1 and t1.col76 > 1 and t1.col77 > 1 and t1.col78 > 1 and t1.col79 > 1 and t1.col80 > 1 and t1.col81 > 1 and t1.col82 > 1 and t1.col83 > 1 and t1.col84 > 1 and t1.col85 > 1 and t1.col86 > 1 and t1.col87 > 1 and t1.col88 > 1 and t1.col89 > 1 and t1.col90 > 1 and t1.col91 > 1 and t1.col92 > 1 and t1.col93 > 1 and t1.col94 > 1 and t1.col95 > 1 and t1.col96 > 1 and t1.col97 > 1 and t1.col98 > 1 and t1.col99 > 1 and t1.col100 > 1 and t1.col101 > 1 and t1.col102 > 1 and t1.col103 > 1 and t1.col104 > 1 and t1.col105 > 1 and t1.col106 > 1 and t1.col107 > 1 and t1.col108 > 1 and t1.col109 > 1 and t1.col110 > 1 and t1.col111 > 1 and t1.col112 > 1 and t1.col113 > 1 and t1.col114 > 1 and t1.col115 > 1 and t1.col116 > 1 and t1.col117 > 1 and t1.col118 > 1 and t1.col119 > 1 and t1.col120 > 1 and t1.col121 > 1 and t1.col122 > 1 and t1.col123 > 1 and t1.col124 > 1 and t1.col125 > 1 and t1.col126 > 1 and t1.col127 > 1 and t1.col128 > 1 and t1.col129 > 1 and t1.col130 > 1 and t1.col131 > 1 and t1.col132 > 1 and t1.col133 > 1 and t1.col134 > 1 and t1.col135 > 1 and t1.col136 > 1 and t1.col137 > 1 and t1.col138 > 1 and t1.col139 > 1 and t1.col140 > 1 and t1.col141 > 1 and t1.col142 > 1 and t1.col143 > 1 and t1.col144 > 1 and t1.col145 > 1 and t1.col146 > 1 and t1.col147 > 1 and t1.col148 > 1 and t1.col149 > 1 and t1.col150 > 1 and t1.col151 > 1 and t1.col152 > 1 and t1.col153 > 1 and t1.col154 > 1 and t1.col155 > 1 and t1.col156 > 1 and t1.col157 > 1 and t1.col158 > 1 and t1.col159 > 1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
select
|
||||
json_detailed(json_extract(trace,'$**.selectivity_for_columns[159]')) as JS
|
||||
from
|
||||
information_schema.optimizer_trace;
|
||||
JS
|
||||
[
|
||||
{
|
||||
"column_name": "col159",
|
||||
"ranges":
|
||||
["1 < col159"],
|
||||
"selectivity_from_histogram": 0.996078431
|
||||
}
|
||||
]
|
||||
#
|
||||
# Check if not being able to infer anything for the first MAX_KEY
|
||||
# columns doesn't prevent further inferences.
|
||||
#
|
||||
# explain extended select * from t1
|
||||
# where (1>2 or col0>1 or col1>1 or ...) and col99>1
|
||||
#
|
||||
$query_tbl;
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
"select_id": 1,
|
||||
"nested_loop": [
|
||||
{
|
||||
"table": {
|
||||
"table_name": "t1",
|
||||
"access_type": "ALL",
|
||||
"rows": 100,
|
||||
"filtered": 99.60784149,
|
||||
"attached_condition": "(t1.col1 > 1 or t1.col2 > 1 or t1.col3 > 1 or t1.col4 > 1 or t1.col5 > 1 or t1.col6 > 1 or t1.col7 > 1 or t1.col8 > 1 or t1.col9 > 1 or t1.col10 > 1 or t1.col11 > 1 or t1.col12 > 1 or t1.col13 > 1 or t1.col14 > 1 or t1.col15 > 1 or t1.col16 > 1 or t1.col17 > 1 or t1.col18 > 1 or t1.col19 > 1 or t1.col20 > 1 or t1.col21 > 1 or t1.col22 > 1 or t1.col23 > 1 or t1.col24 > 1 or t1.col25 > 1 or t1.col26 > 1 or t1.col27 > 1 or t1.col28 > 1 or t1.col29 > 1 or t1.col30 > 1 or t1.col31 > 1 or t1.col32 > 1 or t1.col33 > 1 or t1.col34 > 1 or t1.col35 > 1 or t1.col36 > 1 or t1.col37 > 1 or t1.col38 > 1 or t1.col39 > 1 or t1.col40 > 1 or t1.col41 > 1 or t1.col42 > 1 or t1.col43 > 1 or t1.col44 > 1 or t1.col45 > 1 or t1.col46 > 1 or t1.col47 > 1 or t1.col48 > 1 or t1.col49 > 1 or t1.col50 > 1 or t1.col51 > 1 or t1.col52 > 1 or t1.col53 > 1 or t1.col54 > 1 or t1.col55 > 1 or t1.col56 > 1 or t1.col57 > 1 or t1.col58 > 1 or t1.col59 > 1 or t1.col60 > 1 or t1.col61 > 1 or t1.col62 > 1 or t1.col63 > 1 or t1.col64 > 1 or t1.col65 > 1 or t1.col66 > 1 or t1.col67 > 1 or t1.col68 > 1 or t1.col69 > 1 or t1.col70 > 1 or t1.col71 > 1 or t1.col72 > 1 or t1.col73 > 1 or t1.col74 > 1 or t1.col75 > 1 or t1.col76 > 1 or t1.col77 > 1 or t1.col78 > 1 or t1.col79 > 1 or t1.col80 > 1 or t1.col81 > 1 or t1.col82 > 1 or t1.col83 > 1 or t1.col84 > 1 or t1.col85 > 1 or t1.col86 > 1 or t1.col87 > 1 or t1.col88 > 1 or t1.col89 > 1 or t1.col90 > 1 or t1.col91 > 1 or t1.col92 > 1 or t1.col93 > 1 or t1.col94 > 1 or t1.col95 > 1 or t1.col96 > 1 or t1.col97 > 1 or t1.col98 > 1 or t1.col99 > 1 or t1.col100 > 1 or t1.col101 > 1 or t1.col102 > 1 or t1.col103 > 1 or t1.col104 > 1 or t1.col105 > 1 or t1.col106 > 1 or t1.col107 > 1 or t1.col108 > 1 or t1.col109 > 1 or t1.col110 > 1 or t1.col111 > 1 or t1.col112 > 1 or t1.col113 > 1 or t1.col114 > 1 or t1.col115 > 1 or t1.col116 > 1 or t1.col117 > 1 or t1.col118 > 1 or t1.col119 > 1 or t1.col120 > 1 or t1.col121 > 1 or t1.col122 > 1 or t1.col123 > 1 or t1.col124 > 1 or t1.col125 > 1 or t1.col126 > 1 or t1.col127 > 1 or t1.col128 > 1 or t1.col129 > 1 or t1.col130 > 1 or t1.col131 > 1 or t1.col132 > 1 or t1.col133 > 1 or t1.col134 > 1 or t1.col135 > 1 or t1.col136 > 1 or t1.col137 > 1 or t1.col138 > 1 or t1.col139 > 1 or t1.col140 > 1 or t1.col141 > 1 or t1.col142 > 1 or t1.col143 > 1 or t1.col144 > 1 or t1.col145 > 1 or t1.col146 > 1 or t1.col147 > 1 or t1.col148 > 1 or t1.col149 > 1 or t1.col150 > 1 or t1.col151 > 1 or t1.col152 > 1 or t1.col153 > 1 or t1.col154 > 1 or t1.col155 > 1 or t1.col156 > 1 or t1.col157 > 1 or t1.col158 > 1) and t1.col159 > 1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
select
|
||||
json_detailed(json_extract(trace,'$**.selectivity_for_columns')) as JS
|
||||
from
|
||||
information_schema.optimizer_trace;
|
||||
JS
|
||||
[
|
||||
[
|
||||
{
|
||||
"column_name": "col159",
|
||||
"ranges":
|
||||
["1 < col159"],
|
||||
"selectivity_from_histogram": 0.996078431
|
||||
}
|
||||
]
|
||||
]
|
||||
set optimizer_trace=@trace_tmp;
|
||||
drop table t1;
|
||||
#
|
||||
# Clean up
|
||||
#
|
||||
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
|
||||
set use_stat_tables= @save_use_stat_tables;
|
||||
set @@global.histogram_size=@save_histogram_size;
|
||||
|
||||
@@ -105,17 +105,113 @@ from information_schema.optimizer_trace;
|
||||
set optimizer_trace=@tmp;
|
||||
drop table t0,t1,t10;
|
||||
|
||||
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
|
||||
set histogram_size=@save_histogram_size;
|
||||
set use_stat_tables= @save_use_stat_tables;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.4 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-33314: Crash inside calculate_cond_selectivity_for_table() with many columns
|
||||
--echo #
|
||||
set optimizer_use_condition_selectivity= 4;
|
||||
set use_stat_tables= preferably;
|
||||
|
||||
let $N_CONDS=160;
|
||||
let $N_LAST_COND=159;
|
||||
--echo #
|
||||
--echo # create table t1 (col0 int, col1 int, col2 int, ...);
|
||||
--echo #
|
||||
let $create_tbl= create table t1 ( col0 int;
|
||||
let $i=1;
|
||||
|
||||
while ($i < $N_CONDS) {
|
||||
let $create_tbl= $create_tbl, col$i int;
|
||||
let $i=`select $i + 1`;
|
||||
}
|
||||
|
||||
let $create_tbl= $create_tbl );
|
||||
#echo $create_tbl;
|
||||
evalp $create_tbl;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # insert into t1 select seq, ... seq from seq_1_to_10;
|
||||
--echo #
|
||||
let $insert_cmd= insert into t1 select seq;
|
||||
let $i=1;
|
||||
|
||||
while ($i < $N_CONDS) {
|
||||
let $insert_cmd = $insert_cmd ,seq;
|
||||
let $i=`select $i + 1`;
|
||||
}
|
||||
let $insert_cmd= $insert_cmd from seq_1_to_100;
|
||||
|
||||
# echo $insert_cmd;
|
||||
evalp $insert_cmd;
|
||||
|
||||
analyze table t1 persistent for all;
|
||||
set @trace_tmp=@@optimizer_trace;
|
||||
set optimizer_trace=1;
|
||||
|
||||
--echo #
|
||||
--echo # Basic testcase: don't crash for many-column selectivity
|
||||
--echo # explain extended select * from t1 where col0>1 and col1>1 and col2>1 and ...
|
||||
--echo #
|
||||
let $query_tbl= explain format=json select * from t1 where col0>1;
|
||||
|
||||
let $i=1;
|
||||
while ($i < $N_CONDS) {
|
||||
let $query_tbl= $query_tbl and col$i>1;
|
||||
let $i=`select $i + 1`;
|
||||
}
|
||||
|
||||
#echo $query_tbl;
|
||||
evalp $query_tbl;
|
||||
|
||||
select
|
||||
json_detailed(json_extract(trace,'$**.selectivity_for_columns[0]')) as JS
|
||||
from
|
||||
information_schema.optimizer_trace;
|
||||
|
||||
evalp $query_tbl;
|
||||
eval select
|
||||
json_detailed(json_extract(trace,'\$**.selectivity_for_columns[$N_LAST_COND]')) as JS
|
||||
from
|
||||
information_schema.optimizer_trace;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Check if not being able to infer anything for the first MAX_KEY
|
||||
--echo # columns doesn't prevent further inferences.
|
||||
--echo #
|
||||
--echo # explain extended select * from t1
|
||||
--echo # where (1>2 or col0>1 or col1>1 or ...) and col99>1
|
||||
--echo #
|
||||
let $query_tbl= explain format=json select * from t1 where (1>2 ;
|
||||
|
||||
let $i=1;
|
||||
while ($i < $N_LAST_COND) {
|
||||
let $query_tbl= $query_tbl or col$i>1;
|
||||
let $i=`select $i + 1`;
|
||||
}
|
||||
let $query_tbl= $query_tbl) and col$N_LAST_COND>1;
|
||||
|
||||
#echo $query_tbl;
|
||||
evalp $query_tbl;
|
||||
|
||||
select
|
||||
json_detailed(json_extract(trace,'$**.selectivity_for_columns')) as JS
|
||||
from
|
||||
information_schema.optimizer_trace;
|
||||
|
||||
set optimizer_trace=@trace_tmp;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # Clean up
|
||||
--echo #
|
||||
--source include/restore_charset.inc
|
||||
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
|
||||
set use_stat_tables= @save_use_stat_tables;
|
||||
set @@global.histogram_size=@save_histogram_size;
|
||||
|
||||
@@ -3101,7 +3101,7 @@ sub mysql_install_db {
|
||||
mtr_add_arg($args, "--core-file");
|
||||
mtr_add_arg($args, "--console");
|
||||
mtr_add_arg($args, "--character-set-server=latin1");
|
||||
mtr_add_arg($args, "--disable-performance-schema");
|
||||
mtr_add_arg($args, "--loose-disable-performance-schema");
|
||||
|
||||
if ( $opt_debug )
|
||||
{
|
||||
|
||||
BIN
mysql-test/std_data/autoinc_import_101.frm
Normal file
BIN
mysql-test/std_data/autoinc_import_101.frm
Normal file
Binary file not shown.
BIN
mysql-test/std_data/autoinc_import_57.frm
Normal file
BIN
mysql-test/std_data/autoinc_import_57.frm
Normal file
Binary file not shown.
@@ -23,6 +23,15 @@ insert into t2 select * from t1;
|
||||
insert into t3 select * from t1;
|
||||
insert into t4 select * from t1;
|
||||
commit;
|
||||
|
||||
# Flush all dirty pages from buffer pool
|
||||
SET @no_checkpoint_save_pct= @@GLOBAL.innodb_max_dirty_pages_pct;
|
||||
SET @no_checkpoint_save_pct_lwm= @@GLOBAL.innodb_max_dirty_pages_pct_lwm;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=0.0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct= @no_checkpoint_save_pct;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm= @no_checkpoint_save_pct_lwm;
|
||||
|
||||
CREATE TABLE t5 (a VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES;
|
||||
SET GLOBAL innodb_flush_log_at_trx_commit=1;
|
||||
begin;
|
||||
@@ -42,6 +51,6 @@ SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
||||
WHERE engine = 'innodb'
|
||||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
FOUND 1 /\[ERROR\] InnoDB: Encryption key is not found for .*test.t1.ibd/ in mysqld.1.err
|
||||
FOUND 1 /\[ERROR\] InnoDB: Encryption key is not found for .*test.t[1-5].ibd/ in mysqld.1.err
|
||||
# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt
|
||||
drop table t1,t2,t3,t4,t5;
|
||||
|
||||
@@ -44,7 +44,9 @@ insert into t3 select * from t1;
|
||||
insert into t4 select * from t1;
|
||||
commit;
|
||||
|
||||
let $no_checkpoint_flush= 1;
|
||||
--source ../../suite/innodb/include/no_checkpoint_start.inc
|
||||
|
||||
#
|
||||
# We test redo log page read at recv_read_page using
|
||||
# keys that are not in std_data/keys.txt. If checkpoint
|
||||
@@ -77,7 +79,7 @@ WHERE engine = 'innodb'
|
||||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||
|
||||
let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err;
|
||||
let SEARCH_PATTERN = \[ERROR\] InnoDB: Encryption key is not found for .*test.t1.ibd;
|
||||
let SEARCH_PATTERN = \[ERROR\] InnoDB: Encryption key is not found for .*test.t[1-5].ibd;
|
||||
--source include/search_pattern_in_file.inc
|
||||
|
||||
#
|
||||
|
||||
@@ -521,6 +521,23 @@ use federated;
|
||||
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
|
||||
WHERE id=2) dt2) dt;
|
||||
id name
|
||||
PREPARE stmt FROM "
|
||||
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
|
||||
WHERE id=3) dt2) dt;
|
||||
";
|
||||
EXECUTE stmt;
|
||||
id name
|
||||
3 xxx
|
||||
EXECUTE stmt;
|
||||
id name
|
||||
3 xxx
|
||||
DEALLOCATE PREPARE stmt;
|
||||
EXPLAIN
|
||||
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
|
||||
WHERE id=3) dt2) dt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 5 Using where
|
||||
4 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL
|
||||
connection slave;
|
||||
CREATE TABLE federated.t10 (a INT,b INT);
|
||||
CREATE TABLE federated.t11 (a INT, b INT);
|
||||
@@ -541,6 +558,54 @@ WHERE id=2) dt2) dt
|
||||
a b a b id name
|
||||
1 1 NULL NULL NULL NULL
|
||||
2 2 NULL NULL NULL NULL
|
||||
#
|
||||
# MDEV-31361: Second execution of PS for query with derived table
|
||||
#
|
||||
connection slave;
|
||||
DROP TABLE IF EXISTS federated.t1;
|
||||
CREATE TABLE federated.t1 (
|
||||
id int(20) NOT NULL,
|
||||
name varchar(16) NOT NULL default ''
|
||||
)
|
||||
DEFAULT CHARSET=latin1;
|
||||
INSERT INTO federated.t1 VALUES
|
||||
(3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy');
|
||||
connection master;
|
||||
DROP TABLE IF EXISTS federated.t1;
|
||||
CREATE TABLE federated.t1 (
|
||||
id int(20) NOT NULL,
|
||||
name varchar(16) NOT NULL default ''
|
||||
)
|
||||
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
||||
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
|
||||
use federated;
|
||||
SELECT * FROM
|
||||
(SELECT * FROM
|
||||
(SELECT * FROM
|
||||
(SELECT * FROM t1 where id>3) dt3
|
||||
WHERE id>3) dt2
|
||||
) dt;
|
||||
id name
|
||||
7 yyy
|
||||
4 xxx
|
||||
5 yyy
|
||||
PREPARE stmt FROM "SELECT * FROM
|
||||
(SELECT * FROM
|
||||
(SELECT * FROM
|
||||
(SELECT * FROM t1 where id>3) dt3
|
||||
WHERE id>3) dt2
|
||||
) dt";
|
||||
EXECUTE stmt;
|
||||
id name
|
||||
7 yyy
|
||||
4 xxx
|
||||
5 yyy
|
||||
EXECUTE stmt;
|
||||
id name
|
||||
7 yyy
|
||||
4 xxx
|
||||
5 yyy
|
||||
DEALLOCATE PREPARE stmt;
|
||||
set global federated_pushdown=0;
|
||||
connection master;
|
||||
DROP TABLE IF EXISTS federated.t1;
|
||||
|
||||
@@ -94,12 +94,9 @@ DEFAULT CHARSET=latin1;
|
||||
INSERT INTO federated.t3 VALUES
|
||||
('yyy'), ('www'), ('yyy'), ('xxx'), ('www'), ('yyy'), ('www');
|
||||
|
||||
#Enable after fix MDEV-31361
|
||||
--disable_ps2_protocol
|
||||
SELECT *
|
||||
FROM federated.t3, (SELECT * FROM federated.t1 WHERE id > 3) t
|
||||
WHERE federated.t3.name=t.name;
|
||||
--enable_ps2_protocol
|
||||
|
||||
EXPLAIN
|
||||
SELECT *
|
||||
@@ -354,6 +351,18 @@ use federated;
|
||||
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
|
||||
WHERE id=2) dt2) dt;
|
||||
|
||||
PREPARE stmt FROM "
|
||||
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
|
||||
WHERE id=3) dt2) dt;
|
||||
";
|
||||
EXECUTE stmt;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3
|
||||
WHERE id=3) dt2) dt;
|
||||
|
||||
connection slave;
|
||||
CREATE TABLE federated.t10 (a INT,b INT);
|
||||
CREATE TABLE federated.t11 (a INT, b INT);
|
||||
@@ -379,6 +388,52 @@ SELECT * FROM t10 LEFT JOIN
|
||||
WHERE id=2) dt2) dt
|
||||
) ON t10.a=t11.a;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-31361: Second execution of PS for query with derived table
|
||||
--echo #
|
||||
|
||||
connection slave;
|
||||
DROP TABLE IF EXISTS federated.t1;
|
||||
|
||||
CREATE TABLE federated.t1 (
|
||||
id int(20) NOT NULL,
|
||||
name varchar(16) NOT NULL default ''
|
||||
)
|
||||
DEFAULT CHARSET=latin1;
|
||||
|
||||
INSERT INTO federated.t1 VALUES
|
||||
(3,'xxx'), (7,'yyy'), (4,'xxx'), (1,'zzz'), (5,'yyy');
|
||||
|
||||
connection master;
|
||||
DROP TABLE IF EXISTS federated.t1;
|
||||
|
||||
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||
eval
|
||||
CREATE TABLE federated.t1 (
|
||||
id int(20) NOT NULL,
|
||||
name varchar(16) NOT NULL default ''
|
||||
)
|
||||
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
||||
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
|
||||
|
||||
use federated;
|
||||
|
||||
let $q=
|
||||
SELECT * FROM
|
||||
(SELECT * FROM
|
||||
(SELECT * FROM
|
||||
(SELECT * FROM t1 where id>3) dt3
|
||||
WHERE id>3) dt2
|
||||
) dt;
|
||||
|
||||
eval $q;
|
||||
|
||||
eval PREPARE stmt FROM "$q";
|
||||
EXECUTE stmt;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
|
||||
set global federated_pushdown=0;
|
||||
|
||||
source include/federated_cleanup.inc;
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
connection node_2;
|
||||
connection node_1;
|
||||
#
|
||||
# MDEV-33355 Add a Galera-2-node-to-MariaDB replication MTR test cloning the slave with mariadb-backup
|
||||
#
|
||||
connect master, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
connect slave, 127.0.0.1, root, , test, $NODE_MYPORT_3;
|
||||
START SLAVE;
|
||||
include/wait_for_slave_to_start.inc
|
||||
connection master;
|
||||
connection slave;
|
||||
##############################################################
|
||||
### Initial block with some transactions
|
||||
### Slave: Make sure replication is not using GTID
|
||||
connection slave;
|
||||
# Using_Gtid=No
|
||||
### Master: Create and populate t1
|
||||
connection master;
|
||||
CREATE TABLE t1(a TEXT) ENGINE=InnoDB;
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#00:stmt#00 - slave run#0, before backup');
|
||||
INSERT INTO t1 VALUES ('tr#00:stmt#01 - slave run#0, before backup');
|
||||
INSERT INTO t1 VALUES ('tr#00:stmt#02 - slave run#0, before backup');
|
||||
COMMIT;
|
||||
connection slave;
|
||||
##############################################################
|
||||
### Run the last transaction before mariadb-backup --backup
|
||||
### Remember SHOW MASTER STATUS and @@gtid_binlog_pos
|
||||
### before and after the transaction.
|
||||
### Master: Rember MASTER STATUS and @@gtid_binlog_pos before tr#01
|
||||
connection master;
|
||||
### Slave: Remember MASTER STATUS and @@gtid_binlog_pos before tr#01
|
||||
connection slave;
|
||||
### Master: Run the actual last transaction before the backup
|
||||
connection master;
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#01:stmt#00 - slave run#0, before backup');
|
||||
INSERT INTO t1 VALUES ('tr#01:stmt#01 - slave run#0, before backup');
|
||||
INSERT INTO t1 VALUES ('tr#01:stmt#02 - slave run#0, before backup');
|
||||
COMMIT;
|
||||
connection slave;
|
||||
### Master: Remember MASTER STATUS and @@gtid_binlog_pos after tr#01
|
||||
connection master;
|
||||
### Slave: Remember MASTER STATUS and @@gtid_binlog_pos after tr#01
|
||||
connection slave;
|
||||
##############################################################
|
||||
### Running `mariadb-backup --backup,--prepare` and checking
|
||||
### that xtrabackup_slave_info and xtrabackup_binlog_info are OK
|
||||
### Slave: Create a backup
|
||||
### Slave: Prepare the backup
|
||||
### Slave: xtrabackup files:
|
||||
############################ xtrabackup_slave_info
|
||||
CHANGE MASTER TO MASTER_LOG_FILE='master_after_tr01_show_master_status_file', MASTER_LOG_POS=master_after_tr01_show_master_status_position;
|
||||
############################ xtrabackup_binlog_info
|
||||
slave_after_tr01_show_master_status_file slave_after_tr01_show_master_status_position slave_after_tr01_gtid_binlog_pos
|
||||
############################
|
||||
##############################################################
|
||||
### Run more transactions after the backup:
|
||||
### - while the slave is still running, then
|
||||
### - while the slave is shut down
|
||||
### Master: Run another transaction while the slave is still running
|
||||
connection master;
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup');
|
||||
INSERT INTO t1 VALUES ('tr#02:stmt#01 - slave run#0, after backup');
|
||||
INSERT INTO t1 VALUES ('tr#02:stmt@02 - slave run#0, after backup');
|
||||
COMMIT;
|
||||
connection slave;
|
||||
### Master: Remember MASTER STATUS and @@gtid_binlog_pos after tr#02
|
||||
connection master;
|
||||
### Slave: Remember MASTER STATUS and @@gtid_binlog_pos after tr#02
|
||||
connection slave;
|
||||
### Master: Checking SHOW BINLOG EVENTS
|
||||
connection master;
|
||||
SHOW BINLOG EVENTS IN 'master_after_tr01_show_master_status_file' FROM master_after_tr01_show_master_status_position LIMIT 0,1;
|
||||
Log_name master_after_tr01_show_master_status_file
|
||||
Pos master_after_tr01_show_master_status_position
|
||||
Event_type Gtid
|
||||
Server_id #
|
||||
End_log_pos #
|
||||
Info BEGIN GTID master_after_tr02_gtid_binlog_pos
|
||||
SHOW BINLOG EVENTS IN 'master_after_tr01_show_master_status_file' FROM master_after_tr01_show_master_status_position LIMIT 1,1;
|
||||
Log_name master_after_tr01_show_master_status_file
|
||||
Pos #
|
||||
Event_type Query_or_Annotate_rows
|
||||
Server_id #
|
||||
End_log_pos #
|
||||
Info INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup')
|
||||
### Slave: Checking SHOW BINLOG EVENTS
|
||||
connection slave;
|
||||
SHOW BINLOG EVENTS IN 'slave_after_tr01_show_master_status_file' FROM slave_after_tr01_show_master_status_position LIMIT 0,1;
|
||||
Log_name slave_after_tr01_show_master_status_file
|
||||
Pos #
|
||||
Event_type Gtid
|
||||
Server_id 1
|
||||
End_log_pos #
|
||||
Info BEGIN GTID slave_after_tr02_gtid_binlog_pos
|
||||
SHOW BINLOG EVENTS IN 'slave_after_tr01_show_master_status_file' FROM slave_after_tr01_show_master_status_position LIMIT 1,1;
|
||||
Log_name slave_after_tr01_show_master_status_file
|
||||
Pos #
|
||||
Event_type Query_or_Annotate_rows
|
||||
Server_id #
|
||||
End_log_pos #
|
||||
Info INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup')
|
||||
### Slave: Stop replication
|
||||
connection slave;
|
||||
STOP SLAVE;
|
||||
include/wait_for_slave_to_stop.inc
|
||||
RESET SLAVE;
|
||||
Warnings:
|
||||
Note 4190 RESET SLAVE is implicitly changing the value of 'Using_Gtid' from 'No' to 'Slave_Pos'
|
||||
### Slave: Shutdown the server
|
||||
connection slave;
|
||||
### Master: Run a transaction while the slave is shut down
|
||||
connection master;
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#03:stmt#00 - after slave run#0, slave is shut down, after backup');
|
||||
INSERT INTO t1 VALUES ('tr#03:stmt#01 - after slave run#0, slave is shut down, after backup');
|
||||
INSERT INTO t1 VALUES ('tr#03:stmt#02 - after slave run#0, slave is shut down, after backup');
|
||||
COMMIT;
|
||||
##############################################################
|
||||
### Emulate starting a new virgin slave
|
||||
### Slave: Remove the data directory
|
||||
### Slave: Copy back the backup
|
||||
### Slave: Restart the server
|
||||
connection slave;
|
||||
# restart
|
||||
### Slave: Display the restored data before START SLAVE
|
||||
connection slave;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
tr#00:stmt#00 - slave run#0, before backup
|
||||
tr#00:stmt#01 - slave run#0, before backup
|
||||
tr#00:stmt#02 - slave run#0, before backup
|
||||
tr#01:stmt#00 - slave run#0, before backup
|
||||
tr#01:stmt#01 - slave run#0, before backup
|
||||
tr#01:stmt#02 - slave run#0, before backup
|
||||
### Slave: Execute the CHANGE MASTER statement to set up the host and port
|
||||
CHANGE MASTER '' TO MASTER_USER='root', MASTER_HOST='127.0.0.1', MASTER_PORT=###, MASTER_CONNECT_RETRY=1;
|
||||
### Slave: Execute the CHANGE MASTER statement from xtrabackup_slave_info
|
||||
CHANGE MASTER TO MASTER_LOG_FILE='master_after_tr01_show_master_status_file', MASTER_LOG_POS=master_after_tr01_show_master_status_position;
|
||||
Warnings:
|
||||
Note 4190 CHANGE MASTER TO is implicitly changing the value of 'Using_Gtid' from 'Slave_Pos' to 'No'
|
||||
### Slave: Execute START SLAVE
|
||||
include/start_slave.inc
|
||||
### Master: Wait for the slave to apply all master events
|
||||
connection master;
|
||||
connection slave;
|
||||
### Slave: Make sure replication is not using GTID after the slave restart
|
||||
connection slave;
|
||||
# Using_Gtid=No
|
||||
### Slave: Display the restored data after START SLAVE
|
||||
connection slave;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
tr#00:stmt#00 - slave run#0, before backup
|
||||
tr#00:stmt#01 - slave run#0, before backup
|
||||
tr#00:stmt#02 - slave run#0, before backup
|
||||
tr#01:stmt#00 - slave run#0, before backup
|
||||
tr#01:stmt#01 - slave run#0, before backup
|
||||
tr#01:stmt#02 - slave run#0, before backup
|
||||
tr#02:stmt#00 - slave run#0, after backup
|
||||
tr#02:stmt#01 - slave run#0, after backup
|
||||
tr#02:stmt@02 - slave run#0, after backup
|
||||
tr#03:stmt#00 - after slave run#0, slave is shut down, after backup
|
||||
tr#03:stmt#01 - after slave run#0, slave is shut down, after backup
|
||||
tr#03:stmt#02 - after slave run#0, slave is shut down, after backup
|
||||
##############################################################
|
||||
### Continue master transactions, check the new slave replicates well.
|
||||
### Master: Run a transaction after restarting replication
|
||||
connection master;
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#04:stmt#00 - slave run#1');
|
||||
INSERT INTO t1 VALUES ('tr#04:stmt#01 - slave run#1');
|
||||
INSERT INTO t1 VALUES ('tr#04:stmt#02 - slave run#1');
|
||||
COMMIT;
|
||||
connection slave;
|
||||
### Slave: Display the restored data + new transactions
|
||||
connection slave;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
tr#00:stmt#00 - slave run#0, before backup
|
||||
tr#00:stmt#01 - slave run#0, before backup
|
||||
tr#00:stmt#02 - slave run#0, before backup
|
||||
tr#01:stmt#00 - slave run#0, before backup
|
||||
tr#01:stmt#01 - slave run#0, before backup
|
||||
tr#01:stmt#02 - slave run#0, before backup
|
||||
tr#02:stmt#00 - slave run#0, after backup
|
||||
tr#02:stmt#01 - slave run#0, after backup
|
||||
tr#02:stmt@02 - slave run#0, after backup
|
||||
tr#03:stmt#00 - after slave run#0, slave is shut down, after backup
|
||||
tr#03:stmt#01 - after slave run#0, slave is shut down, after backup
|
||||
tr#03:stmt#02 - after slave run#0, slave is shut down, after backup
|
||||
tr#04:stmt#00 - slave run#1
|
||||
tr#04:stmt#01 - slave run#1
|
||||
tr#04:stmt#02 - slave run#1
|
||||
##############################################################
|
||||
### Cleanup
|
||||
### Removing the backup directory
|
||||
connection master;
|
||||
DROP TABLE t1;
|
||||
connection slave;
|
||||
STOP SLAVE;
|
||||
include/wait_for_slave_to_stop.inc
|
||||
RESET SLAVE ALL;
|
||||
Warnings:
|
||||
Note 4190 RESET SLAVE is implicitly changing the value of 'Using_Gtid' from 'No' to 'Slave_Pos'
|
||||
connection master;
|
||||
set global wsrep_on=OFF;
|
||||
RESET MASTER;
|
||||
set global wsrep_on=ON;
|
||||
@@ -0,0 +1 @@
|
||||
!include ../galera_2nodes_as_master.cnf
|
||||
@@ -0,0 +1,9 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/galera_cluster.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-33355 Add a Galera-2-node-to-MariaDB replication MTR test cloning the slave with mariadb-backup
|
||||
--echo #
|
||||
|
||||
--let cnf=galera2_to_mariadb
|
||||
--source include/rpl_clone_slave_using_mariadb-backup.inc
|
||||
@@ -1,5 +1,28 @@
|
||||
# Preparation for using no_checkpoint_end.inc
|
||||
|
||||
# no_checkpoint_flush: Set to trigger flushing the dirty pages from buffer pool
|
||||
# and checkpoint before the "no checkpoint" block.
|
||||
|
||||
if ($no_checkpoint_flush) {
|
||||
--echo
|
||||
--echo # Flush all dirty pages from buffer pool
|
||||
SET @no_checkpoint_save_pct= @@GLOBAL.innodb_max_dirty_pages_pct;
|
||||
SET @no_checkpoint_save_pct_lwm= @@GLOBAL.innodb_max_dirty_pages_pct_lwm;
|
||||
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=0.0;
|
||||
|
||||
let $wait_condition =
|
||||
SELECT variable_value = 0
|
||||
FROM information_schema.global_status
|
||||
WHERE variable_name = 'INNODB_BUFFER_POOL_PAGES_DIRTY';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
SET GLOBAL innodb_max_dirty_pages_pct= @no_checkpoint_save_pct;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm= @no_checkpoint_save_pct_lwm;
|
||||
--echo
|
||||
}
|
||||
|
||||
let MYSQLD_DATADIR= `select @@datadir`;
|
||||
--replace_regex /.*Last checkpoint at[ ]*([0-9]+).*/\1/
|
||||
let CHECKPOINT_LSN=`SHOW ENGINE INNODB STATUS`;
|
||||
|
||||
232
mysql-test/suite/innodb/r/autoinc_import.result
Normal file
232
mysql-test/suite/innodb/r/autoinc_import.result
Normal file
@@ -0,0 +1,232 @@
|
||||
CREATE TABLE t1 (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(42);
|
||||
CREATE TABLE t1b LIKE t1;
|
||||
INSERT INTO t1b VALUES(3);
|
||||
CREATE TABLE t1z LIKE t1;
|
||||
CREATE TABLE t1t (id TINYINT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
|
||||
CREATE TABLE t0t LIKE t1t;
|
||||
INSERT INTO t1t VALUES(123);
|
||||
FLUSH TABLES t1,t1b,t1t FOR EXPORT;
|
||||
UNLOCK TABLES;
|
||||
CREATE TABLE t5_7 LIKE t1;
|
||||
CREATE TABLE t5_7b LIKE t1b;
|
||||
CREATE TABLE t10_1 LIKE t1;
|
||||
CREATE TABLE t10_1b LIKE t1b;
|
||||
ALTER TABLE t1 DISCARD TABLESPACE;
|
||||
ALTER TABLE t1b DISCARD TABLESPACE;
|
||||
ALTER TABLE t1z DISCARD TABLESPACE;
|
||||
ALTER TABLE t1t DISCARD TABLESPACE;
|
||||
ALTER TABLE t0t DISCARD TABLESPACE;
|
||||
ALTER TABLE t5_7 DISCARD TABLESPACE;
|
||||
ALTER TABLE t5_7b DISCARD TABLESPACE;
|
||||
ALTER TABLE t10_1 DISCARD TABLESPACE;
|
||||
ALTER TABLE t10_1b DISCARD TABLESPACE;
|
||||
FLUSH TABLES;
|
||||
ALTER TABLE t0t IMPORT TABLESPACE;
|
||||
Warnings:
|
||||
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t0t.cfg', will attempt to import without schema verification
|
||||
INSERT INTO t0t VALUES(NULL);
|
||||
SELECT * FROM t0t;
|
||||
id
|
||||
123
|
||||
124
|
||||
DROP TABLE t0t;
|
||||
ALTER TABLE t1 IMPORT TABLESPACE;
|
||||
Warnings:
|
||||
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t1.cfg', will attempt to import without schema verification
|
||||
ALTER TABLE t1b IMPORT TABLESPACE;
|
||||
Warnings:
|
||||
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t1b.cfg', will attempt to import without schema verification
|
||||
ALTER TABLE t1z IMPORT TABLESPACE;
|
||||
Warnings:
|
||||
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t1z.cfg', will attempt to import without schema verification
|
||||
ALTER TABLE t1t IMPORT TABLESPACE;
|
||||
Warnings:
|
||||
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t1t.cfg', will attempt to import without schema verification
|
||||
ALTER TABLE t5_7 IMPORT TABLESPACE;
|
||||
Warnings:
|
||||
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t5_7.cfg', will attempt to import without schema verification
|
||||
ALTER TABLE t5_7b IMPORT TABLESPACE;
|
||||
Warnings:
|
||||
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t5_7b.cfg', will attempt to import without schema verification
|
||||
ALTER TABLE t10_1 IMPORT TABLESPACE;
|
||||
Warnings:
|
||||
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t10_1.cfg', will attempt to import without schema verification
|
||||
ALTER TABLE t10_1b IMPORT TABLESPACE;
|
||||
Warnings:
|
||||
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t10_1b.cfg', will attempt to import without schema verification
|
||||
FOUND 1 /InnoDB: Resetting PAGE_ROOT_AUTO_INC from 128 to 123 on table `test`\.`t0t`/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: Resetting PAGE_ROOT_AUTO_INC from 0 to 42 on table `test`\.`t1z`/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: Resetting PAGE_ROOT_AUTO_INC from 128 to 123 on table `test`\.`t1t`/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: Resetting PAGE_ROOT_AUTO_INC from 3 to 42 on table `test`\.`t5_7` \(created with version 50744\)/ in mysqld.1.err
|
||||
FOUND 1 /InnoDB: Resetting PAGE_ROOT_AUTO_INC from 3 to 42 on table `test`\.`t10_1` \(created with version 100149\)/ in mysqld.1.err
|
||||
FOUND 5 /InnoDB: Resetting PAGE_ROOT_AUTO_INC/ in mysqld.1.err
|
||||
# restart: --read-only
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
test.t1b check status OK
|
||||
test.t1t check status OK
|
||||
test.t1z check status OK
|
||||
test.t5_7 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t5_7 check status OK
|
||||
test.t5_7b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t5_7b check status OK
|
||||
test.t10_1 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t10_1 check status OK
|
||||
test.t10_1b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t10_1b check status OK
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
test.t1b check status OK
|
||||
test.t1t check status OK
|
||||
test.t1z check status OK
|
||||
test.t5_7 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t5_7 check status OK
|
||||
test.t5_7b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t5_7b check status OK
|
||||
test.t10_1 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t10_1 check status OK
|
||||
test.t10_1b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t10_1b check status OK
|
||||
# restart: --innodb-read-only --read-only
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
test.t1b check status OK
|
||||
test.t1t check status OK
|
||||
test.t1z check status OK
|
||||
test.t5_7 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t5_7 check status OK
|
||||
test.t5_7b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t5_7b check status OK
|
||||
test.t10_1 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t10_1 check status OK
|
||||
test.t10_1b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t10_1b check status OK
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
test.t1b check status OK
|
||||
test.t1t check status OK
|
||||
test.t1z check status OK
|
||||
test.t5_7 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t5_7 check status OK
|
||||
test.t5_7b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t5_7b check status OK
|
||||
test.t10_1 check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t10_1 check status OK
|
||||
test.t10_1b check note Auto_increment will be checked on each open until CHECK TABLE FOR UPGRADE is executed
|
||||
test.t10_1b check status OK
|
||||
# restart: --innodb-read-only
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
test.t1b check status OK
|
||||
test.t1t check status OK
|
||||
test.t1z check status OK
|
||||
test.t5_7 check status Operation failed
|
||||
test.t5_7b check status Operation failed
|
||||
test.t10_1 check status Operation failed
|
||||
test.t10_1b check status Operation failed
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
test.t1b check status OK
|
||||
test.t1t check status OK
|
||||
test.t1z check status OK
|
||||
test.t5_7 check status Operation failed
|
||||
test.t5_7b check status Operation failed
|
||||
test.t10_1 check status Operation failed
|
||||
test.t10_1b check status Operation failed
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
1
|
||||
SELECT COUNT(*) FROM t1b;
|
||||
COUNT(*)
|
||||
1
|
||||
SELECT COUNT(*) FROM t1t;
|
||||
COUNT(*)
|
||||
1
|
||||
SELECT COUNT(*) FROM t1z;
|
||||
COUNT(*)
|
||||
1
|
||||
SELECT COUNT(*) FROM t5_7;
|
||||
COUNT(*)
|
||||
1
|
||||
SELECT COUNT(*) FROM t5_7b;
|
||||
COUNT(*)
|
||||
1
|
||||
SELECT COUNT(*) FROM t10_1;
|
||||
COUNT(*)
|
||||
1
|
||||
SELECT COUNT(*) FROM t10_1b;
|
||||
COUNT(*)
|
||||
1
|
||||
# restart
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
test.t1b check status OK
|
||||
test.t1t check status OK
|
||||
test.t1z check status OK
|
||||
test.t5_7 check note Auto_increment checked and .frm file version updated
|
||||
test.t5_7 check status OK
|
||||
test.t5_7b check note Auto_increment checked and .frm file version updated
|
||||
test.t5_7b check status OK
|
||||
test.t10_1 check note Auto_increment checked and .frm file version updated
|
||||
test.t10_1 check status OK
|
||||
test.t10_1b check note Auto_increment checked and .frm file version updated
|
||||
test.t10_1b check status OK
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1b VALUES(NULL);
|
||||
INSERT INTO t1t VALUES(NULL);
|
||||
INSERT INTO t1z VALUES(NULL);
|
||||
INSERT INTO t5_7 VALUES(NULL);
|
||||
INSERT INTO t5_7b VALUES(NULL);
|
||||
INSERT INTO t10_1 VALUES(NULL);
|
||||
INSERT INTO t10_1b VALUES(NULL);
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
test.t1b check status OK
|
||||
test.t1t check status OK
|
||||
test.t1z check status OK
|
||||
test.t5_7 check status OK
|
||||
test.t5_7b check status OK
|
||||
test.t10_1 check status OK
|
||||
test.t10_1b check status OK
|
||||
SELECT * FROM t1;
|
||||
id
|
||||
4
|
||||
42
|
||||
SELECT * FROM t1b;
|
||||
id
|
||||
3
|
||||
347
|
||||
SELECT * FROM t1t;
|
||||
id
|
||||
123
|
||||
124
|
||||
SELECT * FROM t1z;
|
||||
id
|
||||
42
|
||||
43
|
||||
SELECT * FROM t5_7;
|
||||
id
|
||||
42
|
||||
43
|
||||
SELECT * FROM t5_7b;
|
||||
id
|
||||
3
|
||||
347
|
||||
SELECT * FROM t10_1;
|
||||
id
|
||||
42
|
||||
43
|
||||
SELECT * FROM t10_1b;
|
||||
id
|
||||
3
|
||||
347
|
||||
DROP TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b;
|
||||
@@ -1035,9 +1035,22 @@ BEGIN;
|
||||
INSERT INTO child SET a=1;
|
||||
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`))
|
||||
connection default;
|
||||
TRUNCATE TABLE parent;
|
||||
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`parent` (`a`))
|
||||
DROP TABLE parent;
|
||||
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
|
||||
SET innodb_lock_wait_timeout=0;
|
||||
RENAME TABLE parent TO transparent;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
ALTER TABLE parent FORCE, ALGORITHM=COPY;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
SET innodb_lock_wait_timeout=0, foreign_key_checks=0;
|
||||
TRUNCATE TABLE parent;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
DROP TABLE parent;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
ALTER TABLE parent FORCE, ALGORITHM=COPY;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
|
||||
@@ -1052,7 +1065,13 @@ TRUNCATE TABLE parent;
|
||||
ALTER TABLE parent FORCE, ALGORITHM=COPY;
|
||||
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
|
||||
ALTER TABLE parent ADD COLUMN b INT, ALGORITHM=INSTANT;
|
||||
DROP TABLE child, parent;
|
||||
SET foreign_key_checks=ON;
|
||||
TRUNCATE TABLE parent;
|
||||
ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`parent` (`a`))
|
||||
ALTER TABLE parent FORCE, ALGORITHM=COPY;
|
||||
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
|
||||
RENAME TABLE parent TO transparent;
|
||||
DROP TABLE child, transparent;
|
||||
#
|
||||
# MDEV-26217 Failing assertion: list.count > 0 in ut_list_remove
|
||||
# or Assertion `lock->trx == this' failed in dberr_t trx_t::drop_table
|
||||
|
||||
@@ -50,7 +50,15 @@ t1 CREATE TABLE `t1` (
|
||||
`b` blob DEFAULT NULL,
|
||||
`c` blob DEFAULT NULL,
|
||||
PRIMARY KEY (`a`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC
|
||||
# Auto increment value must be more than maximum column value
|
||||
SELECT MAX(a) FROM t1;
|
||||
MAX(a)
|
||||
45
|
||||
SELECT auto_increment FROM information_schema.tables
|
||||
WHERE table_name like 't1';
|
||||
auto_increment
|
||||
46
|
||||
UPDATE t1 set b = repeat("de", 100) where b = repeat("cd", 200);
|
||||
explain SELECT a FROM t1 where b = repeat("de", 100);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
@@ -132,7 +140,15 @@ t1 CREATE TABLE `t1` (
|
||||
`c2` point NOT NULL,
|
||||
`c3` linestring NOT NULL,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=16372 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=14325 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC
|
||||
# Auto increment value must be more than maximum column value
|
||||
SELECT MAX(c1) FROM t1;
|
||||
MAX(c1)
|
||||
14324
|
||||
SELECT auto_increment FROM information_schema.tables
|
||||
WHERE table_name like 't1';
|
||||
auto_increment
|
||||
14325
|
||||
UPDATE t1 SET C2 = ST_GeomFromText('POINT(0 0)');
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
|
||||
@@ -15,6 +15,41 @@ CREATE TABLE imp_t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||
DROP TABLE imp_t1, t1;
|
||||
SET GLOBAL innodb_checksum_algorithm=@save_innodb_checksum_algorithm;
|
||||
#
|
||||
# MDEV-18288: Transportable Tablespaces leave AUTO_INCREMENT in mismatched
|
||||
# state, causing INSERT errors in newly imported tables when .cfg is not used.
|
||||
#
|
||||
CREATE TABLE t1(
|
||||
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
ALTER TABLE t2 DISCARD TABLESPACE;
|
||||
INSERT INTO t1() VALUES();
|
||||
INSERT INTO t1() VALUES();
|
||||
FLUSH TABLES test.t1 FOR EXPORT;
|
||||
# Copy data file
|
||||
# Skip CFG file copy
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE t1;
|
||||
ALTER TABLE t2 IMPORT TABLESPACE;
|
||||
Warnings:
|
||||
Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t2.cfg', will attempt to import without schema verification
|
||||
SELECT * FROM t2 ORDER BY id;
|
||||
id
|
||||
1
|
||||
2
|
||||
INSERT INTO t2() VALUES();
|
||||
INSERT INTO t2() VALUES();
|
||||
INSERT INTO t2() VALUES();
|
||||
SELECT * FROM t2 ORDER BY id;
|
||||
id
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
DROP TABLE t2;
|
||||
#
|
||||
# MDEV-27006 Assertion `!lock_trx_has_sys_table_locks(trx)'
|
||||
# failed in dberr_t row_discard_tablespace_for_mysql
|
||||
# (dict_table_t*, trx_t*)
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
CREATE TABLE t (c INT) ENGINE=INNODB;
|
||||
SET @save_dbug = @@debug_dbug;
|
||||
SET debug_dbug = '+d,test_ut_format_name';
|
||||
DROP TABLE t;
|
||||
SET debug_dbug = @save_dbug;
|
||||
@@ -4,15 +4,14 @@ Variable_name Value
|
||||
innodb_doublewrite ON
|
||||
create table t1(f1 int not null, f2 int not null)engine=innodb;
|
||||
insert into t1 values (1, 1);
|
||||
InnoDB 0 transactions not purged
|
||||
set GLOBAL innodb_log_checkpoint_now=1;
|
||||
SET GLOBAL innodb_fast_shutdown = 0;
|
||||
# restart: --debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0
|
||||
# Make the first page dirty for undo tablespace
|
||||
set global innodb_saved_page_number_debug = 0;
|
||||
set global innodb_fil_make_page_dirty_debug = 1;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=0.0;
|
||||
SET GLOBAL innodb_buf_flush_list_now = 1;
|
||||
# Kill the server
|
||||
# restart
|
||||
# restart: --debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0
|
||||
FOUND 1 /Checksum mismatch in the first page of file/ in mysqld.1.err
|
||||
check table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
|
||||
168
mysql-test/suite/innodb/t/autoinc_import.test
Normal file
168
mysql-test/suite/innodb/t/autoinc_import.test
Normal file
@@ -0,0 +1,168 @@
|
||||
--source include/have_innodb.inc
|
||||
|
||||
CREATE TABLE t1 (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(42);
|
||||
CREATE TABLE t1b LIKE t1;
|
||||
INSERT INTO t1b VALUES(3);
|
||||
CREATE TABLE t1z LIKE t1;
|
||||
CREATE TABLE t1t (id TINYINT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
|
||||
CREATE TABLE t0t LIKE t1t;
|
||||
INSERT INTO t1t VALUES(123);
|
||||
--let DATADIR=`select @@datadir`
|
||||
--let PAGE_SIZE=`select @@innodb_page_size`
|
||||
FLUSH TABLES t1,t1b,t1t FOR EXPORT;
|
||||
--copy_file $DATADIR/test/t1.ibd $DATADIR/test/t.ibd
|
||||
--copy_file $DATADIR/test/t1.ibd $DATADIR/test/tz.ibd
|
||||
--copy_file $DATADIR/test/t1b.ibd $DATADIR/test/tb.ibd
|
||||
--copy_file $DATADIR/test/t1t.ibd $DATADIR/test/tt.ibd
|
||||
UNLOCK TABLES;
|
||||
CREATE TABLE t5_7 LIKE t1;
|
||||
CREATE TABLE t5_7b LIKE t1b;
|
||||
CREATE TABLE t10_1 LIKE t1;
|
||||
CREATE TABLE t10_1b LIKE t1b;
|
||||
ALTER TABLE t1 DISCARD TABLESPACE;
|
||||
ALTER TABLE t1b DISCARD TABLESPACE;
|
||||
ALTER TABLE t1z DISCARD TABLESPACE;
|
||||
ALTER TABLE t1t DISCARD TABLESPACE;
|
||||
ALTER TABLE t0t DISCARD TABLESPACE;
|
||||
ALTER TABLE t5_7 DISCARD TABLESPACE;
|
||||
ALTER TABLE t5_7b DISCARD TABLESPACE;
|
||||
ALTER TABLE t10_1 DISCARD TABLESPACE;
|
||||
ALTER TABLE t10_1b DISCARD TABLESPACE;
|
||||
FLUSH TABLES;
|
||||
|
||||
# Update the PAGE_ROOT_AUTO_INC field of a few files.
|
||||
perl;
|
||||
do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
|
||||
sub update_autoinc
|
||||
{
|
||||
my ($file, $value) = @_;
|
||||
open(FILE, "+<$file") || die "Unable to open $file";
|
||||
binmode FILE;
|
||||
my $ps= $ENV{PAGE_SIZE};
|
||||
my $page;
|
||||
die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
|
||||
my $full_crc32 = unpack("N",substr($page,54,4)) & 0x10; # FIL_SPACE_FLAGS
|
||||
sysseek(FILE, 3*$ps, 0) || die "Unable to seek $file\n";
|
||||
die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
|
||||
substr($page,56,8)=pack("NN",0,$value);
|
||||
my $polynomial = 0x82f63b78; # CRC-32C
|
||||
if ($full_crc32) {
|
||||
my $ck = mycrc32(substr($page, 0, $ps-4), 0, $polynomial);
|
||||
substr($page, $ps-4, 4) = pack("N", $ck);
|
||||
}
|
||||
else
|
||||
{
|
||||
my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^
|
||||
mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial));
|
||||
substr($page,0,4)=$ck;
|
||||
substr($page,$ps-8,4)=$ck;
|
||||
}
|
||||
sysseek(FILE, 3*$ps, 0) || die "Unable to rewind $file\n";
|
||||
syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n";
|
||||
close(FILE) || die "Unable to close $file";
|
||||
}
|
||||
update_autoinc("$ENV{DATADIR}/test/tz.ibd", 0);
|
||||
update_autoinc("$ENV{DATADIR}/test/t.ibd", 3);
|
||||
update_autoinc("$ENV{DATADIR}/test/tb.ibd", 346);
|
||||
update_autoinc("$ENV{DATADIR}/test/tt.ibd", 128);
|
||||
EOF
|
||||
|
||||
--remove_file $DATADIR/test/t5_7.frm
|
||||
--remove_file $DATADIR/test/t5_7b.frm
|
||||
--copy_file $MYSQL_TEST_DIR/std_data/autoinc_import_57.frm $DATADIR/test/t5_7.frm
|
||||
--copy_file $MYSQL_TEST_DIR/std_data/autoinc_import_57.frm $DATADIR/test/t5_7b.frm
|
||||
--remove_file $DATADIR/test/t10_1.frm
|
||||
--remove_file $DATADIR/test/t10_1b.frm
|
||||
--copy_file $MYSQL_TEST_DIR/std_data/autoinc_import_101.frm $DATADIR/test/t10_1.frm
|
||||
--copy_file $MYSQL_TEST_DIR/std_data/autoinc_import_101.frm $DATADIR/test/t10_1b.frm
|
||||
--copy_file $DATADIR/test/t.ibd $DATADIR/test/t5_7.ibd
|
||||
--copy_file $DATADIR/test/tb.ibd $DATADIR/test/t5_7b.ibd
|
||||
--copy_file $DATADIR/test/t.ibd $DATADIR/test/t10_1.ibd
|
||||
--copy_file $DATADIR/test/tb.ibd $DATADIR/test/t10_1b.ibd
|
||||
--move_file $DATADIR/test/t.ibd $DATADIR/test/t1.ibd
|
||||
--move_file $DATADIR/test/tb.ibd $DATADIR/test/t1b.ibd
|
||||
--copy_file $DATADIR/test/tt.ibd $DATADIR/test/t0t.ibd
|
||||
--move_file $DATADIR/test/tt.ibd $DATADIR/test/t1t.ibd
|
||||
--move_file $DATADIR/test/tz.ibd $DATADIR/test/t1z.ibd
|
||||
|
||||
ALTER TABLE t0t IMPORT TABLESPACE;
|
||||
INSERT INTO t0t VALUES(NULL);
|
||||
SELECT * FROM t0t;
|
||||
DROP TABLE t0t;
|
||||
ALTER TABLE t1 IMPORT TABLESPACE;
|
||||
ALTER TABLE t1b IMPORT TABLESPACE;
|
||||
ALTER TABLE t1z IMPORT TABLESPACE;
|
||||
ALTER TABLE t1t IMPORT TABLESPACE;
|
||||
ALTER TABLE t5_7 IMPORT TABLESPACE;
|
||||
ALTER TABLE t5_7b IMPORT TABLESPACE;
|
||||
ALTER TABLE t10_1 IMPORT TABLESPACE;
|
||||
ALTER TABLE t10_1b IMPORT TABLESPACE;
|
||||
|
||||
--let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let SEARCH_PATTERN= InnoDB: Resetting PAGE_ROOT_AUTO_INC from 128 to 123 on table `test`\.`t0t`
|
||||
--source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN= InnoDB: Resetting PAGE_ROOT_AUTO_INC from 0 to 42 on table `test`\.`t1z`
|
||||
--source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN= InnoDB: Resetting PAGE_ROOT_AUTO_INC from 128 to 123 on table `test`\.`t1t`
|
||||
--source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN= InnoDB: Resetting PAGE_ROOT_AUTO_INC from 3 to 42 on table `test`\.`t5_7` \(created with version 50744\)
|
||||
--source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN= InnoDB: Resetting PAGE_ROOT_AUTO_INC from 3 to 42 on table `test`\.`t10_1` \(created with version 100149\)
|
||||
--source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN= InnoDB: Resetting PAGE_ROOT_AUTO_INC
|
||||
--source include/search_pattern_in_file.inc
|
||||
|
||||
# Restart, so that the InnoDB tables will be loaded into the data dictionary.
|
||||
--let $restart_parameters=--read-only
|
||||
--source include/restart_mysqld.inc
|
||||
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b;
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE;
|
||||
|
||||
--let $restart_parameters=--innodb-read-only --read-only
|
||||
--source include/restart_mysqld.inc
|
||||
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b;
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE;
|
||||
|
||||
--let $restart_parameters=--innodb-read-only
|
||||
--source include/restart_mysqld.inc
|
||||
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b;
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE;
|
||||
|
||||
SELECT COUNT(*) FROM t1;
|
||||
SELECT COUNT(*) FROM t1b;
|
||||
SELECT COUNT(*) FROM t1t;
|
||||
SELECT COUNT(*) FROM t1z;
|
||||
SELECT COUNT(*) FROM t5_7;
|
||||
SELECT COUNT(*) FROM t5_7b;
|
||||
SELECT COUNT(*) FROM t10_1;
|
||||
SELECT COUNT(*) FROM t10_1b;
|
||||
|
||||
--let $restart_parameters=
|
||||
--source include/restart_mysqld.inc
|
||||
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE;
|
||||
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1b VALUES(NULL);
|
||||
INSERT INTO t1t VALUES(NULL);
|
||||
INSERT INTO t1z VALUES(NULL);
|
||||
INSERT INTO t5_7 VALUES(NULL);
|
||||
INSERT INTO t5_7b VALUES(NULL);
|
||||
INSERT INTO t10_1 VALUES(NULL);
|
||||
INSERT INTO t10_1b VALUES(NULL);
|
||||
|
||||
CHECK TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b FOR UPGRADE;
|
||||
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t1b;
|
||||
SELECT * FROM t1t;
|
||||
SELECT * FROM t1z;
|
||||
SELECT * FROM t5_7;
|
||||
SELECT * FROM t5_7b;
|
||||
SELECT * FROM t10_1;
|
||||
SELECT * FROM t10_1b;
|
||||
DROP TABLE t1, t1b, t1t, t1z, t5_7, t5_7b, t10_1, t10_1b;
|
||||
@@ -1077,10 +1077,23 @@ BEGIN;
|
||||
--error ER_NO_REFERENCED_ROW_2
|
||||
INSERT INTO child SET a=1;
|
||||
connection default;
|
||||
--error ER_TRUNCATE_ILLEGAL_FK
|
||||
TRUNCATE TABLE parent;
|
||||
--error ER_ROW_IS_REFERENCED_2
|
||||
DROP TABLE parent;
|
||||
SET innodb_lock_wait_timeout=0;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
RENAME TABLE parent TO transparent;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
ALTER TABLE parent FORCE, ALGORITHM=COPY;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
|
||||
SET innodb_lock_wait_timeout=0, foreign_key_checks=0;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
TRUNCATE TABLE parent;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
DROP TABLE parent;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
ALTER TABLE parent FORCE, ALGORITHM=COPY;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
|
||||
@@ -1095,7 +1108,13 @@ TRUNCATE TABLE parent;
|
||||
ALTER TABLE parent FORCE, ALGORITHM=COPY;
|
||||
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
|
||||
ALTER TABLE parent ADD COLUMN b INT, ALGORITHM=INSTANT;
|
||||
DROP TABLE child, parent;
|
||||
SET foreign_key_checks=ON;
|
||||
--error ER_TRUNCATE_ILLEGAL_FK
|
||||
TRUNCATE TABLE parent;
|
||||
ALTER TABLE parent FORCE, ALGORITHM=COPY;
|
||||
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
|
||||
RENAME TABLE parent TO transparent;
|
||||
DROP TABLE child, transparent;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-26217 Failing assertion: list.count > 0 in ut_list_remove
|
||||
|
||||
@@ -63,6 +63,12 @@ ALTER TABLE t1 DROP INDEX b;
|
||||
ALTER TABLE t1 IMPORT TABLESPACE;
|
||||
--enable_warnings
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo # Auto increment value must be more than maximum column value
|
||||
SELECT MAX(a) FROM t1;
|
||||
SELECT auto_increment FROM information_schema.tables
|
||||
WHERE table_name like 't1';
|
||||
|
||||
UPDATE t1 set b = repeat("de", 100) where b = repeat("cd", 200);
|
||||
--replace_column 9 #
|
||||
explain SELECT a FROM t1 where b = repeat("de", 100);
|
||||
@@ -145,6 +151,12 @@ ALTER TABLE t1 DROP INDEX idx1;
|
||||
ALTER TABLE t1 IMPORT TABLESPACE;
|
||||
--disable_warnings
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--echo # Auto increment value must be more than maximum column value
|
||||
SELECT MAX(c1) FROM t1;
|
||||
SELECT auto_increment FROM information_schema.tables
|
||||
WHERE table_name like 't1';
|
||||
|
||||
UPDATE t1 SET C2 = ST_GeomFromText('POINT(0 0)');
|
||||
SELECT COUNT(*) FROM t1;
|
||||
DELETE FROM t1;
|
||||
|
||||
@@ -22,6 +22,47 @@ DROP TABLE imp_t1, t1;
|
||||
|
||||
SET GLOBAL innodb_checksum_algorithm=@save_innodb_checksum_algorithm;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-18288: Transportable Tablespaces leave AUTO_INCREMENT in mismatched
|
||||
--echo # state, causing INSERT errors in newly imported tables when .cfg is not used.
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1(
|
||||
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=INNODB;
|
||||
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
|
||||
ALTER TABLE t2 DISCARD TABLESPACE;
|
||||
|
||||
INSERT INTO t1() VALUES();
|
||||
INSERT INTO t1() VALUES();
|
||||
|
||||
FLUSH TABLES test.t1 FOR EXPORT;
|
||||
|
||||
--echo # Copy data file
|
||||
--copy_file $datadir/test/t1.ibd $datadir/test/t2.ibd
|
||||
|
||||
--echo # Skip CFG file copy
|
||||
#--copy_file $datadir/test/t1.cfg $datadir/test/t2.cfg
|
||||
--remove_file $datadir/test/t1.cfg
|
||||
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE t1;
|
||||
|
||||
--replace_regex /opening '.*\/test\//opening '.\/test\//
|
||||
ALTER TABLE t2 IMPORT TABLESPACE;
|
||||
|
||||
SELECT * FROM t2 ORDER BY id;
|
||||
|
||||
INSERT INTO t2() VALUES();
|
||||
INSERT INTO t2() VALUES();
|
||||
INSERT INTO t2() VALUES();
|
||||
|
||||
SELECT * FROM t2 ORDER BY id;
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-27006 Assertion `!lock_trx_has_sys_table_locks(trx)'
|
||||
--echo # failed in dberr_t row_discard_tablespace_for_mysql
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#
|
||||
# Test ut_format_name()
|
||||
#
|
||||
|
||||
-- source include/have_debug.inc
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
CREATE TABLE t (c INT) ENGINE=INNODB;
|
||||
|
||||
# This will invoke test_ut_format_name() in debug builds
|
||||
|
||||
SET @save_dbug = @@debug_dbug;
|
||||
SET debug_dbug = '+d,test_ut_format_name';
|
||||
|
||||
DROP TABLE t;
|
||||
|
||||
SET debug_dbug = @save_dbug;
|
||||
@@ -9,19 +9,19 @@ show variables like 'innodb_doublewrite';
|
||||
create table t1(f1 int not null, f2 int not null)engine=innodb;
|
||||
insert into t1 values (1, 1);
|
||||
|
||||
--source include/wait_all_purged.inc
|
||||
# Slow shutdown and restart to make sure ibuf merge is finished
|
||||
SET GLOBAL innodb_fast_shutdown = 0;
|
||||
let $shutdown_timeout=;
|
||||
let $restart_parameters="--debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0";
|
||||
--source include/restart_mysqld.inc
|
||||
|
||||
set GLOBAL innodb_log_checkpoint_now=1;
|
||||
--source ../include/no_checkpoint_start.inc
|
||||
|
||||
--echo # Make the first page dirty for undo tablespace
|
||||
set global innodb_saved_page_number_debug = 0;
|
||||
set global innodb_fil_make_page_dirty_debug = 1;
|
||||
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=0.0;
|
||||
SET GLOBAL innodb_buf_flush_list_now = 1;
|
||||
|
||||
sleep 1;
|
||||
--let CLEANUP_IF_CHECKPOINT=drop table t1;
|
||||
--source ../include/no_checkpoint_end.inc
|
||||
|
||||
|
||||
@@ -14,6 +14,14 @@ ALTER TABLE t1 IMPORT TABLESPACE;
|
||||
SELECT * FROM t1;
|
||||
i
|
||||
1
|
||||
# MDEV-33023 Crash in mariadb-backup --prepare --export after --prepare
|
||||
t1.cfg
|
||||
t21.cfg
|
||||
ALTER TABLE t1 DISCARD TABLESPACE;
|
||||
ALTER TABLE t1 IMPORT TABLESPACE;
|
||||
SELECT * FROM t1;
|
||||
i
|
||||
1
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t21;
|
||||
|
||||
@@ -55,6 +55,25 @@ copy_file $targetdir/test/t1.cfg $MYSQLD_DATADIR/test/t1.cfg;
|
||||
ALTER TABLE t1 IMPORT TABLESPACE;
|
||||
|
||||
SELECT * FROM t1;
|
||||
|
||||
--echo # MDEV-33023 Crash in mariadb-backup --prepare --export after --prepare
|
||||
--disable_result_log
|
||||
exec $XTRABACKUP --defaults-file=$server_cnf --defaults-group-suffix=.1 --prepare --target-dir=$targetdir;
|
||||
exec $XTRABACKUP --defaults-file=$server_cnf --defaults-group-suffix=.1 --prepare --export --target-dir=$targetdir;
|
||||
--enable_result_log
|
||||
|
||||
list_files $targetdir/test *.cfg;
|
||||
# There must not be binary logs created on --prepare step
|
||||
list_files $targetdir/ mysqld-bin.*;
|
||||
|
||||
let $MYSQLD_DATADIR= `select @@datadir`;
|
||||
ALTER TABLE t1 DISCARD TABLESPACE;
|
||||
copy_file $targetdir/test/t1.ibd $MYSQLD_DATADIR/test/t1.ibd;
|
||||
copy_file $targetdir/test/t1.cfg $MYSQLD_DATADIR/test/t1.cfg;
|
||||
ALTER TABLE t1 IMPORT TABLESPACE;
|
||||
|
||||
SELECT * FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t21;
|
||||
|
||||
202
mysql-test/suite/mariabackup/rpl_clone_slave.result
Normal file
202
mysql-test/suite/mariabackup/rpl_clone_slave.result
Normal file
@@ -0,0 +1,202 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
#
|
||||
# MDEV-33342 Add a replication MTR test cloning the slave with mariadb-backup
|
||||
#
|
||||
connection slave;
|
||||
stop slave;
|
||||
change master to master_use_gtid=no;
|
||||
start slave;
|
||||
connection master;
|
||||
connection slave;
|
||||
##############################################################
|
||||
### Initial block with some transactions
|
||||
### Slave: Make sure replication is not using GTID
|
||||
connection slave;
|
||||
# Using_Gtid=No
|
||||
### Master: Create and populate t1
|
||||
connection master;
|
||||
CREATE TABLE t1(a TEXT) ENGINE=InnoDB;
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#00:stmt#00 - slave run#0, before backup');
|
||||
INSERT INTO t1 VALUES ('tr#00:stmt#01 - slave run#0, before backup');
|
||||
INSERT INTO t1 VALUES ('tr#00:stmt#02 - slave run#0, before backup');
|
||||
COMMIT;
|
||||
connection slave;
|
||||
##############################################################
|
||||
### Run the last transaction before mariadb-backup --backup
|
||||
### Remember SHOW MASTER STATUS and @@gtid_binlog_pos
|
||||
### before and after the transaction.
|
||||
### Master: Rember MASTER STATUS and @@gtid_binlog_pos before tr#01
|
||||
connection master;
|
||||
### Slave: Remember MASTER STATUS and @@gtid_binlog_pos before tr#01
|
||||
connection slave;
|
||||
### Master: Run the actual last transaction before the backup
|
||||
connection master;
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#01:stmt#00 - slave run#0, before backup');
|
||||
INSERT INTO t1 VALUES ('tr#01:stmt#01 - slave run#0, before backup');
|
||||
INSERT INTO t1 VALUES ('tr#01:stmt#02 - slave run#0, before backup');
|
||||
COMMIT;
|
||||
connection slave;
|
||||
### Master: Remember MASTER STATUS and @@gtid_binlog_pos after tr#01
|
||||
connection master;
|
||||
### Slave: Remember MASTER STATUS and @@gtid_binlog_pos after tr#01
|
||||
connection slave;
|
||||
##############################################################
|
||||
### Running `mariadb-backup --backup,--prepare` and checking
|
||||
### that xtrabackup_slave_info and xtrabackup_binlog_info are OK
|
||||
### Slave: Create a backup
|
||||
### Slave: Prepare the backup
|
||||
### Slave: xtrabackup files:
|
||||
############################ xtrabackup_slave_info
|
||||
CHANGE MASTER TO MASTER_LOG_FILE='master_after_tr01_show_master_status_file', MASTER_LOG_POS=master_after_tr01_show_master_status_position;
|
||||
############################ xtrabackup_binlog_info
|
||||
slave_after_tr01_show_master_status_file slave_after_tr01_show_master_status_position slave_after_tr01_gtid_binlog_pos
|
||||
############################
|
||||
##############################################################
|
||||
### Run more transactions after the backup:
|
||||
### - while the slave is still running, then
|
||||
### - while the slave is shut down
|
||||
### Master: Run another transaction while the slave is still running
|
||||
connection master;
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup');
|
||||
INSERT INTO t1 VALUES ('tr#02:stmt#01 - slave run#0, after backup');
|
||||
INSERT INTO t1 VALUES ('tr#02:stmt@02 - slave run#0, after backup');
|
||||
COMMIT;
|
||||
connection slave;
|
||||
### Master: Remember MASTER STATUS and @@gtid_binlog_pos after tr#02
|
||||
connection master;
|
||||
### Slave: Remember MASTER STATUS and @@gtid_binlog_pos after tr#02
|
||||
connection slave;
|
||||
### Master: Checking SHOW BINLOG EVENTS
|
||||
connection master;
|
||||
SHOW BINLOG EVENTS IN 'master_after_tr01_show_master_status_file' FROM master_after_tr01_show_master_status_position LIMIT 0,1;
|
||||
Log_name master_after_tr01_show_master_status_file
|
||||
Pos master_after_tr01_show_master_status_position
|
||||
Event_type Gtid
|
||||
Server_id #
|
||||
End_log_pos #
|
||||
Info BEGIN GTID master_after_tr02_gtid_binlog_pos
|
||||
SHOW BINLOG EVENTS IN 'master_after_tr01_show_master_status_file' FROM master_after_tr01_show_master_status_position LIMIT 1,1;
|
||||
Log_name master_after_tr01_show_master_status_file
|
||||
Pos #
|
||||
Event_type Query_or_Annotate_rows
|
||||
Server_id #
|
||||
End_log_pos #
|
||||
Info INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup')
|
||||
### Slave: Checking SHOW BINLOG EVENTS
|
||||
connection slave;
|
||||
SHOW BINLOG EVENTS IN 'slave_after_tr01_show_master_status_file' FROM slave_after_tr01_show_master_status_position LIMIT 0,1;
|
||||
Log_name slave_after_tr01_show_master_status_file
|
||||
Pos #
|
||||
Event_type Gtid
|
||||
Server_id 1
|
||||
End_log_pos #
|
||||
Info BEGIN GTID slave_after_tr02_gtid_binlog_pos
|
||||
SHOW BINLOG EVENTS IN 'slave_after_tr01_show_master_status_file' FROM slave_after_tr01_show_master_status_position LIMIT 1,1;
|
||||
Log_name slave_after_tr01_show_master_status_file
|
||||
Pos #
|
||||
Event_type Query_or_Annotate_rows
|
||||
Server_id #
|
||||
End_log_pos #
|
||||
Info INSERT INTO t1 VALUES ('tr#02:stmt#00 - slave run#0, after backup')
|
||||
### Slave: Stop replication
|
||||
connection slave;
|
||||
STOP SLAVE;
|
||||
include/wait_for_slave_to_stop.inc
|
||||
RESET SLAVE;
|
||||
Warnings:
|
||||
Note 4190 RESET SLAVE is implicitly changing the value of 'Using_Gtid' from 'No' to 'Slave_Pos'
|
||||
### Slave: Shutdown the server
|
||||
include/rpl_stop_server.inc [server_number=2]
|
||||
### Master: Run a transaction while the slave is shut down
|
||||
connection master;
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#03:stmt#00 - after slave run#0, slave is shut down, after backup');
|
||||
INSERT INTO t1 VALUES ('tr#03:stmt#01 - after slave run#0, slave is shut down, after backup');
|
||||
INSERT INTO t1 VALUES ('tr#03:stmt#02 - after slave run#0, slave is shut down, after backup');
|
||||
COMMIT;
|
||||
##############################################################
|
||||
### Emulate starting a new virgin slave
|
||||
### Slave: Remove the data directory
|
||||
### Slave: Copy back the backup
|
||||
### Slave: Restart the server
|
||||
include/rpl_start_server.inc [server_number=2]
|
||||
### Slave: Display the restored data before START SLAVE
|
||||
connection slave;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
tr#00:stmt#00 - slave run#0, before backup
|
||||
tr#00:stmt#01 - slave run#0, before backup
|
||||
tr#00:stmt#02 - slave run#0, before backup
|
||||
tr#01:stmt#00 - slave run#0, before backup
|
||||
tr#01:stmt#01 - slave run#0, before backup
|
||||
tr#01:stmt#02 - slave run#0, before backup
|
||||
### Slave: Execute the CHANGE MASTER statement to set up the host and port
|
||||
CHANGE MASTER '' TO MASTER_USER='root', MASTER_HOST='127.0.0.1', MASTER_PORT=###, MASTER_CONNECT_RETRY=1;
|
||||
### Slave: Execute the CHANGE MASTER statement from xtrabackup_slave_info
|
||||
CHANGE MASTER TO MASTER_LOG_FILE='master_after_tr01_show_master_status_file', MASTER_LOG_POS=master_after_tr01_show_master_status_position;
|
||||
Warnings:
|
||||
Note 4190 CHANGE MASTER TO is implicitly changing the value of 'Using_Gtid' from 'Slave_Pos' to 'No'
|
||||
### Slave: Execute START SLAVE
|
||||
include/start_slave.inc
|
||||
### Master: Wait for the slave to apply all master events
|
||||
connection master;
|
||||
connection slave;
|
||||
### Slave: Make sure replication is not using GTID after the slave restart
|
||||
connection slave;
|
||||
# Using_Gtid=No
|
||||
### Slave: Display the restored data after START SLAVE
|
||||
connection slave;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
tr#00:stmt#00 - slave run#0, before backup
|
||||
tr#00:stmt#01 - slave run#0, before backup
|
||||
tr#00:stmt#02 - slave run#0, before backup
|
||||
tr#01:stmt#00 - slave run#0, before backup
|
||||
tr#01:stmt#01 - slave run#0, before backup
|
||||
tr#01:stmt#02 - slave run#0, before backup
|
||||
tr#02:stmt#00 - slave run#0, after backup
|
||||
tr#02:stmt#01 - slave run#0, after backup
|
||||
tr#02:stmt@02 - slave run#0, after backup
|
||||
tr#03:stmt#00 - after slave run#0, slave is shut down, after backup
|
||||
tr#03:stmt#01 - after slave run#0, slave is shut down, after backup
|
||||
tr#03:stmt#02 - after slave run#0, slave is shut down, after backup
|
||||
##############################################################
|
||||
### Continue master transactions, check the new slave replicates well.
|
||||
### Master: Run a transaction after restarting replication
|
||||
connection master;
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES ('tr#04:stmt#00 - slave run#1');
|
||||
INSERT INTO t1 VALUES ('tr#04:stmt#01 - slave run#1');
|
||||
INSERT INTO t1 VALUES ('tr#04:stmt#02 - slave run#1');
|
||||
COMMIT;
|
||||
connection slave;
|
||||
### Slave: Display the restored data + new transactions
|
||||
connection slave;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
tr#00:stmt#00 - slave run#0, before backup
|
||||
tr#00:stmt#01 - slave run#0, before backup
|
||||
tr#00:stmt#02 - slave run#0, before backup
|
||||
tr#01:stmt#00 - slave run#0, before backup
|
||||
tr#01:stmt#01 - slave run#0, before backup
|
||||
tr#01:stmt#02 - slave run#0, before backup
|
||||
tr#02:stmt#00 - slave run#0, after backup
|
||||
tr#02:stmt#01 - slave run#0, after backup
|
||||
tr#02:stmt@02 - slave run#0, after backup
|
||||
tr#03:stmt#00 - after slave run#0, slave is shut down, after backup
|
||||
tr#03:stmt#01 - after slave run#0, slave is shut down, after backup
|
||||
tr#03:stmt#02 - after slave run#0, slave is shut down, after backup
|
||||
tr#04:stmt#00 - slave run#1
|
||||
tr#04:stmt#01 - slave run#1
|
||||
tr#04:stmt#02 - slave run#1
|
||||
##############################################################
|
||||
### Cleanup
|
||||
### Removing the backup directory
|
||||
connection master;
|
||||
DROP TABLE t1;
|
||||
connection slave;
|
||||
include/rpl_end.inc
|
||||
17
mysql-test/suite/mariabackup/rpl_clone_slave.test
Normal file
17
mysql-test/suite/mariabackup/rpl_clone_slave.test
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Cloning a slave using mariadb-backup
|
||||
#
|
||||
--source include/have_innodb.inc
|
||||
--source include/master-slave.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-33342 Add a replication MTR test cloning the slave with mariadb-backup
|
||||
--echo #
|
||||
|
||||
connection slave;
|
||||
stop slave;
|
||||
change master to master_use_gtid=no;
|
||||
start slave;
|
||||
|
||||
--let cnf=mariadb_to_mariadb
|
||||
--source include/rpl_clone_slave_using_mariadb-backup.inc
|
||||
@@ -449,3 +449,85 @@ VALUES
|
||||
('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc');
|
||||
ERROR 23000: Duplicate entry 'abc-2001-01-01 00:00:00.000000-2000-01-01 00:00:00.000000' for key 'index_name'
|
||||
DROP TABLE t1;
|
||||
# MDEV-25370 Update for portion changes autoincrement key in period table
|
||||
create or replace table cars(id int auto_increment,
|
||||
price int, s date, e date,
|
||||
period for p(s,e),
|
||||
primary key(id, p without overlaps));
|
||||
insert into cars(price, s, e) values (1000, '2018-01-01', '2020-01-01');
|
||||
select * from cars;
|
||||
id price s e
|
||||
1 1000 2018-01-01 2020-01-01
|
||||
update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100;
|
||||
select * from cars;
|
||||
id price s e
|
||||
1 1000 2018-01-01 2019-01-01
|
||||
1 1000 2019-12-01 2020-01-01
|
||||
1 1100 2019-01-01 2019-12-01
|
||||
delete from cars for portion of p from '2019-12-10' to '2019-12-20';
|
||||
select * from cars;
|
||||
id price s e
|
||||
1 1000 2018-01-01 2019-01-01
|
||||
1 1000 2019-12-01 2019-12-10
|
||||
1 1000 2019-12-20 2020-01-01
|
||||
1 1100 2019-01-01 2019-12-01
|
||||
# AUTO_INCREMENT field is separate from WITHOUT OVERLAPS
|
||||
create or replace table cars(id int primary key auto_increment,
|
||||
car_id int,
|
||||
price int, s date, e date,
|
||||
period for p(s,e),
|
||||
unique(car_id, p without overlaps));
|
||||
insert cars(car_id, price, s, e) values (1, 1000, '2018-01-01', '2020-01-01');
|
||||
select * from cars;
|
||||
id car_id price s e
|
||||
1 1 1000 2018-01-01 2020-01-01
|
||||
update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100;
|
||||
select * from cars;
|
||||
id car_id price s e
|
||||
1 1 1100 2019-01-01 2019-12-01
|
||||
2 1 1000 2018-01-01 2019-01-01
|
||||
3 1 1000 2019-12-01 2020-01-01
|
||||
delete from cars for portion of p from '2019-12-10' to '2019-12-20';
|
||||
select * from cars;
|
||||
id car_id price s e
|
||||
1 1 1100 2019-01-01 2019-12-01
|
||||
2 1 1000 2018-01-01 2019-01-01
|
||||
4 1 1000 2019-12-01 2019-12-10
|
||||
5 1 1000 2019-12-20 2020-01-01
|
||||
# AUTO_INCREMENT field is both standalone and in WITHOUT OVERLAPS
|
||||
create or replace table cars(id int primary key auto_increment,
|
||||
price int, s date, e date,
|
||||
period for p(s,e),
|
||||
unique(id, p without overlaps));
|
||||
insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01');
|
||||
insert cars(price, s, e) values (1000, '2021-01-01', '2022-01-01');
|
||||
update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100;
|
||||
# autoincrement index is: id int primary key
|
||||
# id increments each time.
|
||||
select * from cars;
|
||||
id price s e
|
||||
1 1100 2019-01-01 2019-12-01
|
||||
2 1000 2021-01-01 2022-01-01
|
||||
3 1000 2018-01-01 2019-01-01
|
||||
4 1000 2019-12-01 2020-01-01
|
||||
truncate cars;
|
||||
insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01');
|
||||
delete from cars for portion of p from '2019-12-10' to '2019-12-20';
|
||||
select * from cars;
|
||||
id price s e
|
||||
2 1000 2018-01-01 2019-12-10
|
||||
3 1000 2019-12-20 2020-01-01
|
||||
create or replace table cars(id int unique auto_increment,
|
||||
price int, s date, e date,
|
||||
period for p(s,e),
|
||||
primary key (id, p without overlaps));
|
||||
insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01');
|
||||
# autoincrement index is: primary key (id, p without overlaps)
|
||||
# id is not incremented, hence duplication error
|
||||
update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100;
|
||||
ERROR 23000: Duplicate entry '1' for key 'id'
|
||||
truncate cars;
|
||||
insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01');
|
||||
delete from cars for portion of p from '2019-12-10' to '2019-12-20';
|
||||
ERROR 23000: Duplicate entry '1' for key 'id'
|
||||
drop table cars;
|
||||
|
||||
@@ -458,3 +458,80 @@ VALUES
|
||||
('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc '),
|
||||
('2000-01-01 00:00:00.000000', '2001-01-01 00:00:00.000000', 'abc');
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo # MDEV-25370 Update for portion changes autoincrement key in period table
|
||||
create or replace table cars(id int auto_increment,
|
||||
price int, s date, e date,
|
||||
period for p(s,e),
|
||||
primary key(id, p without overlaps));
|
||||
|
||||
insert into cars(price, s, e) values (1000, '2018-01-01', '2020-01-01');
|
||||
select * from cars;
|
||||
|
||||
update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100;
|
||||
--sorted_result
|
||||
select * from cars;
|
||||
|
||||
delete from cars for portion of p from '2019-12-10' to '2019-12-20';
|
||||
--sorted_result
|
||||
select * from cars;
|
||||
|
||||
--echo # AUTO_INCREMENT field is separate from WITHOUT OVERLAPS
|
||||
create or replace table cars(id int primary key auto_increment,
|
||||
car_id int,
|
||||
price int, s date, e date,
|
||||
period for p(s,e),
|
||||
unique(car_id, p without overlaps));
|
||||
|
||||
insert cars(car_id, price, s, e) values (1, 1000, '2018-01-01', '2020-01-01');
|
||||
select * from cars;
|
||||
|
||||
update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100;
|
||||
--sorted_result
|
||||
select * from cars;
|
||||
|
||||
delete from cars for portion of p from '2019-12-10' to '2019-12-20';
|
||||
--sorted_result
|
||||
select * from cars;
|
||||
|
||||
|
||||
--echo # AUTO_INCREMENT field is both standalone and in WITHOUT OVERLAPS
|
||||
create or replace table cars(id int primary key auto_increment,
|
||||
price int, s date, e date,
|
||||
period for p(s,e),
|
||||
unique(id, p without overlaps));
|
||||
|
||||
insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01');
|
||||
insert cars(price, s, e) values (1000, '2021-01-01', '2022-01-01');
|
||||
|
||||
update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100;
|
||||
--echo # autoincrement index is: id int primary key
|
||||
--echo # id increments each time.
|
||||
--sorted_result
|
||||
select * from cars;
|
||||
|
||||
truncate cars;
|
||||
insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01');
|
||||
|
||||
delete from cars for portion of p from '2019-12-10' to '2019-12-20';
|
||||
--sorted_result
|
||||
select * from cars;
|
||||
|
||||
create or replace table cars(id int unique auto_increment,
|
||||
price int, s date, e date,
|
||||
period for p(s,e),
|
||||
primary key (id, p without overlaps));
|
||||
|
||||
insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01');
|
||||
--echo # autoincrement index is: primary key (id, p without overlaps)
|
||||
--echo # id is not incremented, hence duplication error
|
||||
--error ER_DUP_ENTRY
|
||||
update cars for portion of p from '2019-01-01' to '2019-12-01' set price= 1100;
|
||||
|
||||
truncate cars;
|
||||
insert cars(price, s, e) values (1000, '2018-01-01', '2020-01-01');
|
||||
|
||||
--error ER_DUP_ENTRY
|
||||
delete from cars for portion of p from '2019-12-10' to '2019-12-20';
|
||||
|
||||
drop table cars;
|
||||
|
||||
@@ -22,7 +22,4 @@ Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be
|
||||
set global innodb_saved_page_number_debug = 0;
|
||||
set global innodb_fil_make_page_dirty_debug = @space_id;
|
||||
drop table t1;
|
||||
# Must always be 0.
|
||||
SELECT @@global.innodb_fil_make_page_dirty_debug;
|
||||
@@global.innodb_fil_make_page_dirty_debug
|
||||
0
|
||||
set global innodb_fil_make_page_dirty_debug = 0;
|
||||
|
||||
@@ -23,6 +23,7 @@ set global innodb_saved_page_number_debug = 0;
|
||||
set global innodb_fil_make_page_dirty_debug = @space_id;
|
||||
drop table t1;
|
||||
set global innodb_saved_page_number_debug = 0;
|
||||
set global innodb_fil_make_page_dirty_debug = 0;
|
||||
SELECT @@global.innodb_saved_page_number_debug;
|
||||
@@global.innodb_saved_page_number_debug
|
||||
0
|
||||
|
||||
@@ -31,6 +31,4 @@ set global innodb_saved_page_number_debug = 0;
|
||||
set global innodb_fil_make_page_dirty_debug = @space_id;
|
||||
drop table t1;
|
||||
|
||||
--echo # Must always be 0.
|
||||
SELECT @@global.innodb_fil_make_page_dirty_debug;
|
||||
|
||||
set global innodb_fil_make_page_dirty_debug = 0;
|
||||
|
||||
@@ -32,6 +32,7 @@ set global innodb_fil_make_page_dirty_debug = @space_id;
|
||||
drop table t1;
|
||||
|
||||
set global innodb_saved_page_number_debug = 0;
|
||||
set global innodb_fil_make_page_dirty_debug = 0;
|
||||
|
||||
SELECT @@global.innodb_saved_page_number_debug;
|
||||
|
||||
|
||||
@@ -32,11 +32,12 @@ IF (HAVE_ALLOCA_H AND HAVE_CRACK_H AND HAVE_LIBCRACK AND HAVE_MEMCPY)
|
||||
IF(CHECKMODULE AND SEMODULE_PACKAGE)
|
||||
FOREACH(pol mariadb-plugin-cracklib-password-check)
|
||||
SET(src ${CMAKE_CURRENT_SOURCE_DIR}/policy/selinux/${pol}.te)
|
||||
SET(tmp ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${pol}-pp.dir/${pol}.mod)
|
||||
SET(tmp ${CMAKE_CURRENT_BINARY_DIR}/${pol}.mod)
|
||||
SET(out ${CMAKE_CURRENT_BINARY_DIR}/${pol}.pp)
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${out}
|
||||
COMMAND ${CHECKMODULE} -M -m ${src} -o ${tmp}
|
||||
COMMAND ${SEMODULE_PACKAGE} -m ${tmp} -o ${out}
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${tmp}
|
||||
DEPENDS ${src})
|
||||
ADD_CUSTOM_TARGET(${pol}-pp ALL DEPENDS ${out})
|
||||
INSTALL(FILES ${out} DESTINATION ${inst_location}/policy/selinux COMPONENT cracklib-password-check)
|
||||
|
||||
@@ -5024,7 +5024,7 @@ int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
|
||||
if (unlikely((error= check(thd, check_opt))))
|
||||
return error;
|
||||
/* Skip updating frm version if not main handler. */
|
||||
if (table->file != this)
|
||||
if (table->file != this || opt_readonly)
|
||||
return error;
|
||||
return update_frm_version(table);
|
||||
}
|
||||
@@ -5073,7 +5073,7 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
|
||||
DBUG_ASSERT(result == HA_ADMIN_NOT_IMPLEMENTED ||
|
||||
ha_table_flags() & HA_CAN_REPAIR);
|
||||
|
||||
if (result == HA_ADMIN_OK)
|
||||
if (result == HA_ADMIN_OK && !opt_readonly)
|
||||
result= update_frm_version(table);
|
||||
return result;
|
||||
}
|
||||
@@ -6007,7 +6007,7 @@ err:
|
||||
|
||||
void st_ha_check_opt::init()
|
||||
{
|
||||
flags= sql_flags= 0;
|
||||
flags= sql_flags= handler_flags= 0;
|
||||
start_time= my_time(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -2673,6 +2673,7 @@ typedef struct st_ha_check_opt
|
||||
st_ha_check_opt() = default; /* Remove gcc warning */
|
||||
uint flags; /* isam layer flags (e.g. for myisamchk) */
|
||||
uint sql_flags; /* sql layer flags - for something myisamchk cannot do */
|
||||
uint handler_flags; /* Reserved for handler usage */
|
||||
time_t start_time; /* When check/repair starts */
|
||||
KEY_CACHE *key_cache; /* new key cache when changing key cache */
|
||||
void init();
|
||||
|
||||
186
sql/opt_range.cc
186
sql/opt_range.cc
@@ -3135,6 +3135,53 @@ SQL_SELECT::test_quick_select(THD *thd,
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
@brief
|
||||
Create a bitmap of columns for which to perform Range Analysis for EITS
|
||||
condition selectivity estimates.
|
||||
|
||||
@detail
|
||||
Walk through the bitmap of fields used in the query, and
|
||||
- pick columns for which EITS data is usable (see is_eits_usable() call)
|
||||
- do not produce more than MAX_KEY columns. Range Analyzer cannot handle
|
||||
more than that. If there are more than MAX_KEY eligible columns,
|
||||
this function should be called multiple times to produce multiple
|
||||
bitmaps.
|
||||
|
||||
@param used_fields Columns used by the query
|
||||
@param col_no Start from this column
|
||||
@param out OUT Filled column bitmap
|
||||
|
||||
@return
|
||||
(uint)-1 If there are no more columns for range analysis.
|
||||
Other Index of the last considered column. Pass this to next call to
|
||||
this function
|
||||
*/
|
||||
|
||||
uint get_columns_for_pseudo_indexes(const TABLE *table,
|
||||
const MY_BITMAP *used_fields, int col_no,
|
||||
MY_BITMAP *out)
|
||||
{
|
||||
bitmap_clear_all(out);
|
||||
int n_bits= 0;
|
||||
|
||||
for (; table->field[col_no]; col_no++)
|
||||
{
|
||||
if (bitmap_is_set(used_fields, col_no) &&
|
||||
is_eits_usable(table->field[col_no]))
|
||||
{
|
||||
bitmap_set_bit(out, col_no);
|
||||
if (++n_bits == MAX_KEY)
|
||||
{
|
||||
col_no++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return n_bits? col_no: (uint)-1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Build descriptors of pseudo-indexes over columns to perform range analysis
|
||||
|
||||
@@ -3160,22 +3207,11 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param,
|
||||
{
|
||||
Field **field_ptr;
|
||||
TABLE *table= param->table;
|
||||
uint parts= 0;
|
||||
|
||||
for (field_ptr= table->field; *field_ptr; field_ptr++)
|
||||
{
|
||||
Field *field= *field_ptr;
|
||||
if (bitmap_is_set(used_fields, field->field_index) &&
|
||||
is_eits_usable(field))
|
||||
parts++;
|
||||
}
|
||||
uint parts= bitmap_bits_set(used_fields);
|
||||
|
||||
KEY_PART *key_part;
|
||||
uint keys= 0;
|
||||
|
||||
if (!parts)
|
||||
return TRUE;
|
||||
|
||||
if (!(key_part= (KEY_PART *) alloc_root(param->mem_root,
|
||||
sizeof(KEY_PART) * parts)))
|
||||
return TRUE;
|
||||
@@ -3187,9 +3223,6 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param,
|
||||
Field *field= *field_ptr;
|
||||
if (bitmap_is_set(used_fields, field->field_index))
|
||||
{
|
||||
if (!is_eits_usable(field))
|
||||
continue;
|
||||
|
||||
uint16 store_length;
|
||||
uint16 max_key_part_length= (uint16) table->file->max_key_part_length();
|
||||
key_part->key= keys;
|
||||
@@ -3534,8 +3567,6 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond)
|
||||
PARAM param;
|
||||
MEM_ROOT alloc;
|
||||
SEL_TREE *tree;
|
||||
double rows;
|
||||
|
||||
init_sql_alloc(key_memory_quick_range_select_root, &alloc,
|
||||
thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC));
|
||||
bzero((void*) ¶m, sizeof(param));
|
||||
@@ -3545,67 +3576,90 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond)
|
||||
param.table= table;
|
||||
param.remove_false_where_parts= true;
|
||||
|
||||
if (create_key_parts_for_pseudo_indexes(¶m, used_fields))
|
||||
goto free_alloc;
|
||||
|
||||
param.prev_tables= param.read_tables= 0;
|
||||
param.current_table= table->map;
|
||||
param.using_real_indexes= FALSE;
|
||||
param.real_keynr[0]= 0;
|
||||
MEM_UNDEFINED(¶m.real_keynr, sizeof(param.real_keynr));
|
||||
|
||||
param.alloced_sel_args= 0;
|
||||
param.max_key_parts= 0;
|
||||
|
||||
thd->no_errors=1;
|
||||
|
||||
tree= cond[0]->get_mm_tree(¶m, cond);
|
||||
|
||||
if (!tree)
|
||||
goto free_alloc;
|
||||
|
||||
thd->no_errors=1;
|
||||
table->reginfo.impossible_range= 0;
|
||||
if (tree->type == SEL_TREE::IMPOSSIBLE)
|
||||
{
|
||||
rows= 0;
|
||||
table->reginfo.impossible_range= 1;
|
||||
goto free_alloc;
|
||||
}
|
||||
else if (tree->type == SEL_TREE::ALWAYS)
|
||||
{
|
||||
rows= table_records;
|
||||
goto free_alloc;
|
||||
}
|
||||
else if (tree->type == SEL_TREE::MAYBE)
|
||||
{
|
||||
rows= table_records;
|
||||
goto free_alloc;
|
||||
}
|
||||
|
||||
for (uint idx= 0; idx < param.keys; idx++)
|
||||
uint used_fields_buff_size= bitmap_buffer_size(table->s->fields);
|
||||
uint32 *used_fields_buff= (uint32*)thd->alloc(used_fields_buff_size);
|
||||
MY_BITMAP cols_for_indexes;
|
||||
(void) my_bitmap_init(&cols_for_indexes, used_fields_buff, table->s->fields);
|
||||
bitmap_clear_all(&cols_for_indexes);
|
||||
|
||||
uint column_no= 0; // Start looping from the first column.
|
||||
/*
|
||||
Try getting selectivity estimates for every field that is used in the
|
||||
query and has EITS statistics. We do this:
|
||||
|
||||
for every usable field col
|
||||
create a pseudo INDEX(col);
|
||||
Run the range analyzer (get_mm_tree) for these pseudo-indexes;
|
||||
Look at produced ranges and get their selectivity estimates;
|
||||
|
||||
Note that the range analyzer can process at most MAX_KEY indexes. If
|
||||
the table has >MAX_KEY eligible columns, we will do several range
|
||||
analyzer runs.
|
||||
*/
|
||||
|
||||
while (1)
|
||||
{
|
||||
SEL_ARG *key= tree->keys[idx];
|
||||
if (key)
|
||||
column_no= get_columns_for_pseudo_indexes(table, used_fields, column_no,
|
||||
&cols_for_indexes);
|
||||
if (column_no == (uint)-1)
|
||||
break; /* Couldn't create any pseudo-indexes. This means we're done */
|
||||
|
||||
if (create_key_parts_for_pseudo_indexes(¶m, &cols_for_indexes))
|
||||
goto free_alloc;
|
||||
|
||||
tree= cond[0]->get_mm_tree(¶m, cond);
|
||||
|
||||
if (!tree ||
|
||||
tree->type == SEL_TREE::ALWAYS ||
|
||||
tree->type == SEL_TREE::MAYBE)
|
||||
{
|
||||
Json_writer_object selectivity_for_column(thd);
|
||||
selectivity_for_column.add("column_name", key->field->field_name);
|
||||
if (key->type == SEL_ARG::IMPOSSIBLE)
|
||||
/* Couldn't infer anything. But there could be more fields, so continue */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tree->type == SEL_TREE::IMPOSSIBLE)
|
||||
{
|
||||
table->reginfo.impossible_range= 1;
|
||||
goto free_alloc;
|
||||
}
|
||||
|
||||
for (uint idx= 0; idx < param.keys; idx++)
|
||||
{
|
||||
SEL_ARG *key= tree->keys[idx];
|
||||
if (key)
|
||||
{
|
||||
rows= 0;
|
||||
table->reginfo.impossible_range= 1;
|
||||
selectivity_for_column.add("selectivity_from_histogram", rows);
|
||||
selectivity_for_column.add("cause", "impossible range");
|
||||
goto free_alloc;
|
||||
}
|
||||
else
|
||||
{
|
||||
enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
|
||||
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
|
||||
rows= records_in_column_ranges(¶m, idx, key);
|
||||
thd->count_cuted_fields= save_count_cuted_fields;
|
||||
if (rows != DBL_MAX)
|
||||
Json_writer_object selectivity_for_column(thd);
|
||||
selectivity_for_column.add("column_name", key->field->field_name);
|
||||
if (key->type == SEL_ARG::IMPOSSIBLE)
|
||||
{
|
||||
key->field->cond_selectivity= rows/table_records;
|
||||
selectivity_for_column.add("selectivity_from_histogram",
|
||||
key->field->cond_selectivity);
|
||||
table->reginfo.impossible_range= 1;
|
||||
selectivity_for_column.add("selectivity_from_histogram", 0);
|
||||
selectivity_for_column.add("cause", "impossible range");
|
||||
goto free_alloc;
|
||||
}
|
||||
else
|
||||
{
|
||||
enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
|
||||
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
|
||||
double rows= records_in_column_ranges(¶m, idx, key);
|
||||
thd->count_cuted_fields= save_count_cuted_fields;
|
||||
if (rows != DBL_MAX)
|
||||
{
|
||||
key->field->cond_selectivity= rows/table_records;
|
||||
selectivity_for_column.add("selectivity_from_histogram",
|
||||
key->field->cond_selectivity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5707,6 +5707,40 @@ extern "C" void *thd_mdl_context(MYSQL_THD thd)
|
||||
return &thd->mdl_context;
|
||||
}
|
||||
|
||||
/**
|
||||
Send check/repair message to the user
|
||||
|
||||
@param op one of check or repair
|
||||
@param msg_type one of info, warning or error
|
||||
@param print_to_log <> 0 if we should also print the message to error log.
|
||||
*/
|
||||
|
||||
extern "C" void
|
||||
print_check_msg(THD *thd, const char *db_name, const char *table_name, const char *op,
|
||||
const char *msg_type, const char *message, my_bool print_to_log)
|
||||
{
|
||||
char name[NAME_LEN * 2 + 2];
|
||||
Protocol *protocol= thd->protocol;
|
||||
|
||||
DBUG_ASSERT(strlen(db_name) <= NAME_LEN);
|
||||
DBUG_ASSERT(strlen(table_name) <= NAME_LEN);
|
||||
|
||||
size_t length= size_t(strxnmov(name, sizeof name - 1,
|
||||
db_name, ".", table_name, NullS) -
|
||||
name);
|
||||
protocol->prepare_for_resend();
|
||||
protocol->store(name, length, system_charset_info);
|
||||
protocol->store(op, strlen(op), system_charset_info);
|
||||
protocol->store(msg_type, strlen(msg_type), system_charset_info);
|
||||
protocol->store(message, strlen(message), system_charset_info);
|
||||
if (protocol->write())
|
||||
sql_print_error("Failed on my_net_write, writing to stderr instead: %s: %s\n",
|
||||
table_name, message);
|
||||
else if (thd->variables.log_warnings > 2 && print_to_log)
|
||||
sql_print_error("%s: table '%s' got '%s' during %s",
|
||||
msg_type, table_name, message, op);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Handling of statement states in functions and triggers.
|
||||
|
||||
@@ -263,7 +263,10 @@ int update_portion_of_time(THD *thd, TABLE *table,
|
||||
res= src->save_in_field(table->field[dst_fieldno], true);
|
||||
|
||||
if (likely(!res))
|
||||
{
|
||||
table->period_prepare_autoinc();
|
||||
res= table->update_generated_fields();
|
||||
}
|
||||
|
||||
if(likely(!res))
|
||||
res= table->file->ha_update_row(table->record[1], table->record[0]);
|
||||
|
||||
@@ -1233,7 +1233,9 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
|
||||
/* Execute the query that specifies the derived table by a foreign engine */
|
||||
res= derived->pushdown_derived->execute();
|
||||
unit->executed= true;
|
||||
if (res)
|
||||
DBUG_RETURN(res);
|
||||
goto after_exec;
|
||||
}
|
||||
|
||||
if (unit->executed && !derived_is_recursive &&
|
||||
@@ -1294,6 +1296,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
|
||||
derived_result, unit, first_select);
|
||||
}
|
||||
|
||||
after_exec:
|
||||
if (!res && !derived_is_recursive)
|
||||
{
|
||||
if (derived_result->flush())
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <service_versions.h>
|
||||
#include <mysql/service_wsrep.h>
|
||||
#include <mysql/service_thd_mdl.h>
|
||||
#include <mysql/service_print_check_msg.h>
|
||||
|
||||
struct st_service_ref {
|
||||
const char *name;
|
||||
@@ -219,6 +220,11 @@ static struct my_print_error_service_st my_print_error_handler=
|
||||
my_printv_error
|
||||
};
|
||||
|
||||
static struct print_check_msg_service_st print_check_msg_handler=
|
||||
{
|
||||
print_check_msg
|
||||
};
|
||||
|
||||
static struct json_service_st json_handler=
|
||||
{
|
||||
json_type,
|
||||
@@ -336,6 +342,7 @@ static struct st_service_ref list_of_services[]=
|
||||
{ "my_crypt_service", VERSION_my_crypt, &crypt_handler},
|
||||
{ "my_md5_service", VERSION_my_md5, &my_md5_handler},
|
||||
{ "my_print_error_service", VERSION_my_print_error, &my_print_error_handler},
|
||||
{ "print_check_msg_service", VERSION_print_check_msg, &print_check_msg_handler},
|
||||
{ "my_sha1_service", VERSION_my_sha1, &my_sha1_handler},
|
||||
{ "my_sha2_service", VERSION_my_sha2, &my_sha2_handler},
|
||||
{ "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
|
||||
|
||||
20
sql/table.cc
20
sql/table.cc
@@ -9159,10 +9159,9 @@ int TABLE::update_default_fields(bool ignore_errors)
|
||||
int TABLE::update_generated_fields()
|
||||
{
|
||||
int res= 0;
|
||||
if (found_next_number_field)
|
||||
if (next_number_field)
|
||||
{
|
||||
next_number_field= found_next_number_field;
|
||||
res= found_next_number_field->set_default();
|
||||
res= next_number_field->set_default();
|
||||
if (likely(!res))
|
||||
res= file->update_auto_increment();
|
||||
next_number_field= NULL;
|
||||
@@ -9177,6 +9176,18 @@ int TABLE::update_generated_fields()
|
||||
return res;
|
||||
}
|
||||
|
||||
void TABLE::period_prepare_autoinc()
|
||||
{
|
||||
if (!found_next_number_field)
|
||||
return;
|
||||
/* Don't generate a new value if the autoinc index is WITHOUT OVERLAPS */
|
||||
DBUG_ASSERT(s->next_number_index != (uint)-1);
|
||||
if (key_info[s->next_number_index].without_overlaps)
|
||||
return;
|
||||
|
||||
next_number_field= found_next_number_field;
|
||||
}
|
||||
|
||||
int TABLE::period_make_insert(Item *src, Field *dst)
|
||||
{
|
||||
THD *thd= in_use;
|
||||
@@ -9186,7 +9197,10 @@ int TABLE::period_make_insert(Item *src, Field *dst)
|
||||
int res= src->save_in_field(dst, true);
|
||||
|
||||
if (likely(!res))
|
||||
{
|
||||
period_prepare_autoinc();
|
||||
res= update_generated_fields();
|
||||
}
|
||||
|
||||
if (likely(!res) && triggers)
|
||||
res= triggers->process_triggers(thd, TRG_EVENT_INSERT,
|
||||
|
||||
@@ -1840,6 +1840,7 @@ public:
|
||||
#endif
|
||||
|
||||
int update_generated_fields();
|
||||
void period_prepare_autoinc();
|
||||
int period_make_insert(Item *src, Field *dst);
|
||||
int insert_portion_of_time(THD *thd, const vers_select_conds_t &period_conds,
|
||||
ha_rows *rows_inserted);
|
||||
|
||||
@@ -1291,54 +1291,71 @@ btr_read_autoinc(dict_index_t* index)
|
||||
return autoinc;
|
||||
}
|
||||
|
||||
dict_index_t *dict_table_t::get_index(const dict_col_t &col) const
|
||||
{
|
||||
dict_index_t *index= dict_table_get_first_index(this);
|
||||
|
||||
while (index && (index->fields[0].col != &col || index->is_corrupted()))
|
||||
index= dict_table_get_next_index(index);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/** Read the last used AUTO_INCREMENT value from PAGE_ROOT_AUTO_INC,
|
||||
or fall back to MAX(auto_increment_column).
|
||||
@param[in] table table containing an AUTO_INCREMENT column
|
||||
@param[in] col_no index of the AUTO_INCREMENT column
|
||||
@return the AUTO_INCREMENT value
|
||||
@retval 0 on error or if no AUTO_INCREMENT value was used yet */
|
||||
ib_uint64_t
|
||||
btr_read_autoinc_with_fallback(const dict_table_t* table, unsigned col_no)
|
||||
@param table table containing an AUTO_INCREMENT column
|
||||
@param col_no index of the AUTO_INCREMENT column
|
||||
@param mysql_version TABLE_SHARE::mysql_version
|
||||
@param max the maximum value of the AUTO_INCREMENT column
|
||||
@return the AUTO_INCREMENT value
|
||||
@retval 0 on error or if no AUTO_INCREMENT value was used yet */
|
||||
uint64_t btr_read_autoinc_with_fallback(const dict_table_t *table,
|
||||
unsigned col_no, ulong mysql_version,
|
||||
uint64_t max)
|
||||
{
|
||||
ut_ad(table->persistent_autoinc);
|
||||
ut_ad(!table->is_temporary());
|
||||
ut_ad(table->persistent_autoinc);
|
||||
ut_ad(!table->is_temporary());
|
||||
|
||||
dict_index_t* index = dict_table_get_first_index(table);
|
||||
uint64_t autoinc= 0;
|
||||
mtr_t mtr;
|
||||
mtr.start();
|
||||
|
||||
if (index == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (buf_block_t *block=
|
||||
buf_page_get(page_id_t(table->space_id,
|
||||
dict_table_get_first_index(table)->page),
|
||||
table->space->zip_size(), RW_SX_LATCH, &mtr))
|
||||
{
|
||||
autoinc= page_get_autoinc(block->page.frame);
|
||||
|
||||
mtr_t mtr;
|
||||
mtr.start();
|
||||
buf_block_t* block = buf_page_get(
|
||||
page_id_t(index->table->space_id, index->page),
|
||||
index->table->space->zip_size(),
|
||||
RW_S_LATCH, &mtr);
|
||||
if (autoinc > 0 && autoinc <= max && mysql_version >= 100210);
|
||||
else if (dict_index_t *index=
|
||||
table->get_index(*dict_table_get_nth_col(table, col_no)))
|
||||
{
|
||||
/* Read MAX(autoinc_col), in case this table had originally been
|
||||
created before MariaDB 10.2.4 introduced persistent AUTO_INCREMENT
|
||||
and MariaDB 10.2.10 fixed MDEV-12123, and there could be a garbage
|
||||
value in the PAGE_ROOT_AUTO_INC field. */
|
||||
const uint64_t max_autoinc= row_search_max_autoinc(index);
|
||||
const bool need_adjust{autoinc > max || autoinc < max_autoinc};
|
||||
ut_ad(max_autoinc <= max);
|
||||
|
||||
ib_uint64_t autoinc = block
|
||||
? page_get_autoinc(block->page.frame) : 0;
|
||||
const bool retry = block && autoinc == 0
|
||||
&& !page_is_empty(block->page.frame);
|
||||
mtr.commit();
|
||||
if (UNIV_UNLIKELY(need_adjust) && !high_level_read_only && !opt_readonly)
|
||||
{
|
||||
sql_print_information("InnoDB: Resetting PAGE_ROOT_AUTO_INC from "
|
||||
UINT64PF " to " UINT64PF
|
||||
" on table %`.*s.%`s (created with version %lu)",
|
||||
autoinc, max_autoinc,
|
||||
int(table->name.dblen()), table->name.m_name,
|
||||
table->name.basename(), mysql_version);
|
||||
autoinc= max_autoinc;
|
||||
index->set_modified(mtr);
|
||||
page_set_autoinc(block, max_autoinc, &mtr, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (retry) {
|
||||
/* This should be an old data file where
|
||||
PAGE_ROOT_AUTO_INC was initialized to 0.
|
||||
Fall back to reading MAX(autoinc_col).
|
||||
There should be an index on it. */
|
||||
const dict_col_t* autoinc_col
|
||||
= dict_table_get_nth_col(table, col_no);
|
||||
while (index && index->fields[0].col != autoinc_col) {
|
||||
index = dict_table_get_next_index(index);
|
||||
}
|
||||
|
||||
if (index) {
|
||||
autoinc = row_search_max_autoinc(index);
|
||||
}
|
||||
}
|
||||
|
||||
return autoinc;
|
||||
mtr.commit();
|
||||
return autoinc;
|
||||
}
|
||||
|
||||
/** Write the next available AUTO_INCREMENT value to PAGE_ROOT_AUTO_INC.
|
||||
|
||||
@@ -657,47 +657,22 @@ dict_table_t::parse_name<>(char(&)[NAME_LEN + 1], char(&)[NAME_LEN + 1],
|
||||
/** Acquire MDL shared for the table name.
|
||||
@tparam trylock whether to use non-blocking operation
|
||||
@param[in,out] table table object
|
||||
@param[in,out] thd background thread
|
||||
@param[out] mdl mdl ticket
|
||||
@param[in,out] mdl_context MDL context
|
||||
@param[out] mdl MDL ticket
|
||||
@param[in] table_op operation to perform when opening
|
||||
@return table object after locking MDL shared
|
||||
@retval nullptr if the table is not readable, or if trylock && MDL blocked */
|
||||
template<bool trylock>
|
||||
__attribute__((nonnull, warn_unused_result))
|
||||
dict_table_t*
|
||||
dict_acquire_mdl_shared(dict_table_t *table,
|
||||
THD *thd,
|
||||
MDL_ticket **mdl,
|
||||
MDL_context *mdl_context, MDL_ticket **mdl,
|
||||
dict_table_op_t table_op)
|
||||
{
|
||||
if (!table || !mdl)
|
||||
return table;
|
||||
|
||||
MDL_context *mdl_context= static_cast<MDL_context*>(thd_mdl_context(thd));
|
||||
size_t db_len;
|
||||
dict_table_t *not_found= nullptr;
|
||||
|
||||
if (trylock)
|
||||
{
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
db_len= dict_get_db_name_len(table->name.m_name);
|
||||
dict_sys.unfreeze();
|
||||
}
|
||||
else
|
||||
{
|
||||
ut_ad(dict_sys.frozen_not_locked());
|
||||
db_len= dict_get_db_name_len(table->name.m_name);
|
||||
}
|
||||
|
||||
if (db_len == 0)
|
||||
return table; /* InnoDB system tables are not covered by MDL */
|
||||
|
||||
if (!mdl_context)
|
||||
return nullptr;
|
||||
|
||||
table_id_t table_id= table->id;
|
||||
char db_buf[NAME_LEN + 1], db_buf1[NAME_LEN + 1];
|
||||
char tbl_buf[NAME_LEN + 1], tbl_buf1[NAME_LEN + 1];
|
||||
size_t tbl_len;
|
||||
size_t db_len, tbl_len;
|
||||
bool unaccessible= false;
|
||||
|
||||
if (!table->parse_name<!trylock>(db_buf, tbl_buf, &db_len, &tbl_len))
|
||||
@@ -768,7 +743,6 @@ retry:
|
||||
|
||||
if (!table || !table->is_accessible())
|
||||
{
|
||||
table= nullptr;
|
||||
return_without_mdl:
|
||||
if (trylock)
|
||||
dict_sys.unfreeze();
|
||||
@@ -777,7 +751,7 @@ return_without_mdl:
|
||||
mdl_context->release_lock(*mdl);
|
||||
*mdl= nullptr;
|
||||
}
|
||||
return not_found;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t db1_len, tbl1_len;
|
||||
@@ -814,6 +788,50 @@ return_without_mdl:
|
||||
goto retry;
|
||||
}
|
||||
|
||||
template dict_table_t* dict_acquire_mdl_shared<false>
|
||||
(dict_table_t*,MDL_context*,MDL_ticket**,dict_table_op_t);
|
||||
|
||||
/** Acquire MDL shared for the table name.
|
||||
@tparam trylock whether to use non-blocking operation
|
||||
@param[in,out] table table object
|
||||
@param[in,out] thd background thread
|
||||
@param[out] mdl mdl ticket
|
||||
@param[in] table_op operation to perform when opening
|
||||
@return table object after locking MDL shared
|
||||
@retval nullptr if the table is not readable, or if trylock && MDL blocked */
|
||||
template<bool trylock>
|
||||
dict_table_t*
|
||||
dict_acquire_mdl_shared(dict_table_t *table,
|
||||
THD *thd,
|
||||
MDL_ticket **mdl,
|
||||
dict_table_op_t table_op)
|
||||
{
|
||||
if (!table || !mdl)
|
||||
return table;
|
||||
|
||||
MDL_context *mdl_context= static_cast<MDL_context*>(thd_mdl_context(thd));
|
||||
size_t db_len;
|
||||
|
||||
if (trylock)
|
||||
{
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
db_len= dict_get_db_name_len(table->name.m_name);
|
||||
dict_sys.unfreeze();
|
||||
}
|
||||
else
|
||||
{
|
||||
ut_ad(dict_sys.frozen_not_locked());
|
||||
db_len= dict_get_db_name_len(table->name.m_name);
|
||||
}
|
||||
|
||||
if (db_len == 0)
|
||||
return table; /* InnoDB system tables are not covered by MDL */
|
||||
|
||||
return mdl_context
|
||||
? dict_acquire_mdl_shared<trylock>(table, mdl_context, mdl, table_op)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
template dict_table_t* dict_acquire_mdl_shared<false>
|
||||
(dict_table_t*,THD*,MDL_ticket**,dict_table_op_t);
|
||||
template dict_table_t* dict_acquire_mdl_shared<true>
|
||||
@@ -960,9 +978,6 @@ void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line))
|
||||
{
|
||||
latch.wr_lock(SRW_LOCK_ARGS(file, line));
|
||||
latch_ex_wait_start.store(0, std::memory_order_relaxed);
|
||||
ut_ad(!latch_readers);
|
||||
ut_ad(!latch_ex);
|
||||
ut_d(latch_ex= pthread_self());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -978,31 +993,21 @@ void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line))
|
||||
ib::warn() << "A long wait (" << waited
|
||||
<< " seconds) was observed for dict_sys.latch";
|
||||
latch.wr_lock(SRW_LOCK_ARGS(file, line));
|
||||
ut_ad(!latch_readers);
|
||||
ut_ad(!latch_ex);
|
||||
ut_d(latch_ex= pthread_self());
|
||||
}
|
||||
|
||||
#ifdef UNIV_PFS_RWLOCK
|
||||
ATTRIBUTE_NOINLINE void dict_sys_t::unlock()
|
||||
{
|
||||
ut_ad(latch_ex == pthread_self());
|
||||
ut_ad(!latch_readers);
|
||||
ut_d(latch_ex= 0);
|
||||
latch.wr_unlock();
|
||||
}
|
||||
|
||||
ATTRIBUTE_NOINLINE void dict_sys_t::freeze(const char *file, unsigned line)
|
||||
{
|
||||
latch.rd_lock(file, line);
|
||||
ut_ad(!latch_ex);
|
||||
ut_d(latch_readers++);
|
||||
}
|
||||
|
||||
ATTRIBUTE_NOINLINE void dict_sys_t::unfreeze()
|
||||
{
|
||||
ut_ad(!latch_ex);
|
||||
ut_ad(latch_readers--);
|
||||
latch.rd_unlock();
|
||||
}
|
||||
#endif /* UNIV_PFS_RWLOCK */
|
||||
|
||||
@@ -47,10 +47,13 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <my_bitmap.h>
|
||||
#include <mysql/service_thd_alloc.h>
|
||||
#include <mysql/service_thd_wait.h>
|
||||
#include <mysql/service_print_check_msg.h>
|
||||
#include "sql_type_geom.h"
|
||||
#include "scope.h"
|
||||
#include "srv0srv.h"
|
||||
|
||||
extern my_bool opt_readonly;
|
||||
|
||||
// MYSQL_PLUGIN_IMPORT extern my_bool lower_case_file_system;
|
||||
// MYSQL_PLUGIN_IMPORT extern char mysql_unpacked_real_data_home[];
|
||||
|
||||
@@ -116,6 +119,7 @@ thread_local ha_handler_stats *mariadb_stats= &mariadb_dummy_stats;
|
||||
#include "snappy-c.h"
|
||||
|
||||
#include <limits>
|
||||
#include <myisamchk.h> // TT_FOR_UPGRADE
|
||||
|
||||
#define thd_get_trx_isolation(X) ((enum_tx_isolation)thd_tx_isolation(X))
|
||||
|
||||
@@ -5345,67 +5349,6 @@ test_normalize_table_name_low()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Test ut_format_name(). */
|
||||
static
|
||||
void
|
||||
test_ut_format_name()
|
||||
/*=================*/
|
||||
{
|
||||
char buf[NAME_LEN * 3];
|
||||
|
||||
struct {
|
||||
const char* name;
|
||||
ulint buf_size;
|
||||
const char* expected;
|
||||
} test_data[] = {
|
||||
{"test/t1", sizeof(buf), "`test`.`t1`"},
|
||||
{"test/t1", 12, "`test`.`t1`"},
|
||||
{"test/t1", 11, "`test`.`t1"},
|
||||
{"test/t1", 10, "`test`.`t"},
|
||||
{"test/t1", 9, "`test`.`"},
|
||||
{"test/t1", 8, "`test`."},
|
||||
{"test/t1", 7, "`test`"},
|
||||
{"test/t1", 6, "`test"},
|
||||
{"test/t1", 5, "`tes"},
|
||||
{"test/t1", 4, "`te"},
|
||||
{"test/t1", 3, "`t"},
|
||||
{"test/t1", 2, "`"},
|
||||
{"test/t1", 1, ""},
|
||||
{"test/t1", 0, "BUF_NOT_CHANGED"},
|
||||
{"table", sizeof(buf), "`table`"},
|
||||
{"ta'le", sizeof(buf), "`ta'le`"},
|
||||
{"ta\"le", sizeof(buf), "`ta\"le`"},
|
||||
{"ta`le", sizeof(buf), "`ta``le`"},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < UT_ARR_SIZE(test_data); i++) {
|
||||
|
||||
memcpy(buf, "BUF_NOT_CHANGED", strlen("BUF_NOT_CHANGED") + 1);
|
||||
|
||||
char* ret;
|
||||
|
||||
ret = ut_format_name(test_data[i].name,
|
||||
buf,
|
||||
test_data[i].buf_size);
|
||||
|
||||
ut_a(ret == buf);
|
||||
|
||||
if (strcmp(buf, test_data[i].expected) == 0) {
|
||||
ib::info() << "ut_format_name(" << test_data[i].name
|
||||
<< ", buf, " << test_data[i].buf_size << "),"
|
||||
" expected " << test_data[i].expected
|
||||
<< ", OK";
|
||||
} else {
|
||||
ib::error() << "ut_format_name(" << test_data[i].name
|
||||
<< ", buf, " << test_data[i].buf_size << "),"
|
||||
" expected " << test_data[i].expected
|
||||
<< ", ERROR: got " << buf;
|
||||
ut_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* !DBUG_OFF */
|
||||
|
||||
/** Match index columns between MySQL and InnoDB.
|
||||
@@ -5763,9 +5706,9 @@ func_exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Get the upper limit of the MySQL integral and floating-point type.
|
||||
@return maximum allowed value for the field */
|
||||
/** Get the maximum integer value of a numeric column.
|
||||
@param field column definition
|
||||
@return maximum allowed integer value */
|
||||
ulonglong innobase_get_int_col_max_value(const Field *field)
|
||||
{
|
||||
ulonglong max_value = 0;
|
||||
@@ -5830,46 +5773,45 @@ ha_innobase::open().
|
||||
|
||||
@param[in,out] table persistent table
|
||||
@param[in] field the AUTO_INCREMENT column */
|
||||
static
|
||||
void
|
||||
initialize_auto_increment(dict_table_t* table, const Field* field)
|
||||
static void initialize_auto_increment(dict_table_t *table, const Field& field,
|
||||
const TABLE_SHARE &s)
|
||||
{
|
||||
ut_ad(!table->is_temporary());
|
||||
ut_ad(!table->is_temporary());
|
||||
const unsigned col_no= innodb_col_no(&field);
|
||||
table->autoinc_mutex.wr_lock();
|
||||
table->persistent_autoinc=
|
||||
uint16_t(dict_table_get_nth_col_pos(table, col_no, nullptr) + 1) &
|
||||
dict_index_t::MAX_N_FIELDS;
|
||||
if (table->autoinc)
|
||||
/* Already initialized. Our caller checked
|
||||
table->persistent_autoinc without
|
||||
autoinc_mutex protection, and there might be multiple
|
||||
ha_innobase::open() executing concurrently. */;
|
||||
else if (srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN)
|
||||
/* If innodb_force_recovery is set so high that writes
|
||||
are disabled we force the AUTOINC counter to 0
|
||||
value effectively disabling writes to the table.
|
||||
Secondly, we avoid reading the table in case the read
|
||||
results in failure due to a corrupted table/index.
|
||||
|
||||
const unsigned col_no = innodb_col_no(field);
|
||||
We will not return an error to the client, so that the
|
||||
tables can be dumped with minimal hassle. If an error
|
||||
were returned in this case, the first attempt to read
|
||||
the table would fail and subsequent SELECTs would succeed. */;
|
||||
else if (table->persistent_autoinc)
|
||||
{
|
||||
uint64_t max_value= innobase_get_int_col_max_value(&field);
|
||||
table->autoinc=
|
||||
innobase_next_autoinc(btr_read_autoinc_with_fallback(table, col_no,
|
||||
s.mysql_version,
|
||||
max_value),
|
||||
1 /* need */,
|
||||
1 /* auto_increment_increment */,
|
||||
0 /* auto_increment_offset */,
|
||||
max_value);
|
||||
}
|
||||
|
||||
table->autoinc_mutex.wr_lock();
|
||||
|
||||
table->persistent_autoinc = static_cast<uint16_t>(
|
||||
dict_table_get_nth_col_pos(table, col_no, NULL) + 1)
|
||||
& dict_index_t::MAX_N_FIELDS;
|
||||
|
||||
if (table->autoinc) {
|
||||
/* Already initialized. Our caller checked
|
||||
table->persistent_autoinc without
|
||||
autoinc_mutex protection, and there might be multiple
|
||||
ha_innobase::open() executing concurrently. */
|
||||
} else if (srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) {
|
||||
/* If the recovery level is set so high that writes
|
||||
are disabled we force the AUTOINC counter to 0
|
||||
value effectively disabling writes to the table.
|
||||
Secondly, we avoid reading the table in case the read
|
||||
results in failure due to a corrupted table/index.
|
||||
|
||||
We will not return an error to the client, so that the
|
||||
tables can be dumped with minimal hassle. If an error
|
||||
were returned in this case, the first attempt to read
|
||||
the table would fail and subsequent SELECTs would succeed. */
|
||||
} else if (table->persistent_autoinc) {
|
||||
table->autoinc = innobase_next_autoinc(
|
||||
btr_read_autoinc_with_fallback(table, col_no),
|
||||
1 /* need */,
|
||||
1 /* auto_increment_increment */,
|
||||
0 /* auto_increment_offset */,
|
||||
innobase_get_int_col_max_value(field));
|
||||
}
|
||||
|
||||
table->autoinc_mutex.wr_unlock();
|
||||
table->autoinc_mutex.wr_unlock();
|
||||
}
|
||||
|
||||
/** Open an InnoDB table
|
||||
@@ -6105,7 +6047,7 @@ ha_innobase::open(const char* name, int, uint)
|
||||
|| m_prebuilt->table->persistent_autoinc
|
||||
|| !m_prebuilt->table->is_readable()) {
|
||||
} else if (const Field* ai = table->found_next_number_field) {
|
||||
initialize_auto_increment(m_prebuilt->table, ai);
|
||||
initialize_auto_increment(m_prebuilt->table, *ai, *table->s);
|
||||
}
|
||||
|
||||
/* Set plugin parser for fulltext index */
|
||||
@@ -13383,6 +13325,49 @@ ha_innobase::discard_or_import_tablespace(
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/** Report a DROP TABLE failure due to a FOREIGN KEY constraint.
|
||||
@param name table name
|
||||
@param foreign constraint */
|
||||
ATTRIBUTE_COLD
|
||||
static void delete_table_cannot_drop_foreign(const table_name_t &name,
|
||||
const dict_foreign_t &foreign)
|
||||
{
|
||||
mysql_mutex_lock(&dict_foreign_err_mutex);
|
||||
rewind(dict_foreign_err_file);
|
||||
ut_print_timestamp(dict_foreign_err_file);
|
||||
fputs(" Cannot drop table ", dict_foreign_err_file);
|
||||
ut_print_name(dict_foreign_err_file, nullptr, name.m_name);
|
||||
fputs("\nbecause it is referenced by ", dict_foreign_err_file);
|
||||
ut_print_name(dict_foreign_err_file, nullptr, foreign.foreign_table_name);
|
||||
putc('\n', dict_foreign_err_file);
|
||||
mysql_mutex_unlock(&dict_foreign_err_mutex);
|
||||
}
|
||||
|
||||
/** Check if DROP TABLE would fail due to a FOREIGN KEY constraint.
|
||||
@param table table to be dropped
|
||||
@param sqlcom thd_sql_command(current_thd)
|
||||
@return whether child tables that refer to this table exist */
|
||||
static bool delete_table_check_foreigns(const dict_table_t &table,
|
||||
enum_sql_command sqlcom)
|
||||
{
|
||||
const bool drop_db{sqlcom == SQLCOM_DROP_DB};
|
||||
for (const auto foreign : table.referenced_set)
|
||||
{
|
||||
/* We should allow dropping a referenced table if creating
|
||||
that referenced table has failed for some reason. For example
|
||||
if referenced table is created but it column types that are
|
||||
referenced do not match. */
|
||||
if (foreign->foreign_table == &table ||
|
||||
(drop_db &&
|
||||
dict_tables_have_same_db(table.name.m_name,
|
||||
foreign->foreign_table_name_lookup)))
|
||||
continue;
|
||||
delete_table_cannot_drop_foreign(table.name, *foreign);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** DROP TABLE (possibly as part of DROP DATABASE, CREATE/ALTER TABLE)
|
||||
@param name table name
|
||||
@@ -13397,8 +13382,8 @@ int ha_innobase::delete_table(const char *name)
|
||||
|
||||
DBUG_EXECUTE_IF("test_normalize_table_name_low",
|
||||
test_normalize_table_name_low(););
|
||||
DBUG_EXECUTE_IF("test_ut_format_name", test_ut_format_name(););
|
||||
|
||||
const enum_sql_command sqlcom= enum_sql_command(thd_sql_command(thd));
|
||||
trx_t *parent_trx= check_trx_exists(thd);
|
||||
dict_table_t *table;
|
||||
|
||||
@@ -13435,6 +13420,13 @@ int ha_innobase::delete_table(const char *name)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
if (parent_trx->check_foreigns &&
|
||||
delete_table_check_foreigns(*table, sqlcom))
|
||||
{
|
||||
dict_sys.unlock();
|
||||
DBUG_RETURN(HA_ERR_ROW_IS_REFERENCED);
|
||||
}
|
||||
|
||||
table->acquire();
|
||||
dict_sys.unlock();
|
||||
|
||||
@@ -13467,14 +13459,7 @@ int ha_innobase::delete_table(const char *name)
|
||||
/* FOREIGN KEY constraints cannot exist on partitioned tables. */;
|
||||
#endif
|
||||
else
|
||||
{
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
for (const dict_foreign_t* f : table->referenced_set)
|
||||
if (dict_table_t* child= f->foreign_table)
|
||||
if ((err= lock_table_for_trx(child, trx, LOCK_X)) != DB_SUCCESS)
|
||||
break;
|
||||
dict_sys.unfreeze();
|
||||
}
|
||||
err= lock_table_children(table, trx);
|
||||
}
|
||||
|
||||
dict_table_t *table_stats= nullptr, *index_stats= nullptr;
|
||||
@@ -13484,7 +13469,6 @@ int ha_innobase::delete_table(const char *name)
|
||||
|
||||
const bool fts= err == DB_SUCCESS &&
|
||||
(table->flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS));
|
||||
const enum_sql_command sqlcom= enum_sql_command(thd_sql_command(thd));
|
||||
|
||||
if (fts)
|
||||
{
|
||||
@@ -13642,36 +13626,16 @@ err_exit:
|
||||
DBUG_RETURN(convert_error_code_to_mysql(err, 0, NULL));
|
||||
}
|
||||
|
||||
if (!table->no_rollback() && trx->check_foreigns)
|
||||
if (!table->no_rollback())
|
||||
{
|
||||
const bool drop_db= sqlcom == SQLCOM_DROP_DB;
|
||||
for (auto foreign : table->referenced_set)
|
||||
if (trx->check_foreigns && delete_table_check_foreigns(*table, sqlcom))
|
||||
{
|
||||
/* We should allow dropping a referenced table if creating
|
||||
that referenced table has failed for some reason. For example
|
||||
if referenced table is created but it column types that are
|
||||
referenced do not match. */
|
||||
if (foreign->foreign_table == table ||
|
||||
(drop_db &&
|
||||
dict_tables_have_same_db(table->name.m_name,
|
||||
foreign->foreign_table_name_lookup)))
|
||||
continue;
|
||||
mysql_mutex_lock(&dict_foreign_err_mutex);
|
||||
rewind(dict_foreign_err_file);
|
||||
ut_print_timestamp(dict_foreign_err_file);
|
||||
fputs(" Cannot drop table ", dict_foreign_err_file);
|
||||
ut_print_name(dict_foreign_err_file, trx, table->name.m_name);
|
||||
fputs("\nbecause it is referenced by ", dict_foreign_err_file);
|
||||
ut_print_name(dict_foreign_err_file, trx, foreign->foreign_table_name);
|
||||
putc('\n', dict_foreign_err_file);
|
||||
mysql_mutex_unlock(&dict_foreign_err_mutex);
|
||||
err= DB_CANNOT_DROP_CONSTRAINT;
|
||||
goto err_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!table->no_rollback())
|
||||
err= trx->drop_table_foreign(table->name);
|
||||
}
|
||||
|
||||
if (err == DB_SUCCESS && table_stats && index_stats)
|
||||
err= trx->drop_table_statistics(table->name);
|
||||
@@ -13790,6 +13754,19 @@ int ha_innobase::truncate()
|
||||
|
||||
update_thd();
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (!thd_test_options(m_user_thd, OPTION_NO_FOREIGN_KEY_CHECKS))
|
||||
{
|
||||
/* fk_truncate_illegal_if_parent() should have failed in
|
||||
Sql_cmd_truncate_table::handler_truncate() if foreign_key_checks=ON
|
||||
and child tables exist. */
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
for (const auto foreign : m_prebuilt->table->referenced_set)
|
||||
ut_ad(foreign->foreign_table == m_prebuilt->table);
|
||||
dict_sys.unfreeze();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (is_read_only())
|
||||
DBUG_RETURN(HA_ERR_TABLE_READONLY);
|
||||
|
||||
@@ -13872,14 +13849,7 @@ int ha_innobase::truncate()
|
||||
dict_table_t *table_stats = nullptr, *index_stats = nullptr;
|
||||
MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr;
|
||||
|
||||
dberr_t error= DB_SUCCESS;
|
||||
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
for (const dict_foreign_t *f : ib_table->referenced_set)
|
||||
if (dict_table_t *child= f->foreign_table)
|
||||
if ((error= lock_table_for_trx(child, trx, LOCK_X)) != DB_SUCCESS)
|
||||
break;
|
||||
dict_sys.unfreeze();
|
||||
dberr_t error= lock_table_children(ib_table, trx);
|
||||
|
||||
if (error == DB_SUCCESS)
|
||||
error= lock_table_for_trx(ib_table, trx, LOCK_X);
|
||||
@@ -14070,16 +14040,7 @@ ha_innobase::rename_table(
|
||||
/* There is no need to lock any FOREIGN KEY child tables. */
|
||||
} else if (dict_table_t *table = dict_table_open_on_name(
|
||||
norm_from, false, DICT_ERR_IGNORE_FK_NOKEY)) {
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
for (const dict_foreign_t* f : table->referenced_set) {
|
||||
if (dict_table_t* child = f->foreign_table) {
|
||||
error = lock_table_for_trx(child, trx, LOCK_X);
|
||||
if (error != DB_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dict_sys.unfreeze();
|
||||
error = lock_table_children(table, trx);
|
||||
if (error == DB_SUCCESS) {
|
||||
error = lock_table_for_trx(table, trx, LOCK_X);
|
||||
}
|
||||
@@ -15140,6 +15101,7 @@ ha_innobase::check(
|
||||
ulint n_rows_in_table = ULINT_UNDEFINED;
|
||||
bool is_ok = true;
|
||||
dberr_t ret;
|
||||
uint handler_flags= check_opt->handler_flags;
|
||||
|
||||
DBUG_ENTER("ha_innobase::check");
|
||||
DBUG_ASSERT(thd == ha_thd());
|
||||
@@ -15148,6 +15110,27 @@ ha_innobase::check(
|
||||
ut_a(m_prebuilt->trx == thd_to_trx(thd));
|
||||
ut_ad(m_prebuilt->trx->mysql_thd == thd);
|
||||
|
||||
if (handler_flags || check_for_upgrade(check_opt)) {
|
||||
/* The file was already checked and fixed as part of open */
|
||||
print_check_msg(thd, table->s->db.str, table->s->table_name.str,
|
||||
"check", "note",
|
||||
(opt_readonly || high_level_read_only
|
||||
|| !(check_opt->sql_flags & TT_FOR_UPGRADE))
|
||||
? "Auto_increment will be"
|
||||
" checked on each open until"
|
||||
" CHECK TABLE FOR UPGRADE is executed"
|
||||
: "Auto_increment checked and"
|
||||
" .frm file version updated", 1);
|
||||
if (handler_flags && (check_opt->sql_flags & TT_FOR_UPGRADE)) {
|
||||
/*
|
||||
No other issues found (as handler_flags was only
|
||||
set if there as not other problems with the table
|
||||
than auto_increment).
|
||||
*/
|
||||
DBUG_RETURN(HA_ADMIN_OK);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_prebuilt->mysql_template == NULL) {
|
||||
/* Build the template; we will use a dummy template
|
||||
in index scans done in checking */
|
||||
@@ -15351,6 +15334,35 @@ func_exit:
|
||||
DBUG_RETURN(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
|
||||
}
|
||||
|
||||
/**
|
||||
Check if we there is a problem with the InnoDB table.
|
||||
@param check_opt check options
|
||||
@retval HA_ADMIN_OK if Table is ok
|
||||
@retval HA_ADMIN_NEEDS_ALTER User should run ALTER TABLE FOR UPGRADE
|
||||
@retval HA_ADMIN_NEEDS_CHECK User should run CHECK TABLE FOR UPGRADE
|
||||
@retval HA_ADMIN_FAILED if InnoDB is in read-only mode */
|
||||
int ha_innobase::check_for_upgrade(HA_CHECK_OPT *check_opt)
|
||||
{
|
||||
/*
|
||||
Check if there is a possibility that the auto increment value
|
||||
stored in PAGE_ROOT_AUTO_INC could be corrupt.
|
||||
*/
|
||||
if (table->s->mysql_version >= 100210);
|
||||
else if (const Field *auto_increment= table->found_next_number_field)
|
||||
{
|
||||
uint col_no= innodb_col_no(auto_increment);
|
||||
const dict_col_t *autoinc_col=
|
||||
dict_table_get_nth_col(m_prebuilt->table, col_no);
|
||||
if (m_prebuilt->table->get_index(*autoinc_col))
|
||||
{
|
||||
check_opt->handler_flags= 1;
|
||||
return (high_level_read_only && !opt_readonly)
|
||||
? HA_ADMIN_FAILED : HA_ADMIN_NEEDS_CHECK;
|
||||
}
|
||||
}
|
||||
return HA_ADMIN_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Gets the foreign key create info for a table stored in InnoDB.
|
||||
@return own: character string in the form which can be inserted to the
|
||||
@@ -17535,6 +17547,7 @@ innodb_make_page_dirty(THD*, st_mysql_sys_var*, void*, const void* save)
|
||||
{
|
||||
mtr_t mtr;
|
||||
uint space_id = *static_cast<const uint*>(save);
|
||||
srv_fil_make_page_dirty_debug= space_id;
|
||||
mysql_mutex_unlock(&LOCK_global_system_variables);
|
||||
fil_space_t* space = fil_space_t::get(space_id);
|
||||
|
||||
@@ -18261,13 +18274,15 @@ buf_flush_list_now_set(THD*, st_mysql_sys_var*, void*, const void* save)
|
||||
return;
|
||||
const uint s= srv_fil_make_page_dirty_debug;
|
||||
mysql_mutex_unlock(&LOCK_global_system_variables);
|
||||
if (s)
|
||||
buf_flush_sync();
|
||||
else
|
||||
if (s == 0 || srv_is_undo_tablespace(s))
|
||||
{
|
||||
while (buf_flush_list_space(fil_system.sys_space, nullptr));
|
||||
fil_space_t *space= fil_system.sys_space;
|
||||
if (s) { space= fil_space_get(s); }
|
||||
while (buf_flush_list_space(space, nullptr));
|
||||
os_aio_wait_until_no_pending_writes(true);
|
||||
}
|
||||
else
|
||||
buf_flush_sync();
|
||||
mysql_mutex_lock(&LOCK_global_system_variables);
|
||||
}
|
||||
|
||||
|
||||
@@ -209,6 +209,7 @@ public:
|
||||
int rename_table(const char* from, const char* to) override;
|
||||
inline int defragment_table();
|
||||
int check(THD* thd, HA_CHECK_OPT* check_opt) override;
|
||||
int check_for_upgrade(HA_CHECK_OPT* check_opt) override;
|
||||
|
||||
inline void reload_statistics();
|
||||
|
||||
@@ -909,6 +910,12 @@ unsigned
|
||||
innodb_col_no(const Field* field)
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
|
||||
/** Get the maximum integer value of a numeric column.
|
||||
@param field column definition
|
||||
@return maximum allowed integer value */
|
||||
ulonglong innobase_get_int_col_max_value(const Field *field)
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
|
||||
/********************************************************************//**
|
||||
Helper function to push frm mismatch error to error log and
|
||||
if needed to sql-layer. */
|
||||
|
||||
@@ -1458,11 +1458,6 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
|
||||
}
|
||||
};
|
||||
|
||||
/********************************************************************//**
|
||||
Get the upper limit of the MySQL integral and floating-point type.
|
||||
@return maximum allowed value for the field */
|
||||
ulonglong innobase_get_int_col_max_value(const Field *field);
|
||||
|
||||
/** Determine if fulltext indexes exist in a given table.
|
||||
@param table MySQL table
|
||||
@return number of fulltext indexes */
|
||||
@@ -9865,13 +9860,7 @@ commit_set_autoinc(
|
||||
const dict_col_t* autoinc_col
|
||||
= dict_table_get_nth_col(ctx->old_table,
|
||||
innodb_col_no(ai));
|
||||
dict_index_t* index
|
||||
= dict_table_get_first_index(ctx->old_table);
|
||||
while (index != NULL
|
||||
&& index->fields[0].col != autoinc_col) {
|
||||
index = dict_table_get_next_index(index);
|
||||
}
|
||||
|
||||
auto index = ctx->old_table->get_index(*autoinc_col);
|
||||
ut_ad(index);
|
||||
|
||||
ib_uint64_t max_in_table = index
|
||||
@@ -11224,16 +11213,7 @@ ha_innobase::commit_inplace_alter_table(
|
||||
fts_optimize_remove_table(ctx->old_table);
|
||||
}
|
||||
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
for (auto f : ctx->old_table->referenced_set) {
|
||||
if (dict_table_t* child = f->foreign_table) {
|
||||
error = lock_table_for_trx(child, trx, LOCK_X);
|
||||
if (error != DB_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dict_sys.unfreeze();
|
||||
error = lock_table_children(ctx->old_table, trx);
|
||||
|
||||
if (ctx->new_table->fts) {
|
||||
ut_ad(!ctx->new_table->fts->add_wq);
|
||||
|
||||
@@ -189,13 +189,16 @@ btr_read_autoinc(dict_index_t* index)
|
||||
|
||||
/** Read the last used AUTO_INCREMENT value from PAGE_ROOT_AUTO_INC,
|
||||
or fall back to MAX(auto_increment_column).
|
||||
@param[in] table table containing an AUTO_INCREMENT column
|
||||
@param[in] col_no index of the AUTO_INCREMENT column
|
||||
@return the AUTO_INCREMENT value
|
||||
@retval 0 on error or if no AUTO_INCREMENT value was used yet */
|
||||
ib_uint64_t
|
||||
btr_read_autoinc_with_fallback(const dict_table_t* table, unsigned col_no)
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
@param table table containing an AUTO_INCREMENT column
|
||||
@param col_no index of the AUTO_INCREMENT column
|
||||
@param mysql_version TABLE_SHARE::mysql_version
|
||||
@param max the maximum value of the AUTO_INCREMENT column
|
||||
@return the AUTO_INCREMENT value
|
||||
@retval 0 on error or if no AUTO_INCREMENT value was used yet */
|
||||
uint64_t btr_read_autoinc_with_fallback(const dict_table_t *table,
|
||||
unsigned col_no, ulong mysql_version,
|
||||
uint64_t max)
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
|
||||
/** Write the next available AUTO_INCREMENT value to PAGE_ROOT_AUTO_INC.
|
||||
@param[in,out] index clustered index
|
||||
|
||||
@@ -35,6 +35,7 @@ Created 1/8/1996 Heikki Tuuri
|
||||
#include <my_sys.h>
|
||||
#include <deque>
|
||||
|
||||
class MDL_context;
|
||||
class MDL_ticket;
|
||||
|
||||
/** the first table or index ID for other than hard-coded system tables */
|
||||
@@ -139,6 +140,21 @@ dict_acquire_mdl_shared(dict_table_t *table,
|
||||
MDL_ticket **mdl,
|
||||
dict_table_op_t table_op= DICT_TABLE_OP_NORMAL);
|
||||
|
||||
/** Acquire MDL shared for the table name.
|
||||
@tparam trylock whether to use non-blocking operation
|
||||
@param[in,out] table table object
|
||||
@param[in,out] mdl_context MDL context
|
||||
@param[out] mdl MDL ticket
|
||||
@param[in] table_op operation to perform when opening
|
||||
@return table object after locking MDL shared
|
||||
@retval nullptr if the table is not readable, or if trylock && MDL blocked */
|
||||
template<bool trylock>
|
||||
__attribute__((nonnull, warn_unused_result))
|
||||
dict_table_t*
|
||||
dict_acquire_mdl_shared(dict_table_t *table,
|
||||
MDL_context *mdl_context, MDL_ticket **mdl,
|
||||
dict_table_op_t table_op);
|
||||
|
||||
/** Look up a table by numeric identifier.
|
||||
@param[in] table_id table identifier
|
||||
@param[in] dict_locked data dictionary locked
|
||||
@@ -1314,13 +1330,7 @@ class dict_sys_t
|
||||
std::atomic<ulonglong> latch_ex_wait_start;
|
||||
|
||||
/** the rw-latch protecting the data dictionary cache */
|
||||
alignas(CPU_LEVEL1_DCACHE_LINESIZE) srw_lock latch;
|
||||
#ifdef UNIV_DEBUG
|
||||
/** whether latch is being held in exclusive mode (by any thread) */
|
||||
Atomic_relaxed<pthread_t> latch_ex;
|
||||
/** number of S-latch holders */
|
||||
Atomic_counter<uint32_t> latch_readers;
|
||||
#endif
|
||||
alignas(CPU_LEVEL1_DCACHE_LINESIZE) IF_DBUG(srw_lock_debug,srw_lock) latch;
|
||||
public:
|
||||
/** Indexes of SYS_TABLE[] */
|
||||
enum
|
||||
@@ -1488,15 +1498,12 @@ public:
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/** @return whether any thread (not necessarily the current thread)
|
||||
is holding the latch; that is, this check may return false
|
||||
positives */
|
||||
bool frozen() const { return latch_readers || latch_ex; }
|
||||
/** @return whether any thread (not necessarily the current thread)
|
||||
is holding a shared latch */
|
||||
bool frozen_not_locked() const { return latch_readers; }
|
||||
/** @return whether the current thread is holding the latch */
|
||||
bool frozen() const { return latch.have_any(); }
|
||||
/** @return whether the current thread is holding a shared latch */
|
||||
bool frozen_not_locked() const { return latch.have_rd(); }
|
||||
/** @return whether the current thread holds the exclusive latch */
|
||||
bool locked() const { return latch_ex == pthread_self(); }
|
||||
bool locked() const { return latch.have_wr(); }
|
||||
#endif
|
||||
private:
|
||||
/** Acquire the exclusive latch */
|
||||
@@ -1511,13 +1518,7 @@ public:
|
||||
/** Exclusively lock the dictionary cache. */
|
||||
void lock(SRW_LOCK_ARGS(const char *file, unsigned line))
|
||||
{
|
||||
if (latch.wr_lock_try())
|
||||
{
|
||||
ut_ad(!latch_readers);
|
||||
ut_ad(!latch_ex);
|
||||
ut_d(latch_ex= pthread_self());
|
||||
}
|
||||
else
|
||||
if (!latch.wr_lock_try())
|
||||
lock_wait(SRW_LOCK_ARGS(file, line));
|
||||
}
|
||||
|
||||
@@ -1530,27 +1531,11 @@ public:
|
||||
ATTRIBUTE_NOINLINE void unfreeze();
|
||||
#else
|
||||
/** Unlock the data dictionary cache. */
|
||||
void unlock()
|
||||
{
|
||||
ut_ad(latch_ex == pthread_self());
|
||||
ut_ad(!latch_readers);
|
||||
ut_d(latch_ex= 0);
|
||||
latch.wr_unlock();
|
||||
}
|
||||
void unlock() { latch.wr_unlock(); }
|
||||
/** Acquire a shared lock on the dictionary cache. */
|
||||
void freeze()
|
||||
{
|
||||
latch.rd_lock();
|
||||
ut_ad(!latch_ex);
|
||||
ut_d(latch_readers++);
|
||||
}
|
||||
void freeze() { latch.rd_lock(); }
|
||||
/** Release a shared lock on the dictionary cache. */
|
||||
void unfreeze()
|
||||
{
|
||||
ut_ad(!latch_ex);
|
||||
ut_ad(latch_readers--);
|
||||
latch.rd_unlock();
|
||||
}
|
||||
void unfreeze() { latch.rd_unlock(); }
|
||||
#endif
|
||||
|
||||
/** Estimate the used memory occupied by the data dictionary
|
||||
|
||||
@@ -2448,6 +2448,9 @@ public:
|
||||
/** @return number of unique columns in FTS_DOC_ID index */
|
||||
unsigned fts_n_uniq() const { return versioned() ? 2 : 1; }
|
||||
|
||||
/** @return the index for that starts with a specific column */
|
||||
dict_index_t *get_index(const dict_col_t &col) const;
|
||||
|
||||
/** Create metadata.
|
||||
@param name table name
|
||||
@param space tablespace
|
||||
|
||||
@@ -347,7 +347,6 @@ struct fil_space_t final
|
||||
~fil_space_t()
|
||||
{
|
||||
ut_ad(!latch_owner);
|
||||
ut_ad(!latch_count);
|
||||
latch.destroy();
|
||||
}
|
||||
|
||||
@@ -411,9 +410,9 @@ private:
|
||||
/** The reference count */
|
||||
static constexpr uint32_t PENDING= ~(STOPPING | CLOSING | NEEDS_FSYNC);
|
||||
/** latch protecting all page allocation bitmap pages */
|
||||
srw_lock latch;
|
||||
IF_DBUG(srw_lock_debug, srw_lock) latch;
|
||||
/** the thread that holds the exclusive latch, or 0 */
|
||||
pthread_t latch_owner;
|
||||
ut_d(Atomic_relaxed<uint32_t> latch_count;)
|
||||
public:
|
||||
/** MariaDB encryption data */
|
||||
fil_space_crypt_t *crypt_data;
|
||||
@@ -1004,40 +1003,32 @@ public:
|
||||
bool recheck, bool encrypt);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
bool is_latched() const { return latch_count != 0; }
|
||||
bool is_latched() const { return latch.have_any(); }
|
||||
#endif
|
||||
bool is_owner() const { return latch_owner == pthread_self(); }
|
||||
bool is_owner() const
|
||||
{
|
||||
const bool owner{latch_owner == pthread_self()};
|
||||
ut_ad(owner == latch.have_wr());
|
||||
return owner;
|
||||
}
|
||||
/** Acquire the allocation latch in exclusive mode */
|
||||
void x_lock()
|
||||
{
|
||||
latch.wr_lock(SRW_LOCK_CALL);
|
||||
ut_ad(!latch_owner);
|
||||
latch_owner= pthread_self();
|
||||
ut_ad(!latch_count.fetch_add(1));
|
||||
}
|
||||
/** Release the allocation latch from exclusive mode */
|
||||
void x_unlock()
|
||||
{
|
||||
ut_ad(latch_count.fetch_sub(1) == 1);
|
||||
ut_ad(latch_owner == pthread_self());
|
||||
latch_owner= 0;
|
||||
latch.wr_unlock();
|
||||
}
|
||||
/** Acquire the allocation latch in shared mode */
|
||||
void s_lock()
|
||||
{
|
||||
ut_ad(!is_owner());
|
||||
latch.rd_lock(SRW_LOCK_CALL);
|
||||
ut_ad(!latch_owner);
|
||||
ut_d(latch_count.fetch_add(1));
|
||||
}
|
||||
void s_lock() { latch.rd_lock(SRW_LOCK_CALL); }
|
||||
/** Release the allocation latch from shared mode */
|
||||
void s_unlock()
|
||||
{
|
||||
ut_ad(latch_count.fetch_sub(1));
|
||||
ut_ad(!latch_owner);
|
||||
latch.rd_unlock();
|
||||
}
|
||||
void s_unlock() { latch.rd_unlock(); }
|
||||
|
||||
typedef span<const char> name_type;
|
||||
|
||||
|
||||
@@ -438,6 +438,13 @@ dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, lock_mode mode,
|
||||
bool no_wait= false)
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
|
||||
/** Lock the child tables of a table.
|
||||
@param table parent table
|
||||
@param trx transaction
|
||||
@return error code */
|
||||
dberr_t lock_table_children(dict_table_t *table, trx_t *trx)
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
|
||||
/** Exclusively lock the data dictionary tables.
|
||||
@param trx dictionary transaction
|
||||
@return error code
|
||||
@@ -724,13 +731,8 @@ private:
|
||||
bool m_initialised;
|
||||
|
||||
/** mutex proteting the locks */
|
||||
alignas(CPU_LEVEL1_DCACHE_LINESIZE) srw_spin_lock latch;
|
||||
#ifdef UNIV_DEBUG
|
||||
/** The owner of exclusive latch (0 if none); protected by latch */
|
||||
std::atomic<pthread_t> writer{0};
|
||||
/** Number of shared latches */
|
||||
std::atomic<ulint> readers{0};
|
||||
#endif
|
||||
alignas(CPU_LEVEL1_DCACHE_LINESIZE)
|
||||
IF_DBUG(srw_lock_debug,srw_spin_lock) latch;
|
||||
#ifdef SUX_LOCK_GENERIC
|
||||
protected:
|
||||
/** mutex for hash_latch::wait() */
|
||||
@@ -789,71 +791,35 @@ public:
|
||||
void wr_lock()
|
||||
{
|
||||
mysql_mutex_assert_not_owner(&wait_mutex);
|
||||
ut_ad(!is_writer());
|
||||
latch.wr_lock();
|
||||
ut_ad(!writer.exchange(pthread_self(),
|
||||
std::memory_order_relaxed));
|
||||
}
|
||||
/** Release exclusive lock_sys.latch */
|
||||
void wr_unlock()
|
||||
{
|
||||
ut_ad(writer.exchange(0, std::memory_order_relaxed) ==
|
||||
pthread_self());
|
||||
latch.wr_unlock();
|
||||
}
|
||||
void wr_unlock() { latch.wr_unlock(); }
|
||||
/** Acquire shared lock_sys.latch */
|
||||
void rd_lock()
|
||||
{
|
||||
mysql_mutex_assert_not_owner(&wait_mutex);
|
||||
ut_ad(!is_writer());
|
||||
latch.rd_lock();
|
||||
ut_ad(!writer.load(std::memory_order_relaxed));
|
||||
ut_d(readers.fetch_add(1, std::memory_order_relaxed));
|
||||
}
|
||||
/** Release shared lock_sys.latch */
|
||||
void rd_unlock()
|
||||
{
|
||||
ut_ad(!is_writer());
|
||||
ut_ad(readers.fetch_sub(1, std::memory_order_relaxed));
|
||||
latch.rd_unlock();
|
||||
}
|
||||
void rd_unlock() { latch.rd_unlock(); }
|
||||
#endif
|
||||
/** Try to acquire exclusive lock_sys.latch
|
||||
@return whether the latch was acquired */
|
||||
bool wr_lock_try()
|
||||
{
|
||||
ut_ad(!is_writer());
|
||||
if (!latch.wr_lock_try()) return false;
|
||||
ut_ad(!writer.exchange(pthread_self(),
|
||||
std::memory_order_relaxed));
|
||||
return true;
|
||||
}
|
||||
bool wr_lock_try() { return latch.wr_lock_try(); }
|
||||
/** Try to acquire shared lock_sys.latch
|
||||
@return whether the latch was acquired */
|
||||
bool rd_lock_try()
|
||||
{
|
||||
ut_ad(!is_writer());
|
||||
if (!latch.rd_lock_try()) return false;
|
||||
ut_ad(!writer.load(std::memory_order_relaxed));
|
||||
ut_d(readers.fetch_add(1, std::memory_order_relaxed));
|
||||
return true;
|
||||
}
|
||||
bool rd_lock_try() { return latch.rd_lock_try(); }
|
||||
|
||||
/** Assert that wr_lock() has been invoked by this thread */
|
||||
void assert_locked() const { ut_ad(is_writer()); }
|
||||
void assert_locked() const { ut_ad(latch.have_wr()); }
|
||||
/** Assert that wr_lock() has not been invoked by this thread */
|
||||
void assert_unlocked() const { ut_ad(!is_writer()); }
|
||||
void assert_unlocked() const { ut_ad(!latch.have_wr()); }
|
||||
#ifdef UNIV_DEBUG
|
||||
/** @return whether the current thread is the lock_sys.latch writer */
|
||||
bool is_writer() const
|
||||
{
|
||||
# ifdef SUX_LOCK_GENERIC
|
||||
return writer.load(std::memory_order_relaxed) == pthread_self();
|
||||
# else
|
||||
return writer.load(std::memory_order_relaxed) == pthread_self() ||
|
||||
(xtest() && !latch.is_locked_or_waiting());
|
||||
# endif
|
||||
}
|
||||
bool is_writer() const { return latch.have_wr(); }
|
||||
/** @return whether the current thread is holding lock_sys.latch */
|
||||
bool is_holder() const { return latch.have_any(); }
|
||||
/** Assert that a lock shard is exclusively latched (by some thread) */
|
||||
void assert_locked(const lock_t &lock) const;
|
||||
/** Assert that a table lock shard is exclusively latched by this thread */
|
||||
@@ -965,14 +931,14 @@ extern lock_sys_t lock_sys;
|
||||
/** @return the index of an array element */
|
||||
inline ulint lock_sys_t::hash_table::calc_hash(ulint fold) const
|
||||
{
|
||||
ut_ad(lock_sys.is_writer() || lock_sys.readers);
|
||||
ut_ad(lock_sys.is_holder());
|
||||
return calc_hash(fold, n_cells);
|
||||
}
|
||||
|
||||
/** Get a hash table cell. */
|
||||
inline hash_cell_t *lock_sys_t::hash_table::cell_get(ulint fold) const
|
||||
{
|
||||
ut_ad(lock_sys.is_writer() || lock_sys.readers);
|
||||
ut_ad(lock_sys.is_holder());
|
||||
return &array[calc_hash(fold)];
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ template<bool spinloop> class srw_lock_impl;
|
||||
|
||||
/** Slim shared-update-exclusive lock with no recursion */
|
||||
template<bool spinloop>
|
||||
class ssux_lock_impl final
|
||||
class ssux_lock_impl
|
||||
{
|
||||
#ifdef UNIV_PFS_RWLOCK
|
||||
friend class ssux_lock;
|
||||
@@ -550,3 +550,51 @@ typedef srw_lock_impl<false> srw_lock;
|
||||
typedef srw_lock_impl<true> srw_spin_lock;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
# include <unordered_set>
|
||||
|
||||
class srw_lock_debug : private srw_lock
|
||||
{
|
||||
/** The owner of the exclusive lock (0 if none) */
|
||||
std::atomic<pthread_t> writer;
|
||||
/** Protects readers */
|
||||
mutable srw_mutex readers_lock;
|
||||
/** Threads that hold the lock in shared mode */
|
||||
std::atomic<std::unordered_multiset<pthread_t>*> readers;
|
||||
|
||||
/** Register a read lock. */
|
||||
void readers_register();
|
||||
|
||||
public:
|
||||
void SRW_LOCK_INIT(mysql_pfs_key_t key);
|
||||
void destroy();
|
||||
|
||||
#ifndef SUX_LOCK_GENERIC
|
||||
/** @return whether any lock may be held by any thread */
|
||||
bool is_locked_or_waiting() const noexcept
|
||||
{ return srw_lock::is_locked_or_waiting(); }
|
||||
/** @return whether an exclusive lock may be held by any thread */
|
||||
bool is_write_locked() const noexcept { return srw_lock::is_write_locked(); }
|
||||
#endif
|
||||
|
||||
/** Acquire an exclusive lock */
|
||||
void wr_lock(SRW_LOCK_ARGS(const char *file, unsigned line));
|
||||
/** @return whether an exclusive lock was acquired */
|
||||
bool wr_lock_try();
|
||||
/** Release after wr_lock() */
|
||||
void wr_unlock();
|
||||
/** Acquire a shared lock */
|
||||
void rd_lock(SRW_LOCK_ARGS(const char *file, unsigned line));
|
||||
/** @return whether a shared lock was acquired */
|
||||
bool rd_lock_try();
|
||||
/** Release after rd_lock() */
|
||||
void rd_unlock();
|
||||
/** @return whether this thread is between rd_lock() and rd_unlock() */
|
||||
bool have_rd() const noexcept;
|
||||
/** @return whether this thread is between wr_lock() and wr_unlock() */
|
||||
bool have_wr() const noexcept;
|
||||
/** @return whether this thread is holding rd_lock() or wr_lock() */
|
||||
bool have_any() const noexcept;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -59,7 +59,7 @@ struct alignas(CPU_LEVEL1_DCACHE_LINESIZE) trx_rseg_t
|
||||
/** tablespace containing the rollback segment; constant after init() */
|
||||
fil_space_t *space;
|
||||
/** latch protecting everything except page_no, space */
|
||||
srw_spin_lock latch;
|
||||
IF_DBUG(srw_lock_debug,srw_spin_lock) latch;
|
||||
/** rollback segment header page number; constant after init() */
|
||||
uint32_t page_no;
|
||||
/** length of the TRX_RSEG_HISTORY list (number of transactions) */
|
||||
|
||||
@@ -242,20 +242,6 @@ ut_print_name(
|
||||
FILE* ef, /*!< in: stream */
|
||||
const trx_t* trx, /*!< in: transaction */
|
||||
const char* name); /*!< in: table name to print */
|
||||
/** Format a table name, quoted as an SQL identifier.
|
||||
If the name contains a slash '/', the result will contain two
|
||||
identifiers separated by a period (.), as in SQL
|
||||
database_name.table_name.
|
||||
@see table_name_t
|
||||
@param[in] name table or index name
|
||||
@param[out] formatted formatted result, will be NUL-terminated
|
||||
@param[in] formatted_size size of the buffer in bytes
|
||||
@return pointer to 'formatted' */
|
||||
char*
|
||||
ut_format_name(
|
||||
const char* name,
|
||||
char* formatted,
|
||||
ulint formatted_size);
|
||||
|
||||
/**********************************************************************//**
|
||||
Catenate files. */
|
||||
|
||||
@@ -47,6 +47,7 @@ Created 5/7/1996 Heikki Tuuri
|
||||
#include "que0que.h"
|
||||
#include "scope.h"
|
||||
#include <debug_sync.h>
|
||||
#include <mysql/service_thd_mdl.h>
|
||||
|
||||
#include <set>
|
||||
|
||||
@@ -173,7 +174,7 @@ void lock_sys_t::assert_locked(const dict_table_t &table) const
|
||||
ut_ad(!table.is_temporary());
|
||||
if (is_writer())
|
||||
return;
|
||||
ut_ad(readers);
|
||||
ut_ad(latch.have_rd());
|
||||
ut_ad(table.lock_mutex_is_owner());
|
||||
}
|
||||
|
||||
@@ -182,7 +183,7 @@ void lock_sys_t::hash_table::assert_locked(const page_id_t id) const
|
||||
{
|
||||
if (lock_sys.is_writer())
|
||||
return;
|
||||
ut_ad(lock_sys.readers);
|
||||
ut_ad(lock_sys.is_holder());
|
||||
ut_ad(latch(cell_get(id.fold()))->is_locked());
|
||||
}
|
||||
|
||||
@@ -191,7 +192,7 @@ void lock_sys_t::assert_locked(const hash_cell_t &cell) const
|
||||
{
|
||||
if (is_writer())
|
||||
return;
|
||||
ut_ad(lock_sys.readers);
|
||||
ut_ad(lock_sys.is_holder());
|
||||
ut_ad(hash_table::latch(const_cast<hash_cell_t*>(&cell))->is_locked());
|
||||
}
|
||||
#endif
|
||||
@@ -426,13 +427,10 @@ void lock_sys_t::wr_lock(const char *file, unsigned line)
|
||||
{
|
||||
mysql_mutex_assert_not_owner(&wait_mutex);
|
||||
latch.wr_lock(file, line);
|
||||
ut_ad(!writer.exchange(pthread_self(), std::memory_order_relaxed));
|
||||
}
|
||||
/** Release exclusive lock_sys.latch */
|
||||
void lock_sys_t::wr_unlock()
|
||||
{
|
||||
ut_ad(writer.exchange(0, std::memory_order_relaxed) ==
|
||||
pthread_self());
|
||||
latch.wr_unlock();
|
||||
}
|
||||
|
||||
@@ -441,15 +439,11 @@ void lock_sys_t::rd_lock(const char *file, unsigned line)
|
||||
{
|
||||
mysql_mutex_assert_not_owner(&wait_mutex);
|
||||
latch.rd_lock(file, line);
|
||||
ut_ad(!writer.load(std::memory_order_relaxed));
|
||||
ut_d(readers.fetch_add(1, std::memory_order_relaxed));
|
||||
}
|
||||
|
||||
/** Release shared lock_sys.latch */
|
||||
void lock_sys_t::rd_unlock()
|
||||
{
|
||||
ut_ad(!writer.load(std::memory_order_relaxed));
|
||||
ut_ad(readers.fetch_sub(1, std::memory_order_relaxed));
|
||||
latch.rd_unlock();
|
||||
}
|
||||
#endif
|
||||
@@ -3940,6 +3934,8 @@ static void lock_table_dequeue(lock_t *in_lock, bool owns_wait_mutex)
|
||||
dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, lock_mode mode,
|
||||
bool no_wait)
|
||||
{
|
||||
ut_ad(!dict_sys.frozen());
|
||||
|
||||
mem_heap_t *heap= mem_heap_create(512);
|
||||
sel_node_t *node= sel_node_create(heap);
|
||||
que_thr_t *thr= pars_complete_graph_for_exec(node, trx, heap, nullptr);
|
||||
@@ -3976,6 +3972,67 @@ run_again:
|
||||
return err;
|
||||
}
|
||||
|
||||
/** Lock the child tables of a table.
|
||||
@param table parent table
|
||||
@param trx transaction
|
||||
@return error code */
|
||||
dberr_t lock_table_children(dict_table_t *table, trx_t *trx)
|
||||
{
|
||||
MDL_context *mdl_context=
|
||||
static_cast<MDL_context*>(thd_mdl_context(trx->mysql_thd));
|
||||
ut_ad(mdl_context);
|
||||
struct table_mdl{dict_table_t* table; MDL_ticket *mdl;};
|
||||
std::vector<table_mdl> children;
|
||||
children.emplace_back(table_mdl{table, nullptr});
|
||||
|
||||
dberr_t err= DB_SUCCESS;
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
|
||||
rescan:
|
||||
for (auto f : table->referenced_set)
|
||||
if (dict_table_t *child= f->foreign_table)
|
||||
{
|
||||
if (std::find_if(children.begin(), children.end(),
|
||||
[&](const table_mdl &c){ return c.table == child; }) !=
|
||||
children.end())
|
||||
continue; /* We already acquired MDL on this child table. */
|
||||
MDL_ticket *mdl= nullptr;
|
||||
child->acquire();
|
||||
child= dict_acquire_mdl_shared<false>(child, mdl_context, &mdl,
|
||||
DICT_TABLE_OP_NORMAL);
|
||||
if (child)
|
||||
{
|
||||
if (!mdl)
|
||||
child->release();
|
||||
children.emplace_back(table_mdl{child, mdl});
|
||||
goto rescan;
|
||||
}
|
||||
err= DB_LOCK_WAIT_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
dict_sys.unfreeze();
|
||||
|
||||
if (err == DB_SUCCESS)
|
||||
for (const table_mdl &child : children)
|
||||
if (child.mdl)
|
||||
if ((err= lock_table_for_trx(child.table, trx, LOCK_X)) != DB_SUCCESS)
|
||||
break;
|
||||
|
||||
dict_sys.freeze(SRW_LOCK_CALL);
|
||||
for (table_mdl &child : children)
|
||||
{
|
||||
if (child.mdl)
|
||||
{
|
||||
child.table->release();
|
||||
mdl_context->release_lock(child.mdl);
|
||||
}
|
||||
}
|
||||
dict_sys.unfreeze();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/** Exclusively lock the data dictionary tables.
|
||||
@param trx dictionary transaction
|
||||
@return error code
|
||||
|
||||
@@ -175,7 +175,9 @@ void log_file_t::write(os_offset_t offset, span<const byte> buf) noexcept
|
||||
ut_ad(is_opened());
|
||||
if (dberr_t err= os_file_write_func(IORequestWrite, "ib_logfile0", m_file,
|
||||
buf.data(), offset, buf.size()))
|
||||
ib::fatal() << "write(\"ib_logfile0\") returned " << err;
|
||||
ib::fatal() << "write(\"ib_logfile0\") returned " << err
|
||||
<< ". Operating system error number "
|
||||
<< IF_WIN(GetLastError(), errno) << ".";
|
||||
}
|
||||
|
||||
#ifdef HAVE_PMEM
|
||||
|
||||
@@ -4120,9 +4120,10 @@ static bool recv_scan_log(bool last_phase)
|
||||
|
||||
const lsn_t end{recv_sys.file_checkpoint};
|
||||
ut_ad(!end || end == recv_sys.lsn);
|
||||
bool corrupt_fs= recv_sys.is_corrupt_fs();
|
||||
mysql_mutex_unlock(&recv_sys.mutex);
|
||||
|
||||
if (!end)
|
||||
if (!end && !corrupt_fs)
|
||||
{
|
||||
recv_sys.set_corrupt_log();
|
||||
sql_print_error("InnoDB: Missing FILE_CHECKPOINT(" LSN_PF
|
||||
@@ -4602,6 +4603,9 @@ read_only_recovery:
|
||||
LSN_PF, recv_sys.lsn);
|
||||
goto err_exit;
|
||||
}
|
||||
if (recv_sys.is_corrupt_fs()) {
|
||||
goto err_exit;
|
||||
}
|
||||
ut_ad(recv_sys.file_checkpoint);
|
||||
if (rewind) {
|
||||
recv_sys.lsn = log_sys.next_checkpoint_lsn;
|
||||
@@ -4640,9 +4644,9 @@ read_only_recovery:
|
||||
|
||||
do {
|
||||
rescan = recv_scan_log(false);
|
||||
ut_ad(!recv_sys.is_corrupt_fs());
|
||||
|
||||
if (recv_sys.is_corrupt_log()) {
|
||||
if (recv_sys.is_corrupt_log() ||
|
||||
recv_sys.is_corrupt_fs()) {
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
|
||||
@@ -513,10 +513,8 @@ void mtr_t::rollback_to_savepoint(ulint begin, ulint end)
|
||||
/** Set create_lsn. */
|
||||
inline void fil_space_t::set_create_lsn(lsn_t lsn)
|
||||
{
|
||||
#ifndef SUX_LOCK_GENERIC
|
||||
/* Concurrent log_checkpoint_low() must be impossible. */
|
||||
ut_ad(latch.is_write_locked());
|
||||
#endif
|
||||
ut_ad(latch.have_wr());
|
||||
create_lsn= lsn;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ Created 2012-02-08 by Sunny Bains.
|
||||
#include "lzo/lzo1x.h"
|
||||
#include "snappy-c.h"
|
||||
#include "log.h"
|
||||
#include "table.h"
|
||||
#include "ha_innodb.h"
|
||||
|
||||
#include "scope.h"
|
||||
|
||||
@@ -4228,6 +4230,37 @@ fil_tablespace_iterate(
|
||||
return(err);
|
||||
}
|
||||
|
||||
static void row_import_autoinc(dict_table_t *table, row_prebuilt_t *prebuilt,
|
||||
uint64_t autoinc)
|
||||
{
|
||||
if (!table->persistent_autoinc)
|
||||
{
|
||||
ut_ad(!autoinc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (autoinc)
|
||||
{
|
||||
btr_write_autoinc(dict_table_get_first_index(table), autoinc - 1);
|
||||
autoinc_set:
|
||||
table->autoinc= autoinc;
|
||||
sql_print_information("InnoDB: %`.*s.%`s autoinc value set to " UINT64PF,
|
||||
int(table->name.dblen()), table->name.m_name,
|
||||
table->name.basename(), autoinc);
|
||||
}
|
||||
else if (TABLE *t= prebuilt->m_mysql_table)
|
||||
{
|
||||
if (const Field *ai= t->found_next_number_field)
|
||||
{
|
||||
autoinc= 1 +
|
||||
btr_read_autoinc_with_fallback(table, innodb_col_no(ai),
|
||||
t->s->mysql_version,
|
||||
innobase_get_int_col_max_value(ai));
|
||||
goto autoinc_set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Imports a tablespace. The space id in the .ibd file must match the space id
|
||||
of the table in the data dictionary.
|
||||
@@ -4565,14 +4598,8 @@ row_import_for_mysql(
|
||||
table->flags2 &= ~DICT_TF2_DISCARDED & ((1U << DICT_TF2_BITS) - 1);
|
||||
|
||||
/* Set autoinc value read from .cfg file, if one was specified.
|
||||
Otherwise, keep the PAGE_ROOT_AUTO_INC as is. */
|
||||
if (autoinc) {
|
||||
ib::info() << table->name << " autoinc value set to "
|
||||
<< autoinc;
|
||||
|
||||
table->autoinc = autoinc--;
|
||||
btr_write_autoinc(dict_table_get_first_index(table), autoinc);
|
||||
}
|
||||
Otherwise, read the PAGE_ROOT_AUTO_INC and set it to table autoinc. */
|
||||
row_import_autoinc(table, prebuilt, autoinc);
|
||||
|
||||
return row_import_cleanup(prebuilt, err);
|
||||
}
|
||||
|
||||
@@ -548,3 +548,120 @@ template void ssux_lock_impl<false>::rd_unlock();
|
||||
template void ssux_lock_impl<false>::u_unlock();
|
||||
template void ssux_lock_impl<false>::wr_unlock();
|
||||
#endif /* UNIV_PFS_RWLOCK */
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
void srw_lock_debug::SRW_LOCK_INIT(mysql_pfs_key_t key)
|
||||
{
|
||||
srw_lock::SRW_LOCK_INIT(key);
|
||||
readers_lock.init();
|
||||
ut_ad(!readers.load(std::memory_order_relaxed));
|
||||
ut_ad(!have_any());
|
||||
}
|
||||
|
||||
void srw_lock_debug::destroy()
|
||||
{
|
||||
ut_ad(!writer);
|
||||
if (auto r= readers.load(std::memory_order_relaxed))
|
||||
{
|
||||
readers.store(0, std::memory_order_relaxed);
|
||||
ut_ad(r->empty());
|
||||
delete r;
|
||||
}
|
||||
srw_lock::destroy();
|
||||
}
|
||||
|
||||
bool srw_lock_debug::wr_lock_try()
|
||||
{
|
||||
ut_ad(!have_any());
|
||||
if (!srw_lock::wr_lock_try())
|
||||
return false;
|
||||
ut_ad(!writer);
|
||||
writer.store(pthread_self(), std::memory_order_relaxed);
|
||||
return true;
|
||||
}
|
||||
|
||||
void srw_lock_debug::wr_lock(SRW_LOCK_ARGS(const char *file, unsigned line))
|
||||
{
|
||||
ut_ad(!have_any());
|
||||
srw_lock::wr_lock(SRW_LOCK_ARGS(file, line));
|
||||
ut_ad(!writer);
|
||||
writer.store(pthread_self(), std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void srw_lock_debug::wr_unlock()
|
||||
{
|
||||
ut_ad(have_wr());
|
||||
writer.store(0, std::memory_order_relaxed);
|
||||
srw_lock::wr_unlock();
|
||||
}
|
||||
|
||||
void srw_lock_debug::readers_register()
|
||||
{
|
||||
readers_lock.wr_lock();
|
||||
auto r= readers.load(std::memory_order_relaxed);
|
||||
if (!r)
|
||||
{
|
||||
r= new std::unordered_multiset<pthread_t>();
|
||||
readers.store(r, std::memory_order_relaxed);
|
||||
}
|
||||
r->emplace(pthread_self());
|
||||
readers_lock.wr_unlock();
|
||||
}
|
||||
|
||||
bool srw_lock_debug::rd_lock_try()
|
||||
{
|
||||
ut_ad(!have_any());
|
||||
if (!srw_lock::rd_lock_try())
|
||||
return false;
|
||||
readers_register();
|
||||
return true;
|
||||
}
|
||||
|
||||
void srw_lock_debug::rd_lock(SRW_LOCK_ARGS(const char *file, unsigned line))
|
||||
{
|
||||
ut_ad(!have_any());
|
||||
srw_lock::rd_lock(SRW_LOCK_ARGS(file, line));
|
||||
readers_register();
|
||||
}
|
||||
|
||||
void srw_lock_debug::rd_unlock()
|
||||
{
|
||||
const pthread_t self= pthread_self();
|
||||
ut_ad(writer != self);
|
||||
readers_lock.wr_lock();
|
||||
auto r= readers.load(std::memory_order_relaxed);
|
||||
ut_ad(r);
|
||||
auto i= r->find(self);
|
||||
ut_ad(i != r->end());
|
||||
r->erase(i);
|
||||
readers_lock.wr_unlock();
|
||||
|
||||
srw_lock::rd_unlock();
|
||||
}
|
||||
|
||||
bool srw_lock_debug::have_rd() const noexcept
|
||||
{
|
||||
if (auto r= readers.load(std::memory_order_relaxed))
|
||||
{
|
||||
readers_lock.wr_lock();
|
||||
bool found= r->find(pthread_self()) != r->end();
|
||||
readers_lock.wr_unlock();
|
||||
ut_ad(!found || is_locked());
|
||||
return found;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool srw_lock_debug::have_wr() const noexcept
|
||||
{
|
||||
if (writer != pthread_self())
|
||||
return false;
|
||||
ut_ad(is_write_locked());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool srw_lock_debug::have_any() const noexcept
|
||||
{
|
||||
return have_wr() || have_rd();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -396,9 +396,7 @@ static void trx_purge_free_segment(buf_block_t *rseg_hdr, buf_block_t *block,
|
||||
void purge_sys_t::rseg_enable(trx_rseg_t &rseg)
|
||||
{
|
||||
ut_ad(this == &purge_sys);
|
||||
#ifndef SUX_LOCK_GENERIC
|
||||
ut_ad(rseg.latch.is_write_locked());
|
||||
#endif
|
||||
ut_ad(rseg.latch.have_wr());
|
||||
uint8_t skipped= skipped_rseg;
|
||||
ut_ad(skipped < TRX_SYS_N_RSEGS);
|
||||
if (&rseg == &trx_sys.rseg_array[skipped])
|
||||
@@ -874,9 +872,7 @@ void purge_sys_t::rseg_get_next_history_log()
|
||||
{
|
||||
fil_addr_t prev_log_addr;
|
||||
|
||||
#ifndef SUX_LOCK_GENERIC
|
||||
ut_ad(rseg->latch.is_write_locked());
|
||||
#endif
|
||||
ut_ad(rseg->latch.have_wr());
|
||||
ut_a(rseg->last_page_no != FIL_NULL);
|
||||
|
||||
tail.trx_no= rseg->last_trx_no() + 1;
|
||||
@@ -992,9 +988,7 @@ inline trx_purge_rec_t purge_sys_t::get_next_rec(roll_ptr_t roll_ptr)
|
||||
{
|
||||
ut_ad(next_stored);
|
||||
ut_ad(tail.trx_no < low_limit_no());
|
||||
#ifndef SUX_LOCK_GENERIC
|
||||
ut_ad(rseg->latch.is_write_locked());
|
||||
#endif
|
||||
ut_ad(rseg->latch.have_wr());
|
||||
|
||||
if (!offset)
|
||||
{
|
||||
|
||||
@@ -258,47 +258,6 @@ ut_print_name(
|
||||
}
|
||||
}
|
||||
|
||||
/** Format a table name, quoted as an SQL identifier.
|
||||
If the name contains a slash '/', the result will contain two
|
||||
identifiers separated by a period (.), as in SQL
|
||||
database_name.table_name.
|
||||
@see table_name_t
|
||||
@param[in] name table or index name
|
||||
@param[out] formatted formatted result, will be NUL-terminated
|
||||
@param[in] formatted_size size of the buffer in bytes
|
||||
@return pointer to 'formatted' */
|
||||
char*
|
||||
ut_format_name(
|
||||
const char* name,
|
||||
char* formatted,
|
||||
ulint formatted_size)
|
||||
{
|
||||
switch (formatted_size) {
|
||||
case 1:
|
||||
formatted[0] = '\0';
|
||||
/* FALL-THROUGH */
|
||||
case 0:
|
||||
return(formatted);
|
||||
}
|
||||
|
||||
char* end;
|
||||
|
||||
end = innobase_convert_name(formatted, formatted_size,
|
||||
name, strlen(name), NULL);
|
||||
|
||||
/* If the space in 'formatted' was completely used, then sacrifice
|
||||
the last character in order to write '\0' at the end. */
|
||||
if ((ulint) (end - formatted) == formatted_size) {
|
||||
end--;
|
||||
}
|
||||
|
||||
ut_a((ulint) (end - formatted) < formatted_size);
|
||||
|
||||
*end = '\0';
|
||||
|
||||
return(formatted);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Catenate files. */
|
||||
void
|
||||
|
||||
@@ -45,6 +45,7 @@ C_MODE_END
|
||||
#include "key.h"
|
||||
#include "log.h"
|
||||
#include "sql_parse.h"
|
||||
#include "mysql/service_print_check_msg.h"
|
||||
#include "debug.h"
|
||||
|
||||
/*
|
||||
@@ -428,10 +429,8 @@ static void _ma_check_print_msg(HA_CHECK *param, const LEX_CSTRING *msg_type,
|
||||
const char *fmt, va_list args)
|
||||
{
|
||||
THD *thd= (THD *) param->thd;
|
||||
Protocol *protocol= thd->protocol;
|
||||
size_t length, msg_length;
|
||||
size_t msg_length __attribute__((unused));
|
||||
char msgbuf[MYSQL_ERRMSG_SIZE];
|
||||
char name[NAME_LEN * 2 + 2];
|
||||
|
||||
if (param->testflag & T_SUPPRESS_ERR_HANDLING)
|
||||
return;
|
||||
@@ -460,27 +459,10 @@ static void _ma_check_print_msg(HA_CHECK *param, const LEX_CSTRING *msg_type,
|
||||
_ma_check_print(param, msg_type, msgbuf);
|
||||
return;
|
||||
}
|
||||
length= (uint) (strxmov(name, param->db_name, ".", param->table_name,
|
||||
NullS) - name);
|
||||
/*
|
||||
TODO: switch from protocol to push_warning here. The main reason we didn't
|
||||
it yet is parallel repair, which threads have no THD object accessible via
|
||||
current_thd.
|
||||
|
||||
Also we likely need to lock mutex here (in both cases with protocol and
|
||||
push_warning).
|
||||
*/
|
||||
protocol->prepare_for_resend();
|
||||
protocol->store(name, (uint)length, system_charset_info);
|
||||
protocol->store(param->op_name, strlen(param->op_name), system_charset_info);
|
||||
protocol->store(msg_type, system_charset_info);
|
||||
protocol->store(msgbuf, msg_length, system_charset_info);
|
||||
if (protocol->write())
|
||||
sql_print_error("Failed on my_net_write, writing to stderr instead: %s.%s: %s\n",
|
||||
param->db_name, param->table_name, msgbuf);
|
||||
else if (thd->variables.log_warnings > 2)
|
||||
print_check_msg(thd, param->db_name, param->table_name,
|
||||
param->op_name, msg_type->str, msgbuf, 0);
|
||||
if (thd->variables.log_warnings > 2)
|
||||
_ma_check_print(param, msg_type, msgbuf);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ struct st_row_applier_status {
|
||||
enum_rpl_yes_no service_state;
|
||||
uint remaining_delay;
|
||||
bool remaining_delay_is_set;
|
||||
ulong count_transactions_retries;
|
||||
ulonglong count_transactions_retries;
|
||||
};
|
||||
|
||||
/** Table PERFORMANCE_SCHEMA.replication_applier_status */
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
set @old_old_mode=@@global.old_mode;
|
||||
set global old_mode=4;
|
||||
INSTALL SONAME 'ha_spider.so';
|
||||
set global old_mode=@old_old_mode;
|
||||
@@ -0,0 +1,6 @@
|
||||
set @old_old_mode=@@global.old_mode;
|
||||
set global old_mode=4;
|
||||
INSTALL SONAME 'ha_spider.so';
|
||||
set global old_mode=@old_old_mode;
|
||||
--disable_query_log
|
||||
--source ../../include/clean_up_spider.inc
|
||||
@@ -19,8 +19,10 @@ eval create table t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "$srv",
|
||||
eval alter table t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "$srv",TABLE "t0"';
|
||||
--error 12719
|
||||
select * from t0;
|
||||
--replace_result test.t1 test.t0 test.t2 test.t0
|
||||
--error 12719
|
||||
select * from t1;
|
||||
--replace_result test.t1 test.t0 test.t2 test.t0
|
||||
--error 12719
|
||||
select * from t2;
|
||||
drop table t0, t1, t2;
|
||||
|
||||
@@ -23,6 +23,9 @@ static LEX_STRING spider_init_queries[] = {
|
||||
{C_STRING_WITH_LEN(
|
||||
"SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'ORACLE', '');"
|
||||
)},
|
||||
{C_STRING_WITH_LEN(
|
||||
"SET @@OLD_MODE = CONCAT(@@OLD_MODE, ',UTF8_IS_UTF8MB3');"
|
||||
)},
|
||||
{C_STRING_WITH_LEN(
|
||||
"create table if not exists mysql.spider_xa("
|
||||
" format_id int not null default 0,"
|
||||
|
||||
Reference in New Issue
Block a user