1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

Merge 10.11 into 11.0

This commit is contained in:
Marko Mäkelä
2023-04-27 15:11:18 +03:00
31 changed files with 646 additions and 109 deletions

View File

@@ -41,7 +41,11 @@ usr/share/mysql/mysql-test/README.stress
usr/share/mysql/mysql-test/dgcov.pl usr/share/mysql/mysql-test/dgcov.pl
usr/share/mysql/mysql-test/lib usr/share/mysql/mysql-test/lib
usr/share/mysql/mysql-test/mariadb-stress-test.pl usr/share/mysql/mysql-test/mariadb-stress-test.pl
usr/share/mysql/mysql-test/mariadb-test-run
usr/share/mysql/mysql-test/mariadb-test-run.pl usr/share/mysql/mysql-test/mariadb-test-run.pl
usr/share/mysql/mysql-test/mtr
usr/share/mysql/mysql-test/mysql-test-run
usr/share/mysql/mysql-test/mysql-test-run.pl
usr/share/mysql/mysql-test/purify.supp usr/share/mysql/mysql-test/purify.supp
usr/share/mysql/mysql-test/suite.pm usr/share/mysql/mysql-test/suite.pm
usr/share/mysql/mysql-test/valgrind.supp usr/share/mysql/mysql-test/valgrind.supp

View File

@@ -1 +0,0 @@
usr/share/mysql/mysql-test/mariadb-test-run.pl usr/share/mysql/mysql-test/mysql-test-run.pl

View File

@@ -72,6 +72,26 @@ struct my_timer_info
typedef struct my_timer_info MY_TIMER_INFO; typedef struct my_timer_info MY_TIMER_INFO;
#define MY_TIMER_ROUTINE_RDTSC 5
#define MY_TIMER_ROUTINE_ASM_IA64 6
#define MY_TIMER_ROUTINE_PPC_GET_TIMEBASE 7
#define MY_TIMER_ROUTINE_GETHRTIME 9
#define MY_TIMER_ROUTINE_READ_REAL_TIME 10
#define MY_TIMER_ROUTINE_CLOCK_GETTIME 11
#define MY_TIMER_ROUTINE_GETTIMEOFDAY 13
#define MY_TIMER_ROUTINE_QUERYPERFORMANCECOUNTER 14
#define MY_TIMER_ROUTINE_GETTICKCOUNT 15
#define MY_TIMER_ROUTINE_TIME 16
#define MY_TIMER_ROUTINE_TIMES 17
#define MY_TIMER_ROUTINE_FTIME 18
#define MY_TIMER_ROUTINE_ASM_GCC_SPARC64 23
#define MY_TIMER_ROUTINE_ASM_GCC_SPARC32 24
#define MY_TIMER_ROUTINE_MACH_ABSOLUTE_TIME 25
#define MY_TIMER_ROUTINE_GETSYSTEMTIMEASFILETIME 26
#define MY_TIMER_ROUTINE_ASM_S390 28
#define MY_TIMER_ROUTINE_AARCH64 29
#define MY_TIMER_ROUTINE_RISCV 30
C_MODE_START C_MODE_START
/** /**
@@ -133,28 +153,36 @@ C_MODE_START
static inline ulonglong my_timer_cycles(void) static inline ulonglong my_timer_cycles(void)
{ {
# if __has_builtin(__builtin_readcyclecounter) && !defined (__aarch64__) # if __has_builtin(__builtin_readcyclecounter) && !defined (__aarch64__)
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_AARCH64
return __builtin_readcyclecounter(); return __builtin_readcyclecounter();
# elif defined _M_IX86 || defined _M_X64 || defined __i386__ || defined __x86_64__ # elif defined _M_IX86 || defined _M_X64 || defined __i386__ || defined __x86_64__
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_RDTSC
return __rdtsc(); return __rdtsc();
#elif defined _M_ARM64 #elif defined _M_ARM64
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_AARCH64
return _ReadStatusReg(ARM64_CNTVCT); return _ReadStatusReg(ARM64_CNTVCT);
# elif defined(__INTEL_COMPILER) && defined(__ia64__) && defined(HAVE_IA64INTRIN_H) # elif defined(__INTEL_COMPILER) && defined(__ia64__) && defined(HAVE_IA64INTRIN_H)
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_ASM_IA64
return (ulonglong) __getReg(_IA64_REG_AR_ITC); /* (3116) */ return (ulonglong) __getReg(_IA64_REG_AR_ITC); /* (3116) */
#elif defined(__GNUC__) && defined(__ia64__) #elif defined(__GNUC__) && defined(__ia64__)
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_ASM_IA64
{ {
ulonglong result; ulonglong result;
__asm __volatile__ ("mov %0=ar.itc" : "=r" (result)); __asm __volatile__ ("mov %0=ar.itc" : "=r" (result));
return result; return result;
} }
#elif defined __GNUC__ && defined __powerpc__ #elif defined __GNUC__ && defined __powerpc__
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_PPC_GET_TIMEBASE
return __builtin_ppc_get_timebase(); return __builtin_ppc_get_timebase();
#elif defined(__GNUC__) && defined(__sparcv9) && defined(_LP64) #elif defined(__GNUC__) && defined(__sparcv9) && defined(_LP64)
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_ASM_GCC_SPARC64
{ {
ulonglong result; ulonglong result;
__asm __volatile__ ("rd %%tick,%0" : "=r" (result)); __asm __volatile__ ("rd %%tick,%0" : "=r" (result));
return result; return result;
} }
#elif defined(__GNUC__) && defined(__sparc__) && !defined(_LP64) #elif defined(__GNUC__) && defined(__sparc__) && !defined(_LP64)
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_ASM_GCC_SPARC32
{ {
union { union {
ulonglong wholeresult; ulonglong wholeresult;
@@ -167,6 +195,7 @@ static inline ulonglong my_timer_cycles(void)
return result.wholeresult; return result.wholeresult;
} }
#elif defined(__GNUC__) && defined(__s390__) #elif defined(__GNUC__) && defined(__s390__)
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_ASM_S390
/* covers both s390 and s390x */ /* covers both s390 and s390x */
{ {
ulonglong result; ulonglong result;
@@ -174,12 +203,14 @@ static inline ulonglong my_timer_cycles(void)
return result; return result;
} }
#elif defined(__GNUC__) && defined (__aarch64__) #elif defined(__GNUC__) && defined (__aarch64__)
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_AARCH64
{ {
ulonglong result; ulonglong result;
__asm __volatile("mrs %0, CNTVCT_EL0" : "=&r" (result)); __asm __volatile("mrs %0, CNTVCT_EL0" : "=&r" (result));
return result; return result;
} }
#elif defined(__riscv) #elif defined(__riscv)
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_RISCV
/* Use RDCYCLE (and RDCYCLEH on riscv32) */ /* Use RDCYCLE (and RDCYCLEH on riscv32) */
{ {
# if __riscv_xlen == 32 # if __riscv_xlen == 32
@@ -202,9 +233,11 @@ static inline ulonglong my_timer_cycles(void)
} }
# endif # endif
#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME) #elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_GETHRTIME
/* gethrtime may appear as either cycle or nanosecond counter */ /* gethrtime may appear as either cycle or nanosecond counter */
return (ulonglong) gethrtime(); return (ulonglong) gethrtime();
#else #else
#define MY_TIMER_ROUTINE_CYCLES 0
return 0; return 0;
#endif #endif
} }
@@ -241,25 +274,5 @@ void my_timer_init(MY_TIMER_INFO *mti);
C_MODE_END C_MODE_END
#define MY_TIMER_ROUTINE_RDTSC 5
#define MY_TIMER_ROUTINE_ASM_IA64 6
#define MY_TIMER_ROUTINE_PPC_GET_TIMEBASE 7
#define MY_TIMER_ROUTINE_GETHRTIME 9
#define MY_TIMER_ROUTINE_READ_REAL_TIME 10
#define MY_TIMER_ROUTINE_CLOCK_GETTIME 11
#define MY_TIMER_ROUTINE_GETTIMEOFDAY 13
#define MY_TIMER_ROUTINE_QUERYPERFORMANCECOUNTER 14
#define MY_TIMER_ROUTINE_GETTICKCOUNT 15
#define MY_TIMER_ROUTINE_TIME 16
#define MY_TIMER_ROUTINE_TIMES 17
#define MY_TIMER_ROUTINE_FTIME 18
#define MY_TIMER_ROUTINE_ASM_GCC_SPARC64 23
#define MY_TIMER_ROUTINE_ASM_GCC_SPARC32 24
#define MY_TIMER_ROUTINE_MACH_ABSOLUTE_TIME 25
#define MY_TIMER_ROUTINE_GETSYSTEMTIMEASFILETIME 26
#define MY_TIMER_ROUTINE_ASM_S390 28
#define MY_TIMER_ROUTINE_AARCH64 29
#define MY_TIMER_ROUTINE_RISCV 30
#endif #endif

