mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 15:50:51 +03:00 
			
		
		
		
	from log):
When row-based logging is used, the CREATE-SELECT is written as two
parts: as a CREATE TABLE statement and as the rows for the table. For
both transactional and non-transactional tables, the CREATE TABLE
statement was written to the transaction cache, as were the rows, and
on statement end, the entire transaction cache was written to the binary
log if the table was non-transactional. For transactional tables, the
events were kept in the transaction cache until end of transaction (or
statement that were not part of a transaction).
For the case when AUTOCOMMIT=0 and we are creating a transactional table
using a create select, we would then keep the CREATE TABLE statement and
the rows for the CREATE-SELECT, while executing the following statements.
On a rollback, the transaction cache would then be cleared, which would
also remove the CREATE TABLE statement. Hence no table would be created
on the slave, while there is an empty table on the master.
This relates to BUG#22865 where the table being created exists on the
master, but not on the slave during insertion of rows into the newly
created table. This occurs since the CREATE TABLE statement were still
in the transaction cache until the statement finished executing, and
possibly longer if the table was transactional.
This patch changes the behaviour of the CREATE-SELECT statement by
adding an implicit commit at the end of the statement when creating
non-temporary tables. Hence, non-temporary tables will be written to the
binary log on completion, and in the even of AUTOCOMMIT=0, a new
transaction will be started. Temporary tables do not commit an ongoing
transaction: neither as a pre- not a post-commit.
The events for both transactional and non-transactional tables are
saved in the transaction cache, and written to the binary log at end
of the statement.
mysql-test/r/rpl_row_create_table.result:
  Result change
mysql-test/t/rpl_row_create_table.test:
  Requring InnoDB for slave as well.
  Adding test CREATE-SELECT that is rolled back explicitly.
  Changing binlog positions.
sql/log.cc:
  Adding helper class to handle lock/unlock of mutexes using RAII.
  Factoring out code into write_cache() function to transaction cache
    to binary log.
  Adding function THD::binlog_flush_transaction_cache() to flush the
    transaction cache to the binary log file.
  Factoring out code into binlog_set_stmt_begin() to set the beginning
    of statement savepoint.
  Clearing before statement point when transaction cache is truncated
   so that these points are out of range.
sql/log.h:
  Adding method MYSQL_BIN_LOG::write_cache()
sql/log_event.h:
  Replicating OPTION_NOT_AUTOCOMMIT flag (see changeset comment)
sql/mysql_priv.h:
  Although left-shifting signed integer values is well-defined,
  it has potential for strange errors. Using unsigned long long
  instead of signed long long since this is the type of the options
  flags.
sql/slave.cc:
  Adding printout of transaction-critical thread flags.
sql/sql_class.h:
  Adding function THD::binlog_flush_transaction_cache()
  Adding function THD::binlog_set_stmt_begin()
sql/sql_insert.cc:
  Adding code to cache events for a CREATE-SELECT statement.
  Disabling binlog for SBR (but not RBR) when sending error for select part
  of CREATE-SELECT statement.
  Adding implicit commit at end of statement for non-temporary tables.
mysql-test/t/rpl_row_create_table-slave.opt:
  New BitKeeper file ``mysql-test/t/rpl_row_create_table-slave.opt''
		
	
		
			
				
	
	
		
			404 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			404 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| stop slave;
 | |
| drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
 | |
| reset master;
 | |
| reset slave;
 | |
| drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
 | |
| start slave;
 | |
| CREATE TABLE t1 (a INT, b INT);
 | |
| CREATE TABLE t2 (a INT, b INT) ENGINE=Merge;
 | |
| CREATE TABLE t3 (a INT, b INT) CHARSET=utf8;
 | |
| CREATE TABLE t4 (a INT, b INT) ENGINE=Merge CHARSET=utf8;
 | |
| SHOW BINLOG EVENTS FROM 212;
 | |
| Log_name	#
 | |
| Pos	212
 | |
| Event_type	Query
 | |
| Server_id	#
 | |
| End_log_pos	#
 | |
| Info	use `test`; CREATE TABLE t1 (a INT, b INT)
 | |
| Log_name	#
 | |
| Pos	305
 | |
| Event_type	Query
 | |
