1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge 10.11 into 11.4

This commit is contained in:
Marko Mäkelä
2025-04-02 10:15:08 +03:00
105 changed files with 1780 additions and 208 deletions

View File

@@ -634,7 +634,7 @@ IF(NOT WITHOUT_SERVER)
perror
replace)
IF(WIN32)
ADD_DEPENDENCIES(minbuild echo mariadb-install-db my_safe_kill)
ADD_DEPENDENCIES(minbuild echo mariadb-install-db my_safe_kill mariadb-upgrade-service)
ENDIF()
ADD_CUSTOM_TARGET(smoketest
COMMAND perl ./mysql-test-run.pl main.1st

View File

@@ -2973,6 +2973,15 @@ my_bool regex_list_check_match(
const regex_list_t& list,
const char* name)
{
if (list.empty()) return (FALSE);
/*
regexec/pcre2_regexec is not threadsafe, also documented.
Serialize access from multiple threads to compiled regexes.
*/
static std::mutex regex_match_mutex;
std::lock_guard<std::mutex> lock(regex_match_mutex);
regmatch_t tables_regmatch[1];
for (regex_list_t::const_iterator i = list.begin(), end = list.end();
i != end; ++i) {

View File

@@ -0,0 +1,35 @@
use mysql;
# run mysql_install_db with --service parameter
# Start service
# -- Upgrade service (online) --
Phase 1/10: Stopping service
Phase 2/10: Start and stop server in the old version, to avoid crash recovery (skipped)
Phase 3/10: Fixing server config file
Phase 4/10: Starting mysqld for upgrade
Phase 5/10: Waiting for startup to complete
Phase 6/10: Running mysql_upgrade
Phase 7/10: Changing service configuration
Phase 8/10: Initiating server shutdown
Phase 9/10: Waiting for shutdown to complete
Phase 10/10: Starting service
Service 'SERVICE_NAME' successfully upgraded.
Log file is written to UPGRADE_LOG
# upgrade_success(online)=1
# Service stopped
# -- Upgrade service (offline) --
Phase 1/10: Stopping service
Phase 2/10: Start and stop server in the old version, to avoid crash recovery ,this can take some time
Phase 3/10: Fixing server config file
Phase 4/10: Starting mysqld for upgrade
Phase 5/10: Waiting for startup to complete
Phase 6/10: Running mysql_upgrade
Phase 7/10: Changing service configuration
Phase 8/10: Initiating server shutdown
Phase 9/10: Waiting for shutdown to complete
Phase 10/10: Starting service (skipped)
Service 'SERVICE_NAME' successfully upgraded.
Log file is written to UPGRADE_LOG
# upgrade_success(offline)=1
# Delete service
connection default;
# restart

View File

@@ -0,0 +1,113 @@
source include/windows.inc;
let $datadir_name=data;
let $service_name_prefix=mariadb;
let $password=password;
source include/check_windows_admin.inc;
# The test uses return code from sc.exe utility, which are as follows
let $ERROR_SERVICE_DOES_NOT_EXIST= 1060;
let $ERROR_SERVICE_CANNOT_ACCEPT_CTRL=1061;# intermediate, during start or stop
let $ERROR_SERVICE_NOT_ACTIVE=1062;# service stopped
let $ERROR_INVALID_SERVICE_CONTROL=1052; # The requested control is not valid for this service
let $sc_exe= C:\Windows\System32\sc.exe;
let $ddir= $MYSQLTEST_VARDIR/tmp/$datadir_name;
let $service_name=$service_name_prefix$MASTER_MYPORT;
let TMP= $MYSQLTEST_VARDIR/tmp;
let $upgrade_log=$TMP/mysql_upgrade_service.$service_name.log;
use mysql;
error 0,1;
rmdir $ddir;
--disable_result_log
error 0,$ERROR_SERVICE_DOES_NOT_EXIST;
exec $sc_exe delete $service_name;
--enable_result_log
source include/shutdown_mysqld.inc;
echo # run mysql_install_db with --service parameter;
--disable_result_log
exec $MYSQL_INSTALL_DB_EXE --datadir=$ddir --port=$MASTER_MYPORT --password=$password --service=$service_name --verbose-bootstrap -R;
--enable_result_log
echo # Start service;
--disable_result_log
exec $sc_exe start $service_name;
--enable_result_log
enable_reconnect;
source include/wait_until_connected_again.inc;
disable_reconnect;
echo # -- Upgrade service (online) --;
--replace_result $upgrade_log UPGRADE_LOG $service_name SERVICE_NAME
let $sys_errno=0;
let $upgrade_success = 1;
error 0,1;
exec $MARIADB_UPGRADE_SERVICE_EXE --service=$service_name;
if($sys_errno != 0)
{
let $upgrade_success = 0;
}
echo # upgrade_success(online)=$upgrade_success;
file_exists $upgrade_log;
if ($upgrade_success == 0)
{
echo --detailed error(online upgrade)--;
cat_file $upgrade_log;
}
# stop service
--disable_result_log
# Wait until stopped
let $sys_errno=0;
while($sys_errno != $ERROR_SERVICE_NOT_ACTIVE)
{
--error 0,$ERROR_SERVICE_CANNOT_ACCEPT_CTRL,$ERROR_SERVICE_NOT_ACTIVE, $ERROR_INVALID_SERVICE_CONTROL
exec $sc_exe stop $service_name;
if($sys_errno != $ERROR_SERVICE_NOT_ACTIVE)
{
--real_sleep 0.1
}
}
--enable_result_log
echo # Service stopped;
echo # -- Upgrade service (offline) --;
--replace_result $upgrade_log UPGRADE_LOG $service_name SERVICE_NAME
let $sys_errno=0;
let $upgrade_success = 1;
error 0,1;
exec $MARIADB_UPGRADE_SERVICE_EXE --service=$service_name;
if($sys_errno != 0)
{
let $upgrade_success = 0;
}
echo # upgrade_success(offline)=$upgrade_success;
file_exists $upgrade_log;
if ($upgrade_success == 0)
{
echo --detailed error(online upgrade)--;
cat_file $upgrade_log;
}
echo # Delete service;
let $sys_errno=0;
--disable_result_log
exec $sc_exe delete $service_name;
--enable_result_log
# Cleanup
source include/wait_until_disconnected.inc;
rmdir $ddir;
remove_file $upgrade_log;
let TEMP=$old_temp;
#restart original server
connection default;
source include/start_mysqld.inc;

View File

@@ -259,3 +259,24 @@ CHECK TABLE `t1` EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
#
# MDEV-31122 Server crash in get_lock_data / mysql_lock_abort_for_thread
#
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT, c varchar(5))
PARTITION BY RANGE COLUMNS(c)
SUBPARTITION by key(b) SUBPARTITIONS 2 (
PARTITION p0 VALUES LESS THAN ('m'),
PARTITION p1 VALUES LESS THAN ('z')
);
connect con1,localhost,root,,;
HANDLER t1 OPEN;
SELECT b FROM t2 PARTITION (p0);
connection default;
SET lock_wait_timeout= 1;
ALTER TABLE t1 FORCE;
connection con1;
b
disconnect con1;
connection default;
DROP TABLE t2, t1;

View File

@@ -249,3 +249,31 @@ ALTER TABLE `t1` ADD PRIMARY KEY (`a`);
ALTER TABLE `t1` REMOVE PARTITIONING;
CHECK TABLE `t1` EXTENDED;
DROP TABLE t1;
--echo #
--echo # MDEV-31122 Server crash in get_lock_data / mysql_lock_abort_for_thread
--echo #
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT, c varchar(5))
PARTITION BY RANGE COLUMNS(c)
SUBPARTITION by key(b) SUBPARTITIONS 2 (
PARTITION p0 VALUES LESS THAN ('m'),
PARTITION p1 VALUES LESS THAN ('z')
);
--connect (con1,localhost,root,,)
HANDLER t1 OPEN;
--send
SELECT b FROM t2 PARTITION (p0);
--connection default
SET lock_wait_timeout= 1;
--error 0,ER_STATEMENT_TIMEOUT,ER_LOCK_WAIT_TIMEOUT
ALTER TABLE t1 FORCE;
--connection con1
--reap
--disconnect con1
--connection default
DROP TABLE t2, t1;

View File

@@ -2233,6 +2233,9 @@ sub environment_setup {
{
$ENV{'MYSQL_INSTALL_DB_EXE'}= mtr_exe_exists("$bindir/sql$multiconfig/mariadb-install-db",
"$bindir/bin/mariadb-install-db");
$ENV{'MARIADB_UPGRADE_SERVICE_EXE'}= mtr_exe_exists("$bindir/sql$multiconfig/mariadb-upgrade-service",
"$bindir/bin/mariadb-upgrade-service");
$ENV{'MARIADB_UPGRADE_EXE'}= mtr_exe_exists("$path_client_bindir/mariadb-upgrade");
}
my $client_config_exe=
@@ -4495,6 +4498,7 @@ sub extract_warning_lines ($$) {
qr/InnoDB: innodb_open_files .* should not be greater than/,
qr/InnoDB: Trying to delete tablespace.*but there are.*pending/,
qr/InnoDB: Tablespace 1[0-9]* was not found at .*, and innodb_force_recovery was set/,
qr/InnoDB: Long wait \([0-9]+ seconds\) for double-write buffer flush/,
qr/Slave: Unknown table 't1' .* 1051/,
qr/Slave SQL:.*(Internal MariaDB error code: [[:digit:]]+|Query:.*)/,
qr/slave SQL thread aborted/,

View File

@@ -10,7 +10,6 @@
#
##############################################################################
galera_sequences : MDEV-35934/MDEV-33850 For Galera, create sequence with low cache got signal 6 error: [ERROR] WSREP: FSM: no such a transition REPLICATING -> COMMITTED
galera_wan : MDEV-35940 Unallowed state transition: donor -> synced in galera_wan
galera_vote_rejoin_ddl : MDEV-35940 Unallowed state transition: donor -> synced in galera_wan
MW-329 : MDEV-35951 Complete freeze during MW-329 test

View File

@@ -24,6 +24,6 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`f1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
DROP TABLE t1;
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender (.*) is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender .+ ?is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
connection node_1;
SET GLOBAL wsrep_provider_options = 'pc.ignore_sb=false';

View File

@@ -66,7 +66,7 @@ SHOW STATUS LIKE 'wsrep_desync_count';
Variable_name Value
wsrep_desync_count 0
SET @@global.wsrep_desync = 0;
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender (.*) is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender .+ ?is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
connection node_1;
# Wait until both nodes are back to cluster
SET GLOBAL wsrep_provider_options = 'pc.ignore_sb=false';

View File

@@ -13,4 +13,4 @@ SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME
VARIABLE_VALUE
Primary
SET SESSION wsrep_sync_wait=DEFAULT;
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender (.*) is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender .+ ?is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");

View File

@@ -0,0 +1,22 @@
connection node_2;
connection node_1;
connect con1,127.0.0.1,root,,test,$NODE_MYPORT_1;
connection node_1;
CALL mtr.add_suppression("CREATE TABLE isolation failure");
SET DEBUG_SYNC = 'wsrep_kill_thd_before_enter_toi SIGNAL may_kill WAIT_FOR continue';
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
connection con1;
SET DEBUG_SYNC = 'now WAIT_FOR may_kill';
SET DEBUG_SYNC = 'now SIGNAL continue';
connection node_1;
Got one of the listed errors
connection node_2;
SHOW TABLES LIKE 't1';
Tables_in_test (t1)
connection con1;
SHOW TABLES LIKE 't1';
Tables_in_test (t1)
SET DEBUG_SYNC = 'RESET';
disconnect con1;
disconnect node_2;
disconnect node_1;

View File

@@ -26,3 +26,4 @@ COUNT(*) = 1
1
DROP TABLE t1;
connection node_1;
SET GLOBAL wsrep_mode = DEFAULT;

View File

@@ -53,7 +53,7 @@ FOUND 2 /Resuming and resyncing the provider/ in mysqld.2.err
FOUND 1 /Server not desynched from group at BLOCK_DDL because WSREP_MODE_BF_MARIABACKUP is used./ in mysqld.2.err
# Should return FOUND 1 as server did desync and pause at BLOCK_COMMIT
FOUND 1 /Server desynched from group during BACKUP STAGE BLOCK_COMMIT./ in mysqld.2.err
SET GLOBAL wsrep_mode = "";
SET GLOBAL wsrep_mode = DEFAULT;
connection node_1;
DROP TABLE t;
disconnect node_2;

View File

@@ -1,9 +1,9 @@
connection node_2;
connection node_1;
# Correct Galera library found
SELECT COUNT(*) `expect 51` FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep_%';
expect 51
51
SELECT COUNT(*) `expect 50` FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep_%';
expect 50
50
SELECT VARIABLE_NAME, VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME LIKE 'wsrep_%'

View File

@@ -2,14 +2,14 @@ connection node_2;
connection node_1;
# Correct Galera library found
connection node_1;
CALL mtr.add_suppression("\\[Warning\\] WSREP: evicting member .* at .* permanently from group");
CALL mtr.add_suppression("\\[Warning\\] WSREP: evicting member .* ?at .+ permanently from group");
connection node_2;
CALL mtr.add_suppression("\\[Warning\\] WSREP: handshake with .* .* failed: 'evicted'");
CALL mtr.add_suppression("\\[Warning\\] WSREP: handshake with .* ?.+ failed: 'evicted'");
CALL mtr.add_suppression("\\[ERROR\\] WSREP: exception from gcomm, backend must be restarted: this node has been evicted out of the cluster, gcomm backend restart is required \\(FATAL\\)");
connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3;
CALL mtr.add_suppression("\\[Warning\\] WSREP: evicting member .* at .* permanently from group");
CALL mtr.add_suppression("\\[Warning\\] WSREP: evicting member .* ?at .+ permanently from group");
connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4;
CALL mtr.add_suppression("\\[Warning\\] WSREP: evicting member .* at .* permanently from group");
CALL mtr.add_suppression("\\[Warning\\] WSREP: evicting member .* ?at .+ permanently from group");
connection node_1;
connection node_2;
connection node_3;

View File

@@ -47,6 +47,9 @@ select NEXT VALUE FOR Seq1_1;
NEXT VALUE FOR Seq1_1
4
connection node_1;
SHOW CREATE SEQUENCE Seq1_1;
Table Create Table
Seq1_1 CREATE SEQUENCE `Seq1_1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 nocache nocycle ENGINE=InnoDB
DROP SEQUENCE Seq1_1;
connection node_1;
CREATE TABLE t2 (d CHAR(1)KEY);

View File

@@ -0,0 +1,152 @@
connection node_2;
connection node_1;
connection node_1;
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY, f2 INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1, 0), (3, 0);
connection node_1;
START TRANSACTION;
INSERT INTO t1 VALUES (4, next value for s);
INSERT INTO t1 VALUES (5, next value for s);
INSERT INTO t1 VALUES (6, next value for s);
INSERT INTO t1 VALUES (7, next value for s);
INSERT INTO t1 VALUES (8, next value for s);
INSERT INTO t1 VALUES (9, next value for s);
INSERT INTO t1 VALUES (10, next value for s);
INSERT INTO t1 VALUES (11, next value for s);
INSERT INTO t1 VALUES (12, next value for s);
INSERT INTO t1 VALUES (13, next value for s);
INSERT INTO t1 VALUES (14, next value for s);
SELECT * FROM t1 WHERE f1 > 0 FOR UPDATE;
f1 f2
1 0
3 0
4 1
5 3
6 5
7 7
8 9
9 11
10 13
11 15
12 17
13 19
14 21
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
SET SESSION wsrep_sync_wait=0;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
INSERT INTO t1 VALUES (2, 2);
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_master_enter_sync';
connection node_1;
COMMIT;
connection node_1a;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'dbug=d,abort_trx_end';
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'signal=abort_trx_end';
SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_master_enter_sync';
connection node_1;
wsrep_local_replays
1
INSERT INTO t1 VALUES (22, next value for s);
INSERT INTO t1 VALUES (23, next value for s);
INSERT INTO t1 VALUES (24, next value for s);
INSERT INTO t1 VALUES (25, next value for s);
INSERT INTO t1 VALUES (26, next value for s);
INSERT INTO t1 VALUES (27, next value for s);
INSERT INTO t1 VALUES (28, next value for s);
INSERT INTO t1 VALUES (29, next value for s);
INSERT INTO t1 VALUES (30, next value for s);
INSERT INTO t1 VALUES (31, next value for s);
INSERT INTO t1 VALUES (32, next value for s);
INSERT INTO t1 VALUES (33, next value for s);
INSERT INTO t1 VALUES (34, next value for s);
INSERT INTO t1 VALUES (35, next value for s);
connection node_1;
SELECT * FROM t1;
f1 f2
1 0
2 2
3 0
4 1
5 3
6 5
7 7
8 9
9 11
10 13
11 15
12 17
13 19
14 21
22 31
23 33
24 35
25 37
26 39
27 41
28 43
29 45
30 47
31 49
32 51
33 53
34 55
35 57
SELECT LASTVAL(s);
LASTVAL(s)
57
connection node_2;
SELECT * FROM t1;
f1 f2
1 0
2 2
3 0
4 1
5 3
6 5
7 7
8 9
9 11
10 13
11 15
12 17
13 19
14 21
22 31
23 33
24 35
25 37
26 39
27 41
28 43
29 45
30 47
31 49
32 51
33 53
34 55
35 57
SELECT LASTVAL(s);
LASTVAL(s)
NULL
connection node_1;
SELECT NEXTVAL(s);
NEXTVAL(s)
59
connection node_2;
SELECT NEXTVAL(s);
NEXTVAL(s)
62
DROP SEQUENCE s;
DROP TABLE t1;

View File

@@ -0,0 +1,350 @@
connection node_2;
connection node_1;
connection node_1;
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY DEFAULT NEXTVAL(s), f2 INT) ENGINE=InnoDB;
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
connection node_1;
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
COMMIT;
connection node_2;
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
COMMIT;
connection node_2a;
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
COMMIT;
connection node_1a;
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
COMMIT;
connection node_2;
SELECT LASTVAL(s);
LASTVAL(s)
40
connection node_1;
SELECT LASTVAL(s);
LASTVAL(s)
19
connection node_2a;
SELECT LASTVAL(s);
LASTVAL(s)
60
connection node_1a;
SELECT LASTVAL(s);
LASTVAL(s)
79
connection node_1;
SELECT * FROM t1;
f1 f2
1 1
3 1
5 1
7 1
9 1
11 1
13 1
15 1
17 1
19 1
22 1
24 1
26 1
28 1
30 1
32 1
34 1
36 1
38 1
40 1
42 1
44 1
46 1
48 1
50 1
52 1
54 1
56 1
58 1
60 1
61 1
63 1
65 1
67 1
69 1
71 1
73 1
75 1
77 1
79 1
connection node_2;
SELECT * FROM t1;
f1 f2
1 1
3 1
5 1
7 1
9 1
11 1
13 1
15 1
17 1
19 1
22 1
24 1
26 1
28 1
30 1
32 1
34 1
36 1
38 1
40 1
42 1
44 1
46 1
48 1
50 1
52 1
54 1
56 1
58 1
60 1
61 1
63 1
65 1
67 1
69 1
71 1
73 1
75 1
77 1
79 1
connection node_1;
DROP TABLE t1;
DROP SEQUENCE s;
connection node_1;
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY DEFAULT NEXTVAL(s), f2 INT) ENGINE=InnoDB;
connection node_1;
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
ROLLBACK;
connection node_2;
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
ROLLBACK;
connection node_2a;
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
ROLLBACK;
connection node_1a;
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
ROLLBACK;
connection node_2;
SELECT LASTVAL(s);
LASTVAL(s)
20
connection node_1;
SELECT LASTVAL(s);
LASTVAL(s)
19
connection node_2a;
SELECT LASTVAL(s);
LASTVAL(s)
40
connection node_1a;
SELECT LASTVAL(s);
LASTVAL(s)
39
connection node_1;
SELECT * FROM t1;
f1 f2
connection node_2;
SELECT * FROM t1;
f1 f2
connection node_1;
DROP TABLE t1;
DROP SEQUENCE s;
connection node_1;
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY DEFAULT NEXTVAL(s), f2 INT) ENGINE=InnoDB;
connection node_1;
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
connection node_1a;
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
connection node_2a;
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
connection node_2;
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
connection node_1;
COMMIT;
connection node_1a;
ROLLBACK;
connection node_2;
COMMIT;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
connection node_2a;
ROLLBACK;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
connection node_2;
SELECT LASTVAL(s);
LASTVAL(s)
40
connection node_1;
SELECT LASTVAL(s);
LASTVAL(s)
19
connection node_2a;
SELECT LASTVAL(s);
LASTVAL(s)
20
connection node_1a;
SELECT LASTVAL(s);
LASTVAL(s)
39
connection node_1;
SELECT * FROM t1;
f1 f2
1 1
3 1
5 1
7 1
9 1
11 1
13 1
15 1
17 1
19 1
connection node_2;
SELECT * FROM t1;
f1 f2
1 1
3 1
5 1
7 1
9 1
11 1
13 1
15 1
17 1
19 1
connection node_1;
DROP TABLE t1;
DROP SEQUENCE s;