View File

@@ -575,6 +575,8 @@ int init_embedded_server(int argc, char **argv, char **groups)
if (ho_error != 0) if (ho_error != 0)
return 1; return 1;
my_timer_init(&sys_timer_info);
if (init_common_variables()) if (init_common_variables())
{ {
mysql_server_end(); mysql_server_end();

View File

@@ -0,0 +1,11 @@
#
# MDEV-31121: ANALYZE statement produces 0 for all timings in embedded serve
#
create table t1 (a int);
insert into t1 values (0),(0);
set @js='$out';
set @out=(select json_extract(@js,'$**.query_block.r_total_time_ms'));
select cast(json_extract(@out,'$[0]') as DOUBLE) > 0;
cast(json_extract(@out,'$[0]') as DOUBLE) > 0
1
drop table t1;

View File

@@ -0,0 +1,18 @@
--source include/is_embedded.inc
--source include/big_test.inc
--echo #
--echo # MDEV-31121: ANALYZE statement produces 0 for all timings in embedded serve
--echo #
create table t1 (a int);
insert into t1 values (0),(0);
let $out=`
analyze format=json select sleep(1+a) from t1
`;
evalp set @js='$out';
set @out=(select json_extract(@js,'$**.query_block.r_total_time_ms'));
select cast(json_extract(@out,'$[0]') as DOUBLE) > 0;
drop table t1;

View File

@@ -22604,6 +22604,103 @@ id select_type table type possible_keys key key_len ref rows Extra
3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary 3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary
drop view v1; drop view v1;
drop table t1; drop table t1;
#
# MDEV-31102: execution of PS for query where pushdown of condition
# into view defined as union is applied
#
create table t1 (
n int,
lv varchar(31) charset latin1,
mv varchar(31) charset utf8mb3
) engine=myisam;
insert into t1 values (1,'aa','xxx'), ('2','bb','yyy'), (3,'cc','zzz');
create view v1 as
select case when n=1 then lv when n=2 then mv else NULL end as r from t1
union
select 'a';
select * from v1 where r < 'x';
r
aa
a
explain extended select * from v1 where r < 'x';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 100.00 Using where
2 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using where
3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `v1`.`r` AS `r` from `test`.`v1` where `v1`.`r` < 'x'
explain format=json select * from v1 where r < 'x';
EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 0.012461052,
"nested_loop": [
{
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"loops": 1,
"rows": 3,
"cost": 0.012461052,
"filtered": 100,
"attached_condition": "v1.r < 'x'",
"materialized": {
"query_block": {
"union_result": {
"table_name": "<union2,3>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 2,
"cost": 0.010504815,
"nested_loop": [
{
"table": {
"table_name": "t1",
"access_type": "ALL",
"loops": 1,
"rows": 3,
"cost": 0.010504815,
"filtered": 100,
"attached_condition": "case when t1.n = 1 then convert(t1.lv using utf8mb3) when t1.n = 2 then t1.mv else NULL end < 'x'"
}
}
]
}
},
{
"query_block": {
"select_id": 3,
"operation": "UNION",
"table": {
"message": "No tables used"
}
}
}
]
}
}
}
}
}
]
}
}
prepare stmt from "select * from v1 where r < 'x'";
execute stmt;
r
aa
a
execute stmt;
r
aa
a
deallocate prepare stmt;
drop view v1;
drop table t1;
# End of 10.4 tests # End of 10.4 tests
# #
# MDEV-28958: condition pushable into view after simplification # MDEV-28958: condition pushable into view after simplification

