Skip to content
  • Sven Sandberg's avatar
    21ec004b
    BUG#20883676: ASSERT `THD->OWNED_GTID.SIDNO == THD::OWNED_SIDNO_ANONYMOUS' AT BINLOG.CC:1144 · 21ec004b
    Sven Sandberg authored
    Background:
    
    For 5.7 binary logs (after WL#7592), the slave applier thread sets
    GTID_NEXT according to the Gtid_log_event or Anonymous_log_event
    preceding every transaction.  For 5.6 binary logs using GTID_MODE=ON,
    it does the same.  But for 5.6 binary log using GTID_MODE=OFF, or for
    5.5 or earlier binary logs, there are no Gtid_log_events or
    Anonymous_gtid_log_event.  In order to set gtid_next correctly also
    for this case, we use a special mechanism: when any
    Format_description_log_event is applied, it sets
    thd->variables.gtid_next.type=NOT_YET_DETERMINED_GROUP.  The next
    statement to execute then sets the real value for gtid_next: if the
    next statement is SET GTID_NEXT, then gtid_next is set accordingly. If
    the next statement is anything else, it assumes that this is an old
    binary log and changes NOT_YET_DETERMINED_GROUP to ANONYMOUS_GROUP.
    
    The code that changes NOT_YET_DETERMINED_GROUP to ANONYMOUS_GROUP
    invoked for SQL statements (from mysql_parse). This normally covers
    also the RBR case, because RBR transactions begin with a
    query_log_event(BEGIN), so it will set gtid_next=ANONYMOUS for the
    BEGIN statement.
    
    However, if the applier thread begins execution in the middle of a
    transaction, it is possible that a row event is processed when
    gtid_next.type is NOT_YET_DETERMINED_GROUP.  This can happen if
    an explicit CHANGE MASTER TO RELAY_LOG_POS statement positions the
    applier thread after the BEGIN statement, or if an explicit CHANGE
    MASTER TO MASTER_LOG_POS statement positions the receiver thread in
    the middle of a transaction.  Therefore, even Rows_log_events need to upgrade
    NOT_YET_DETERMINED_GROUP to ANONYMOUS.
    
    Problem:
    
    Rows_log_events did not upgrade NOT_YET_DETERMINED to ANONYMOUS.  This
    was a regression introduced by WL#7592 step 14.  Prior to WL#7592 step
    14, this logic was invoked from the function
    gtid_pre_statement_checks, which was invoked from Rows_log_event.
    However in WL#7592 step 14, gtid_pre_statement_checks was split into
    two functions, gtid_pre_statement_checks and
    gtid_pre_statement_post_implicit_commit_checks, where the latter
    contained the logic to upgrade NOT_YET_DETERMINED to ANONYMOUS.  The
    place where Rows_log_event calls gtid_pre_statement_checks was not
    updated so it still only called gtid_pre_statement_checks.
    
    Fix:
    
    Call gtid_pre_statement_post_implicit_commit_checks from
    Rows_log_event.
    21ec004b
    BUG#20883676: ASSERT `THD->OWNED_GTID.SIDNO == THD::OWNED_SIDNO_ANONYMOUS' AT BINLOG.CC:1144
    Sven Sandberg authored
    Background:
    
    For 5.7 binary logs (after WL#7592), the slave applier thread sets
    GTID_NEXT according to the Gtid_log_event or Anonymous_log_event
    preceding every transaction.  For 5.6 binary logs using GTID_MODE=ON,
    it does the same.  But for 5.6 binary log using GTID_MODE=OFF, or for
    5.5 or earlier binary logs, there are no Gtid_log_events or
    Anonymous_gtid_log_event.  In order to set gtid_next correctly also
    for this case, we use a special mechanism: when any
    Format_description_log_event is applied, it sets
    thd->variables.gtid_next.type=NOT_YET_DETERMINED_GROUP.  The next
    statement to execute then sets the real value for gtid_next: if the
    next statement is SET GTID_NEXT, then gtid_next is set accordingly. If
    the next statement is anything else, it assumes that this is an old
    binary log and changes NOT_YET_DETERMINED_GROUP to ANONYMOUS_GROUP.
    
    The code that changes NOT_YET_DETERMINED_GROUP to ANONYMOUS_GROUP
    invoked for SQL statements (from mysql_parse). This normally covers
    also the RBR case, because RBR transactions begin with a
    query_log_event(BEGIN), so it will set gtid_next=ANONYMOUS for the
    BEGIN statement.
    
    However, if the applier thread begins execution in the middle of a
    transaction, it is possible that a row event is processed when
    gtid_next.type is NOT_YET_DETERMINED_GROUP.  This can happen if
    an explicit CHANGE MASTER TO RELAY_LOG_POS statement positions the
    applier thread after the BEGIN statement, or if an explicit CHANGE
    MASTER TO MASTER_LOG_POS statement positions the receiver thread in
    the middle of a transaction.  Therefore, even Rows_log_events need to upgrade
    NOT_YET_DETERMINED_GROUP to ANONYMOUS.
    
    Problem:
    
    Rows_log_events did not upgrade NOT_YET_DETERMINED to ANONYMOUS.  This
    was a regression introduced by WL#7592 step 14.  Prior to WL#7592 step
    14, this logic was invoked from the function
    gtid_pre_statement_checks, which was invoked from Rows_log_event.
    However in WL#7592 step 14, gtid_pre_statement_checks was split into
    two functions, gtid_pre_statement_checks and
    gtid_pre_statement_post_implicit_commit_checks, where the latter
    contained the logic to upgrade NOT_YET_DETERMINED to ANONYMOUS.  The
    place where Rows_log_event calls gtid_pre_statement_checks was not
    updated so it still only called gtid_pre_statement_checks.
    
    Fix:
    
    Call gtid_pre_statement_post_implicit_commit_checks from
    Rows_log_event.
Loading