View File

@@ -48,7 +48,7 @@ SET @@global.wsrep_desync = 0;
SET SESSION wsrep_sync_wait=15;
SHOW CREATE TABLE t1;
DROP TABLE t1;
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender (.*) is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender .+ ?is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
--connection node_1
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';

View File

@@ -77,7 +77,7 @@ SET @@global.wsrep_desync = 0;
--let $wait_condition = SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
--source include/wait_condition.inc
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender (.*) is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender .+ ?is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
--connection node_1
--echo # Wait until both nodes are back to cluster

View File

@@ -25,7 +25,6 @@ SET SESSION wsrep_sync_wait=DEFAULT;
--error ER_LOCK_WAIT_TIMEOUT
DELETE FROM mysql.wsrep_streaming_log;
#
# Reconnect to the cluster
#
@@ -36,6 +35,5 @@ SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0';
SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
SET SESSION wsrep_sync_wait=DEFAULT;
--source include/auto_increment_offset_restore.inc
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender (.*) is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender .+ ?is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");

View File

@@ -0,0 +1,43 @@
#
# MDEV-36116: TOI crashes in debug assert if executing thread is killed.
#
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_debug_sync.inc
--source include/have_debug.inc
--connect con1,127.0.0.1,root,,test,$NODE_MYPORT_1
# Start TOI operation and wait for the thread to be killed.
--connection node_1
CALL mtr.add_suppression("CREATE TABLE isolation failure");
--let $connection_id = `SELECT CONNECTION_ID()`
SET DEBUG_SYNC = 'wsrep_kill_thd_before_enter_toi SIGNAL may_kill WAIT_FOR continue';
--send
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
# Kill the thread and let it continue.
--connection con1
SET DEBUG_SYNC = 'now WAIT_FOR may_kill';
--disable_query_log
--eval KILL CONNECTION $connection_id
--enable_query_log
SET DEBUG_SYNC = 'now SIGNAL continue';
--connection node_1
--error 2013,2026
--reap
# Verify no tables created on either nodes.
--connection node_2
SHOW TABLES LIKE 't1';
--connection con1
SHOW TABLES LIKE 't1';
# Cleanup
SET DEBUG_SYNC = 'RESET';
--disconnect con1
--source include/galera_end.inc

