Skip to content
  • Venkatesh Duggirala's avatar
    27ed5bb4
    BUG#21253415 MULTIPLE DROP TEMP TABLE STATEMENTS IN SF CAUSE REPLICATION · 27ed5bb4
    Venkatesh Duggirala authored
     FAILS USING 5.6 GTID
     Problem: When there are more than one drop temp table in stored function
              or trigger, replication is failing when GTIDs are enabled.
    
     Analysis: In ROW based replication format, even though CREATE TEMPORARY
               TABLE query is not replicated, DROP TEMPORARY TABLE queries
               are replicated to achieve proper clean up on Slave end (CREATE
               TEMPORARY TABLE query would have executed and replicated when
               the replication format is STATEMENT) by adding 'IF EXISTS'
               clause. When DROP TEMPORARY TABLE query is in a stored function
               along with some DML statements, the binlog equivalent query
               for that function execution will look like
               BEGIN
                 DROP TEMP TABLE ...
                 ROW EVENT FOR DML 1
                 ROW EVENT FOR DML 2
               END
               But when GTIDs are enabled, it is documented that CREATE/DROP
               TEMPORARY TABLE queries are not allowed in Multi Statement
               Transactions because half executed gtid transactions (rolled
               back of these transactions) can leave these temporary tables
               in a bad state.
               In the old code, one DROP TEMPORARY TABLE in a function is
               working fine because the 'DROP TEMP TABLE' is going into
               STMT_CACHE (which does not be wrapped with BEGIN/COMMIT).
               //STMT_CACHE
               GTID_EVENT
               DROP TEMP TABLE ...
               //TRANS_CACHE
               GTID_EVENT
               BEGIN
                 ROW EVENT FOR DML 1
                 ROW EVENT FOR DML 2
               END
    
               But if the function contains two 'DROP TEMP TABLE's, both
               of them are going into 'STMT_CACHE' (which does not be wrapped
               with BEGIN/COMMIT) and STMT_CACHE with one gtid_event cannot
               accommodate two separate DROP TEMP TABLE queries. And with above
               Multi Statement Transactions + GTID restriction, we cannot
               add 'BEGIN/COMMIT'.
    
    Fix:  Stored functions and Triggers are also considered as another form of
          Multi Statement Transactions across the server. To maintain gtid
          consistency and to avoid the problems that are mentioned in this bug
          scenario,  CREATE/DROP temp tables are disallowed from stored functions
          and triggers also just like how they were restricted in Multi Statement
          Transactions. Now function execution that has CREATE/DROP TEMP TABLES
          will throw ER_GTID_UNSAFE_CREATE_DROP_TEMPORARY_TABLE_IN_TRANSACTION.
          ("When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, the statements CREATE
            TEMPORARY TABLE and DROP TEMPORARY TABLE can be executed in a
            non-transactional context only, and require that AUTOCOMMIT = 1. These
            statements are not allowed in Functions or Triggers also as they are also
            considered as Multi Statement transaction.)
    27ed5bb4
    BUG#21253415 MULTIPLE DROP TEMP TABLE STATEMENTS IN SF CAUSE REPLICATION
    Venkatesh Duggirala authored
     FAILS USING 5.6 GTID
     Problem: When there are more than one drop temp table in stored function
              or trigger, replication is failing when GTIDs are enabled.
    
     Analysis: In ROW based replication format, even though CREATE TEMPORARY
               TABLE query is not replicated, DROP TEMPORARY TABLE queries
               are replicated to achieve proper clean up on Slave end (CREATE
               TEMPORARY TABLE query would have executed and replicated when
               the replication format is STATEMENT) by adding 'IF EXISTS'
               clause. When DROP TEMPORARY TABLE query is in a stored function
               along with some DML statements, the binlog equivalent query
               for that function execution will look like
               BEGIN
                 DROP TEMP TABLE ...
                 ROW EVENT FOR DML 1
                 ROW EVENT FOR DML 2
               END
               But when GTIDs are enabled, it is documented that CREATE/DROP
               TEMPORARY TABLE queries are not allowed in Multi Statement
               Transactions because half executed gtid transactions (rolled
               back of these transactions) can leave these temporary tables
               in a bad state.
               In the old code, one DROP TEMPORARY TABLE in a function is
               working fine because the 'DROP TEMP TABLE' is going into
               STMT_CACHE (which does not be wrapped with BEGIN/COMMIT).
               //STMT_CACHE
               GTID_EVENT
               DROP TEMP TABLE ...
               //TRANS_CACHE
               GTID_EVENT
               BEGIN
                 ROW EVENT FOR DML 1
                 ROW EVENT FOR DML 2
               END
    
               But if the function contains two 'DROP TEMP TABLE's, both
               of them are going into 'STMT_CACHE' (which does not be wrapped
               with BEGIN/COMMIT) and STMT_CACHE with one gtid_event cannot
               accommodate two separate DROP TEMP TABLE queries. And with above
               Multi Statement Transactions + GTID restriction, we cannot
               add 'BEGIN/COMMIT'.
    
    Fix:  Stored functions and Triggers are also considered as another form of
          Multi Statement Transactions across the server. To maintain gtid
          consistency and to avoid the problems that are mentioned in this bug
          scenario,  CREATE/DROP temp tables are disallowed from stored functions
          and triggers also just like how they were restricted in Multi Statement
          Transactions. Now function execution that has CREATE/DROP TEMP TABLES
          will throw ER_GTID_UNSAFE_CREATE_DROP_TEMPORARY_TABLE_IN_TRANSACTION.
          ("When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, the statements CREATE
            TEMPORARY TABLE and DROP TEMPORARY TABLE can be executed in a
            non-transactional context only, and require that AUTOCOMMIT = 1. These
            statements are not allowed in Functions or Triggers also as they are also
            considered as Multi Statement transaction.)
Loading