mariadb/mysql-test/suite/innodb/t/group_commit_binlog_pos.test
Brandon Nesterenko e4afa61053 MDEV-7850: Extend GTID Binlog Events with Thread Id
This patch augments Gtid_log_event with the user thread-id.
In particular that compensates for the loss of this info in
Rows_log_events.

Gtid_log_event::thread_id gets visible in mysqlbinlog output like

  #231025 16:21:45 server id 1  end_log_pos 537 CRC32 0x1cf1d963  GTID 0-1-2 ddl thread_id=10

as a 32 bit unsigned integer. Note this is a 32-bit value, as
the connection id can only be 32 bits (see MDEV-15089 for
details).

While the size of Gtid event has grown by 4 bytes
replication from OLD <-> NEW is not affected by it. This patch
also slightly changes the logic to convert Gtid events to Query
events for older replicas which don't support Gtid. Instead of
hard-coding the padding of the sys var section of the generated
Query event, the length to pad is dynamically calculated based
on the length of the Gtid event.

This work was started by the late Sujatha Sivakumar.
Brandon Nesterenko took it over, reviewed initial patches and
extended the work.

Also thanks to Andrei for his help in finalizing the fixes for
MDEV-33924, which were squashed into this patch.

Reviewed-by:
=============
Andrei Elkin <andrei.elkin@mariadb.com>
Kristian Nielsen <knielsen@knielsen-hq.org>
2024-05-03 13:58:19 -06:00

106 lines
3.7 KiB
Text

--source include/have_innodb.inc
--source include/have_debug_sync.inc
--source include/have_log_bin.inc
--source include/have_binlog_format_mixed_or_statement.inc
--source include/binlog_start_pos.inc
# Need DBUG to crash the server intentionally
--source include/have_debug.inc
# Don't test this under valgrind, memory leaks will occur as we crash
--source include/not_valgrind.inc
# The test case currently uses sed and tail, which may be unavailable on
# some windows systems. But see MWL#191 for how to remove the need for grep.
--source include/not_windows.inc
# XtraDB stores the binlog position corresponding to the last commit, and
# prints it during crash recovery.
# Test that we get the correct position when we group commit several
# transactions together.
# What we really want to test here is what happens when a group of
# transactions get written only partially to disk inside InnoDB before
# the crash. But that is hard to test in mysql-test-run automated
# tests. Instead, we use debug_sync to tightly control when each
# transaction is written to the redo log. And we set
# innodb_flush_log_at_trx_commit=3 so that we can write out
# transactions individually - as with
# innodb_flush_log_at_trx_commit=1, all commits are written together,
# as part of a commit_checkpoint.
# (Note that we do not have to restore innodb_flush_log_at_trx_commit, as
# we crash the server).
SET GLOBAL innodb_flush_log_at_trx_commit=3;
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
INSERT INTO t1 VALUES (0);
connect(con1,localhost,root,,);
connect(con2,localhost,root,,);
connect(con3,localhost,root,,);
# Queue up three commits for group commit.
connection con1;
SET DEBUG_SYNC= "commit_after_get_LOCK_log SIGNAL con1_waiting WAIT_FOR con3_queued";
SET DEBUG_SYNC= "commit_loop_entry_commit_ordered SIGNAL con1_loop WAIT_FOR con1_loop_cont EXECUTE 3";
send INSERT INTO t1 VALUES (1);
connection con2;
SET DEBUG_SYNC= "now WAIT_FOR con1_waiting";
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con2_queued";
send INSERT INTO t1 VALUES (2);
connection con3;
SET DEBUG_SYNC= "now WAIT_FOR con2_queued";
SET DEBUG_SYNC= "commit_after_prepare_ordered SIGNAL con3_queued";
send INSERT INTO t1 VALUES (3);
connection default;
SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
# At this point, no transactions are committed.
SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
# At this point, 1 transaction is committed.
SET DEBUG_SYNC= "now SIGNAL con1_loop_cont";
SET DEBUG_SYNC= "now WAIT_FOR con1_loop";
# At this point, 2 transactions are committed.
SELECT * FROM t1 ORDER BY a;
connection con2;
reap;
# Now crash the server with 1+2 in-memory committed, 3 only prepared.
connection default;
system echo wait-group_commit_binlog_pos.test >> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
SET SESSION debug_dbug="+d,crash_dispatch_command_before";
--error 2006,2013
SELECT 1;
connection con1;
--error 2006,2013
reap;
connection con3;
--error 2006,2013
reap;
system echo restart-group_commit_binlog_pos.test >> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
connection default;
--enable_reconnect
--source include/wait_until_connected_again.inc
# Crash recovery should recover all three transactions.
SELECT * FROM t1 ORDER BY a;
# Check that the binlog position reported by InnoDB is the correct one
# for the end of the second transaction (as can be checked with
# mysqlbinlog).
let $MYSQLD_DATADIR= `SELECT @@datadir`;
# GTID thread_id increased the event size by 2*(1+4)
let pos=`select $binlog_start_pos + 739 + 2*(1+4)`;
--replace_result $pos <pos>
--exec sed -ne 's/.*\(InnoDB: Last binlog file .* position.*\)/\1/p' $MYSQLD_DATADIR/../../log/mysqld.1.err | tail -1
SET DEBUG_SYNC= 'RESET';
DROP TABLE t1;