View File

@@ -4,7 +4,7 @@
--connection node_2
--disable_query_log
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3, MASTER_SSL_VERIFY_SERVER_CERT=0, MASTER_USE_GTID=slave_pos;
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_SSL_VERIFY_SERVER_CERT=0, MASTER_PORT=$NODE_MYPORT_3, master_use_gtid=slave_pos;
--enable_query_log
START SLAVE;

View File

@@ -11,7 +11,7 @@ call mtr.add_suppression("\\[ERROR\\] Error reading packet from server: WSREP ha
call mtr.add_suppression("WSREP has not yet prepared node for application use");
--disable_query_log
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$NODE_MYPORT_1, MASTER_USER='root', master_connect_retry=1, MASTER_SSL_VERIFY_SERVER_CERT=0;
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_SSL_VERIFY_SERVER_CERT=0, MASTER_PORT=$NODE_MYPORT_1, master_connect_retry=1;
--enable_query_log
--connection node_1

View File

@@ -49,13 +49,13 @@ grant all on *.* to repl2@'%';
--echo # Galera replica changing master to primary1
SET @@default_master_connection='stream1';
--disable_query_log
--eval CHANGE MASTER 'stream1' TO master_host='127.0.0.1', master_user='repl', master_password='repl', master_port=$NODE_MYPORT_3, master_use_gtid=slave_pos;
--eval CHANGE MASTER 'stream1' TO master_host='127.0.0.1', master_user='repl', master_password='repl', master_ssl_verify_server_cert=0, master_port=$NODE_MYPORT_3, master_use_gtid=slave_pos;
--enable_query_log
--echo # Primary node changing master to primary2
SET @@default_master_connection='stream2';
--disable_query_log
--eval CHANGE MASTER 'stream2' TO master_host='127.0.0.1', master_user='repl2', master_password='repl2', master_port=$NODE_MYPORT_4, master_use_gtid=slave_pos;
--eval CHANGE MASTER 'stream2' TO master_host='127.0.0.1', master_user='repl2', master_password='repl2', master_ssl_verify_server_cert=0, master_port=$NODE_MYPORT_4, master_use_gtid=slave_pos;
--enable_query_log
START ALL SLAVES;

View File

@@ -36,6 +36,4 @@ SELECT COUNT(*) = 1 FROM t1;
DROP TABLE t1;
--connection node_1
--disable_query_log
SET GLOBAL wsrep_mode = DEFAULT;
--enable_query_log

View File

@@ -16,7 +16,7 @@ SELECT @@wsrep_on;
--connection node_1
--disable_query_log
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3, master_ssl_verify_server_cert=0;
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_SSL_VERIFY_SERVER_CERT=0, MASTER_PORT=$NODE_MYPORT_3;
--enable_query_log
START SLAVE;

View File

@@ -17,7 +17,7 @@
--connection node_2
--disable_query_log
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_4, MASTER_SSL_VERIFY_SERVER_CERT=0;
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_SSL_VERIFY_SERVER_CERT=0, MASTER_PORT=$NODE_MYPORT_4;
--enable_query_log
START SLAVE;

View File

@@ -12,7 +12,7 @@
--connection node_1
--disable_query_log
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3;
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_SSL_VERIFY_SERVER_CERT=0, MASTER_PORT=$NODE_MYPORT_3;
--enable_query_log
START SLAVE;

View File

@@ -36,7 +36,7 @@ RESET MASTER;
# nodes 1 and 2 form a galera cluster, node 2 operates as slave for native MariaDB master in node 3
#
--disable_query_log
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3;
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_SSL_VERIFY_SERVER_CERT=0, MASTER_PORT=$NODE_MYPORT_3;
--enable_query_log
START SLAVE;

View File

@@ -129,7 +129,7 @@ let SEARCH_PATTERN = Server not desynched from group at BLOCK_DDL because WSREP_
let SEARCH_PATTERN = Server desynched from group during BACKUP STAGE BLOCK_COMMIT.;
--source include/search_pattern_in_file.inc
SET GLOBAL wsrep_mode = "";
SET GLOBAL wsrep_mode = DEFAULT;
--connection node_1
DROP TABLE t;

View File

@@ -51,7 +51,7 @@ ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
--connection replica1
--echo # Galera replica changing master to primary1
--disable_query_log
--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='repl', master_password='repl', master_port=$NODE_MYPORT_4, master_use_gtid=slave_pos;
--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='repl', master_password='repl', master_ssl_verify_server_cert=0, master_port=$NODE_MYPORT_4, master_use_gtid=slave_pos;
--enable_query_log
START SLAVE;
@@ -63,7 +63,7 @@ grant all on *.* to repl2@'%';
--connection replica2
--echo # replica2 changing master to primary2
--disable_query_log
--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='repl2', master_password='repl2', master_port=$NODE_MYPORT_3, master_use_gtid=slave_pos;
--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='repl2', master_password='repl2', master_ssl_verify_server_cert=0, master_port=$NODE_MYPORT_3, master_use_gtid=slave_pos;
--enable_query_log
START SLAVE;

View File

@@ -18,7 +18,7 @@ source ../wsrep/include/check_galera_version.inc;
# Global Variables
SELECT COUNT(*) `expect 51` FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep_%';
SELECT COUNT(*) `expect 50` FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep_%';
SELECT VARIABLE_NAME, VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES

View File

@@ -1,14 +1,14 @@
!include ../galera_4nodes.cnf
[mysqld.1]
wsrep_provider_options='base_port=@mysqld.1.#galera_port;evs.auto_evict=1'
wsrep_provider_options='evs.auto_evict=1;gmcast.segment=1;repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.wait_prim_timeout=PT60S;gcache.size=10M'
[mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;evs.auto_evict=1'
wsrep_provider_options='evs.auto_evict=1;gmcast.segment=1;repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.wait_prim_timeout=PT60S;gcache.size=10M'
wsrep_status_file='status2.json'
[mysqld.3]
wsrep_provider_options='base_port=@mysqld.3.#galera_port;evs.auto_evict=1'
wsrep_provider_options='evs.auto_evict=1;gmcast.segment=1;repl.causal_read_timeout=PT90S;base_port=@mysqld.3.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.wait_prim_timeout=PT60S;gcache.size=10M'
[mysqld.4]
wsrep_provider_options='base_port=@mysqld.4.#galera_port;evs.auto_evict=1'
wsrep_provider_options='evs.auto_evict=1;gmcast.segment=1;repl.causal_read_timeout=PT90S;base_port=@mysqld.4.#galera_port;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;pc.wait_prim_timeout=PT60S;gcache.size=10M'

View File

@@ -11,17 +11,17 @@
--source suite/wsrep/include/check_galera_version.inc
--connection node_1
CALL mtr.add_suppression("\\[Warning\\] WSREP: evicting member .* at .* permanently from group");
CALL mtr.add_suppression("\\[Warning\\] WSREP: evicting member .* ?at .+ permanently from group");
--connection node_2
CALL mtr.add_suppression("\\[Warning\\] WSREP: handshake with .* .* failed: 'evicted'");
CALL mtr.add_suppression("\\[Warning\\] WSREP: handshake with .* ?.+ failed: 'evicted'");
CALL mtr.add_suppression("\\[ERROR\\] WSREP: exception from gcomm, backend must be restarted: this node has been evicted out of the cluster, gcomm backend restart is required \\(FATAL\\)");
--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
CALL mtr.add_suppression("\\[Warning\\] WSREP: evicting member .* at .* permanently from group");
CALL mtr.add_suppression("\\[Warning\\] WSREP: evicting member .* ?at .+ permanently from group");
--connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4
CALL mtr.add_suppression("\\[Warning\\] WSREP: evicting member .* at .* permanently from group");
CALL mtr.add_suppression("\\[Warning\\] WSREP: evicting member .* ?at .+ permanently from group");
# Save original auto_increment_offset values.

View File

@@ -29,7 +29,7 @@ call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node");
--connection node_3
--disable_query_log
--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_1, master_ssl_verify_server_cert=0, master_use_gtid=current_pos
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_SSL_VERIFY_SERVER_CERT=0, MASTER_PORT=$NODE_MYPORT_1, master_use_gtid=current_pos;
--enable_query_log
START SLAVE;
--source include/wait_for_slave_to_start.inc

View File

@@ -23,7 +23,7 @@ ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
--connection node_2
--disable_query_log
--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='repl', master_password='repl', master_port=$NODE_MYPORT_3, master_use_gtid=slave_pos;
--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='repl', master_password='repl', master_ssl_verify_server_cert=0, master_port=$NODE_MYPORT_3, master_use_gtid=slave_pos;
--enable_query_log
START SLAVE;

View File

@@ -45,7 +45,7 @@ ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
--connection replica
--disable_query_log
--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='repl', master_password='repl', master_port=$NODE_MYPORT_3, master_use_gtid=slave_pos;
--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='repl', master_password='repl', master_ssl_verify_server_cert=0, master_port=$NODE_MYPORT_3, master_use_gtid=slave_pos;
--enable_query_log
START SLAVE;

View File

@@ -3,6 +3,7 @@
--source include/have_sequence.inc
--source include/have_aria.inc
--disable_ps2_protocol
#
# MDEV-19353 : Alter Sequence do not replicate to another nodes with in Galera Cluster
#
@@ -47,6 +48,7 @@ SHOW CREATE SEQUENCE Seq1_1;
select NEXT VALUE FOR Seq1_1;
--connection node_1
SHOW CREATE SEQUENCE Seq1_1;
DROP SEQUENCE Seq1_1;
#

View File

@@ -0,0 +1,9 @@
!include ../galera_2nodes.cnf
[mysqld.1]
auto-increment-increment=2
auto-increment-offset=1
[mysqld.2]
auto-increment-increment=2
auto-increment-offset=2

View File

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

View File

@@ -0,0 +1,115 @@
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/galera_have_debug_sync.inc
--disable_ps2_protocol
#
# We create InnoDB seqeuence with small cache that is then
# used as default value for column in table.
#
--connection node_1
--let $wsrep_local_replays_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'`
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY, f2 INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1, 0), (3, 0);
--connection node_1
START TRANSACTION;
INSERT INTO t1 VALUES (4, next value for s); # No conflict in cert
INSERT INTO t1 VALUES (5, next value for s); # No conflict in cert
INSERT INTO t1 VALUES (6, next value for s); # No conflict in cert
INSERT INTO t1 VALUES (7, next value for s); # No conflict in cert
INSERT INTO t1 VALUES (8, next value for s); # No conflict in cert
INSERT INTO t1 VALUES (9, next value for s); # No conflict in cert
INSERT INTO t1 VALUES (10, next value for s); # No conflict in cert
INSERT INTO t1 VALUES (11, next value for s); # No conflict in cert
INSERT INTO t1 VALUES (12, next value for s); # No conflict in cert
INSERT INTO t1 VALUES (13, next value for s); # No conflict in cert
INSERT INTO t1 VALUES (14, next value for s); # No conflict in cert
SELECT * FROM t1 WHERE f1 > 0 FOR UPDATE; # Should cause GAP lock between 1 and 3
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
SET SESSION wsrep_sync_wait=0;
# Block the applier on node #1 and issue a conflicting update on node #2
--let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_set_sync_point.inc
#
# Send conflicting INSERT
#
--connection node_2
INSERT INTO t1 VALUES (2, 2); # This should BF abort because of GAP lock
--connection node_1a
--source include/galera_wait_sync_point.inc
--source include/galera_clear_sync_point.inc
# Block the commit, send the COMMIT and wait until it gets blocked
--let $galera_sync_point = commit_monitor_master_enter_sync
--source include/galera_set_sync_point.inc
--connection node_1
--send COMMIT
--connection node_1a
--let $galera_sync_point = apply_monitor_slave_enter_sync commit_monitor_master_enter_sync
--source include/galera_wait_sync_point.inc
--source include/galera_clear_sync_point.inc
--let $galera_sync_point = abort_trx_end
--source include/galera_set_sync_point.inc
--let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_signal_sync_point.inc
--let $galera_sync_point = abort_trx_end commit_monitor_master_enter_sync
--source include/galera_wait_sync_point.inc
# Let the transactions proceed
--source include/galera_clear_sync_point.inc
--let $galera_sync_point = abort_trx_end
--source include/galera_signal_sync_point.inc
--let $galera_sync_point = commit_monitor_master_enter_sync
--source include/galera_signal_sync_point.inc
# Commit succeeds
--connection node_1
--reap
# wsrep_local_replays has increased by 1
--let $wsrep_local_replays_new = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'`
--disable_query_log
--eval SELECT $wsrep_local_replays_new - $wsrep_local_replays_old = 1 AS wsrep_local_replays;
--enable_query_log
INSERT INTO t1 VALUES (22, next value for s);
INSERT INTO t1 VALUES (23, next value for s);
INSERT INTO t1 VALUES (24, next value for s);
INSERT INTO t1 VALUES (25, next value for s);
INSERT INTO t1 VALUES (26, next value for s);
INSERT INTO t1 VALUES (27, next value for s);
INSERT INTO t1 VALUES (28, next value for s);
INSERT INTO t1 VALUES (29, next value for s);
INSERT INTO t1 VALUES (30, next value for s);
INSERT INTO t1 VALUES (31, next value for s);
INSERT INTO t1 VALUES (32, next value for s);
INSERT INTO t1 VALUES (33, next value for s);
INSERT INTO t1 VALUES (34, next value for s);
INSERT INTO t1 VALUES (35, next value for s);
--connection node_1
SELECT * FROM t1;
SELECT LASTVAL(s);
--connection node_2
SELECT * FROM t1;
SELECT LASTVAL(s);
--connection node_1
SELECT NEXTVAL(s);
--connection node_2
SELECT NEXTVAL(s);
DROP SEQUENCE s;
DROP TABLE t1;

View File

@@ -0,0 +1,9 @@
!include ../galera_2nodes.cnf
[mysqld.1]
auto-increment-increment=2
auto-increment-offset=1
[mysqld.2]
auto-increment-increment=2
auto-increment-offset=2

View File

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

View File

@@ -0,0 +1,255 @@
--source include/galera_cluster.inc
--source include/have_sequence.inc
--disable_ps2_protocol
#
# Case 1: Separate transactions from few connections
#
--connection node_1
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY DEFAULT NEXTVAL(s), f2 INT) ENGINE=InnoDB;
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
--connection node_1
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
COMMIT;
--connection node_2
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
COMMIT;
--connection node_2a
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
COMMIT;
--connection node_1a
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
COMMIT;
--connection node_2
SELECT LASTVAL(s);
--connection node_1
SELECT LASTVAL(s);
--connection node_2a
SELECT LASTVAL(s);
--connection node_1a
SELECT LASTVAL(s);
--connection node_1
SELECT * FROM t1;
--connection node_2
SELECT * FROM t1;
--connection node_1
DROP TABLE t1;
DROP SEQUENCE s;
#
# Case 2: All rollback
#
--connection node_1
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY DEFAULT NEXTVAL(s), f2 INT) ENGINE=InnoDB;
--connection node_1
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
ROLLBACK;
--connection node_2
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
ROLLBACK;
--connection node_2a
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
ROLLBACK;
--connection node_1a
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
ROLLBACK;
--connection node_2
SELECT LASTVAL(s);
--connection node_1
SELECT LASTVAL(s);
--connection node_2a
SELECT LASTVAL(s);
--connection node_1a
SELECT LASTVAL(s);
--connection node_1
SELECT * FROM t1;
--connection node_2
SELECT * FROM t1;
--connection node_1
DROP TABLE t1;
DROP SEQUENCE s;
#
# Case 3: Mixed transactions
#
--connection node_1
CREATE SEQUENCE s INCREMENT=0 CACHE=5 ENGINE=InnoDB;
CREATE TABLE t1 (f1 INT PRIMARY KEY DEFAULT NEXTVAL(s), f2 INT) ENGINE=InnoDB;
--connection node_1
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
--connection node_1a
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
--connection node_2a
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
--connection node_2
BEGIN;
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
INSERT INTO t1(f2) values (1);
--connection node_1
COMMIT;
--connection node_1a
ROLLBACK;
--connection node_2
--error ER_LOCK_DEADLOCK
COMMIT;
--connection node_2a
--error ER_LOCK_DEADLOCK
ROLLBACK;
--connection node_2
SELECT LASTVAL(s);
--connection node_1
SELECT LASTVAL(s);
--connection node_2a
SELECT LASTVAL(s);
--connection node_1a
SELECT LASTVAL(s);
--connection node_1
SELECT * FROM t1;
--connection node_2
SELECT * FROM t1;
--connection node_1
DROP TABLE t1;
DROP SEQUENCE s;