| Server_id	#
 | |
| End_log_pos	#
 | |
| Info	use `test`; CREATE TABLE t2 (a INT, b INT) ENGINE=Merge
 | |
| Log_name	#
 | |
| Pos	411
 | |
| Event_type	Query
 | |
| Server_id	#
 | |
| End_log_pos	#
 | |
| Info	use `test`; CREATE TABLE t3 (a INT, b INT) CHARSET=utf8
 | |
| Log_name	#
 | |
| Pos	517
 | |
| Event_type	Query
 | |
| Server_id	#
 | |
| End_log_pos	#
 | |
| Info	use `test`; CREATE TABLE t4 (a INT, b INT) ENGINE=Merge CHARSET=utf8
 | |
| **** On Master ****
 | |
| SHOW CREATE TABLE t1;
 | |
| Table	t1
 | |
| Create Table	CREATE TABLE `t1` (
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 | |
| SHOW CREATE TABLE t2;
 | |
| Table	t2
 | |
| Create Table	CREATE TABLE `t2` (
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=()
 | |
| SHOW CREATE TABLE t3;
 | |
| Table	t3
 | |
| Create Table	CREATE TABLE `t3` (
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MyISAM DEFAULT CHARSET=utf8
 | |
| **** On Slave ****
 | |
| SHOW CREATE TABLE t1;
 | |
| Table	t1
 | |
| Create Table	CREATE TABLE `t1` (
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MEMORY DEFAULT CHARSET=latin1
 | |
| SHOW CREATE TABLE t2;
 | |
| Table	t2
 | |
| Create Table	CREATE TABLE `t2` (
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=()
 | |
| SHOW CREATE TABLE t3;
 | |
| Table	t3
 | |
| Create Table	CREATE TABLE `t3` (
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MEMORY DEFAULT CHARSET=utf8
 | |
| CREATE TABLE t5 (b INT, c INT) SELECT * FROM t3;
 | |
| CREATE TEMPORARY TABLE tt3 (a INT, b INT);
 | |
| INSERT INTO tt3 VALUES (1,2), (2,4), (3,6), (4,2), (5,10), (6,12);
 | |
| CREATE TABLE t6 (b INT, c INT) SELECT * FROM tt3;
 | |
| **** On Master ****
 | |
| SHOW CREATE TABLE t5;
 | |
| Table	t5
 | |
| Create Table	CREATE TABLE `t5` (
 | |
|   `c` int(11) DEFAULT NULL,
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 | |
| SELECT * FROM t5 ORDER BY a,b,c;
 | |
| c	a	b
 | |
| SHOW CREATE TABLE t6;
 | |
| Table	t6
 | |
| Create Table	CREATE TABLE `t6` (
 | |
|   `c` int(11) DEFAULT NULL,
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 | |
| SELECT * FROM t6 ORDER BY a,b,c;
 | |
| c	a	b
 | |
| NULL	1	2
 | |
| NULL	2	4
 | |
| NULL	3	6
 | |
| NULL	4	2
 | |
| NULL	5	10
 | |
| NULL	6	12
 | |
| **** On Slave ****
 | |
| SHOW CREATE TABLE t5;
 | |
| Table	t5
 | |
| Create Table	CREATE TABLE `t5` (
 | |
|   `c` int(11) DEFAULT NULL,
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MEMORY DEFAULT CHARSET=latin1
 | |
| SELECT * FROM t5 ORDER BY a,b,c;
 | |
| c	a	b
 | |
| SHOW CREATE TABLE t6;
 | |
| Table	t6
 | |
| Create Table	CREATE TABLE `t6` (
 | |
|   `c` int(11) DEFAULT NULL,
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MEMORY DEFAULT CHARSET=latin1
 | |
| SELECT * FROM t6 ORDER BY a,b,c;
 | |
| c	a	b
 | |
| NULL	1	2
 | |
| NULL	2	4
 | |
| NULL	3	6
 | |
| NULL	4	2
 | |
| NULL	5	10
 | |
| NULL	6	12
 | |
| CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3;
 | |
| ERROR 23000: Duplicate entry '2' for key 'b'
 | |
| SHOW BINLOG EVENTS FROM 1118;
 | |
| Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 | |
| CREATE TABLE t7 (a INT, b INT UNIQUE);
 | |
| INSERT INTO t7 SELECT a,b FROM tt3;
 | |
| ERROR 23000: Duplicate entry '2' for key 'b'
 | |
| SELECT * FROM t7 ORDER BY a,b;
 | |
| a	b
 | |
| 1	2
 | |
| 2	4
 | |
| 3	6
 | |
| SHOW BINLOG EVENTS FROM 1118;
 | |
| Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 | |
| master-bin.000001	1118	Query	1	1218	use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE)
 | |
| master-bin.000001	1218	Table_map	1	1258	table_id: # (test.t7)
 | |
| master-bin.000001	1258	Write_rows	1	1314	table_id: # flags: STMT_END_F
 | |
| SELECT * FROM t7 ORDER BY a,b;
 | |
| a	b
 | |
| 1	2
 | |
| 2	4
 | |
| 3	6
 | |
| CREATE TEMPORARY TABLE tt4 (a INT, b INT);
 | |
| INSERT INTO tt4 VALUES (4,8), (5,10), (6,12);
 | |
| BEGIN;
 | |
| INSERT INTO t7 SELECT a,b FROM tt4;
 | |
| ROLLBACK;
 | |
| Warnings:
 | |
| Warning	1196	Some non-transactional changed tables couldn't be rolled back
 | |
| SHOW BINLOG EVENTS FROM 1314;
 | |
| Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 | |
| master-bin.000001	1314	Table_map	1	1354	table_id: # (test.t7)
 | |
| master-bin.000001	1354	Write_rows	1	1410	table_id: # flags: STMT_END_F
 | |
| SELECT * FROM t7 ORDER BY a,b;
 | |
| a	b
 | |
| 1	2
 | |
| 2	4
 | |
| 3	6
 | |
| 4	8
 | |
| 5	10
 | |
| 6	12
 | |
| SELECT * FROM t7 ORDER BY a,b;
 | |
| a	b
 | |
| 1	2
 | |
| 2	4
 | |
| 3	6
 | |
| 4	8
 | |
| 5	10
 | |
| 6	12
 | |
| CREATE TABLE t8 LIKE t4;
 | |
| CREATE TABLE t9 LIKE tt4;
 | |
| CREATE TEMPORARY TABLE tt5 LIKE t4;
 | |
| CREATE TEMPORARY TABLE tt6 LIKE tt4;
 | |
| CREATE TEMPORARY TABLE tt7 SELECT 1;
 | |
| **** On Master ****
 | |
| SHOW CREATE TABLE t8;
 | |
| Table	t8
 | |
| Create Table	CREATE TABLE `t8` (
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MRG_MyISAM DEFAULT CHARSET=utf8 UNION=()
 | |
| SHOW CREATE TABLE t9;
 | |
| Table	t9
 | |
| Create Table	CREATE TABLE `t9` (
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 | |
| SHOW BINLOG EVENTS FROM 1410;
 | |
| Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 | |
| master-bin.000001	1410	Query	1	1496	use `test`; CREATE TABLE t8 LIKE t4
 | |
| master-bin.000001	1496	Query	1	1635	use `test`; CREATE TABLE `t9` (
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| )
 | |
| **** On Slave ****
 | |
| SHOW CREATE TABLE t8;
 | |
| Table	t8
 | |
| Create Table	CREATE TABLE `t8` (
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MRG_MyISAM DEFAULT CHARSET=utf8 UNION=()
 | |
| SHOW CREATE TABLE t9;
 | |
| Table	t9
 | |
| Create Table	CREATE TABLE `t9` (
 | |
|   `a` int(11) DEFAULT NULL,
 | |
|   `b` int(11) DEFAULT NULL
 | |
| ) ENGINE=MEMORY DEFAULT CHARSET=latin1
 | |
| DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8,t9;
 | |
| STOP SLAVE;
 | |
| SET GLOBAL storage_engine=@storage_engine;
 | |
| START SLAVE;
 | |
| ================ BUG#22864 ================
 | |
| STOP SLAVE;
 | |
| RESET SLAVE;
 | |
| RESET MASTER;
 | |
| START SLAVE;
 | |
| SET AUTOCOMMIT=0;
 | |
| CREATE TABLE t1 (a INT);
 | |
| INSERT INTO t1 VALUES (1),(2),(3);
 | |
| CREATE TABLE t2 ENGINE=INNODB SELECT * FROM t1;
 | |
| ROLLBACK;
 | |
| CREATE TABLE t3 ENGINE=INNODB SELECT * FROM t1;
 | |
| INSERT INTO t3 VALUES (4),(5),(6);
 | |
| ROLLBACK;
 | |
| CREATE TABLE t4 ENGINE=INNODB SELECT * FROM t1;
 | |
| INSERT INTO t1 VALUES (4),(5),(6);
 | |
| ROLLBACK;
 | |
| Warnings:
 | |
| Warning	1196	Some non-transactional changed tables couldn't be rolled back
 | |
| SHOW TABLES;
 | |
| Tables_in_test
 | |
| t1
 | |
| t2
 | |
| t3
 | |
| t4
 | |
| SELECT   TABLE_NAME,ENGINE
 | |
| FROM   INFORMATION_SCHEMA.TABLES
 | |
| WHERE   TABLE_NAME LIKE 't_'
 | |
| ORDER BY TABLE_NAME;
 | |
| TABLE_NAME	ENGINE
 | |
| t1	MyISAM
 | |
| t2	InnoDB
 | |
| t3	InnoDB
 | |
| t4	InnoDB
 | |
| SELECT * FROM t1 ORDER BY a;
 | |
| a
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 6
 | |
| SELECT * FROM t2 ORDER BY a;
 | |
| a
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| SELECT * FROM t3 ORDER BY a;
 | |
| a
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| SELECT * FROM t4 ORDER BY a;
 | |
| a
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| SHOW BINLOG EVENTS;
 | |
| Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 | |
| master-bin.000001	4	Format_desc	1	102	Server ver: #, Binlog ver: #
 | |
| master-bin.000001	102	Query	1	188	use `test`; CREATE TABLE t1 (a INT)
 | |
| master-bin.000001	188	Table_map	1	227	table_id: # (test.t1)
 | |
| master-bin.000001	227	Write_rows	1	271	table_id: # flags: STMT_END_F
 | |
| master-bin.000001	271	Query	1	339	use `test`; BEGIN
 | |
| master-bin.000001	339	Query	1	125	use `test`; CREATE TABLE `t2` (
 | |
|   `a` int(11) DEFAULT NULL
 | |
| ) ENGINE=InnoDB
 | |
| master-bin.000001	464	Table_map	1	164	table_id: # (test.t2)
 | |
| master-bin.000001	503	Write_rows	1	208	table_id: # flags: STMT_END_F
 | |
| master-bin.000001	547	Xid	1	574	COMMIT /* XID */
 | |
| master-bin.000001	574	Query	1	642	use `test`; BEGIN
 | |
| master-bin.000001	642	Query	1	125	use `test`; CREATE TABLE `t3` (
 | |
|   `a` int(11) DEFAULT NULL
 | |
| ) ENGINE=InnoDB
 | |
| master-bin.000001	767	Table_map	1	164	table_id: # (test.t3)
 | |
| master-bin.000001	806	Write_rows	1	208	table_id: # flags: STMT_END_F
 | |
| master-bin.000001	850	Xid	1	877	COMMIT /* XID */
 | |
| master-bin.000001	877	Query	1	945	use `test`; BEGIN
 | |
| master-bin.000001	945	Query	1	125	use `test`; CREATE TABLE `t4` (
 | |
|   `a` int(11) DEFAULT NULL
 | |
| ) ENGINE=InnoDB
 | |
| master-bin.000001	1070	Table_map	1	164	table_id: # (test.t4)
 | |
| master-bin.000001	1109	Write_rows	1	208	table_id: # flags: STMT_END_F
 | |
| master-bin.000001	1153	Xid	1	1180	COMMIT /* XID */
 | |
| master-bin.000001	1180	Table_map	1	1219	table_id: # (test.t1)
 | |
| master-bin.000001	1219	Write_rows	1	1263	table_id: # flags: STMT_END_F
 | |
| SHOW TABLES;
 | |
| Tables_in_test
 | |
| t1
 | |
| t2
 | |
| t3
 | |
| t4
 | |
| SELECT   TABLE_NAME,ENGINE
 | |
| FROM   INFORMATION_SCHEMA.TABLES
 | |
| WHERE   TABLE_NAME LIKE 't_'
 | |
| ORDER BY TABLE_NAME;
 | |
| TABLE_NAME	ENGINE
 | |
| t1	MyISAM
 | |
| t2	InnoDB
 | |
| t3	InnoDB
 | |
| t4	InnoDB
 | |
| SELECT * FROM t1 ORDER BY a;
 | |
| a
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 6
 | |
| SELECT * FROM t2 ORDER BY a;
 | |
| a
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| SELECT * FROM t3 ORDER BY a;
 | |
| a
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| SELECT * FROM t4 ORDER BY a;
 | |
| a
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| DROP TABLE IF EXISTS t1,t2,t3,t4;
 | |
| SET AUTOCOMMIT=1;
 | |
| STOP SLAVE;
 | |
| RESET SLAVE;
 | |
| RESET MASTER;
 | |
| START SLAVE;
 | |
| CREATE TABLE t1 (a INT);
 | |
| INSERT INTO t1 VALUES (1),(2),(3);
 | |
| CREATE TABLE t2 (a INT) ENGINE=INNODB;
 | |
| BEGIN;
 | |
| INSERT INTO t2 SELECT a*a FROM t1;
 | |
| CREATE TEMPORARY TABLE tt1
 | |
| SELECT a+1 AS a
 | |
| FROM t1
 | |
| WHERE a MOD 2 = 1;
 | |
| INSERT INTO t2 SELECT a+2 FROM tt1;
 | |
| COMMIT;
 | |
| SELECT * FROM t2 ORDER BY a;
 | |
| a
 | |
| 1
 | |
| 4
 | |
| 4
 | |
| 6
 | |
| 9
 | |
| SHOW BINLOG EVENTS;
 | |
| Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 | |
| master-bin.000001	4	Format_desc	1	102	Server ver: #, Binlog ver: #
 | |
| master-bin.000001	102	Query	1	188	use `test`; CREATE TABLE t1 (a INT)
 | |
| master-bin.000001	188	Table_map	1	227	table_id: # (test.t1)
 | |
| master-bin.000001	227	Write_rows	1	271	table_id: # flags: STMT_END_F
 | |
| master-bin.000001	271	Query	1	371	use `test`; CREATE TABLE t2 (a INT) ENGINE=INNODB
 | |
| master-bin.000001	371	Query	1	439	use `test`; BEGIN
 | |
| master-bin.000001	439	Table_map	1	39	table_id: # (test.t2)
 | |
| master-bin.000001	478	Write_rows	1	83	table_id: # flags: STMT_END_F
 | |
| master-bin.000001	522	Table_map	1	122	table_id: # (test.t2)
 | |
| master-bin.000001	561	Write_rows	1	161	table_id: # flags: STMT_END_F
 | |
| master-bin.000001	600	Xid	1	627	COMMIT /* XID */
 | |
| SELECT * FROM t2 ORDER BY a;
 | |
| a
 | |
| 1
 | |
| 4
 | |
| 4
 | |
| 6
 | |
| 9
 | |
| TRUNCATE TABLE t2;
 | |
| BEGIN;
 | |
| INSERT INTO t2 SELECT a*a FROM t1;
 | |
| CREATE TEMPORARY TABLE tt2
 | |
| SELECT a+1 AS a
 | |
| FROM t1
 | |
| WHERE a MOD 2 = 1;
 | |
| INSERT INTO t2 SELECT a+2 FROM tt2;
 | |
| ROLLBACK;
 | |
| SELECT * FROM t2 ORDER BY a;
 | |
| a
 | |
| SHOW BINLOG EVENTS FROM 627;
 | |
| Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 | |
| master-bin.000001	627	Query	1	80	use `test`; TRUNCATE TABLE t2
 | |
| master-bin.000001	707	Xid	1	734	COMMIT /* XID */
 | |
| SELECT * FROM t2 ORDER BY a;
 | |
| a
 | |
| DROP TABLE t1,t2;
 |