WL#8872: Allow CREATE TEMPORARY/DROP TEMPORARY in transaction when GTID_MODE=ON in RBR
Affects: Server-8.0
—
Status: Complete
High-Level Description / Executive Summary EXECUTIVE SUMMARY ================= Allow CREATE/DROP TEMPORARY TABLE in a transaction when @@global.gtid_mode=ON and @@session.binlog_format=ROW/MIXED. And don't replicate CREATE TEMPORARY / DROP TEMPORARY when @@session.binlog_format=ROW/MIXED. USER STORIES ============ AS a MySQL user, I want that MySQL is able to support to allow CREATE/DROP TEMPORARY TABLE in a transaction when @@global.gtid_mode=ON and @@session.binlog_format=ROW/MIXED. So that their is no concern to turn GTID_MODE on. DEV STORIES =========== As a MySQL dev, I want to not replicate CREATE TEMPORARY / DROP TEMPORARY when @@session.binlog_format=ROW/MIXED, so that remove the following problems: 1. If a slave has open temporary tables, and the slave is restarted, the temporary tables are lost, because they are dropped when the connection is closed, and subsequently the slave diverges or the applier stops with an error. No DROP TABLE is written to the slave's binary log. 2. When replicating in a chain like A->B->C, and B is restarted while it has open temporary tables, then when C reconnects to B, C will notice the restart and drop its temporary tables. This generates a DROP TEMPORARY TABLE in the binary log on C. If GTID_MODE=ON, the DROP TEMPORARY TABLE will use a new GTID having C's UUID. This is an "errant transaction"; it only exists on a slave and not on its master. If, at any time in the future, there is a failover and C becomes a master of B or C, the errant transaction may cause C to fail to connect. REFERENCES ========== See also contribution: - Redundant GTID unsafe mark for CREATE/DROP TEMPORARY TABLE in RBR/MBR https://bugs.mysql.com/bug.php?id=89467
Functional and Non-Functional Requirements FUNCTIONAL REQUIREMENTS ======================= F-1: When @@session.binlog_format=ROW/MIXED, the server must not write CREATE TEMPORARY TABLE or DROP TEMPORARY TABLE to the binary log. F-2: SET @@session.binlog_format must be disallowed if session has open temporary table(s). F-3: SET @@global.binlog_format and SET @@persist.binlog_format must be disallowed if any replication channel has open temporary table(s). F-4: SET @@global.binlog_format and SET @@persist.binlog_format must be disallowed if any replication channel applier is running. F-5: Allow CREATE/DROP TEMPORARY TABLE inside a transaction when @@global.gtid_mode=ON and @@session.binlog_format=ROW/MIXED. F-6: Allow CREATE/DROP TEMPORARY TABLE inside a PROCDURE when @@global.gtid_mode=ON and @@session.binlog_format=ROW/MIXED. F-7: Allow CREATE/DROP TEMPORARY TABLE inside a FUNCTION when @@global.gtid_mode=ON and @@session.binlog_format=ROW/MIXED. F-8. Allow CREATE/DROP TEMPORARY TABLE inside a TRIGGER when @@global.gtid_mode=ON and @@session.binlog_format=ROW/MIXED. NON-FUNCTIONAL REQUIREMENTS =========================== NF-1: Cross-version replication OLD master -> NEW slave must work. NF-2: Cross-version replication NEW master -> OLD slave must work.
High-Level Specification / Interface Specification HIGH LEVEL SPECIFICATION ======================== 1. When @@session.binlog_format=ROW/MIXED, the server must not write CREATE TEMPORARY TABLE or DROP TEMPORARY TABLE to the binary log (this was already implemented). So that CREATE TEMPORARY TABLE and DROP TEMPORARY TABLE can not be replicated. 2. SET @@session.binlog_format must be disallowed if session has open temporary table(s). Otherwise DROP TEMPORARY TABLE is written into binary log which disobeys F-1 in the following case: SET @@session.binlog_format=STATEMENT; CREATE TEMPORARY TABLE t1 (a INT); SET @@session.binlog_format=ROW; DROP TEMPORARY TABLE t1; This is more restrictive than before. Note: SET @@session.binlog_format to the same binlog format is also disallowed if session has open temporary table(s). 3. SET @@global.binlog_format and SET @@persist.binlog_format must be disallowed if any replication channel has open temporary table(s). Otherwise DROP TEMPORARY TABLE is written into binary log on slave which disobeys F-1 in the following case: slave> SET @@global.binlog_format=STATEMENT; slave> START SLAVE; master> CREATE TEMPORARY TABLE t1(a INT); slave> [wait for t1 to replicate] slave> STOP SLAVE; slave> SET @@global.binlog_format=ROW / SET @@persist.binlog_format=ROW master> DROP TEMPORARY TABLE t1; slave> START SLAVE; This is more restrictive than before. Note: SET @@global.binlog_format and SET @@persist.binlog_format to the same binlog format are also disallowed if any replication channel has open temporary table(s). Note: SET @@persist_only.binlog_format is not disallowed if any replication channel has open temporary table(s), since unlike PERSIST, PERSIST_ONLY does not modify the runtime global system variable value. Note: Nuno and I figured out that group replication channels don't have the functional requirement F-3, because the group_replication_applier and group_replication_applier channels just apply group events in ROW binlog format, they don't have open temporary table(s). 4. SET @@global.binlog_format and SET @@persist.binlog_format must be disallowed if any replication channel applier is running, because SET @@global.binlog_format does not take effect when any replication channel applier is running. SET @@global.binlog_format takes effect on the channel until its applier is (re)starting. This is more restrictive than before. Note: SET @@global.binlog_format and SET @@persist.binlog_format to the same binlog format are also disallowed if any replication channel applier is running. Note: SET @@persist_only.binlog_format is not disallowed if any replication channel applier is running, since unlike PERSIST, PERSIST_ONLY does not modify the runtime global system variable value. Note: Nuno and I figured out that the group_replication_applier channel does not have the requirement F-4, because GR already handles that. If you set global.binlog_format or SET persist.binlog_format while GR is not running, once you try to start Group Replication, it will error out (as expected). If GR is running once the set global is effective on new connections, those connections will not be able to commit (they will be rollback). 5. Allow CREATE/DROP TEMPORARY TABLE inside a transaction when @@global.gtid_mode=ON and @@session.binlog_format=ROW/MIXED. (More specifically, we allow the statements when @@global.enforce_gtid_consistency=ON, which then implies that it is allowed when @@global.gtid_mode=ON). - Suppose user executes the following transactions: BEGIN; CREATE TEMPORARY TABLE t (a INT); COMMIT; BEGIN; DROP TEMPORARY TABLE t (a INT); COMMIT; Then both transactions shall succeed and not be written to the binary log. - Suppose user executes the following transactions: BEGIN; DML on a non-temporary table; CREATE TEMPORARY TABLE t (a INT); COMMIT; BEGIN; DML on a non-temporary table; DROP TEMPORARY TABLE t (a INT); COMMIT; Then, both transactions shall succeed, be written to the binary log without the CREATE/DROP TEMPORARY TABLE statements, and replicate to the slave. Slave_open_temp_tables shall be 0 before, between, and after the two transactions. - Suppose user executes the following transactions: BEGIN; CREATE TEMPORARY TABLE t (a INT); ROLLBACK; BEGIN; DROP TEMPORARY TABLE t (a INT); ROLLBACK; BEGIN; DML on a non-temporary table; CREATE TEMPORARY TABLE temp1 (a INT); DML on a temporary table; ROLLBACK; BEGIN; DML on a non-temporary table; DML on a temporary table; DROP TEMPORARY TABLE temp1 (a INT); ROLLBACK; After rollback, any above transaction shall roll back with a warning "The creation of some temporary tables could not be rolled back." or "Some temporary tables were dropped, but these operations could not be rolled back.", and not be written to the binary log. 6. Allow CREATE/DROP TEMPORARY TABLE inside a PROCDURE when @@global.gtid_mode=ON and @@session.binlog_format=ROW/MIXED. - Suppose user creates the following single statement procedures: delimiter //; CREATE PROCEDURE sp1 () BEGIN CREATE TEMPORARY TABLE temp1 (i INT); END// CREATE PROCEDURE sp2 () BEGIN DROP TEMPORARY TABLE temp1; END// delimiter ;// CREATE/DROP TEMPORARY TABLE shall not be written to the binary log when calling the two procedures. - Suppose user creates the following multi statements procedures: CREATE TABLE t1 (c1 INT); delimiter //; CREATE PROCEDURE sp3 () BEGIN INSERT INTO t1 VALUES (9); CREATE TEMPORARY TABLE temp1 (i INT); INSERT INTO temp1 VALUES (1); END// CREATE PROCEDURE sp4 () BEGIN INSERT INTO t1 VALUES (10); INSERT INTO temp1 VALUES (2); DROP TEMPORARY TABLE temp1; END// delimiter ;// CREATE/DROP TEMPORARY TABLE shall not be written to the binary log when calling the two procedures. 7. Allow CREATE/DROP TEMPORARY TABLE inside a FUNCTION when @@global.gtid_mode=ON and @@session.binlog_format=ROW/MIXED. CREATE/DROP TEMPORARY TABLE in the FUNCTION are not written into binlog when using the FUNCTION in SELECT QUERY and in INSERT/UPDATE/DELETE QUERY. 8. Allow CREATE/DROP TEMPORARY TABLE inside a TRIGGER when @@global.gtid_mode=ON and @@session.binlog_format=ROW/MIXED. CREATE/DROP TEMPORARY TABLE in the TRIGGER are not written into binlog when the TRIGGER is triggered before/after INSERT/UPDATE/DELETE QUERY. UPGRADE/DOWNGRADE and CROSS-VERSION REPLICATION =============================================== NEW->OLD: Suppose user issues CREATE TEMPORARY TABLE or DROP TEMPORARY TABLE inside a transaction on NEW master, when gtid_mode=ON, enforce_gtid_consistency=ON, and binlog_format=ROW/MIXED. Even if this would be disallowed when executed in a client to the OLD slave, it does not cause replication to break, because CREATE/DROP TEMPORARY TABLE is not replicated when committing/rolling back the transaction. NEW->OLD: Suppose user issues CREATE TEMPORARY TABLE or DROP TEMPORARY TABLE inside a PROCDURE/FUNCTION/TRIGGER on NEW master, when gtid_mode=ON, enforce_gtid_consistency=ON, and binlog_format=ROW/MIXED. Even if this would be disallowed when executed in a client to the OLD slave, it does not cause replication to break, because CREATE/DROP TEMPORARY TABLE is not replicated when calling the PROCDURE/FUNCTION/TRIGGER. NEW->OLD: Suppose user issues CREATE TEMPORARY TABLE or DROP TEMPORARY TABLE outside a transaction on a NEW master when @@session.binlog_format=ROW/MIXED. This does not cause replication to break, because CREATE/DROP TEMPORARY TABLE is not replicated. OLD->NEW: Suppose user issues SET @@session.binlog_format=ROW on a OLD master when there are open temporary tables in the session. Even if this would be disallowed when executed on a NEW slave, this does not cause replication to break, because SET is not replicated. The same to SET @@global.binlog_format and SET @@persist.binlog_format. On upgrade, one limitation is removed, see above 5, 6, 7 and 8, there are three new limitations, see above 2, 3 and 4. OBSERVABILITY ============= Introduce several new errors and emit them. See below. ER_TEMP_TABLE_PREVENTS_SWITCH_SESSION_BINLOG_FORMAT eng "Changing @@session.binlog_format is disallowed when the session has open temporary table(s). You could wait until these temporary table(s) are dropped and try again." Emit the above error to the client side on the session when it has open temporary table(s). Don't write the error into error log. ER_TEMP_TABLE_PREVENTS_SWITCH_GLOBAL_BINLOG_FORMAT eng "Changing @@global.binlog_format or @@persist.binlog_format is disallowed when any replication channel has open temporary table(s). You could wait until Slave_open_temp_tables = 0 and try again" Emit the above error to the client side on the session when any replication channel has open temporary table(s). Don't write the error into error log. ER_RUNNING_APPLIER_PREVENTS_SWITCH_GLOBAL_BINLOG_FORMAT eng "Changing @@global.binlog_format or @@persist.binlog_format is disallowed when any replication channel applier thread is running. You could execute STOP SLAVE SQL_THREAD and try again." Emit the above error to the client side on the session when any replication channel applier is running. Don't write the error into error log. ER_CLIENT_GTID_UNSAFE_CREATE_DROP_TEMP_TABLE_IN_TRX_IN_SBR eng "Statement violates GTID consistency: CREATE TEMPORARY TABLE and DROP TEMPORARY TABLE are not allowed inside a transaction or inside a procedure in a transactional context when @@session.binlog_format=STATEMENT." Emit the above error to the client side on the session when creating/droping TEMPORARY TABLE inside a transaction or procedure, in case @@session.binlog_format=STATEMENT. ER_SERVER_GTID_UNSAFE_CREATE_DROP_TEMP_TABLE_IN_TRX_IN_SBR eng "Statement violates GTID consistency: CREATE TEMPORARY TABLE and DROP TEMPORARY TABLE are not allowed inside a transaction or inside a procedure in a transactional context when @@session.binlog_format=STATEMENT." Write the above warning message to server error log when creating/droping TEMPORARY TABLE inside a transaction or procedure, in case @@session.binlog_format=STATEMENT and ENFORCE_GTID_CONSISTENCY = WARN.
Copyright (c) 2000, 2024, Oracle Corporation and/or its affiliates. All rights reserved.