View File

@@ -35,7 +35,7 @@ RESET MASTER;
# nodes 1 and 2 form a galera cluster, node 2 operates as slave for native MariaDB master in node 3
#
--disable_query_log
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_PORT=$NODE_MYPORT_3;
--eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_SSL_VERIFY_SERVER_CERT=0, MASTER_PORT=$NODE_MYPORT_3;
--enable_query_log
START SLAVE;

View File

@@ -1,5 +1,6 @@
--source include/big_test.inc
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_mariabackup.inc
# Save original auto_increment_offset values.

View File

@@ -0,0 +1,61 @@
connection node_2;
connection node_1;
connection node_1;
connection node_2;
connection node_3;
connection node_1;
CREATE TABLE parent (
id INT PRIMARY KEY
) ENGINE=InnoDB;
CREATE TABLE child (
id INT PRIMARY KEY,
parent_id INT,
KEY (parent_id),
CONSTRAINT FOREIGN KEY (parent_id) REFERENCES parent(id)
) ENGINE=InnoDB;
INSERT INTO parent VALUES (1), (2);
connection node_3;
SET SESSION wsrep_on = OFF;
DELETE FROM parent WHERE id = 1;
SET SESSION wsrep_on = ON;
Restarting server 3 with one applier thread having FK and UK checks disabled
SET GLOBAL DEBUG_DBUG = 'd,sync.wsrep_after_write_row';
connection node_1;
INSERT INTO child VALUES (1, 1);
connection node_3;
SET DEBUG_SYNC = 'now WAIT_FOR sync.wsrep_after_write_row_reached';
SET GLOBAL DEBUG_DBUG = '';
SET wsrep_sync_wait = 0;
SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL signal.wsrep_after_write_row';
INSERT INTO child VALUES (2, 2);
SET DEBUG_SYNC = 'RESET';
include/assert_grep.inc [no FK constraint failure]
Server 3
SELECT COUNT(*) AS EXPECT_1 FROM parent;
EXPECT_1
1
SELECT COUNT(*) AS EXPECT_2 FROM child;
EXPECT_2
2
connection node_1;
Server 1
SET wsrep_sync_wait = 15;
SELECT COUNT(*) AS EXPECT_2 FROM parent;
EXPECT_2
2
SELECT COUNT(*) AS EXPECT_2 FROM child;
EXPECT_2
2
connection node_2;
Server 2
SET wsrep_sync_wait = 15;
SELECT COUNT(*) AS EXPECT_2 FROM parent;
EXPECT_2
2
SELECT COUNT(*) AS EXPECT_2 FROM child;
EXPECT_2
2
DROP TABLE child;
DROP TABLE parent;
disconnect node_2;
disconnect node_1;

View File

@@ -2,8 +2,6 @@ connection node_2;
connection node_1;
connection node_1;
connection node_2;
connection node_1;
connection node_2;
connection node_3;
Killing node #3 to free ports for garbd ...
connection node_3;
@@ -26,8 +24,8 @@ DROP TABLE t1;
Restarting node #3 to satisfy MTR's end-of-test checks
connection node_3;
connection node_1;
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0 (.*) is not in state transfer \\(SYNCED\\)");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
connection node_2;
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0 (.*) is not in state transfer \\(SYNCED\\)");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
connection node_3;
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0 (.*) is not in state transfer \\(SYNCED\\)");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");

View File

@@ -11,7 +11,6 @@ CREATE TABLE t1 (f1 INTEGER, f2 varchar(1024)) Engine=InnoDB;
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
INSERT INTO t1 (f2) SELECT REPEAT('x', 1024) FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
connection node_2;
Killing node #3 to free ports for garbd ...
connection node_3;
connection node_1;
@@ -33,8 +32,8 @@ Restarting node #3 to satisfy MTR's end-of-test checks
connection node_3;
connection node_1;
connection node_1;
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0 (.*) is not in state transfer \\(SYNCED\\)");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
connection node_2;
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0 (.*) is not in state transfer \\(SYNCED\\)");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
connection node_3;
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0 (.*) is not in state transfer \\(SYNCED\\)");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");

View File