View File

@@ -4143,6 +4143,36 @@ explain select * from v1;
drop view v1; drop view v1;
drop table t1; drop table t1;
--echo #
--echo # MDEV-31102: execution of PS for query where pushdown of condition
--echo # into view defined as union is applied
--echo #
create table t1 (
n int,
lv varchar(31) charset latin1,
mv varchar(31) charset utf8mb3
) engine=myisam;
insert into t1 values (1,'aa','xxx'), ('2','bb','yyy'), (3,'cc','zzz');
create view v1 as
select case when n=1 then lv when n=2 then mv else NULL end as r from t1
union
select 'a';
let $q=
select * from v1 where r < 'x';
eval $q;
eval explain extended $q;
eval explain format=json $q;
eval prepare stmt from "$q";
execute stmt;
execute stmt;
deallocate prepare stmt;
drop view v1;
drop table t1;
--echo # End of 10.4 tests --echo # End of 10.4 tests
--echo # --echo #

View File

@@ -1,6 +1,12 @@
--- a/mysql-test/r/mysqld--help.result @@ -180,6 +180,7 @@
+++ b/mysql-test/r/mysqld--help.result --console Write error output on screen; don't remove the console
@@ -685,6 +685,7 @@ window on windows.
--core-file Write core on crashes
+ (Defaults to on; use --skip-core-file to disable.)
-h, --datadir=name Path to the database root directory
--date-format=name The DATE format (ignored)
--datetime-format=name
@@ -650,6 +651,7 @@
Use MySQL-5.6 (instead of MariaDB-5.3) format for TIME, Use MySQL-5.6 (instead of MariaDB-5.3) format for TIME,
DATETIME, TIMESTAMP columns. DATETIME, TIMESTAMP columns.
(Defaults to on; use --skip-mysql56-temporal-format to disable.) (Defaults to on; use --skip-mysql56-temporal-format to disable.)

View File

@@ -190,7 +190,7 @@ The following specify which files/extra groups are read (specified before remain
ALWAYS ALWAYS
--console Write error output on screen; don't remove the console --console Write error output on screen; don't remove the console
window on windows. window on windows.
--core-file Write core on errors. --core-file Write core on crashes
-h, --datadir=name Path to the database root directory -h, --datadir=name Path to the database root directory
--date-format=name The DATE format (ignored) --date-format=name The DATE format (ignored)
--datetime-format=name --datetime-format=name
@@ -1583,6 +1583,7 @@ column-compression-zlib-wrap FALSE
completion-type NO_CHAIN completion-type NO_CHAIN
concurrent-insert AUTO concurrent-insert AUTO
console TRUE console TRUE
core-file TRUE
date-format %Y-%m-%d date-format %Y-%m-%d
datetime-format %Y-%m-%d %H:%i:%s datetime-format %Y-%m-%d %H:%i:%s
deadlock-search-depth-long 15 deadlock-search-depth-long 15

View File

@@ -9,6 +9,7 @@ include/start_slave.inc
connection server_1; connection server_1;
connection server_2; connection server_2;
include/stop_slave.inc include/stop_slave.inc
CHANGE MASTER TO MASTER_USE_GTID=NO;
##################################################### #####################################################
# Part 1: unencrypted master # Part 1: unencrypted master
##################################################### #####################################################

View File

@@ -1,14 +1,19 @@
# #
# TODO: write here what the test checks after MDEV-11288 is fixed # The test starts with unencrypted master.
#
# The test starts with unencrypted master.
# It stops replication, generates a few statement and row events # It stops replication, generates a few statement and row events
# on the master, then restarts the server with encrypted binlog, # on the master, then restarts the server with encrypted binlog,
# generates some more events and restarts it back without encryption # generates some more events and restarts it back without encryption
# (no encryption plugin). # (no encryption plugin).
# Then it resumes replication and checks what happens when the server # Then it resumes replication and should error with
# tries to feed the binary logs (included the encrypted ones) # ER_MASTER_FATAL_ERROR_READING_BINLOG because the encrypted binlog is
# to the slave. # sent and unable to be decrypted.
#
# Note this variation of encrypted_master_switch_to_unencrypted tests
# using MASTER_USE_GTID=NO. In contrast to the GTID variant of this
# test, at part 3 (the error case), the master will scan binlogs
# starting from the first one (which is unencrypted initially, so
# replication is okay) and continue until the slave encounters the
# first encrypted event, which causes the slave to error.
# #
--source include/have_binlog_format_mixed.inc --source include/have_binlog_format_mixed.inc
@@ -34,6 +39,7 @@ CHANGE MASTER TO MASTER_USE_GTID=NO;
--connection server_2 --connection server_2
--disable_connect_log --disable_connect_log
--source include/stop_slave.inc --source include/stop_slave.inc
CHANGE MASTER TO MASTER_USE_GTID=NO;
--enable_connect_log --enable_connect_log
--echo ##################################################### --echo #####################################################
@@ -48,7 +54,7 @@ CREATE TABLE table1_no_encryption (
pk INT AUTO_INCREMENT PRIMARY KEY, pk INT AUTO_INCREMENT PRIMARY KEY,
ts TIMESTAMP NULL, ts TIMESTAMP NULL,
b BLOB b BLOB
) ENGINE=MyISAM; ) ENGINE=MyISAM;
INSERT INTO table1_no_encryption VALUES (NULL,NOW(),'data_no_encryption'); INSERT INTO table1_no_encryption VALUES (NULL,NOW(),'data_no_encryption');
INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption; INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
@@ -81,7 +87,7 @@ CREATE TABLE table2_to_encrypt (
pk INT AUTO_INCREMENT PRIMARY KEY, pk INT AUTO_INCREMENT PRIMARY KEY,
ts TIMESTAMP NULL, ts TIMESTAMP NULL,
b BLOB b BLOB
) ENGINE=MyISAM; ) ENGINE=MyISAM;
INSERT INTO table2_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt'); INSERT INTO table2_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt');
INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
@@ -108,7 +114,7 @@ CREATE TABLE table3_no_encryption (
pk INT AUTO_INCREMENT PRIMARY KEY, pk INT AUTO_INCREMENT PRIMARY KEY,
ts TIMESTAMP NULL, ts TIMESTAMP NULL,
b BLOB b BLOB
) ENGINE=MyISAM; ) ENGINE=MyISAM;
INSERT INTO table3_no_encryption VALUES (NULL,NOW(),'data_no_encryption'); INSERT INTO table3_no_encryption VALUES (NULL,NOW(),'data_no_encryption');
INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption; INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption;
@@ -120,7 +126,7 @@ INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption;
--connection server_2 --connection server_2
start slave; start slave;
# The slave should be able to synchronize with master up to # The slave should be able to synchronize with master up to
# the previously saved position (when the log was still unencrypted) # the previously saved position (when the log was still unencrypted)
--sync_with_master --sync_with_master

