File tree Expand file tree Collapse file tree 2 files changed +48
-1
lines changed Expand file tree Collapse file tree 2 files changed +48
-1
lines changed Original file line number Diff line number Diff line change @@ -354,8 +354,28 @@ void mysql_client_binlog_statement(THD* thd)
354
354
(ev->flags & LOG_EVENT_SKIP_REPLICATION_F ?
355
355
OPTION_SKIP_REPLICATION : 0 );
356
356
357
- err= ev->apply_event (rgi);
357
+ {
358
+ /*
359
+ For conventional statements thd->lex points to thd->main_lex, that is
360
+ thd->lex == &thd->main_lex. On the other hand, for prepared statement
361
+ thd->lex points to the LEX object explicitly allocated for execution
362
+ of the prepared statement and in this case thd->lex != &thd->main_lex.
363
+ On handling the BINLOG statement, invocation of ev->apply_event(rgi)
364
+ initiates the following sequence of calls
365
+ Rows_log_event::do_apply_event -> THD::reset_for_next_command
366
+ Since the method THD::reset_for_next_command() contains assert
367
+ DBUG_ASSERT(lex == &main_lex)
368
+ this sequence of calls results in crash when a binlog event is
369
+ applied in PS mode. So, reset the current lex temporary to point to
370
+ thd->main_lex before running ev->apply_event() and restore its
371
+ original value on return.
372
+ */
373
+ LEX *backup_lex;
358
374
375
+ thd->backup_and_reset_current_lex (&backup_lex);
376
+ err= ev->apply_event (rgi);
377
+ thd->restore_current_lex (backup_lex);
378
+ }
359
379
thd->variables .option_bits =
360
380
(thd->variables .option_bits & ~OPTION_SKIP_REPLICATION) |
361
381
save_skip_replication;
Original file line number Diff line number Diff line change @@ -5453,6 +5453,33 @@ class THD: public THD_count, /* this must be first */
5453
5453
return (variables.old_behavior & OLD_MODE_UTF8_IS_UTF8MB3 ?
5454
5454
MY_UTF8_IS_UTF8MB3 : 0 );
5455
5455
}
5456
+
5457
+ /* *
5458
+ Save current lex to the output parameter and reset it to point to
5459
+ main_lex. This method is called from mysql_client_binlog_statement()
5460
+ to temporary
5461
+
5462
+ @param[out] backup_lex original value of current lex
5463
+ */
5464
+
5465
+ void backup_and_reset_current_lex (LEX **backup_lex)
5466
+ {
5467
+ *backup_lex= lex;
5468
+ lex= &main_lex;
5469
+ }
5470
+
5471
+
5472
+ /* *
5473
+ Restore current lex to its original value it had before calling the method
5474
+ backup_and_reset_current_lex().
5475
+
5476
+ @param backup_lex original value of current lex
5477
+ */
5478
+
5479
+ void restore_current_lex (LEX *backup_lex)
5480
+ {
5481
+ lex= backup_lex;
5482
+ }
5456
5483
};
5457
5484
5458
5485
You can’t perform that action at this time.
0 commit comments