@@ -0,0 +1,110 @@
#
# MDEV-36360: Don't grab table-level X locks for applied inserts.
#
# It prevents a debug crash in wsrep_report_error() which happened when appliers would run
# with FK and UK checks disabled and erroneously execute plain inserts as bulk inserts.
#
# Moreover, in release builds such a behavior could lead to deadlocks between two applier
# threads if a thread waiting for a table-level lock was ordered before the lock holder.
# In that case the lock holder would proceed to commit order and wait forever for the
# now-blocked other applier thread to commit before.
#
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_debug_sync.inc
--source include/have_debug.inc
--let $galera_connection_name = node_3
--let $galera_server_number = 3
--source include/galera_connect.inc
# Save original auto_increment_offset values.
--let $node_1=node_1
--let $node_2=node_2
--let $node_3=node_3
--source ../galera/include/auto_increment_offset_save.inc
# Create parent and child tables.
--connection node_1
CREATE TABLE parent (
id INT PRIMARY KEY
) ENGINE=InnoDB;
CREATE TABLE child (
id INT PRIMARY KEY,
parent_id INT,
KEY (parent_id),
CONSTRAINT FOREIGN KEY (parent_id) REFERENCES parent(id)
) ENGINE=InnoDB;
# Fill the parent table with rows that will later be used by the child.
INSERT INTO parent VALUES (1), (2);
# Wait until the rows are replicated on node #3.
--connection node_3
--let $wait_condition = SELECT COUNT(*) = 2 FROM parent
--source include/wait_condition.inc
# Delete one row from the parent table on node #3 and rejoin the cluster.
SET SESSION wsrep_on = OFF;
DELETE FROM parent WHERE id = 1;
SET SESSION wsrep_on = ON;
--echo Restarting server 3 with one applier thread having FK and UK checks disabled
--source include/shutdown_mysqld.inc
--let $start_mysqld_params = --wsrep_slave_FK_checks=0 --wsrep_slave_UK_checks=0
--source ../galera/include/start_mysqld.inc
# Stop the applier after writing a row into the child table.
SET GLOBAL DEBUG_DBUG = 'd,sync.wsrep_after_write_row';
# Insert a child row that will be applied on node #3, but should not
# grab table-level X-lock.
--connection node_1
INSERT INTO child VALUES (1, 1);
--connection node_3
SET DEBUG_SYNC = 'now WAIT_FOR sync.wsrep_after_write_row_reached';
# Now that the applier has hit the global sync point wait, reset it
# so that the upcoming insert avoids it.
SET GLOBAL DEBUG_DBUG = '';
# Don't wait for applied insert to commit.
SET wsrep_sync_wait = 0;
SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL signal.wsrep_after_write_row';
# The insert should pass the sync point, as otherwise if the applied insert
# grabs table-level X-lock, they'll both deadlock forever.
INSERT INTO child VALUES (2, 2);
SET DEBUG_SYNC = 'RESET';
--let $assert_select = foreign key constraint fails
--let $assert_count = 0
--let $assert_text = no FK constraint failure
--let $assert_only_after = CURRENT_TEST
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.3.err
--source include/assert_grep.inc
# Child row insert is applied even though there's no parent row.
--echo Server 3
SELECT COUNT(*) AS EXPECT_1 FROM parent;
SELECT COUNT(*) AS EXPECT_2 FROM child;
# Check other nodes have both parent and child rows.
--connection node_1
--echo Server 1
SET wsrep_sync_wait = 15;
SELECT COUNT(*) AS EXPECT_2 FROM parent;
SELECT COUNT(*) AS EXPECT_2 FROM child;
--connection node_2
--echo Server 2
SET wsrep_sync_wait = 15;
SELECT COUNT(*) AS EXPECT_2 FROM parent;
SELECT COUNT(*) AS EXPECT_2 FROM child;
DROP TABLE child;
DROP TABLE parent;
# Restore original auto_increment_offset values.
--source ../galera/include/auto_increment_offset_restore.inc
--source include/galera_end.inc

View File

@@ -18,7 +18,7 @@
--connection node_4
--disable_query_log
--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_1, master_use_gtid=current_pos;
--eval CHANGE MASTER TO master_host='127.0.0.1', master_user='root', MASTER_SSL_VERIFY_SERVER_CERT=0, master_port=$NODE_MYPORT_1, master_use_gtid=current_pos;
--enable_query_log
START SLAVE;
--source include/wait_for_slave_to_start.inc

View File

@@ -9,14 +9,9 @@
--source include/big_test.inc
# Save galera ports
--connection node_1
--source suite/galera/include/galera_base_port.inc
--let $NODE_GALERAPORT_1 = $_NODE_GALERAPORT
--connection node_2
--source suite/galera/include/galera_base_port.inc
--let $NODE_GALERAPORT_2 = $_NODE_GALERAPORT
--let $galera_connection_name = node_3
--let $galera_server_number = 3
--source include/galera_connect.inc
@@ -81,10 +76,10 @@ let $restart_noprint=2;
# Workaround for galera#101
--connection node_1
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0 (.*) is not in state transfer \\(SYNCED\\)");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
--connection node_2
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0 (.*) is not in state transfer \\(SYNCED\\)");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
--connection node_3
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0 (.*) is not in state transfer \\(SYNCED\\)");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");

View File

@@ -10,6 +10,10 @@
--source include/have_debug.inc
--source include/have_debug_sync.inc
# Save galera ports
--source suite/galera/include/galera_base_port.inc
--let $NODE_GALERAPORT_1 = $_NODE_GALERAPORT
--let $galera_connection_name = node_3
--let $galera_server_number = 3
--source include/galera_connect.inc
@@ -22,10 +26,7 @@
--let $node_3=node_3
--source ../galera/include/auto_increment_offset_save.inc
# Save galera ports
--connection node_1
--source suite/galera/include/galera_base_port.inc
--let $NODE_GALERAPORT_1 = $_NODE_GALERAPORT
--let $datadir= `SELECT @@datadir`
--let $innodb_max_dirty_pages_pct = `SELECT @@innodb_max_dirty_pages_pct`
@@ -39,10 +40,6 @@ CREATE TABLE t1 (f1 INTEGER, f2 varchar(1024)) Engine=InnoDB;
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
INSERT INTO t1 (f2) SELECT REPEAT('x', 1024) FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
--connection node_2
--source suite/galera/include/galera_base_port.inc
--let $NODE_GALERAPORT_2 = $_NODE_GALERAPORT
--echo Killing node #3 to free ports for garbd ...
--connection node_3
@@ -122,13 +119,16 @@ let $restart_noprint=2;
--eval SET GLOBAL innodb_max_dirty_pages_pct_lwm = $innodb_max_dirty_pages_pct_lwm
--enable_query_log
# Restore original auto_increment_offset values.
--source ../galera/include/auto_increment_offset_restore.inc
# Workaround for galera#101
--connection node_1
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0 (.*) is not in state transfer \\(SYNCED\\)");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
--connection node_2
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0 (.*) is not in state transfer \\(SYNCED\\)");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
--connection node_3
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0 (.*) is not in state transfer \\(SYNCED\\)");
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");

View File

@@ -44,7 +44,7 @@ SHOW STATUS LIKE 'wsrep_cluster_size';
--connection node_1
--echo --- ignore_server_ids=(12,13)
--disable_query_log
--eval change master to master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_4, master_use_gtid=current_pos, ignore_server_ids=(12,13);
--eval change master to master_host='127.0.0.1', master_user='root', MASTER_SSL_VERIFY_SERVER_CERT=0, master_port=$NODE_MYPORT_4, master_use_gtid=current_pos, ignore_server_ids=(12,13);
--enable_query_log
start slave;
--source include/wait_for_slave_to_start.inc
@@ -55,7 +55,7 @@ select @@gtid_slave_pos;
--connection node_4
--echo --- ignore_server_ids=(22,23)
--disable_query_log
--eval change master to master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_1, master_use_gtid=current_pos, ignore_server_ids=(22,23);
--eval change master to master_host='127.0.0.1', master_user='root', MASTER_SSL_VERIFY_SERVER_CERT=0, master_port=$NODE_MYPORT_1, master_use_gtid=current_pos, ignore_server_ids=(22,23);
--enable_query_log
start slave;
--source include/wait_for_slave_to_start.inc
@@ -216,7 +216,7 @@ set global wsrep_on=ON;
--connection node_1
--echo --- ignore_server_ids=(12,13)
--disable_query_log
--eval change master to master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_6, master_use_gtid=current_pos, ignore_server_ids=(12,13);
--eval change master to master_host='127.0.0.1', master_user='root', MASTER_SSL_VERIFY_SERVER_CERT=0, master_port=$NODE_MYPORT_6, master_use_gtid=current_pos, ignore_server_ids=(12,13);
--enable_query_log
start slave;
--source include/wait_for_slave_to_start.inc
@@ -227,7 +227,7 @@ select @@gtid_slave_pos;
--connection node_4
--echo --- ignore_server_ids=(22,23)
--disable_query_log
--eval change master to master_host='127.0.0.1', master_user='root', master_port=$NODE_MYPORT_3, master_use_gtid=current_pos, ignore_server_ids=(22,23);
--eval change master to master_host='127.0.0.1', master_user='root', MASTER_SSL_VERIFY_SERVER_CERT=0, master_port=$NODE_MYPORT_3, master_use_gtid=current_pos, ignore_server_ids=(22,23);
--enable_query_log
start slave;
--source include/wait_for_slave_to_start.inc

View File

@@ -37,9 +37,6 @@ f1 f2
SET SESSION wsrep_trx_fragment_size = 10000;
START TRANSACTION;
INSERT INTO t1 VALUE (10, 'node1');
SELECT COUNT(*) FROM mysql.wsrep_streaming_log;
COUNT(*)
0
connection node_1a;
INSERT INTO t1 VALUES(15, 'node2');
connection node_1;
@@ -48,6 +45,7 @@ f1 f2
1 node1
5 node2
10 node1
15 node2
INSERT INTO t1 VALUES(15, 'node1');
ERROR 23000: Duplicate entry '15' for key 'PRIMARY'
COMMIT;

View File

@@ -61,7 +61,6 @@ SET SESSION wsrep_trx_fragment_size = 10000;
START TRANSACTION;
INSERT INTO t1 VALUE (10, 'node1');
SELECT COUNT(*) FROM mysql.wsrep_streaming_log;
--connection node_1a
INSERT INTO t1 VALUES(15, 'node2');

View File