View File

@@ -0,0 +1,8 @@
!include my.cnf
[mysqld.1]
encrypt-binlog=0
skip-file-key-management
[mysqld.2]
gtid-domain-id=1

View File

@@ -0,0 +1,84 @@
#################
# Initialization
#################
include/rpl_init.inc [topology=1->2]
connection server_2;
include/stop_slave.inc
CHANGE MASTER TO MASTER_USE_GTID=SLAVE_POS;
call mtr.add_suppression(" Got fatal error 1236 from master when reading data from binary log: 'Could not set up decryption for binlog.'");
#####################################################
# Part 1: unencrypted master
#####################################################
connection server_1;
CREATE TABLE table1_no_encryption (
pk INT AUTO_INCREMENT PRIMARY KEY,
ts TIMESTAMP NULL,
b BLOB
) ENGINE=MyISAM;
INSERT INTO table1_no_encryption VALUES (NULL,NOW(),'data_no_encryption');
INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
FLUSH BINARY LOGS;
SET binlog_format=ROW;
INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
NOT FOUND /table1_no_encryption/ in master-bin.0*
#####################################################
# Part 2: restart master, now with binlog encryption
#####################################################
connection default;
connection server_1;
CREATE TABLE table2_to_encrypt (
pk INT AUTO_INCREMENT PRIMARY KEY,
ts TIMESTAMP NULL,
b BLOB
) ENGINE=MyISAM;
INSERT INTO table2_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt');
INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
FLUSH BINARY LOGS;
SET binlog_format=ROW;
INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
NOT FOUND /table2_to_encrypt/ in master-bin.0*
#####################################################
# Part 3: restart master again without encryption
#####################################################
connection default;
connection server_1;
CREATE TABLE table3_no_encryption (
pk INT AUTO_INCREMENT PRIMARY KEY,
ts TIMESTAMP NULL,
b BLOB
) ENGINE=MyISAM;
INSERT INTO table3_no_encryption VALUES (NULL,NOW(),'data_no_encryption');
INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption;
INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption;
#####################################################
# Check: resume replication and check how it goes
#####################################################
connection server_2;
start slave;
include/wait_for_slave_io_error.inc [errno=1236]
# Ensuring slave was unable to replicate any transactions..
# ..success
SHOW TABLES;
Tables_in_test
include/stop_slave.inc
reset slave;
##########
# Cleanup
##########
connection server_1;
reset master;
SELECT COUNT(*) FROM table1_no_encryption;
COUNT(*)
8
SELECT COUNT(*) FROM table2_to_encrypt;
COUNT(*)
8
SELECT COUNT(*) FROM table3_no_encryption;
COUNT(*)
4
DROP TABLE table1_no_encryption, table2_to_encrypt, table3_no_encryption;
connection server_2;
include/start_slave.inc
include/rpl_end.inc

View File

@@ -0,0 +1,154 @@
#
# The test starts with unencrypted master.
# It stops replication, generates a few statement and row events
# on the master, then restarts the server with encrypted binlog,
# generates some more events and restarts it back without encryption
# (no encryption plugin).
# Then it resumes replication and should error with
# ER_MASTER_FATAL_ERROR_READING_BINLOG because the encrypted binlog is
# sent and unable to be decrypted.
#
# Note this variation of encrypted_master_switch_to_unencrypted tests
# using MASTER_USE_GTID=SLAVE_POS. encrypted_master_switch_to_unencrypted
# was the original test which only used binlog coordinates. When tested
# using MASTER_USE_GTID=Slave_Pos, the master optimizes the detection of
# an undecryptable binlog. I.e, the master will initially look for a
# Gtid_list_log_event, but fail to decrypt it and fail immediately in
# part 3.
#
--source include/have_binlog_format_mixed.inc
--echo #################
--echo # Initialization
--echo #################
--let $rpl_topology= 1->2
--source include/rpl_init.inc
--enable_connect_log
# We stop replication because we want it to happen after the switch
--connection server_2
--disable_connect_log
--source include/stop_slave.inc
CHANGE MASTER TO MASTER_USE_GTID=SLAVE_POS;
--enable_connect_log
call mtr.add_suppression(" Got fatal error 1236 from master when reading data from binary log: 'Could not set up decryption for binlog.'");
--echo #####################################################
--echo # Part 1: unencrypted master
--echo #####################################################
--connection server_1
CREATE TABLE table1_no_encryption (
pk INT AUTO_INCREMENT PRIMARY KEY,
ts TIMESTAMP NULL,
b BLOB
) ENGINE=MyISAM;
INSERT INTO table1_no_encryption VALUES (NULL,NOW(),'data_no_encryption');
INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
FLUSH BINARY LOGS;
SET binlog_format=ROW;
INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption;
# Make sure that binary logs are not encrypted
--let SEARCH_RANGE = 500000
--let SEARCH_FILE= master-bin.0*
--let SEARCH_PATTERN= table1_no_encryption
--source include/search_pattern_in_file.inc
--echo #####################################################
--echo # Part 2: restart master, now with binlog encryption
--echo #####################################################
--let $rpl_server_parameters= --encrypt-binlog=1 --plugin-load-add=$FILE_KEY_MANAGEMENT_SO --file-key-management --loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys.txt
--let $rpl_server_number= 1
--source restart_server.inc
CREATE TABLE table2_to_encrypt (
pk INT AUTO_INCREMENT PRIMARY KEY,
ts TIMESTAMP NULL,
b BLOB
) ENGINE=MyISAM;
INSERT INTO table2_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt');
INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
FLUSH BINARY LOGS;
SET binlog_format=ROW;
INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt;
# Make sure that binary logs are encrypted
--let SEARCH_FILE= master-bin.0*
--let SEARCH_PATTERN= table2_to_encrypt
--source include/search_pattern_in_file.inc
--echo #####################################################
--echo # Part 3: restart master again without encryption
--echo #####################################################
--let $rpl_server_parameters= --encrypt-binlog=0
--let $rpl_server_number= 1
--source restart_server.inc
CREATE TABLE table3_no_encryption (
pk INT AUTO_INCREMENT PRIMARY KEY,
ts TIMESTAMP NULL,
b BLOB
) ENGINE=MyISAM;
INSERT INTO table3_no_encryption VALUES (NULL,NOW(),'data_no_encryption');
INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption;
INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption;
--echo #####################################################
--echo # Check: resume replication and check how it goes
--echo #####################################################
--connection server_2
start slave;
# Make slave to try to synchronize. It shouldn't work, the slave IO thread is
# expected to abort with an error
--let $slave_io_errno= 1236
--source include/wait_for_slave_io_error.inc
--echo # Ensuring slave was unable to replicate any transactions..
--let $gsp= `SELECT @@global.gtid_slave_pos`
if (`SELECT strcmp("$gsp","")`)
{
die Slave without encryption configured should fail to read encrypted binlog;
}
--echo # ..success
--sorted_result
SHOW TABLES;
--disable_connect_log
--source include/stop_slave.inc
--enable_connect_log
reset slave;
--echo ##########
--echo # Cleanup
--echo ##########
--connection server_1
reset master;
SELECT COUNT(*) FROM table1_no_encryption;
SELECT COUNT(*) FROM table2_to_encrypt;
SELECT COUNT(*) FROM table3_no_encryption;
DROP TABLE table1_no_encryption, table2_to_encrypt, table3_no_encryption;
--connection server_2
--disable_connect_log
--source include/start_slave.inc
--source include/rpl_end.inc

