MDEV-16708: fixed assert firing in the method THD::reset_for_the_next_command
This commit is contained in:
parent
994e3f40b5
commit
fe78495053
@ -354,8 +354,28 @@ void mysql_client_binlog_statement(THD* thd)
|
|||||||
(ev->flags & LOG_EVENT_SKIP_REPLICATION_F ?
|
(ev->flags & LOG_EVENT_SKIP_REPLICATION_F ?
|
||||||
OPTION_SKIP_REPLICATION : 0);
|
OPTION_SKIP_REPLICATION : 0);
|
||||||
|
|
||||||
err= ev->apply_event(rgi);
|
{
|
||||||
|
/*
|
||||||
|
For conventional statements thd->lex points to thd->main_lex, that is
|
||||||
|
thd->lex == &thd->main_lex. On the other hand, for prepared statement
|
||||||
|
thd->lex points to the LEX object explicitly allocated for execution
|
||||||
|
of the prepared statement and in this case thd->lex != &thd->main_lex.
|
||||||
|
On handling the BINLOG statement, invocation of ev->apply_event(rgi)
|
||||||
|
initiates the following sequence of calls
|
||||||
|
Rows_log_event::do_apply_event -> THD::reset_for_next_command
|
||||||
|
Since the method THD::reset_for_next_command() contains assert
|
||||||
|
DBUG_ASSERT(lex == &main_lex)
|
||||||
|
this sequence of calls results in crash when a binlog event is
|
||||||
|
applied in PS mode. So, reset the current lex temporary to point to
|
||||||
|
thd->main_lex before running ev->apply_event() and restore its
|
||||||
|
original value on return.
|
||||||
|
*/
|
||||||
|
LEX *backup_lex;
|
||||||
|
|
||||||
|
thd->backup_and_reset_current_lex(&backup_lex);
|
||||||
|
err= ev->apply_event(rgi);
|
||||||
|
thd->restore_current_lex(backup_lex);
|
||||||
|
}
|
||||||
thd->variables.option_bits=
|
thd->variables.option_bits=
|
||||||
(thd->variables.option_bits & ~OPTION_SKIP_REPLICATION) |
|
(thd->variables.option_bits & ~OPTION_SKIP_REPLICATION) |
|
||||||
save_skip_replication;
|
save_skip_replication;
|
||||||
|
@ -5453,6 +5453,33 @@ public:
|
|||||||
return (variables.old_behavior & OLD_MODE_UTF8_IS_UTF8MB3 ?
|
return (variables.old_behavior & OLD_MODE_UTF8_IS_UTF8MB3 ?
|
||||||
MY_UTF8_IS_UTF8MB3 : 0);
|
MY_UTF8_IS_UTF8MB3 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Save current lex to the output parameter and reset it to point to
|
||||||
|
main_lex. This method is called from mysql_client_binlog_statement()
|
||||||
|
to temporary
|
||||||
|
|
||||||
|
@param[out] backup_lex original value of current lex
|
||||||
|
*/
|
||||||
|
|
||||||
|
void backup_and_reset_current_lex(LEX **backup_lex)
|
||||||
|
{
|
||||||
|
*backup_lex= lex;
|
||||||
|
lex= &main_lex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Restore current lex to its original value it had before calling the method
|
||||||
|
backup_and_reset_current_lex().
|
||||||
|
|
||||||
|
@param backup_lex original value of current lex
|
||||||
|
*/
|
||||||
|
|
||||||
|
void restore_current_lex(LEX *backup_lex)
|
||||||
|
{
|
||||||
|
lex= backup_lex;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user