@@ -2,7 +2,7 @@ SET @save_pct= @@GLOBAL.innodb_max_dirty_pages_pct;
SET @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;
CREATE TABLE t(a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0;
CREATE TABLE t(a INT) ENGINE=InnoDB STATS_PERSISTENT=0;
connect prevent_purge,localhost,root;
START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default;
@@ -11,20 +11,10 @@ SET GLOBAL innodb_max_dirty_pages_pct=90.0;
SELECT variable_value INTO @log_writes FROM information_schema.global_status
WHERE variable_name='innodb_log_writes';
BEGIN;
INSERT INTO t SELECT * FROM seq_1_to_500;
INSERT INTO t SELECT * FROM seq_501_to_1000;
INSERT INTO t SELECT * FROM seq_1001_to_1500;
INSERT INTO t SELECT * FROM seq_1501_to_2000;
INSERT INTO t SELECT * FROM seq_2001_to_2500;
INSERT INTO t SELECT * FROM seq_2501_to_3000;
INSERT INTO t SELECT * FROM seq_3001_to_3500;
INSERT INTO t SELECT * FROM seq_3501_to_4000;
INSERT INTO t SELECT * FROM seq_4001_to_4500;
INSERT INTO t SELECT * FROM seq_4501_to_5000;
ROLLBACK;
SELECT if(variable_value-@log_writes<10,'ok',variable_value-@log_writes)
SELECT if(variable_value-@log_writes<500,'ok',variable_value-@log_writes)
FROM information_schema.global_status WHERE variable_name='innodb_log_writes';
if(variable_value-@log_writes<10,'ok',variable_value-@log_writes)
if(variable_value-@log_writes<500,'ok',variable_value-@log_writes)
ok
disconnect prevent_purge;
SELECT variable_value>0 FROM information_schema.global_status

View File

@@ -7,7 +7,7 @@ SET @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;
CREATE TABLE t(a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=0;
CREATE TABLE t(a INT) ENGINE=InnoDB STATS_PERSISTENT=0;
--connect (prevent_purge,localhost,root)
START TRANSACTION WITH CONSISTENT SNAPSHOT;
--connection default
@@ -27,19 +27,16 @@ WHERE variable_name='innodb_log_writes';
--enable_cursor_protocol
BEGIN;
INSERT INTO t SELECT * FROM seq_1_to_500;
INSERT INTO t SELECT * FROM seq_501_to_1000;
INSERT INTO t SELECT * FROM seq_1001_to_1500;
INSERT INTO t SELECT * FROM seq_1501_to_2000;
INSERT INTO t SELECT * FROM seq_2001_to_2500;
INSERT INTO t SELECT * FROM seq_2501_to_3000;
INSERT INTO t SELECT * FROM seq_3001_to_3500;
INSERT INTO t SELECT * FROM seq_3501_to_4000;
INSERT INTO t SELECT * FROM seq_4001_to_4500;
INSERT INTO t SELECT * FROM seq_4501_to_5000;
--disable_query_log
let $N=500;
while ($N) {
INSERT INTO t SELECT * FROM seq_1_to_10;
dec $N;
}
--enable_query_log
ROLLBACK;
SELECT if(variable_value-@log_writes<10,'ok',variable_value-@log_writes)
SELECT if(variable_value-@log_writes<500,'ok',variable_value-@log_writes)
FROM information_schema.global_status WHERE variable_name='innodb_log_writes';
--disconnect prevent_purge

View File

@@ -3429,6 +3429,20 @@ drop table t;
create table t (a int) with system versioning partition by system_time partitions 3;
ERROR HY000: Maybe missing parameters: no rotation condition for multiple HISTORY partitions.
#
# MDEV-36115 InnoDB: assertion: node->pcur->rel_pos == BTR_PCUR_ON
# in row_update_for_mysql
#
create table t (a int key) engine=innodb
with system versioning
partition by key() partitions 3;
start transaction;
insert into t values (1),(2),(3),(4),(5),(6),(7),(8);
set timestamp=+1;
delete from t;
insert into t values (1),(2);
DELETE from t;
drop table t;
#
# End of 10.5 tests
#
#

View File

@@ -2675,6 +2675,22 @@ drop table t;
--error WARN_VERS_PARAMETERS
create table t (a int) with system versioning partition by system_time partitions 3;
--echo #
--echo # MDEV-36115 InnoDB: assertion: node->pcur->rel_pos == BTR_PCUR_ON
--echo # in row_update_for_mysql
--echo #
create table t (a int key) engine=innodb
with system versioning
partition by key() partitions 3;
start transaction;
insert into t values (1),(2),(3),(4),(5),(6),(7),(8);
set timestamp=+1;
delete from t;
insert into t values (1),(2);
DELETE from t;
drop table t;
--echo #
--echo # End of 10.5 tests
--echo #

View File

@@ -4406,31 +4406,19 @@ THR_LOCK_DATA **ha_partition::store_lock(THD *thd,
DBUG_ENTER("ha_partition::store_lock");
DBUG_ASSERT(thd == current_thd);
/*
This can be called from get_lock_data() in mysql_lock_abort_for_thread(),
even when thd != table->in_use. In that case don't use partition pruning,
but use all partitions instead to avoid using another threads structures.
*/
if (thd != table->in_use)
{
for (i= 0; i < m_tot_parts; i++)
to= m_file[i]->store_lock(thd, to, lock_type);
}
else
{
MY_BITMAP *used_partitions= lock_type == TL_UNLOCK ||
lock_type == TL_IGNORE ?
&m_locked_partitions :
&m_part_info->lock_partitions;
MY_BITMAP *used_partitions= lock_type == TL_UNLOCK ||
lock_type == TL_IGNORE ?
&m_locked_partitions :
&m_part_info->lock_partitions;
for (i= bitmap_get_first_set(used_partitions);
i < m_tot_parts;
i= bitmap_get_next_set(used_partitions, i))
{
DBUG_PRINT("info", ("store lock %u iteration", i));
to= m_file[i]->store_lock(thd, to, lock_type);
}
for (i= bitmap_get_first_set(used_partitions);
i < m_tot_parts;
i= bitmap_get_next_set(used_partitions, i))
{
DBUG_PRINT("info", ("store lock %u iteration", i));
to= m_file[i]->store_lock(thd, to, lock_type);
}
DBUG_RETURN(to);
}
@@ -4757,7 +4745,6 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data)
}
m_last_part= new_part_id;
start_part_bulk_insert(thd, new_part_id);
DBUG_ASSERT(!m_file[new_part_id]->row_logging);
if (new_part_id == old_part_id)
@@ -4792,6 +4779,8 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data)
goto exit;
}
m_last_part= new_part_id;
exit:
/*
if updating an auto_increment column, update

View File

@@ -1784,6 +1784,16 @@ binlog_flush_cache(THD *thd, binlog_cache_mngr *cache_mngr,
if (using_trx && thd->binlog_flush_pending_rows_event(TRUE, TRUE))
DBUG_RETURN(1);
#ifdef WITH_WSREP
/* Wsrep transaction was BF aborted but it must replay because certification
succeeded. The transaction must not be written into binlog yet, it will
be done during commit after the replay. */
if (WSREP(thd) && wsrep_must_replay(thd))
{
DBUG_RETURN(0);
}
#endif /* WITH_WSREP */
/*
Doing a commit or a rollback including non-transactional tables,
i.e., ending a transaction where we might write the transaction
@@ -8282,7 +8292,12 @@ MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd,
{
DBUG_RETURN(0);
}
else if (!(thd->variables.option_bits & OPTION_BIN_LOG))
if (!(thd->variables.option_bits & OPTION_BIN_LOG)
#ifdef WITH_WSREP
&& !WSREP(thd)
#endif
)
{
cache_mngr->need_unlog= false;
DBUG_RETURN(0);
@@ -9191,6 +9206,13 @@ MYSQL_BIN_LOG::write_transaction_or_stmt(group_commit_entry *entry,
bool has_xid= entry->end_event->get_type_code() == XID_EVENT;
DBUG_ENTER("MYSQL_BIN_LOG::write_transaction_or_stmt");
#ifdef WITH_WSREP
if (WSREP(entry->thd) &&
!(entry->thd->variables.option_bits & OPTION_BIN_LOG))
{
DBUG_RETURN(0);
}
#endif /* WITH_WSREP */
/*
An error in the trx_cache will truncate the cache to the last good

View File

@@ -45,7 +45,6 @@ extern int upgrade_config_file(const char *myini_path);
"OPTIONS:"
static char mysqld_path[MAX_PATH];
static char mysqladmin_path[MAX_PATH];
static char mysqlupgrade_path[MAX_PATH];
static char defaults_file_param[MAX_PATH + 16]; /*--defaults-file=<path> */
@@ -302,13 +301,29 @@ void stop_mysqld_service()
our --skip-grant-tables do not work anymore after mysql_upgrade
that does "flush privileges". Instead, the shutdown event is set.
*/
#define OPEN_EVENT_RETRY_SLEEP_MS 100
#define OPEN_EVENT_MAX_RETRIES 50
void initiate_mysqld_shutdown()
{
char event_name[32];
DWORD pid= GetProcessId(mysqld_process);
sprintf_s(event_name, "MySQLShutdown%d", pid);
HANDLE shutdown_handle= OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name);
if(!shutdown_handle)
HANDLE shutdown_handle;
for (int i= 0;; i++)
{
shutdown_handle= OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name);
if(shutdown_handle != nullptr || i == OPEN_EVENT_MAX_RETRIES)
break;
if (WaitForSingleObject(mysqld_process, OPEN_EVENT_RETRY_SLEEP_MS) !=
WAIT_TIMEOUT)
{
die("server process exited before shutdown event was created");
break;
}
}
if (!shutdown_handle)
{
die("OpenEvent() failed for shutdown event");
}
@@ -403,6 +418,26 @@ static void change_service_config()
}
/**
Waits until starting server can be connected to, via given named pipe, with timeout
Dies if either server process exited meanwhile, or when timeout was exceeded.
*/
static void wait_for_server_startup(HANDLE process, const char *named_pipe, DWORD timeout_sec)
{
unsigned long long end_time= GetTickCount64() + 1000ULL*timeout_sec;
for (;;)
{
if (WaitNamedPipe(named_pipe, 0))
return;
if (GetTickCount64() >= end_time)
die("Server did not startup after %lu seconds", timeout_sec);
if (WaitForSingleObject(process, 100) != WAIT_TIMEOUT)
die("Server did not start");
}
}
int main(int argc, char **argv)
{
@@ -419,8 +454,9 @@ int main(int argc, char **argv)
/*
Get full path to mysqld, we need it when changing service configuration.
Assume installation layout, i.e mysqld.exe, mysqladmin.exe, mysqlupgrade.exe
and mysql_upgrade_service.exe are in the same directory.
Assume mysqld.exe in the same directory as this program.
mysql_upgrade.exe is either in the same directory, or pointed to by
MARIADB_UPGRADE_EXE environment variable (in case of MTR running it)
*/
GetModuleFileName(NULL, bindir, FN_REFLEN);
p= strrchr(bindir, FN_LIBCHAR);
@@ -429,15 +465,19 @@ int main(int argc, char **argv)
*p= 0;
}
sprintf_s(mysqld_path, "%s\\mysqld.exe", bindir);
sprintf_s(mysqladmin_path, "%s\\mysqladmin.exe", bindir);
sprintf_s(mysqlupgrade_path, "%s\\mysql_upgrade.exe", bindir);
char *paths[]= {mysqld_path, mysqladmin_path, mysqlupgrade_path};
for(int i= 0; i< 3;i++)
if (access(mysqld_path, 0))
die("File %s does not exist", mysqld_path);
if (access(mysqlupgrade_path, 0))
{
if(GetFileAttributes(paths[i]) == INVALID_FILE_ATTRIBUTES)
die("File %s does not exist", paths[i]);
/* Try to get path from environment variable, set by MTR */
char *alt_mysqlupgrade_path= getenv("MARIADB_UPGRADE_EXE");
if (alt_mysqlupgrade_path)
sprintf_s(mysqlupgrade_path, "%s", alt_mysqlupgrade_path);
}
if (access(mysqlupgrade_path, 0))
die("File %s does not exist", mysqld_path);
/*
Messages written on stdout should not be buffered, GUI upgrade program
@@ -482,6 +522,10 @@ int main(int argc, char **argv)
DWORD start_duration_ms = 0;
char pipe_name[64];
snprintf(pipe_name, sizeof(pipe_name),
"\\\\.\\pipe\\mysql_upgrade_service_%lu", GetCurrentProcessId());
if (do_start_stop_server)
{
/* Start/stop server with --loose-innodb-fast-shutdown=1 */
@@ -493,37 +537,23 @@ int main(int argc, char **argv)
{
die("Cannot start mysqld.exe process, last error =%u", GetLastError());
}
char pipe_name[64];
snprintf(pipe_name, sizeof(pipe_name), "\\\\.\\pipe\\mysql_upgrade_service_%lu",
GetCurrentProcessId());
for (;;)
wait_for_server_startup(mysqld_process, pipe_name, startup_timeout);
// Server started, shut it down.
initiate_mysqld_shutdown();
if (WaitForSingleObject((HANDLE)mysqld_process, shutdown_timeout * 1000) != WAIT_OBJECT_0)
{
if (WaitForSingleObject(mysqld_process, 0) != WAIT_TIMEOUT)
die("mysqld.exe did not start");
if (WaitNamedPipe(pipe_name, 0))
{
// Server started, shut it down.
initiate_mysqld_shutdown();
if (WaitForSingleObject((HANDLE)mysqld_process, shutdown_timeout * 1000) != WAIT_OBJECT_0)
{
die("Could not shutdown server started with '--innodb-fast-shutdown=0'");
}
DWORD exit_code;
if (!GetExitCodeProcess((HANDLE)mysqld_process, &exit_code))
{
die("Could not get mysqld's exit code");
}
if (exit_code)
{
die("Could not get successfully shutdown mysqld");
}
CloseHandle(mysqld_process);
break;
}
Sleep(500);
start_duration_ms += 500;
die("Could not shutdown server");
}
DWORD exit_code;
if (!GetExitCodeProcess((HANDLE)mysqld_process, &exit_code))
{
die("Could not get server's exit code");
}
if (exit_code)
{
die("Could not get successfully shutdown server (exit code %u)",exit_code);
}
CloseHandle(mysqld_process);
}
log("Phase %d/%d: Fixing server config file%s", ++phase, max_phases,
@@ -550,22 +580,7 @@ int main(int argc, char **argv)
}
log("Phase %d/%d: Waiting for startup to complete",++phase,max_phases);
start_duration_ms= 0;
for(;;)
{
if (WaitForSingleObject(mysqld_process, 0) != WAIT_TIMEOUT)
die("mysqld.exe did not start");
if (run_tool(P_WAIT, mysqladmin_path, "--protocol=pipe", socket_param,
"ping", "--no-beep", NULL) == 0)
{
break;
}
if (start_duration_ms > startup_timeout*1000)
die("Server did not come up in %d seconds",startup_timeout);
Sleep(500);
start_duration_ms+= 500;
}
wait_for_server_startup(mysqld_process, pipe_name, startup_timeout);
log("Phase %d/%d: Running mysql_upgrade",++phase,max_phases);
int upgrade_err= (int) run_tool(P_WAIT, mysqlupgrade_path,

View File

@@ -277,7 +277,7 @@ extern "C" sig_handler handle_fatal_signal(int sig)
my_safe_printf_stderr("Status: %s\n", kreason);
my_safe_printf_stderr("Query (%p): ", thd->query());
my_safe_print_str(thd->query(), MY_MIN(65536U, thd->query_length()));
my_safe_printf_stderr("%s", "Optimizer switch: ");
my_safe_printf_stderr("%s", "\nOptimizer switch: ");
ulonglong optsw= thd->variables.optimizer_switch;
for (uint i= 0; optimizer_switch_names[i+1]; i++, optsw >>= 1)
{

View File

@@ -203,6 +203,21 @@ int wsrep_apply_events(THD* thd,
}
}
if (LOG_EVENT_IS_WRITE_ROW(typ) ||
LOG_EVENT_IS_UPDATE_ROW(typ) ||
LOG_EVENT_IS_DELETE_ROW(typ))
{
Rows_log_event* rle = static_cast<Rows_log_event*>(ev);
if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS))
{
rle->set_flags(Rows_log_event::RELAXED_UNIQUE_CHECKS_F);
}
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS))
{
rle->set_flags(Rows_log_event::NO_FOREIGN_KEY_CHECKS_F);
}
}
/* Use the original server id for logging. */
thd->set_server_id(ev->server_id);
thd->lex->current_select= 0;

