Skip to content
  • Daogang Qu's avatar
    adad957b
    Bug#20954452 GTID IS NOT RELEASED PROPERLY WHEN PS_PROTOCOL + GTID + BINLOG OFF COMBINATION · adad957b
    Daogang Qu authored
    When we start server with ps protocol and disabled binlog, executing
    DDL statement did not get a chance to call update_gtids_impl(...) to
    release its specified gtid, due to it miss to call ha_commit_trans(...)
    in trans_commit_stmt(...), since it is not active at that time; DDLs
    were using COM_STMT_PREPARE/COM_STMT_EXECUTE, so it also missed to
    call mysql_parse(...) to release its specified gtid.
    
    We fix the problem by moving the call to gtid_end_transaction(...)
    away from mysql_parse(....), into mysql_execute_command(...), since
    these DDLs with ps protocol are calling mysql_execute_command(...)
    by COM_STMT_EXECUTE and other normal transactions are calling
    mysql_execute_command(...) by mysql_parse(...).
    
    BUG#19774317  GTID_NEXT WITH EMPTY TRANSACTIONS DOES NOT WORK INSIDE STORED PROCEDURES
    
    Setting gtid_next inside a stored procedure and committing an empty
    transaction does not work. The root cause is that we failed to log
    the empty group to consume the GTID specified by setting gtid_next
    , due to the transaction owned gtid is cleared before calling
    gtid_end_transaction in mysql_parse(...).
    
    We also can fix the first problem by moving the call to
    gtid_end_transaction(...) away from mysql_parse(....), into
    mysql_execute_command(...), since committing the empty transaction
    with a specified GTID in stored procedure has a chance to call
    gtid_end_transaction(...) in mysql_execute_command(...) to log an
    empty group to consume the specified GTID.
    
    Bug#20343644  ASSERTION AT BINLOG.CC:1120 WHEN GTID_MODE=ON, GTID_NEXT='UUID:NUMBER'
    Bug#20444828  WL7592: ASSERT `THD->VARIABLES.GTID_NEXT.TYPE == GTID_GROUP' ON CREATE..SELECT
    
    Problem1: When gtid_mode is on, Start a transaction with a specified
    gtid, then create a table to cause an error, on commit we are hitting
    an assertion failure "thd->variables.gtid_next.type != UNDEFINED_GROUP".
    Problem2: When gtid_mode is on, set gtid_next with a specified gtid,
    then execute the statement 'CREATE..SELECT' to cause an error, on
    commit we are hitting the above assertion failure. The root cause is
    that we set gtid_next to undefined in gtid_post_statement_checks(...),
    which is called unconditionally after any statement in
    THD::cleanup_after_query(...). This means that gtid_next will be set
    to undefined for implicitly committing statements, even if the
    statement failed with an error before the implicit commit happened.
    Then, the transaction is still open and gtid_next is undefined. This
    is an invalid state, which triggers the assertion at commit time.
    
    The gtid_post_statement_checks(...) was introduced in BUG#16223835,
    the reason the function is needed is the following case:
     1. SET GTID_NEXT='<GTID that is already included in gtid_executed>';
     2. BEGIN;
     3. ... dml dml dml ...
     4. COMMIT;
    Then, the commit on line 4 will not invoke update_gtids_impl because
    the GTID is already included in GTID_EXECUTED so the thread does not
    own the GTID. So then the call to set_undefined from
    gtid_post_statement_checks is really needed in this case. But this
    causes it to call set_undefined too often and causes the assertion
    reported in this bug.
    
    To fix the problem, we remove gtid_post_statement_checks, add a call
    to set_undefined() in Gtid_state::update_gtids_impl(...), and add a
    call to update_gtids_impl(...) in gtid_end_transaction(...), in case
    the transaction owned gtid is empty and the gtid_next type is
    GTID_GROUP.
    adad957b
    Bug#20954452 GTID IS NOT RELEASED PROPERLY WHEN PS_PROTOCOL + GTID + BINLOG OFF COMBINATION
    Daogang Qu authored
    When we start server with ps protocol and disabled binlog, executing
    DDL statement did not get a chance to call update_gtids_impl(...) to
    release its specified gtid, due to it miss to call ha_commit_trans(...)
    in trans_commit_stmt(...), since it is not active at that time; DDLs
    were using COM_STMT_PREPARE/COM_STMT_EXECUTE, so it also missed to
    call mysql_parse(...) to release its specified gtid.
    
    We fix the problem by moving the call to gtid_end_transaction(...)
    away from mysql_parse(....), into mysql_execute_command(...), since
    these DDLs with ps protocol are calling mysql_execute_command(...)
    by COM_STMT_EXECUTE and other normal transactions are calling
    mysql_execute_command(...) by mysql_parse(...).
    
    BUG#19774317  GTID_NEXT WITH EMPTY TRANSACTIONS DOES NOT WORK INSIDE STORED PROCEDURES
    
    Setting gtid_next inside a stored procedure and committing an empty
    transaction does not work. The root cause is that we failed to log
    the empty group to consume the GTID specified by setting gtid_next
    , due to the transaction owned gtid is cleared before calling
    gtid_end_transaction in mysql_parse(...).
    
    We also can fix the first problem by moving the call to
    gtid_end_transaction(...) away from mysql_parse(....), into
    mysql_execute_command(...), since committing the empty transaction
    with a specified GTID in stored procedure has a chance to call
    gtid_end_transaction(...) in mysql_execute_command(...) to log an
    empty group to consume the specified GTID.
    
    Bug#20343644  ASSERTION AT BINLOG.CC:1120 WHEN GTID_MODE=ON, GTID_NEXT='UUID:NUMBER'
    Bug#20444828  WL7592: ASSERT `THD->VARIABLES.GTID_NEXT.TYPE == GTID_GROUP' ON CREATE..SELECT
    
    Problem1: When gtid_mode is on, Start a transaction with a specified
    gtid, then create a table to cause an error, on commit we are hitting
    an assertion failure "thd->variables.gtid_next.type != UNDEFINED_GROUP".
    Problem2: When gtid_mode is on, set gtid_next with a specified gtid,
    then execute the statement 'CREATE..SELECT' to cause an error, on
    commit we are hitting the above assertion failure. The root cause is
    that we set gtid_next to undefined in gtid_post_statement_checks(...),
    which is called unconditionally after any statement in
    THD::cleanup_after_query(...). This means that gtid_next will be set
    to undefined for implicitly committing statements, even if the
    statement failed with an error before the implicit commit happened.
    Then, the transaction is still open and gtid_next is undefined. This
    is an invalid state, which triggers the assertion at commit time.
    
    The gtid_post_statement_checks(...) was introduced in BUG#16223835,
    the reason the function is needed is the following case:
     1. SET GTID_NEXT='<GTID that is already included in gtid_executed>';
     2. BEGIN;
     3. ... dml dml dml ...
     4. COMMIT;
    Then, the commit on line 4 will not invoke update_gtids_impl because
    the GTID is already included in GTID_EXECUTED so the thread does not
    own the GTID. So then the call to set_undefined from
    gtid_post_statement_checks is really needed in this case. But this
    causes it to call set_undefined too often and causes the assertion
    reported in this bug.
    
    To fix the problem, we remove gtid_post_statement_checks, add a call
    to set_undefined() in Gtid_state::update_gtids_impl(...), and add a
    call to update_gtids_impl(...) in gtid_end_transaction(...), in case
    the transaction owned gtid is empty and the gtid_next type is
    GTID_GROUP.
Loading