-
Sujatha Sivakumar authored
PROPERLY FOR XA ON SLAVE Problem: ======= When transaction instrumentation and consumers are enabled, the events_transaction_% tables can be used to find the XA xid components in a much cleaner way than using XA RECOVER. However this does not work correctly on the replication slave as the XA STATE is COMMITTED even if it should only be PREPARED. Analysis: ========= On master an XA transaction is written to the binary log in two parts. When XA PREPARE is issued, the first part of the transaction up to XA PREPARE is written. When XA COMMIT or XA ROLLBACK is issued, a second part of the transaction is written to the binlog. Hence in binary log few more transactions can be present in between XA PREPARE and XA COMMIT. On slave server applier thread will be applying all these transactions. Each active transaction will register itself with performance schema so that its progress status can be tracked in performance schema table. For each transaction 'begin' and 'commit', there is an internal 'start_transaction' and 'end_transaction' that will happen within performance schema. When applier thread starts executing 'XA PREPARE' it registers itself with performance schema and the transaction state will be 'XA_PREPARE'. At the end of the transaction applier invokes 'applier_reset_xa_trans' to do the cleanup for active XA transaction. Which intern invokes 'MYSQL_COMMIT_TRANSACTION' which will set the XA_STATE to 'COMMITTED' in performance schema. At this point if users execute XA RECOVER on slave the XA_STATE will be shown as 'PREPARED' but performance schema table will show it as 'COMMITTED'. Fix: === During the execution of 'XA PREPARE' don't commit the transaction in PSI context. Leave the PFS state as it is. Clear the current thread transaction PSI specific pointer as NULL. With this current transaction will exit cleanly without altering the XA_STATE. 'XA COMMIT' is not a regular transaction. But it has all the required XA transaction specific information to start a transaction in PSI context alone. Hence start a new transaction in PSI context by executing MYSQL_START_TRANSACTION. Initialize the new PSI transaction with XA details. This process will also ensure that current GTID is updated in PSI transaction. Then call 'MYSQL_COMMIT_TRANSACTION'. This will provide appropriate XA status for 'XA COMMIT' statement.
Sujatha Sivakumar authoredPROPERLY FOR XA ON SLAVE Problem: ======= When transaction instrumentation and consumers are enabled, the events_transaction_% tables can be used to find the XA xid components in a much cleaner way than using XA RECOVER. However this does not work correctly on the replication slave as the XA STATE is COMMITTED even if it should only be PREPARED. Analysis: ========= On master an XA transaction is written to the binary log in two parts. When XA PREPARE is issued, the first part of the transaction up to XA PREPARE is written. When XA COMMIT or XA ROLLBACK is issued, a second part of the transaction is written to the binlog. Hence in binary log few more transactions can be present in between XA PREPARE and XA COMMIT. On slave server applier thread will be applying all these transactions. Each active transaction will register itself with performance schema so that its progress status can be tracked in performance schema table. For each transaction 'begin' and 'commit', there is an internal 'start_transaction' and 'end_transaction' that will happen within performance schema. When applier thread starts executing 'XA PREPARE' it registers itself with performance schema and the transaction state will be 'XA_PREPARE'. At the end of the transaction applier invokes 'applier_reset_xa_trans' to do the cleanup for active XA transaction. Which intern invokes 'MYSQL_COMMIT_TRANSACTION' which will set the XA_STATE to 'COMMITTED' in performance schema. At this point if users execute XA RECOVER on slave the XA_STATE will be shown as 'PREPARED' but performance schema table will show it as 'COMMITTED'. Fix: === During the execution of 'XA PREPARE' don't commit the transaction in PSI context. Leave the PFS state as it is. Clear the current thread transaction PSI specific pointer as NULL. With this current transaction will exit cleanly without altering the XA_STATE. 'XA COMMIT' is not a regular transaction. But it has all the required XA transaction specific information to start a transaction in PSI context alone. Hence start a new transaction in PSI context by executing MYSQL_START_TRANSACTION. Initialize the new PSI transaction with XA details. This process will also ensure that current GTID is updated in PSI transaction. Then call 'MYSQL_COMMIT_TRANSACTION'. This will provide appropriate XA status for 'XA COMMIT' statement.
Loading