View File

@@ -305,6 +305,12 @@ enum wsrep::provider::status Wsrep_client_service::replay()
replayer_service.replay_status(ret);
}
// In Galera we allow only InnoDB sequences, thus
// sequence table updates are in writeset.
// Binlog cache needs reset so that binlog_close
// does not write cache to binlog file yet.
binlog_reset_cache(m_thd);
replayer_thd->main_security_ctx = old_ctx;
delete replayer_thd;
DBUG_RETURN(ret);

View File

@@ -611,7 +611,7 @@ int Wsrep_applier_service::apply_write_set(const wsrep::ws_meta& ws_meta,
int ret= apply_events(thd, m_rli, data, err, true);
thd->close_temporary_tables();
if (!ret && !(ws_meta.flags() & wsrep::provider::flag::commit))
if (!ret && !wsrep::commits_transaction(ws_meta.flags()))
{
thd->wsrep_cs().fragment_applied(ws_meta.seqno());
}
@@ -779,7 +779,7 @@ int Wsrep_replayer_service::apply_write_set(const wsrep::ws_meta& ws_meta,
}
ret= ret || apply_events(thd, m_rli, data, err, true);
thd->close_temporary_tables();
if (!ret && !(ws_meta.flags() & wsrep::provider::flag::commit))
if (!ret && !wsrep::commits_transaction(ws_meta.flags()))
{
thd->wsrep_cs().fragment_applied(ws_meta.seqno());
}

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2008, 2024, Codership Oy <http://www.codership.com>
/* Copyright (c) 2008, 2025, Codership Oy <http://www.codership.com>
Copyright (c) 2020, 2025, MariaDB
This program is free software; you can redistribute it and/or modify
@@ -2527,7 +2527,7 @@ bool wsrep_should_replicate_ddl(THD* thd, const handlerton *hton)
break;
case DB_TYPE_ARIA:
if (wsrep_check_mode(WSREP_MODE_REPLICATE_ARIA))
return true;
return true;
break;
case DB_TYPE_PARTITION_DB:
/* In most cases this means we could not find out
@@ -2828,6 +2828,7 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table,
DBUG_ASSERT(wsrep_OSU_method_get(thd) == WSREP_OSU_TOI);
WSREP_DEBUG("TOI Begin: %s", wsrep_thd_query(thd));
DEBUG_SYNC(thd, "wsrep_before_toi_begin");
if (wsrep_can_run_in_toi(thd, db, table, table_list, create_info) == false)
{
@@ -3068,12 +3069,13 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
const wsrep::key_array *fk_tables,
const HA_CREATE_INFO *create_info)
{
DEBUG_SYNC(thd, "wsrep_kill_thd_before_enter_toi");
mysql_mutex_lock(&thd->LOCK_thd_kill);
const killed_state killed = thd->killed;
mysql_mutex_unlock(&thd->LOCK_thd_kill);
if (killed)
{
DBUG_ASSERT(FALSE);
/* The thread may have been killed as a result of memory pressure. */
return -1;
}

View File

@@ -469,7 +469,7 @@ bool wsrep_sst_received (THD* thd,
if (WSREP_ON)
{
int const rcode(seqno < 0 ? seqno : 0);
error= wsrep_sst_complete(thd,rcode, sst_gtid);
error= wsrep_sst_complete(thd, rcode, sst_gtid);
}
return error;

View File

@@ -600,20 +600,67 @@ static void buf_dblwr_check_block(const buf_page_t *bpage) noexcept
}
#endif /* UNIV_DEBUG */
ATTRIBUTE_COLD void buf_dblwr_t::print_info() const noexcept
{
mysql_mutex_assert_owner(&mutex);
const slot *flush_slot= active_slot == &slots[0] ? &slots[1] : &slots[0];
sql_print_information("InnoDB: Double Write State\n"
"-------------------\n"
"Batch running : %s\n"
"Active Slot - first_free: %zu reserved: %zu\n"
"Flush Slot - first_free: %zu reserved: %zu\n"
"-------------------",
(batch_running ? "true" : "false"),
active_slot->first_free, active_slot->reserved,
flush_slot->first_free, flush_slot->reserved);
}
bool buf_dblwr_t::flush_buffered_writes(const ulint size) noexcept
{
mysql_mutex_assert_owner(&mutex);
ut_ad(size == block_size);
for (;;)
const size_t max_count= 60 * 60;
const size_t first_log_count= 30;
const size_t fatal_threshold=
static_cast<size_t>(srv_fatal_semaphore_wait_threshold);
size_t log_count= first_log_count;
for (ulong count= 0;;)
{
if (!active_slot->first_free)
return false;
if (!batch_running)
break;
my_cond_wait(&cond, &mutex.m_mutex);
}
timespec abstime;
set_timespec(abstime, 1);
my_cond_timedwait(&cond, &mutex.m_mutex, &abstime);
if (count > fatal_threshold)
{
buf_pool.print_flush_info();
print_info();
ib::fatal() << "InnoDB: Long wait (" << count
<< " seconds) for double-write buffer flush.";
}
else if (++count < first_log_count && !(count % 5))
{
sql_print_information("InnoDB: Long wait (%zu seconds) for double-write"
" buffer flush.", count);
buf_pool.print_flush_info();
print_info();
}
else if (!(count % log_count))
{
sql_print_warning("InnoDB: Long wait (%zu seconds) for double-write"
" buffer flush.", count);
buf_pool.print_flush_info();
print_info();
log_count= log_count >= max_count ? max_count : log_count * 2;
}
}
ut_ad(active_slot->reserved == active_slot->first_free);
ut_ad(!flushing_buffered_writes);

View File