View File

@@ -675,13 +675,13 @@ COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME CORE_FILE VARIABLE_NAME CORE_FILE
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN VARIABLE_TYPE BOOLEAN
VARIABLE_COMMENT write a core-file on crashes VARIABLE_COMMENT Write core on crashes
NUMERIC_MIN_VALUE NULL NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST OFF,ON ENUM_VALUE_LIST OFF,ON
READ_ONLY YES READ_ONLY YES
COMMAND_LINE_ARGUMENT NULL COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME DATADIR VARIABLE_NAME DATADIR
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE VARCHAR VARIABLE_TYPE VARCHAR

View File

@@ -685,13 +685,13 @@ COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME CORE_FILE VARIABLE_NAME CORE_FILE
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BOOLEAN VARIABLE_TYPE BOOLEAN
VARIABLE_COMMENT write a core-file on crashes VARIABLE_COMMENT Write core on crashes
NUMERIC_MIN_VALUE NULL NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST OFF,ON ENUM_VALUE_LIST OFF,ON
READ_ONLY YES READ_ONLY YES
COMMAND_LINE_ARGUMENT NULL COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME DATADIR VARIABLE_NAME DATADIR
VARIABLE_SCOPE GLOBAL VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE VARCHAR VARIABLE_TYPE VARCHAR

View File

@@ -165,6 +165,30 @@ update t1 set i = 0;
connection slave; connection slave;
connection master; connection master;
drop table t1; drop table t1;
# check versioned -> versioned replication without any keys on duplicate records
connection master;
create table t1 (a INT) with system versioning;
insert into t1 values (1);
insert into t1 values (1);
delete from t1;
connection slave;
include/diff_tables.inc [master:test.t1,slave:test.t1]
connection master;
drop table t1;
connection slave;
# check unversioned -> versioned replication with non-unique keys on duplicate records
connection master;
set statement sql_log_bin=0 for create table t1 (a INT NOT NULL, b INT, INDEX(a,b));
connection slave;
set statement sql_log_bin=0 for create table t1 (a INT NOT NULL, b INT, INDEX(a,b)) with system versioning;
connection master;
insert into t1 values (1,1);
insert into t1 values (1,1);
delete from t1;
connection slave;
include/diff_tables.inc [master:test.t1,slave:test.t1]
connection master;
drop table t1;
# #
# MDEV-17554 Auto-create new partition for system versioned tables # MDEV-17554 Auto-create new partition for system versioned tables
# with history partitioned by INTERVAL/LIMIT # with history partitioned by INTERVAL/LIMIT

View File

@@ -135,6 +135,40 @@ sync_slave_with_master;
connection master; connection master;
drop table t1; drop table t1;
#
# MDEV-30430: Enabling system versioning on tables without primary key breaks replication
# Note that bugs are only present with row binlog format
#
--echo # check versioned -> versioned replication without any keys on duplicate records
connection master;
create table t1 (a INT) with system versioning;
insert into t1 values (1);
insert into t1 values (1);
delete from t1;
sync_slave_with_master;
--let $diff_tables= master:test.t1,slave:test.t1
--source include/diff_tables.inc
connection master;
drop table t1;
sync_slave_with_master;
--echo # check unversioned -> versioned replication with non-unique keys on duplicate records
connection master;
set statement sql_log_bin=0 for create table t1 (a INT NOT NULL, b INT, INDEX(a,b));
connection slave;
set statement sql_log_bin=0 for create table t1 (a INT NOT NULL, b INT, INDEX(a,b)) with system versioning;
connection master;
insert into t1 values (1,1);
insert into t1 values (1,1);
delete from t1;
sync_slave_with_master;
--let $diff_tables= master:test.t1,slave:test.t1
--source include/diff_tables.inc
connection master;
drop table t1;
--echo # --echo #
--echo # MDEV-17554 Auto-create new partition for system versioned tables --echo # MDEV-17554 Auto-create new partition for system versioned tables
--echo # with history partitioned by INTERVAL/LIMIT --echo # with history partitioned by INTERVAL/LIMIT

