624 lines
23 KiB
Plaintext
624 lines
23 KiB
Plaintext
# ==== Purpose ====
|
|
#
|
|
# Check that the logic for re-executing statements using GTID_NEXT
|
|
# works as specified.
|
|
#
|
|
# The following properties are tested when GTID_NEXT is set:
|
|
#
|
|
# - SET GTID_NEXT sets @@SESSION.GTID_OWNED.
|
|
#
|
|
# - COMMIT sets @@GLOBAL.GTID_EXECUTED and clears @@SESSION.GTID_OWNED.
|
|
#
|
|
# - ROLLBACK does not change @@GLOBAL.GTID_EXECUTED, and clears
|
|
# @@SESSION.GTID_OWNED.
|
|
#
|
|
# - ROLLBACK TO SAVEPOINT never clears @@SESSION.GTID_OWNED
|
|
#
|
|
# - When one thread owns a GTID, another session that sets GTID_NEXT
|
|
# to the same GTID will block.
|
|
#
|
|
# - When a thread rolls back, a thread waiting for ownership gains
|
|
# ownership.
|
|
#
|
|
# - When a thread commits, a thread waiting for ownership skips the
|
|
# transaction.
|
|
#
|
|
# ==== Implementation ====
|
|
#
|
|
# We use a table where each row contains a specification of a
|
|
# statement, together with a description of how we expect
|
|
# @@[GLOBAL|SESSION].GTID_[DONE|OWNED] to change when the statement is
|
|
# executed.
|
|
#
|
|
# In the "main loop", we iterate over the rows in the table. For each
|
|
# row, we execute the statement and check that the @@variables are
|
|
# updated as expected.
|
|
#
|
|
# See comment above "CREATE TABLE stmts" for details.
|
|
#
|
|
# ==== References ====
|
|
#
|
|
# Created as part in WL#3584: Global Transaction Identifiers.
|
|
--source include/not_group_replication_plugin.inc
|
|
--source include/not_valgrind.inc
|
|
--source include/have_debug.inc
|
|
--let $rpl_extra_connections_per_server= 3
|
|
--let $rpl_gtid_utils= 1
|
|
--source include/master-slave.inc
|
|
|
|
--echo #### Initialize ####
|
|
|
|
CREATE table t (a INT PRIMARY KEY) ENGINE = InnoDB;
|
|
INSERT INTO t VALUES (1);
|
|
|
|
--echo #### Specify test cases ####
|
|
|
|
# This table contains specifications of all tests we are going to
|
|
# perform. It contains the connection to execute in, the statement to
|
|
# execute, and the expected outcome in terms of
|
|
# @@[GLOBAL|SESSION].GTID_[DONE|OWNED].
|
|
#
|
|
# Columns:
|
|
# id
|
|
# autoinc PK. This is used only to make it easier to map lines in
|
|
# the result file to what is being tested.
|
|
#
|
|
# connection
|
|
# A number identifying the connection to use.
|
|
#
|
|
# stmt_type
|
|
# Code specifying what type of statement to execute. Can be one of the
|
|
# following:
|
|
# <SIDNO>:<GNO>
|
|
# Execute the statement SET GTID_NEXT="SID:GNO".
|
|
# We don't want to write out full UUIDs in the specification,
|
|
# because they are too long and unreadable. Instead, we use
|
|
# two-digit integers as abbreviations. For instance, 37:1 is an
|
|
# abbreviation for 37373737-3737-3737-3737-373737373737:1
|
|
# (cf. the functions NUMBER_TO_UUID and UUID_TO_NUMBER defined
|
|
# in include/gtid_utils.inc)
|
|
# CREATE, INSERT, BEGIN, COMMIT, ROLLBACK
|
|
# Execute the given statement.
|
|
# CREATE-NODROP
|
|
# Like CREATE, this executes a CREATE TABLE, but unlike CREATE,
|
|
# the statement is expected to be skipped, so we do not have to
|
|
# match the statement by a DROP TABLE at the cleanup stage.
|
|
# SAVEPOINT <N>
|
|
# Execute SAVEPOINT SP_<N>
|
|
# ROLLBACK <N>
|
|
# Execute ROLLBACK TO SAVEPOINT SP_<N>
|
|
# send X
|
|
# Asynchronously send statement X (X is one of the
|
|
# specifications above); do not wait for the result.
|
|
# reap
|
|
# Reap (wait for the result of) last query sent on the
|
|
# connection.
|
|
# running
|
|
# Do nothing; just assert that the last query sent by 'send' is
|
|
# still running.
|
|
#
|
|
# gtid_executed
|
|
# Specifies how @@GLOBAL.GTID_EXECUTE is expected to change after the
|
|
# statement. This has the form of a gtid_set containing the gtids
|
|
# that were added by the statement. If the gtid_set begins with
|
|
# '~', the gtids are expected to be removed instead. UUIDs are
|
|
# abbreviated as in stmt_type (see above).
|
|
#
|
|
# session_gtid_owned, global_gtid_owned
|
|
# Specifies how and @@[SESSION|GLOBAL].GTID_OWNED are expected to change
|
|
# after the statement. These have the same form as gtid_executed
|
|
# (see above).
|
|
#
|
|
# error
|
|
# Expected errno for the statement, or 0 if the statement is
|
|
# expected to succeed.
|
|
CREATE TABLE stmts (
|
|
id INT PRIMARY KEY NOT NULL,
|
|
connection INT NOT NULL,
|
|
stmt_type TEXT(100) NOT NULL,
|
|
gtid_executed TEXT(10000) NOT NULL,
|
|
session_gtid_owned TEXT(10000) NOT NULL,
|
|
global_gtid_owned TEXT(10000) NOT NULL,
|
|
error INT NOT NULL)
|
|
ENGINE = InnoDB;
|
|
|
|
eval INSERT INTO stmts VALUES
|
|
# ID CON STATEMENT_TYPE G.EXECUTED, S.OWNED G.OWNED ERROR
|
|
# DML statements
|
|
(1000, 1, '1:1', '', '1:1', '1:1', 0)
|
|
,(1001, 1, 'AUTOCOMMIT=1', '', '', '', 0)
|
|
,(1002, 1, 'INSERT', '1:1', '~1:1', '~1:1', 0)
|
|
,(1003, 1, '1:3', '', '1:3', '1:3', 0)
|
|
,(1004, 1, 'INSERT', '1:3', '~1:3', '~1:3', 0)
|
|
# skipped DML statements
|
|
,(1010, 1, '1:3', '', '', '', 0)
|
|
,(1011, 1, 'INSERT', '', '', '', 0)
|
|
,(1012, 1, '1:1', '', '', '', 0)
|
|
,(1013, 1, 'INSERT', '', '', '', 0)
|
|
# DDL statements
|
|
,(1020, 1, '2:3', '', '2:3', '2:3', 0)
|
|
,(1021, 1, 'CREATE', '2:3', '~2:3', '~2:3', 0)
|
|
,(1022, 1, '2:4', '', '2:4', '2:4', 0)
|
|
,(1023, 1, 'CREATE', '2:4', '~2:4', '~2:4', 0)
|
|
# skipped DDL statements
|
|
,(1030, 1, '2:3', '', '', '', 0)
|
|
,(1031, 1, 'CREATE-NODROP', '', '', '', 0)
|
|
,(1032, 1, '2:4', '', '', '', 0)
|
|
,(1033, 1, 'CREATE-NODROP', '', '', '', 0)
|
|
# simple transaction
|
|
,(1040, 1, '4:1', '', '4:1', '4:1', 0)
|
|
,(1041, 1, 'BEGIN', '', '', '', 0)
|
|
,(1042, 1, 'INSERT', '', '', '', 0)
|
|
,(1043, 1, 'INSERT', '', '', '', 0)
|
|
,(1044, 1, 'COMMIT', '4:1', '~4:1', '~4:1', 0)
|
|
# skipped simple transaction
|
|
,(1050, 1, '4:1', '', '', '', 0)
|
|
,(1051, 1, 'BEGIN', '', '', '', 0)
|
|
,(1052, 1, 'INSERT', '', '', '', 0)
|
|
,(1053, 1, 'INSERT', '', '', '', 0)
|
|
,(1054, 1, 'COMMIT', '', '', '', 0)
|
|
# rollback transaction
|
|
,(1060, 1, '6:1', '', '6:1', '6:1', 0)
|
|
,(1061, 1, 'BEGIN', '', '', '', 0)
|
|
,(1062, 1, 'INSERT', '', '', '', 0)
|
|
,(1063, 1, 'INSERT', '', '', '', 0)
|
|
,(1064, 1, 'ROLLBACK', '', '~6:1', '~6:1', 0)
|
|
# rollback to savepoint, then rollback
|
|
,(1070, 1, '6:1', '', '6:1', '6:1', 0)
|
|
,(1071, 1, 'BEGIN', '', '', '', 0)
|
|
,(1072, 1, 'SAVEPOINT 1', '', '', '', 0)
|
|
,(1073, 1, 'SAVEPOINT 2', '', '', '', 0)
|
|
,(1074, 1, 'INSERT', '', '', '', 0)
|
|
,(1075, 1, 'INSERT', '', '', '', 0)
|
|
,(1076, 1, 'ROLLBACK 2', '', '', '', 0)
|
|
,(1077, 1, 'SAVEPOINT 3', '', '', '', 0)
|
|
,(1078, 1, 'INSERT', '', '', '', 0)
|
|
,(1079, 1, 'SAVEPOINT 4','', '', '', 0)
|
|
,(1080, 1, 'ROLLBACK 3', '', '', '', 0)
|
|
,(1081, 1, 'INSERT', '', '', '', 0)
|
|
,(1082, 1, 'SAVEPOINT 2', '', '', '', 0)
|
|
,(1083, 1, 'ROLLBACK 2', '', '', '', 0)
|
|
,(1084, 1, 'ROLLBACK 1', '', '', '', 0)
|
|
,(1085, 1, 'ROLLBACK', '', '~6:1', '~6:1', 0)
|
|
# empty group
|
|
,(1090, 1, '9:1', '', '9:1', '9:1', 0)
|
|
,(1091, 1, 'COMMIT', '9:1', '~9:1', '~9:1', 0)
|
|
# skipped empty group
|
|
,(1100, 1, '9:1', '', '', '', 0)
|
|
,(1101, 1, 'COMMIT', '', '', '', 0)
|
|
# rollback 'empty' group
|
|
,(1110, 1, '11:1', '', '11:1', '11:1', 0)
|
|
,(1111, 1, 'ROLLBACK', '', '~11:1', '~11:1', 0)
|
|
# concurrent group: committed and skipped
|
|
,(1120, 1, '12:1', '', '12:1', '12:1', 0)
|
|
,(1121, 2, 'send 12:1', '', '', '', 0)
|
|
,(1122, 1, 'BEGIN', '', '', '', 0)
|
|
,(1123, 1, 'INSERT', '', '', '', 0)
|
|
,(1124, 2, 'running', '', '', '', 0)
|
|
,(1125, 1, 'COMMIT', '12:1', '~12:1', '~12:1', 0)
|
|
,(1126, 2, 'reap', '12:1', '', '~12:1', 0)
|
|
# concurrent group: rolled back, other thread takes over
|
|
,(1130, 1, '13:1', '', '13:1', '13:1', 0)
|
|
,(1131, 2, 'send 13:1', '', '', '', 0)
|
|
,(1132, 1, 'BEGIN', '', '', '', 0)
|
|
,(1133, 1, 'INSERT', '', '', '', 0)
|
|
,(1134, 2, 'running', '', '', '', 0)
|
|
,(1135, 1, 'ROLLBACK', '', '~13:1', '', 0)
|
|
,(1136, 2, 'reap', '', '13:1', '', 0)
|
|
,(1137, 2, 'BEGIN', '', '', '', 0)
|
|
,(1138, 2, 'INSERT', '', '', '', 0)
|
|
,(1139, 2, 'COMMIT', '13:1', '~13:1', '~13:1', 0)
|
|
# concurrent group: rolled back, ownership transferred from 1->2->3->1
|
|
,(1140, 1, '14:1', '', '14:1', '14:1', 0)
|
|
,(1141, 2, 'send 14:1', '', '', '', 0)
|
|
,(1142, 1, 'BEGIN', '', '', '', 0)
|
|
,(1143, 1, 'INSERT', '', '', '', 0)
|
|
,(1144, 2, 'running', '', '', '', 0)
|
|
,(1145, 1, 'ROLLBACK', '', '~14:1', '', 0)
|
|
,(1146, 2, 'reap', '', '14:1', '', 0)
|
|
,(1147, 2, 'BEGIN', '', '', '', 0)
|
|
,(1148, 2, 'INSERT', '', '', '', 0)
|
|
,(1149, 3, 'send 14:1', '', '', '', 0)
|
|
,(1150, 3, 'running', '', '', '', 0)
|
|
,(1151, 2, 'ROLLBACK', '', '~14:1', '', 0)
|
|
,(1152, 3, 'reap', '', '14:1', '', 0)
|
|
,(1153, 1, 'send 14:1', '', '', '', 0)
|
|
,(1154, 3, 'BEGIN', '', '', '', 0)
|
|
,(1155, 3, 'INSERT', '', '', '', 0)
|
|
,(1156, 1, 'running', '', '', '', 0)
|
|
,(1157, 3, 'ROLLBACK', '', '~14:1', '', 0)
|
|
,(1158, 1, 'reap', '', '14:1', '', 0)
|
|
,(1159, 1, 'BEGIN', '', '', '', 0)
|
|
,(1160, 1, 'INSERT', '', '', '', 0)
|
|
,(1161, 1, 'COMMIT', '14:1', '~14:1', '~14:1', 0)
|
|
# concurrent group and rollback to savepoint
|
|
,(1170, 1, '17:1', '', '17:1', '17:1', 0)
|
|
,(1171, 2, 'send 17:1', '', '', '', 0)
|
|
,(1172, 1, 'BEGIN', '', '', '', 0)
|
|
,(1173, 1, 'SAVEPOINT 1', '', '', '', 0)
|
|
,(1174, 1, 'INSERT', '', '', '', 0)
|
|
,(1175, 1, 'ROLLBACK 1', '', '', '', 0)
|
|
,(1176, 1, 'INSERT', '', '', '', 0)
|
|
,(1177, 2, 'running', '', '', '', 0)
|
|
,(1178, 1, 'ROLLBACK', '', '~17:1', '', 0)
|
|
,(1179, 2, 'reap', '', '17:1', '', 0)
|
|
,(1180, 2, 'BEGIN', '', '', '', 0)
|
|
,(1181, 2, 'INSERT', '', '', '', 0)
|
|
,(1182, 2, 'COMMIT', '17:1', '~17:1', '~17:1', 0)
|
|
# rollback to savepoint, then commit
|
|
,(1190, 1, '19:1', '', '19:1', '19:1', 0)
|
|
,(1191, 1, 'BEGIN', '', '', '', 0)
|
|
,(1192, 1, 'SAVEPOINT 1', '', '', '', 0)
|
|
,(1193, 1, 'SAVEPOINT 2', '', '', '', 0)
|
|
,(1194, 1, 'INSERT', '', '', '', 0)
|
|
,(1195, 1, 'INSERT', '', '', '', 0)
|
|
,(1196, 1, 'ROLLBACK 2', '', '', '', 0)
|
|
,(1197, 1, 'SAVEPOINT 3', '', '', '', 0)
|
|
,(1198, 1, 'INSERT', '', '', '', 0)
|
|
,(1199, 1, 'SAVEPOINT 4','', '', '', 0)
|
|
,(1200, 1, 'ROLLBACK 3', '', '', '', 0)
|
|
,(1201, 1, 'INSERT', '', '', '', 0)
|
|
,(1202, 1, 'SAVEPOINT 2', '', '', '', 0)
|
|
,(1203, 1, 'ROLLBACK 2', '', '', '', 0)
|
|
,(1204, 1, 'ROLLBACK 1', '', '', '', 0)
|
|
,(1205, 1, 'COMMIT', '19:1', '~19:1', '~19:1', 0)
|
|
#
|
|
# The following is waiting for BUG#13687542
|
|
#
|
|
# # failing DML in transaction
|
|
# ,(1190, 1, '19:1', '', '19:1', '19:1', 0)
|
|
# ,(1191, 1, 'INSERT-ERROR', '', '', '', 1062)#dup
|
|
# ,(1192, 1, 'ROLLBACK', '', '~19:1', '~19:1', 0)
|
|
# # failing DDL in transaction
|
|
# ,(1200, 1, '20:1', '', '20:1', '20:1', 0)
|
|
# ,(1201, 1, 'CREATE-ERROR', '', '', '', 1062)#dup
|
|
# ,(1202, 1, 'ROLLBACK', '', '~20:1', '~20:1', 0)
|
|
;
|
|
|
|
# Clear binlog to get better debug info
|
|
--source include/rpl_reset.inc
|
|
|
|
--echo #### Test ####
|
|
|
|
if (!$rpl_debug)
|
|
{
|
|
--disable_query_log
|
|
}
|
|
--let $id= `SELECT MIN(id) FROM stmts`
|
|
--let $max_id= `SELECT MAX(id) FROM stmts`
|
|
while ($id <= $max_id)
|
|
{
|
|
while (`SELECT COUNT(*) = 0 FROM stmts WHERE id = $id`)
|
|
{
|
|
--inc $id
|
|
}
|
|
--echo ==== row-id = $id ====
|
|
--let $connection= `SELECT connection FROM stmts WHERE id = $id`
|
|
--let $stmt_type= `SELECT stmt_type FROM stmts WHERE id = $id`
|
|
--let $error= `SELECT error FROM stmts WHERE id = $id`
|
|
--let $orig_stmt_type= $stmt_type
|
|
|
|
--let $send_reap=
|
|
if (`SELECT '$stmt_type' REGEXP '^send '`)
|
|
{
|
|
--let $stmt_type= `SELECT SUBSTR('$stmt_type', 6)`
|
|
--let $send_reap= send
|
|
}
|
|
--let $stmt=
|
|
if ($stmt_type == 'reap')
|
|
{
|
|
--let $send_reap= reap
|
|
}
|
|
if ($stmt_type == 'running')
|
|
{
|
|
--let $send_reap= running
|
|
}
|
|
if ($stmt_type == 'INSERT')
|
|
{
|
|
--let $stmt= INSERT INTO t VALUES ($id)
|
|
}
|
|
if ($stmt_type == 'INSERT-ERROR')
|
|
{
|
|
--let $stmt= INSERT INTO t VALUES (1)
|
|
}
|
|
if ($stmt_type == 'CREATE')
|
|
{
|
|
--let $stmt= CREATE TABLE t_$id (a INT) ENGINE = InnoDB
|
|
--let $drop_stmt= $drop_stmt DROP TABLE t_$id;
|
|
}
|
|
if ($stmt_type == 'CREATE-ERROR')
|
|
{
|
|
--let $stmt= CREATE TABLE t (a INT) ENGINE = InnoDB;
|
|
}
|
|
if ($stmt_type == 'CREATE-NODROP')
|
|
{
|
|
--let $stmt= CREATE TABLE t_$id (a INT) ENGINE = InnoDB
|
|
}
|
|
if ($stmt_type == 'BEGIN')
|
|
{
|
|
--let $stmt= BEGIN
|
|
}
|
|
if ($stmt_type == 'COMMIT')
|
|
{
|
|
--let $stmt= COMMIT
|
|
}
|
|
if ($stmt_type == 'ROLLBACK')
|
|
{
|
|
--let $stmt= ROLLBACK
|
|
}
|
|
if ($stmt_type == 'AUTOCOMMIT=0')
|
|
{
|
|
--let $stmt= SET AUTOCOMMIT = 0
|
|
}
|
|
if ($stmt_type == 'AUTOCOMMIT=1')
|
|
{
|
|
--let $stmt= SET AUTOCOMMIT = 1
|
|
}
|
|
if (`SELECT '$stmt_type' REGEXP '^SAVEPOINT [0-9][0-9]*'`)
|
|
{
|
|
--let $stmt= `SELECT CONCAT('SAVEPOINT SP_', SUBSTR('$stmt_type', 11))`
|
|
}
|
|
if (`SELECT '$stmt_type' REGEXP '^ROLLBACK [0-9][0-9]*'`)
|
|
{
|
|
--let $stmt= `SELECT CONCAT('ROLLBACK TO SP_', SUBSTR('$stmt_type', 10))`
|
|
}
|
|
if (`SELECT '$stmt_type' REGEXP '^[0-9][0-9]*:[0-9][0-9]*'`)
|
|
{
|
|
--let $stmt= `SELECT CONCAT('SET GTID_NEXT = "', NUMBER_TO_UUID('$stmt_type'), '"')`
|
|
}
|
|
if ($stmt == '')
|
|
{
|
|
if ($stmt_type != reap)
|
|
{
|
|
if ($stmt_type != running)
|
|
{
|
|
--echo unrecognized statement specification: stmt_type='$stmt_type' orig_stmt_type='$orig_stmt_type' stmt='$stmt'
|
|
--die error in test: unrecognized statement specification
|
|
}
|
|
}
|
|
}
|
|
|
|
--let $rpl_connection_name= server_1_$connection
|
|
--source include/rpl_connection.inc
|
|
|
|
--let $rpl_connection_silent= 1
|
|
|
|
--echo $orig_stmt_type
|
|
|
|
if ($send_reap != 'reap')
|
|
{
|
|
if ($send_reap != 'running')
|
|
{
|
|
SET @gtid_executed= @@GLOBAL.GTID_EXECUTED;
|
|
SET @session_gtid_owned= @@SESSION.GTID_OWNED;
|
|
SET @global_gtid_owned= SUBSTRING_INDEX(@@GLOBAL.GTID_OWNED, '#', 1);
|
|
|
|
--let $eval_no_result= 1
|
|
--let $include_silent= 1
|
|
--let $eval_expr= SET @binlog_file_before= "[master:SHOW MASTER STATUS, File, 1]"
|
|
--source include/eval.inc
|
|
--let $eval_expr= SET @binlog_pos_before= [master:SHOW MASTER STATUS, Position, 1]
|
|
--source include/eval.inc
|
|
--let $eval_expr= SET @slave_gtid_executed= "[slave:SELECT @@GLOBAL.GTID_EXECUTED]"
|
|
--source include/eval.inc
|
|
--let $include_silent= 0
|
|
--let $eval_no_result= 0
|
|
}
|
|
}
|
|
|
|
if ($rpl_debug)
|
|
{
|
|
--echo DEBUG: stmt='$stmt' connection='$connection' send_reap='$send_reap' error='$error'
|
|
}
|
|
|
|
# Execute statement (or send/reap)
|
|
if ($send_reap == '')
|
|
{
|
|
if ($error != 0)
|
|
{
|
|
# This does not work because of BUG#13687542
|
|
--error $error
|
|
eval $stmt;
|
|
}
|
|
if ($error == 0)
|
|
{
|
|
eval $stmt;
|
|
}
|
|
}
|
|
if ($send_reap == 'send')
|
|
{
|
|
--let $last_send_id= `SELECT CONNECTION_ID()`
|
|
--let $last_send_stmt= $stmt
|
|
--send
|
|
eval $stmt;
|
|
--connection master
|
|
--let $wait_condition= SELECT Info = '$last_send_stmt' FROM INFORMATION_SCHEMA.PROCESSLIST WHERE Id = $last_send_id
|
|
--source include/wait_condition_or_abort.inc
|
|
}
|
|
if ($send_reap == 'reap')
|
|
{
|
|
if ($error != 0)
|
|
{
|
|
--error $error
|
|
reap;
|
|
}
|
|
if ($error == 0)
|
|
{
|
|
reap;
|
|
}
|
|
}
|
|
|
|
--let $rpl_connection_name= master
|
|
--source include/rpl_connection.inc
|
|
|
|
# Check that thread is still running query
|
|
if ($send_reap == 'running')
|
|
{
|
|
# Don't use include/assert.inc because $last_send_stmt may contain quotes
|
|
--echo Checking that thread is still running query
|
|
--let $info= `SELECT Info FROM INFORMATION_SCHEMA.PROCESSLIST WHERE Id = $last_send_id`
|
|
if ($info != $last_send_stmt)
|
|
{
|
|
--source include/show_rpl_debug_info.inc
|
|
--echo info='$info'
|
|
--echo last_send_stmt='$last_send_stmt'
|
|
--die Error: thread was supposed to be still running query
|
|
}
|
|
}
|
|
|
|
# Check that variables have their expected values.
|
|
if ($send_reap != 'send')
|
|
{
|
|
if ($send_reap != 'running')
|
|
{
|
|
--source include/sync_slave_sql_with_master.inc
|
|
--connection master
|
|
# Concurrent tests require two or more connections and at least one connection sends
|
|
# the statements in async mode (via send/reap command). We need to make sure that
|
|
# SET GTID_NEXT is completed for all connections before getting values of
|
|
# GTID variables and if COMMIT/ROLLBACK executed for any connection.
|
|
if (`SELECT '$stmt' REGEXP '^(COMMIT|ROLLBACK)\$'`)
|
|
{
|
|
--let $wait_condition= SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE State LIKE 'waiting for GTID %'
|
|
--source include/wait_condition_or_abort.inc
|
|
}
|
|
|
|
--let $text_0= @@GLOBAL.GTID_EXECUTED
|
|
--let $after_0= [server_1_$connection:SELECT @@GLOBAL.GTID_EXECUTED]
|
|
--let $before_0= @gtid_executed
|
|
--let $col_0= gtid_executed
|
|
|
|
--let $text_1= @@SESSION.GTID_OWNED
|
|
--let $after_1= [server_1_$connection:SELECT @@SESSION.GTID_OWNED]
|
|
--let $before_1= @session_gtid_owned
|
|
--let $col_1= session_gtid_owned
|
|
|
|
--let $text_2= @@GLOBAL.GTID_OWNED
|
|
--let $after_2= [server_1_$connection:SELECT SUBSTRING_INDEX(@@GLOBAL.GTID_OWNED, "#", 1)]
|
|
--let $before_2= @global_gtid_owned
|
|
--let $col_2= global_gtid_owned
|
|
|
|
--let $text_3= slave:@@GLOBAL.GTID_EXECUTED
|
|
--let $after_3= [slave: SELECT @@GLOBAL.GTID_EXECUTED]
|
|
--let $before_3= @slave_gtid_executed
|
|
--let $col_3= gtid_executed
|
|
|
|
--let $i= 0
|
|
while ($i < 4)
|
|
{
|
|
--let $text= \$text_$i
|
|
--let $after= \$after_$i
|
|
--let $before= \$before_$i
|
|
--let $col= \$col_$i
|
|
|
|
# $after = the value of the $variable now
|
|
--let $eval_expr= "$after"
|
|
--let $include_silent= 1
|
|
--source include/eval.inc
|
|
--let $include_silent= 0
|
|
--let $after= $eval_result
|
|
|
|
# $before = the value of the $variable before the statement
|
|
--let $rpl_connection_name= server_1_$connection
|
|
--source include/rpl_connection.inc
|
|
--let $before= `SELECT $before`
|
|
--let $rpl_connection_name= master
|
|
--source include/rpl_connection.inc
|
|
|
|
# $diff = the expected change in the variable
|
|
--let $diff= `SELECT NUMBER_TO_UUID($col) FROM stmts WHERE id = $id`
|
|
|
|
if ($rpl_debug)
|
|
{
|
|
--echo i='$i' before='$before' diff='$diff' after='$after'
|
|
}
|
|
|
|
# Assert that before + diff = after
|
|
let $assert_text= `
|
|
SELECT CONCAT("#$id $text: '",
|
|
UUID_TO_NUMBER('$before'), "' + '",
|
|
UUID_TO_NUMBER('$diff'), "' = '",
|
|
UUID_TO_NUMBER('$after'), "'")`;
|
|
--let $assert_cond= GTID_COMPARE("$before", "$diff", "$after")
|
|
--source include/assert.inc
|
|
|
|
--inc $i
|
|
}
|
|
|
|
# Assert that binlog changed or didn't change (according to
|
|
# whether gtid_executed changed/didn't change).
|
|
|
|
--let $rpl_connection_name= master
|
|
--source include/rpl_connection.inc
|
|
|
|
--let $changed_binlog= `SELECT gtid_executed != '' FROM stmts WHERE id = $id`
|
|
if ($changed_binlog)
|
|
{
|
|
let $assert_cond=
|
|
[SHOW MASTER STATUS, Position, 1] >
|
|
[server_1_$connection:SELECT @binlog_pos_before];
|
|
--let $assert_text= Something was written to the binlog
|
|
--source include/assert.inc
|
|
|
|
let $assert_cond=
|
|
"[SHOW BINLOG EVENTS IN
|
|
"[server_1_$connection:SELECT @binlog_file_before]"
|
|
FROM [server_1_$connection:SELECT @binlog_pos_before]
|
|
LIMIT 1, Event_type, 1]" = "Gtid";
|
|
--let $assert_text= The first added event in the binlog should be a Gtid_log_event
|
|
--source include/assert.inc
|
|
#--let $assert_cond= "[SHOW BINLOG EVENTS IN "$binlog_file_before" FROM $binlog_pos_before LIMIT 1, Info, 1]" = "SET GTID_NEXT = "
|
|
}
|
|
if (!$changed_binlog)
|
|
{
|
|
let $assert_cond=
|
|
"[SHOW MASTER STATUS, File, 1]" =
|
|
"[server_1_$connection:SELECT @binlog_file_before]";
|
|
--let $assert_text= Binlog was not rotated
|
|
--source include/assert.inc
|
|
|
|
let $assert_cond=
|
|
[SHOW MASTER STATUS, Position, 1] =
|
|
[server_1_$connection:SELECT @binlog_pos_before];
|
|
--let $assert_text= Binlog position was not updated
|
|
--source include/assert.inc
|
|
}
|
|
}
|
|
}
|
|
--let $rpl_connection_silent= 0
|
|
|
|
--inc $id
|
|
}
|
|
|
|
--enable_query_log
|
|
|
|
# The following partially tests what should be tested above, in the
|
|
# test cases commented-out waiting for BUG#13687542 to be fixed. When
|
|
# the bug has been fixed, please uncomment the code above and remove
|
|
# this.
|
|
|
|
if (!$fixed_bug13687542)
|
|
{
|
|
SET GTID_NEXT = 'AUTOMATIC';
|
|
CREATE TABLE t1 (a INT);
|
|
eval SET GTID_NEXT = '$uuida:1';
|
|
--error ER_TABLE_EXISTS_ERROR
|
|
CREATE TABLE t1 (a INT);
|
|
|
|
SET GTID_NEXT = 'AUTOMATIC';
|
|
eval SET GTID_NEXT = '$uuida:1';
|
|
--error ER_DUP_ENTRY
|
|
INSERT INTO t VALUES (1);
|
|
|
|
SET GTID_NEXT = 'AUTOMATIC';
|
|
DROP TABLE t1;
|
|
}
|
|
|
|
--echo #### Clean up ####
|
|
|
|
--eval $drop_stmt
|
|
DROP TABLE stmts;
|
|
DROP TABLE t;
|
|
|
|
--source include/rpl_end.inc
|