@@ -1335,7 +1335,10 @@ static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n,
break;
}
if (neighbors && space->is_rotational())
if (neighbors && space->is_rotational() &&
/* Skip neighbourhood flush from LRU list if we haven't yet reached
half of the free page target. */
UT_LIST_GET_LEN(buf_pool.free) * 2 >= free_limit)
n->flushed+= buf_flush_try_neighbors(space, page_id, bpage,
neighbors == 1,
n->flushed, max);
@@ -1725,8 +1728,16 @@ static ulint buf_flush_LRU(ulint max_n) noexcept
buf_do_LRU_batch(max_n, &n);
ulint pages= n.flushed;
ulint evicted= n.evicted;
if (n.evicted)
/* If we have exhausted flush quota, it is likely we exited before
generating enough free pages. Call once more with 0 flush to generate
free pages immediately as required. */
if (pages >= max_n)
buf_do_LRU_batch(0, &n);
evicted+= n.evicted;
if (evicted)
{
buf_pool.try_LRU_scan= true;
pthread_cond_broadcast(&buf_pool.done_free);
@@ -2463,6 +2474,11 @@ static void buf_flush_page_cleaner() noexcept
DBUG_EXECUTE_IF("ib_page_cleaner_sleep",
{
std::this_thread::sleep_for(std::chrono::seconds(1));
/* Cover the logging code in debug mode. */
buf_pool.print_flush_info();
buf_dblwr.lock();
buf_dblwr.print_info();
buf_dblwr.unlock();
});
lsn_limit= buf_flush_sync_lsn;
@@ -2671,6 +2687,10 @@ static void buf_flush_page_cleaner() noexcept
n= srv_max_io_capacity;
n= n >= n_flushed ? n - n_flushed : 0;
/* It is critical to generate free pages to keep the system alive. Make
sure we are not hindered by dirty pages in LRU tail. */
n= std::max<ulint>(n, std::min<ulint>(srv_max_io_capacity,
buf_pool.LRU_scan_depth));
goto LRU_flush;
}
@@ -2712,9 +2732,8 @@ ATTRIBUTE_COLD void buf_pool_t::LRU_warn() noexcept
{
LRU_warned= true;
sql_print_warning("InnoDB: Could not free any blocks in the buffer pool!"
" %zu blocks are in use and %zu free."
" Consider increasing innodb_buffer_pool_size.",
UT_LIST_GET_LEN(LRU), UT_LIST_GET_LEN(free));
" Consider increasing innodb_buffer_pool_size.");
print_flush_info();
}
}
@@ -2799,6 +2818,53 @@ void buf_flush_sync() noexcept
thd_wait_end(nullptr);
}
ATTRIBUTE_COLD void buf_pool_t::print_flush_info() const noexcept
{
/* We do dirty read of UT_LIST count variable. */
size_t lru_size= UT_LIST_GET_LEN(LRU);
size_t dirty_size= UT_LIST_GET_LEN(flush_list);
size_t free_size= UT_LIST_GET_LEN(free);
size_t dirty_pct= lru_size ? dirty_size * 100 / (lru_size + free_size) : 0;
sql_print_information("InnoDB: Buffer Pool pages\n"
"-------------------\n"
"LRU Pages : %zu\n"
"Free Pages : %zu\n"
"Dirty Pages: %zu : %zu%%\n"
"-------------------",
lru_size, free_size, dirty_size, dirty_pct);
lsn_t lsn= log_sys.get_lsn();
lsn_t clsn= log_sys.last_checkpoint_lsn;
sql_print_information("InnoDB: LSN flush parameters\n"
"-------------------\n"
"System LSN : %" PRIu64 "\n"
"Checkpoint LSN: %" PRIu64 "\n"
"Flush ASync LSN: %" PRIu64 "\n"
"Flush Sync LSN: %" PRIu64 "\n"
"-------------------",
lsn, clsn, buf_flush_async_lsn.load(), buf_flush_sync_lsn.load());
lsn_t age= lsn - clsn;
lsn_t age_pct= log_sys.max_checkpoint_age
? age * 100 / log_sys.max_checkpoint_age : 0;
sql_print_information("InnoDB: LSN age parameters\n"
"-------------------\n"
"Current Age : %" PRIu64 " : %" PRIu64 "%%\n"
"Max Age(Async): %" PRIu64 "\n"
"Max Age(Sync) : %" PRIu64 "\n"
"Capacity : %" PRIu64 "\n"
"-------------------",
age, age_pct, log_sys.max_modified_age_async, log_sys.max_checkpoint_age,
log_sys.log_capacity);
sql_print_information("InnoDB: Pending IO count\n"
"-------------------\n"
"Pending Read : %zu\n"
"Pending Write: %zu\n"
"-------------------",
os_aio_pending_reads_approx(), os_aio_pending_writes_approx());
}
#ifdef UNIV_DEBUG
/** Functor to validate the flush list. */
struct Check {

View File

@@ -44,6 +44,7 @@ Created 1/8/1996 Heikki Tuuri
#include "btr0cur.h"
#include "btr0sea.h"
#include "buf0buf.h"
#include "buf0flu.h"
#include "data0type.h"
#include "dict0boot.h"
#include "dict0load.h"
@@ -967,7 +968,10 @@ void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line)) noexc
const ulong threshold= srv_fatal_semaphore_wait_threshold;
if (waited >= threshold)
{
buf_pool.print_flush_info();
ib::fatal() << fatal_msg;
}
if (waited > threshold / 4)
ib::warn() << "A long wait (" << waited

View File

@@ -7953,6 +7953,17 @@ set_max_autoinc:
error, m_prebuilt->table->flags, m_user_thd);
#ifdef WITH_WSREP
#ifdef ENABLED_DEBUG_SYNC
DBUG_EXECUTE_IF("sync.wsrep_after_write_row",
{
const char act[]=
"now "
"SIGNAL sync.wsrep_after_write_row_reached "
"WAIT_FOR signal.wsrep_after_write_row";
DBUG_ASSERT(!debug_sync_set_action(m_user_thd, STRING_WITH_LEN(act)));
};);
#endif /* ENABLED_DEBUG_SYNC */
if (!error_result && trx->is_wsrep()
&& !trx->is_bulk_insert()
&& wsrep_thd_is_local(m_user_thd)

View File

@@ -1776,6 +1776,9 @@ public:
/** Issue a warning that we could not free up buffer pool pages. */
ATTRIBUTE_COLD void LRU_warn() noexcept;
/** Print buffer pool flush state information. */
ATTRIBUTE_COLD void print_flush_info() const noexcept;
/** Collect buffer pool metadata.
@param pool_info buffer pool metadata */
void get_info(buf_pool_info_t *pool_info) noexcept;

View File

@@ -185,6 +185,9 @@ public:
my_cond_wait(&cond, &mutex.m_mutex);
mysql_mutex_unlock(&mutex);
}
/** Print double write state information. */
ATTRIBUTE_COLD void print_info() const noexcept;
};
/** The doublewrite buffer */

View File

@@ -1015,6 +1015,8 @@ size_t os_aio_pending_reads() noexcept;
size_t os_aio_pending_reads_approx() noexcept;
/** @return number of pending writes */
size_t os_aio_pending_writes() noexcept;
/** @return approximate number of pending writes */
size_t os_aio_pending_writes_approx() noexcept;
/** Wait until there are no pending asynchronous writes.
@param declare whether the wait will be declared in tpool */

View File

@@ -3330,6 +3330,12 @@ size_t os_aio_pending_writes() noexcept
return pending;
}
/** @return approximate number of pending writes */
size_t os_aio_pending_writes_approx() noexcept
{
return write_slots->pending_io_count();
}
/** Wait until all pending asynchronous reads have completed.
@param declare whether the wait will be declared in tpool */
void os_aio_wait_until_no_pending_reads(bool declare) noexcept

View File

@@ -2750,6 +2750,12 @@ err_exit:
DBUG_EXECUTE_IF("row_ins_row_level", goto row_level_insert;);
#ifdef WITH_WSREP
/* Appliers never execute bulk insert statements directly. */
if (trx->is_wsrep() && !wsrep_thd_is_local_transaction(trx->mysql_thd))
goto row_level_insert;
#endif /* WITH_WSREP */
if (!(flags & BTR_NO_UNDO_LOG_FLAG)
&& page_is_empty(block->page.frame)
&& !entry->is_metadata() && !trx->duplicates
@@ -2779,15 +2785,11 @@ avoid_bulk:
goto row_level_insert;
}
#ifdef WITH_WSREP
if (trx->is_wsrep())
if (trx->is_wsrep() &&
wsrep_append_table_key(trx->mysql_thd, *index->table))
{
if (!wsrep_thd_is_local_transaction(trx->mysql_thd))
goto row_level_insert;
if (wsrep_append_table_key(trx->mysql_thd, *index->table))
{
trx->error_state = DB_ROLLBACK;
goto err_exit;
}
trx->error_state = DB_ROLLBACK;
goto err_exit;
}
#endif /* WITH_WSREP */

View File

@@ -1052,6 +1052,7 @@ void srv_monitor_task(void*)
now -= start;
ulong waited = static_cast<ulong>(now / 1000000);
if (waited >= threshold) {
buf_pool.print_flush_info();
ib::fatal() << dict_sys.fatal_msg;
}

View File

@@ -5,6 +5,7 @@ for child3
MDEV-26345 SELECT MIN on Spider table returns more rows than expected
set spider_same_server_link= 1;
set global spider_same_server_link= 1;
CREATE SERVER srv FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
create table t2 (a int, b int, PRIMARY KEY (a, b));

View File

@@ -2,6 +2,7 @@ for master_1
for child2
for child3
SET spider_same_server_link= on;
SET global spider_same_server_link= on;
CREATE SERVER s FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t (a INT);

View File

@@ -5,6 +5,7 @@ for master_1
for child2
for child3
set spider_same_server_link=1;
set global spider_same_server_link=1;
CREATE SERVER s FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (b INT);

View File

@@ -5,6 +5,7 @@ for master_1
for child2
for child3
set spider_same_server_link=1;
set global spider_same_server_link=1;
CREATE SERVER $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t (a INT);
INSERT INTO t VALUES (23),(48);

View File

@@ -5,6 +5,7 @@ for master_1
for child2
for child3
set spider_same_server_link= 1;
set global spider_same_server_link= 1;
CREATE SERVER srv FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t (c INT) ENGINE=InnoDB;

View File

@@ -5,6 +5,7 @@ for master_1
for child2
for child3
set spider_same_server_link=1;
set global spider_same_server_link=1;
CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);

View File

@@ -3,6 +3,7 @@ for child2
for child3
set @@optimizer_switch="semijoin=off";
set spider_same_server_link= 1;
set global spider_same_server_link=1;
CREATE SERVER srv FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
create table ten(a int primary key);

View File

@@ -5,6 +5,7 @@ for master_1
for child2
for child3
set spider_same_server_link=1;
set global spider_same_server_link=1;
CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t (c BLOB) ENGINE=InnoDB;
CREATE TABLE ts (c BLOB) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';

View File

@@ -5,6 +5,7 @@ for master_1
for child2
for child3
set spider_same_server_link=1;
set global spider_same_server_link=1;
CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t1 ( a bigint(20) NOT NULL, b bigint(20) DEFAULT 0, PRIMARY KEY (a));
CREATE TABLE t2 ( a bigint(20) NOT NULL, b bigint(20) DEFAULT 0, PRIMARY KEY (a)) ENGINE=SPIDER COMMENT='srv "srv", WRAPPER "mysql", TABLE "t1"';

View File

@@ -2,6 +2,7 @@ for master_1
for child2
for child3
set spider_same_server_link= 1;
set global spider_same_server_link= 1;
CREATE SERVER srv FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
create table t2 (c INT KEY,c1 BLOB,c2 TEXT) ENGINE=InnoDB;

View File

@@ -5,6 +5,7 @@ for master_1
for child2
for child3
set spider_same_server_link= 1;
set global spider_same_server_link= 1;
CREATE SERVER srv FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t1 (c6 decimal(6,0)) ENGINE=InnoDB;

View File

@@ -5,6 +5,7 @@ for master_1
for child2
for child3
set spider_same_server_link=1;
set global spider_same_server_link=1;
CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
create table t1 (c1 int);
create table t2 (c2 int);

View File

@@ -11,6 +11,7 @@
--echo
set spider_same_server_link= 1;
set global spider_same_server_link= 1;
evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');

View File

@@ -4,6 +4,7 @@
--enable_result_log
--enable_query_log
SET spider_same_server_link= on;
SET global spider_same_server_link= on;
evalp CREATE SERVER s FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');

View File

@@ -7,6 +7,7 @@
--enable_result_log
--enable_query_log
set spider_same_server_link=1;
set global spider_same_server_link=1;
evalp CREATE SERVER s FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t1 (a INT);

View File

@@ -9,6 +9,7 @@
--enable_query_log
set spider_same_server_link=1;
set global spider_same_server_link=1;
--let $srv=srv_mdev_29502
evalp CREATE SERVER $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');

View File

@@ -8,6 +8,7 @@
--enable_query_log
set spider_same_server_link= 1;
set global spider_same_server_link= 1;
evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');

View File

@@ -7,6 +7,7 @@
--enable_result_log
--enable_query_log
set spider_same_server_link=1;
set global spider_same_server_link=1;
evalp CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t1 (a INT);

View File

@@ -6,6 +6,7 @@
set @@optimizer_switch="semijoin=off";
set spider_same_server_link= 1;
set global spider_same_server_link=1;
evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');

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