View File

@@ -368,29 +368,7 @@ void my_timer_init(MY_TIMER_INFO *mti)
/* cycles */ /* cycles */
mti->cycles.frequency= 1000000000; mti->cycles.frequency= 1000000000;
#if defined _WIN32 || defined __i386__ || defined __x86_64__ mti->cycles.routine= MY_TIMER_ROUTINE_CYCLES;
mti->cycles.routine= MY_TIMER_ROUTINE_RDTSC;
#elif defined(__INTEL_COMPILER) && defined(__ia64__) && defined(HAVE_IA64INTRIN_H)
mti->cycles.routine= MY_TIMER_ROUTINE_ASM_IA64;
#elif defined(__GNUC__) && defined(__ia64__)
mti->cycles.routine= MY_TIMER_ROUTINE_ASM_IA64;
#elif defined __GNUC__ && defined __powerpc__
mti->cycles.routine= MY_TIMER_ROUTINE_PPC_GET_TIMEBASE;
#elif defined(__GNUC__) && defined(__sparcv9) && defined(_LP64) && (__GNUC__>2)
mti->cycles.routine= MY_TIMER_ROUTINE_ASM_GCC_SPARC64;
#elif defined(__GNUC__) && defined(__sparc__) && !defined(_LP64) && (__GNUC__>2)
mti->cycles.routine= MY_TIMER_ROUTINE_ASM_GCC_SPARC32;
#elif defined(__GNUC__) && defined(__s390__)
mti->cycles.routine= MY_TIMER_ROUTINE_ASM_S390;
#elif defined(__GNUC__) && defined (__aarch64__)
mti->cycles.routine= MY_TIMER_ROUTINE_AARCH64;
#elif defined(__GNUC__) && defined (__riscv)
mti->cycles.routine= MY_TIMER_ROUTINE_RISCV;
#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
mti->cycles.routine= MY_TIMER_ROUTINE_GETHRTIME;
#else
mti->cycles.routine= 0;
#endif
if (!mti->cycles.routine || !my_timer_cycles()) if (!mti->cycles.routine || !my_timer_cycles())
{ {

View File

@@ -7828,7 +7828,7 @@ public:
Item *get_tmp_table_item(THD *thd) Item *get_tmp_table_item(THD *thd)
{ return m_item->get_tmp_table_item(thd); } { return m_item->get_tmp_table_item(thd); }
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
{ return m_item->get_copy(thd); } { return get_item_copy<Item_direct_ref_to_item>(thd, this); }
COND *build_equal_items(THD *thd, COND_EQUAL *inherited, COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
bool link_item_fields, bool link_item_fields,
COND_EQUAL **cond_equal_ref) COND_EQUAL **cond_equal_ref)
@@ -7896,7 +7896,20 @@ public:
bool excl_dep_on_grouping_fields(st_select_lex *sel) bool excl_dep_on_grouping_fields(st_select_lex *sel)
{ return m_item->excl_dep_on_grouping_fields(sel); } { return m_item->excl_dep_on_grouping_fields(sel); }
bool is_expensive() { return m_item->is_expensive(); } bool is_expensive() { return m_item->is_expensive(); }
Item* build_clone(THD *thd) { return get_copy(thd); } void set_item(Item *item) { m_item= item; }
Item *build_clone(THD *thd)
{
Item *clone_item= m_item->build_clone(thd);
if (clone_item)
{
Item_direct_ref_to_item *copy= (Item_direct_ref_to_item *) get_copy(thd);
if (!copy)
return 0;
copy->set_item(clone_item);
return copy;
}
return 0;
}
void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array, void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
List<Item> &fields, uint flags) List<Item> &fields, uint flags)

View File

