mirror of
https://github.com/MariaDB/server.git
synced 2026-01-26 13:29:07 +01:00
There was a bug when a DML used both the stmt and trx cache but the trx cache is empty (in this case INSERT IGNORE that inserts nothing but still allocates from a sequence). The code would put the GTID in the stmt cache but binlog the trx cache with some stray dangling annotate/tablemap event. Thus a completely invalid event group resulted. In general, the logic for selecting stmt or trx cache was complicated and inconsistent in multiple places around the code. This patch improves by introducing a single binlog_cache_mngr::engine_cache_data() which holds the logic and is used in all places. This patch also fixes a few problems with the GTID event binlogged for user XA, found during debugging. Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
106 lines
4.1 KiB
Text
106 lines
4.1 KiB
Text
--source include/have_binlog_format_mixed.inc
|
|
--source include/have_sequence.inc
|
|
--source include/master-slave.inc
|
|
--source include/have_innodb_binlog.inc
|
|
|
|
--echo *** Various tests for event groups using both stmt/trx cache.
|
|
|
|
--let $datadir= `SELECT @@datadir`
|
|
|
|
# Implicit allocation from sequence gets binlogged as a non-transactional
|
|
# part of a transactional INSERT.
|
|
CREATE SEQUENCE s;
|
|
CREATE TABLE t (a int PRIMARY KEY, b int DEFAULT (NEXTVAL(s))) ENGINE=InnoDB;
|
|
--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
|
|
--let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1)
|
|
INSERT INTO t (a) VALUES (1);
|
|
--source include/show_binlog_events2.inc
|
|
|
|
# Multi-table update of both non-transactional and transactional table with
|
|
# autocommit - this populates both the stmt and trx caches.
|
|
|
|
CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(2048)) ENGINE=MyISAM;
|
|
CREATE TABLE t2 (a INT PRIMARY KEY, b VARCHAR(2048)) ENGINE=InnoDB;
|
|
SET binlog_format=ROW;
|
|
INSERT INTO t2 VALUES (1, '');
|
|
INSERT INTO t1 VALUES (1, '');
|
|
--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
|
|
--let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1)
|
|
UPDATE t1, t2 SET t1.b='a', t2.b='b';
|
|
--source include/show_binlog_events2.inc
|
|
|
|
# Larger update so there will be oob data for both stmt and trx caches.
|
|
INSERT INTO t1 SELECT seq, '' FROM seq_2_to_25;
|
|
INSERT INTO t2 SELECT seq, '' FROM seq_2_to_25;
|
|
--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
|
|
--let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1)
|
|
UPDATE t1, t2 SET t1.b=REPEAT('x', 2000), t2.b=REPEAT('y',2000) WHERE t1.a=t2.a;
|
|
--source include/show_binlog_events2.inc
|
|
|
|
# Test that oob refcount is working when both caches are in use.
|
|
# Smaller binlog files to have oob refs across multiple binlog files.
|
|
SET @old_max_size= @@GLOBAL.max_binlog_size;
|
|
SET GLOBAL max_binlog_size= 65536;
|
|
FLUSH BINARY LOGS;
|
|
FLUSH BINARY LOGS;
|
|
|
|
INSERT INTO t1 SELECT seq, '' FROM seq_26_to_50;
|
|
INSERT INTO t2 SELECT seq, '' FROM seq_26_to_50;
|
|
UPDATE t1, t2 SET t1.b=REPEAT('\\', 2000), t2.b=REPEAT('/',2000) WHERE t1.a=t2.a;
|
|
--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
|
|
|
|
--error ER_LOG_IN_USE
|
|
evalp PURGE BINARY LOGS TO '$binlog_file';
|
|
FLUSH BINARY LOGS;
|
|
FLUSH BINARY LOGS;
|
|
# Test mysqlbinlog reading of dual-cache oob data.
|
|
--exec $MYSQL_BINLOG $datadir/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog.txt
|
|
--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
|
|
SET binlog_format=DEFAULT;
|
|
SET GLOBAL max_binlog_size= @old_max_size;
|
|
FLUSH BINARY LOGS;
|
|
FLUSH BINARY LOGS;
|
|
|
|
# Make sure the slave is caught up so we can purge.
|
|
INSERT INTO t(a) SELECT 1+MAX(a) FROM t;
|
|
--source include/save_master_gtid.inc
|
|
--connection slave
|
|
--source include/sync_with_master_gtid.inc
|
|
|
|
--connection master
|
|
evalp PURGE BINARY LOGS TO '$binlog_file';
|
|
|
|
# This asserted due to uninitialized handler_binlog_event_group_info->engine_ptr2
|
|
SET binlog_format=ROW;
|
|
CREATE SEQUENCE ss ENGINE=InnoDB;
|
|
CREATE TABLE tt (a INT, b BIGINT DEFAULT(NEXTVAL(ss))) ENGINE=InnoDB;
|
|
INSERT INTO tt (a) VALUES (1);
|
|
CREATE TABLE xx ENGINE=InnoDB SELECT * FROM tt;
|
|
SET binlog_format=DEFAULT;
|
|
|
|
# A tricky case where a sequence is updated as part of a transactional
|
|
# DML, but the DML ends up binlogging nothing. The code would put the GTID in
|
|
# the stmt cache, but binlog the trx cache, which caused binlogging of a
|
|
# garbage partial event group containing only annotate and table map event
|
|
# but no GTID or rows event/commit event.
|
|
CREATE TABLE t3 (a INT PRIMARY KEY DEFAULT NEXTVAL(ss), b INT) ENGINE=InnoDB;
|
|
INSERT INTO t3 VALUES (10000, 1);
|
|
INSERT INTO t3 SELECT a+1, b+1 FROM t3;
|
|
INSERT INTO t3 SELECT a+2, b+1 FROM t3;
|
|
INSERT INTO t3 SELECT a+4, b+1 FROM t3;
|
|
INSERT INTO t3 SELECT a+8, b+1 FROM t3;
|
|
INSERT INTO t3 SELECT a+16, b+1 FROM t3;
|
|
INSERT INTO t3 SELECT a+32, b+1 FROM t3;
|
|
|
|
SELECT SETVAL(ss, 10005);
|
|
--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
|
|
--let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1)
|
|
INSERT IGNORE INTO t3(b) VALUES (10);
|
|
--source include/show_binlog_events.inc
|
|
|
|
DROP TABLE t;
|
|
DROP SEQUENCE s;
|
|
DROP TABLE t1, t2, t3;
|
|
DROP TABLE tt, xx;
|
|
DROP SEQUENCE ss;
|
|
--source include/rpl_end.inc
|