mirror of
https://github.com/MariaDB/server.git
synced 2025-08-26 01:44:06 +03:00
The problem was that TRUNCATE TABLE didn't take a exclusive lock on a table if it resorted to truncating via delete of all rows in the table. Specifically for InnoDB tables, this could break proper isolation as InnoDB ends up aborting some granted locks when truncating a table. The solution is to take a exclusive metadata lock before TRUNCATE TABLE can proceed. This guarantees that no other transaction is using the table. Incompatible change: Truncate via delete no longer fails if sql_safe_updates is activated (this was a undocumented side effect).
103 lines
3.0 KiB
Plaintext
103 lines
3.0 KiB
Plaintext
SET @old_binlog_format=@@binlog_format;
|
|
SET BINLOG_FORMAT=ROW;
|
|
RESET MASTER;
|
|
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
|
CREATE TABLE t2 (a INT) ENGINE=MyISAM;
|
|
INSERT INTO t2 VALUES (1),(2),(3);
|
|
**** Truncate of empty table shall be logged
|
|
TRUNCATE TABLE t1;
|
|
TRUNCATE TABLE t2;
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
|
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
|
|
DROP TABLE t1,t2;
|
|
#
|
|
# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
|
|
#
|
|
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
|
CREATE TABLE t2 (a INT) ENGINE=MyISAM;
|
|
INSERT INTO t1 VALUES (1),(2);
|
|
# Connection: default
|
|
BEGIN;
|
|
INSERT INTO t2 SELECT * FROM t1;
|
|
# Connection: truncate
|
|
TRUNCATE TABLE t1;
|
|
# Connection: default
|
|
INSERT INTO t2 SELECT * FROM t1;
|
|
SELECT COUNT(*) FROM t2;
|
|
COUNT(*)
|
|
4
|
|
COMMIT;
|
|
# Connection: truncate
|
|
# Reaping TRUNCATE TABLE
|
|
SELECT COUNT(*) FROM t1;
|
|
COUNT(*)
|
|
0
|
|
SELECT COUNT(*) FROM t2;
|
|
COUNT(*)
|
|
4
|
|
# Connection: default
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
|
master-bin.000001 # Query # # COMMIT
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
|
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
|
master-bin.000001 # Query # # COMMIT
|
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
|
|
DROP TABLE t1,t2;
|
|
SET BINLOG_FORMAT=STATEMENT;
|
|
RESET MASTER;
|
|
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
|
CREATE TABLE t2 (a INT) ENGINE=MyISAM;
|
|
INSERT INTO t2 VALUES (1),(2),(3);
|
|
**** Truncate of empty table shall be logged
|
|
TRUNCATE TABLE t1;
|
|
TRUNCATE TABLE t2;
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
|
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
|
|
DROP TABLE t1,t2;
|
|
#
|
|
# Bug#42643: InnoDB does not support replication of TRUNCATE TABLE
|
|
#
|
|
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
|
CREATE TABLE t2 (a INT) ENGINE=MyISAM;
|
|
INSERT INTO t1 VALUES (1),(2);
|
|
# Connection: default
|
|
BEGIN;
|
|
INSERT INTO t2 SELECT * FROM t1;
|
|
# Connection: truncate
|
|
TRUNCATE TABLE t1;
|
|
# Connection: default
|
|
INSERT INTO t2 SELECT * FROM t1;
|
|
SELECT COUNT(*) FROM t2;
|
|
COUNT(*)
|
|
4
|
|
COMMIT;
|
|
# Connection: truncate
|
|
# Reaping TRUNCATE TABLE
|
|
SELECT COUNT(*) FROM t1;
|
|
COUNT(*)
|
|
0
|
|
SELECT COUNT(*) FROM t2;
|
|
COUNT(*)
|
|
4
|
|
# Connection: default
|
|
show binlog events from <binlog_start>;
|
|
Log_name Pos Event_type Server_id End_log_pos Info
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1
|
|
master-bin.000001 # Query # # COMMIT
|
|
master-bin.000001 # Query # # BEGIN
|
|
master-bin.000001 # Query # # use `test`; INSERT INTO t2 SELECT * FROM t1
|
|
master-bin.000001 # Query # # COMMIT
|
|
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
|
|
DROP TABLE t1,t2;
|
|
SET BINLOG_FORMAT=@old_binlog_format;
|