@@ -11980,7 +11980,10 @@ get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list)
if (typ == START_ENCRYPTION_EVENT) if (typ == START_ENCRYPTION_EVENT)
{ {
if (fdle->start_decryption((Start_encryption_log_event*) ev)) if (fdle->start_decryption((Start_encryption_log_event*) ev))
{
errormsg= "Could not set up decryption for binlog."; errormsg= "Could not set up decryption for binlog.";
break;
}
} }
delete ev; delete ev;
if (typ == ROTATE_EVENT || typ == STOP_EVENT || if (typ == ROTATE_EVENT || typ == STOP_EVENT ||

View File

@@ -6986,7 +6986,7 @@ uint8 Write_rows_log_event::get_trg_event_map()
Returns TRUE if different. Returns TRUE if different.
*/ */
static bool record_compare(TABLE *table) static bool record_compare(TABLE *table, bool vers_from_plain= false)
{ {
bool result= FALSE; bool result= FALSE;
/** /**
@@ -7019,10 +7019,19 @@ static bool record_compare(TABLE *table)
/* Compare fields */ /* Compare fields */
for (Field **ptr=table->field ; *ptr ; ptr++) for (Field **ptr=table->field ; *ptr ; ptr++)
{ {
if (table->versioned() && (*ptr)->vers_sys_field()) /*
{ If the table is versioned, don't compare using the version if there is a
primary key. If there isn't a primary key, we need the version to
identify the correct record if there are duplicate rows in the data set.
However, if the primary server is unversioned (vers_from_plain is true),
then we implicitly use row_end as the primary key on our side. This is
because the implicit row_end value will be set to the maximum value for
the latest row update (which is what we care about).
*/
if (table->versioned() && (*ptr)->vers_sys_field() &&
(table->s->primary_key < MAX_KEY ||
(vers_from_plain && table->vers_start_field() == (*ptr))))
continue; continue;
}
/** /**
We only compare field contents that are not null. We only compare field contents that are not null.
NULL fields (i.e., their null bits) were compared NULL fields (i.e., their null bits) were compared
@@ -7416,7 +7425,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
/* We use this to test that the correct key is used in test cases. */ /* We use this to test that the correct key is used in test cases. */
DBUG_EXECUTE_IF("slave_crash_if_index_scan", abort();); DBUG_EXECUTE_IF("slave_crash_if_index_scan", abort(););
while (record_compare(table)) while (record_compare(table, m_vers_from_plain))
{ {
while ((error= table->file->ha_index_next(table->record[0]))) while ((error= table->file->ha_index_next(table->record[0])))
{ {
@@ -7469,7 +7478,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
goto end; goto end;
} }
} }
while (record_compare(table)); while (record_compare(table, m_vers_from_plain));
/* /*
Note: above record_compare will take into accout all record fields Note: above record_compare will take into accout all record fields

View File

@@ -6512,8 +6512,6 @@ struct my_option my_long_options[]=
{"console", OPT_CONSOLE, "Write error output on screen; don't remove the console window on windows.", {"console", OPT_CONSOLE, "Write error output on screen; don't remove the console window on windows.",
&opt_console, &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0, &opt_console, &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0}, 0, 0, 0},
{"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef DBUG_OFF #ifdef DBUG_OFF
{"debug", '#', "Built in DBUG debugger. Disabled in this build.", {"debug", '#', "Built in DBUG debugger. Disabled in this build.",
&current_dbug_option, &current_dbug_option, 0, GET_STR, OPT_ARG, &current_dbug_option, &current_dbug_option, 0, GET_STR, OPT_ARG,
@@ -8280,9 +8278,6 @@ mysqld_get_one_option(const struct my_option *opt, const char *argument,
case (int) OPT_SKIP_HOST_CACHE: case (int) OPT_SKIP_HOST_CACHE:
opt_specialflag|= SPECIAL_NO_HOST_CACHE; opt_specialflag|= SPECIAL_NO_HOST_CACHE;
break; break;
case (int) OPT_WANT_CORE:
test_flags |= TEST_CORE_ON_SIGNAL;
break;
case OPT_CONSOLE: case OPT_CONSOLE:
if (opt_console) if (opt_console)
opt_error_log= 0; // Force logs to stdout opt_error_log= 0; // Force logs to stdout

View File

@@ -2583,14 +2583,16 @@ rpl_parallel::find(uint32 domain_id, Relay_log_info *rli)
e->pause_sub_id= (uint64)ULONGLONG_MAX; e->pause_sub_id= (uint64)ULONGLONG_MAX;
e->pending_start_alters= 0; e->pending_start_alters= 0;
e->rli= rli; e->rli= rli;
if (my_hash_insert(&domain_hash, (uchar *)e))
{
my_free(e);
return NULL;
}
mysql_mutex_init(key_LOCK_parallel_entry, &e->LOCK_parallel_entry, mysql_mutex_init(key_LOCK_parallel_entry, &e->LOCK_parallel_entry,
MY_MUTEX_INIT_FAST); MY_MUTEX_INIT_FAST);
mysql_cond_init(key_COND_parallel_entry, &e->COND_parallel_entry, NULL); mysql_cond_init(key_COND_parallel_entry, &e->COND_parallel_entry, NULL);
if (my_hash_insert(&domain_hash, (uchar *)e))
{
mysql_cond_destroy(&e->COND_parallel_entry);
mysql_mutex_destroy(&e->LOCK_parallel_entry);
my_free(e);
return NULL;
}
} }
else else
{ {

View File

@@ -38,6 +38,16 @@ $stmt").
*/ */
/* fake microseconds as cycles if cycles isn't available */
static inline double timer_tracker_frequency()
{
#if (MY_TIMER_ROUTINE_CYCLES)
return static_cast<double>(sys_timer_info.cycles.frequency);
#else
return static_cast<double>(sys_timer_info.microseconds.frequency);
#endif
}
class Gap_time_tracker; class Gap_time_tracker;
void attach_gap_time_tracker(THD *thd, Gap_time_tracker *gap_tracker, ulonglong timeval); void attach_gap_time_tracker(THD *thd, Gap_time_tracker *gap_tracker, ulonglong timeval);
void process_gap_time_tracker(THD *thd, ulonglong timeval); void process_gap_time_tracker(THD *thd, ulonglong timeval);
@@ -52,9 +62,18 @@ protected:
ulonglong cycles; ulonglong cycles;
ulonglong last_start; ulonglong last_start;
ulonglong measure() const
{
#if (MY_TIMER_ROUTINE_CYCLES)
return my_timer_cycles();
#else
return my_timer_microseconds();
#endif
}
void cycles_stop_tracking(THD *thd) void cycles_stop_tracking(THD *thd)
{ {
ulonglong end= my_timer_cycles(); ulonglong end= measure();
cycles += end - last_start; cycles += end - last_start;
if (unlikely(end < last_start)) if (unlikely(end < last_start))
cycles += ULONGLONG_MAX; cycles += ULONGLONG_MAX;
@@ -80,7 +99,7 @@ public:
// interface for collecting time // interface for collecting time
void start_tracking(THD *thd) void start_tracking(THD *thd)
{ {
last_start= my_timer_cycles(); last_start= measure();
process_gap_time_tracker(thd, last_start); process_gap_time_tracker(thd, last_start);
} }
@@ -96,7 +115,7 @@ public:
{ {
// convert 'cycles' to milliseconds. // convert 'cycles' to milliseconds.
return 1000.0 * static_cast<double>(cycles) / return 1000.0 * static_cast<double>(cycles) /
static_cast<double>(sys_timer_info.cycles.frequency); timer_tracker_frequency();
} }
bool has_timed_statistics() const { return cycles > 0; } bool has_timed_statistics() const { return cycles > 0; }
@@ -122,13 +141,11 @@ public:
double get_time_ms() const double get_time_ms() const
{ {
// convert 'cycles' to milliseconds. // convert 'cycles' to milliseconds.
return 1000.0 * static_cast<double>(cycles) / return 1000.0 * static_cast<double>(cycles) / timer_tracker_frequency();
static_cast<double>(sys_timer_info.cycles.frequency);
} }
}; };
/* /*
A class for counting certain actions (in all queries), and optionally A class for counting certain actions (in all queries), and optionally
collecting the timings (in ANALYZE queries). collecting the timings (in ANALYZE queries).

View File

@@ -604,10 +604,9 @@ bool check_has_super(sys_var *self, THD *thd, set_var *var)
return false; return false;
} }
static Sys_var_bit Sys_core_file("core_file", "write a core-file on crashes", static Sys_var_bit Sys_core_file("core_file", "Write core on crashes",
READ_ONLY GLOBAL_VAR(test_flags), NO_CMD_LINE, READ_ONLY GLOBAL_VAR(test_flags), CMD_LINE(OPT_ARG),
TEST_CORE_ON_SIGNAL, DEFAULT(IF_WIN(TRUE,FALSE)), NO_MUTEX_GUARD, NOT_IN_BINLOG, TEST_CORE_ON_SIGNAL, DEFAULT(IF_WIN(TRUE,FALSE)));
0,0,0);
static bool binlog_format_check(sys_var *self, THD *thd, set_var *var) static bool binlog_format_check(sys_var *self, THD *thd, set_var *var)
{ {

View File

@@ -12,9 +12,9 @@ alter table t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t0"';
select * from t0; select * from t0;
ERROR HY000: An infinite loop is detected when opening table test.t0 ERROR HY000: An infinite loop is detected when opening table test.t0
select * from t1; select * from t1;
ERROR HY000: An infinite loop is detected when opening table test.t1 ERROR HY000: An infinite loop is detected when opening table test.t0
select * from t2; select * from t2;
ERROR HY000: An infinite loop is detected when opening table test.t2 ERROR HY000: An infinite loop is detected when opening table test.t0
drop table t0, t1, t2; drop table t0, t1, t2;
for master_1 for master_1
for child2 for child2

View File

@@ -2223,33 +2223,64 @@ bool spider_db_mbase::is_xa_nota_error(
DBUG_RETURN(xa_nota); DBUG_RETURN(xa_nota);
} }
void spider_db_mbase::fetch_and_print_warnings(struct tm *l_time) int spider_db_mbase::fetch_and_print_warnings(struct tm *l_time)
{ {
int error_num = 0;
DBUG_ENTER("spider_db_mbase::fetch_and_print_warnings"); DBUG_ENTER("spider_db_mbase::fetch_and_print_warnings");
DBUG_PRINT("info",("spider this=%p", this));
if (spider_param_dry_access() || db_conn->status != MYSQL_STATUS_READY || if (spider_param_dry_access() || db_conn->status != MYSQL_STATUS_READY ||
db_conn->server_status & SERVER_MORE_RESULTS_EXISTS) db_conn->server_status & SERVER_MORE_RESULTS_EXISTS ||
DBUG_VOID_RETURN; !db_conn->warning_count)
DBUG_RETURN(0);
if (mysql_real_query(db_conn, SPIDER_SQL_SHOW_WARNINGS_STR, if (mysql_real_query(db_conn, SPIDER_SQL_SHOW_WARNINGS_STR,
SPIDER_SQL_SHOW_WARNINGS_LEN)) SPIDER_SQL_SHOW_WARNINGS_LEN))
DBUG_VOID_RETURN; DBUG_RETURN(0);
MYSQL_RES *res= mysql_store_result(db_conn); MYSQL_RES *res= mysql_store_result(db_conn);
if (!res) if (!res)
DBUG_VOID_RETURN; DBUG_RETURN(0);
if (mysql_num_fields(res) == 3) uint num_fields= mysql_num_fields(res);
while (MYSQL_ROW row= mysql_fetch_row(res)) if (num_fields != 3)
{
mysql_free_result(res);
DBUG_RETURN(0);
}
MYSQL_ROW row= mysql_fetch_row(res);
if (l_time)
{
while (row)
{
fprintf(stderr, fprintf(stderr,
"%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] from [%s] %ld " "%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] from [%s] %ld "
"to %ld: %s %s %s\n", "to %ld: %s %s %s\n",
l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday,
l_time->tm_hour, l_time->tm_min, l_time->tm_sec, conn->tgt_host, l_time->tm_hour, l_time->tm_min, l_time->tm_sec, conn->tgt_host,
(ulong) db_conn->thread_id, (ulong) current_thd->thread_id, (ulong) db_conn->thread_id, (ulong) current_thd->thread_id, row[0],
row[0], row[1], row[2]); row[1], row[2]);
row= mysql_fetch_row(res);
}
} else {
while (row)
{
DBUG_PRINT("info",("spider row[0]=%s", row[0]));
DBUG_PRINT("info",("spider row[1]=%s", row[1]));
DBUG_PRINT("info",("spider row[2]=%s", row[2]));
longlong res_num =
(longlong) my_strtoll10(row[1], (char**) NULL, &error_num);
DBUG_PRINT("info",("spider res_num=%lld", res_num));
my_printf_error((int) res_num, row[2], MYF(0));
error_num = (int) res_num;
row = mysql_fetch_row(res);
}
}
mysql_free_result(res); mysql_free_result(res);
DBUG_VOID_RETURN;
DBUG_RETURN(error_num);
} }
spider_db_result *spider_db_mbase::store_result( spider_db_result *spider_db_mbase::store_result(
@@ -13726,11 +13757,9 @@ int spider_mbase_handler::show_table_status(
DBUG_RETURN(error_num); DBUG_RETURN(error_num);
} }
} }
if ((error_num = ((spider_db_mbase *) conn->db_conn)->fetch_and_print_warnings(NULL)))
{ {
time_t cur_time = (time_t) time((time_t*) 0); DBUG_RETURN(error_num);
struct tm lt;
struct tm *l_time = localtime_r(&cur_time, &lt);
((spider_db_mbase *) conn->db_conn)->fetch_and_print_warnings(l_time);
} }
if (share->static_records_for_status != -1) if (share->static_records_for_status != -1)
{ {

View File

@@ -434,7 +434,7 @@ public:
bool is_xa_nota_error( bool is_xa_nota_error(
int error_num int error_num
); );
void fetch_and_print_warnings(struct tm *l_time); int fetch_and_print_warnings(struct tm *l_time);
spider_db_result *store_result( spider_db_result *store_result(
spider_db_result_buffer **spider_res_buf, spider_db_result_buffer **spider_res_buf,
st_spider_db_request_key *request_key, st_spider_db_request_key *request_key,