@@ -3133,6 +3133,7 @@ void MYSQL_BIN_LOG::cleanup()
3133
3133
mysql_mutex_destroy (&LOCK_index);
3134
3134
mysql_mutex_destroy (&LOCK_xid_list);
3135
3135
mysql_mutex_destroy (&LOCK_binlog_background_thread);
3136
+ mysql_mutex_destroy (&LOCK_binlog_end_pos);
3136
3137
mysql_cond_destroy (&update_cond);
3137
3138
mysql_cond_destroy (&COND_queue_busy);
3138
3139
mysql_cond_destroy (&COND_xid_list);
@@ -3178,6 +3179,9 @@ void MYSQL_BIN_LOG::init_pthread_objects()
3178
3179
&COND_binlog_background_thread, 0 );
3179
3180
mysql_cond_init (key_BINLOG_COND_binlog_background_thread_end,
3180
3181
&COND_binlog_background_thread_end, 0 );
3182
+
3183
+ mysql_mutex_init (m_key_LOCK_binlog_end_pos, &LOCK_binlog_end_pos,
3184
+ MY_MUTEX_INIT_SLOW);
3181
3185
}
3182
3186
3183
3187
@@ -3524,10 +3528,19 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
3524
3528
if (flush_io_cache (&log_file) ||
3525
3529
mysql_file_sync (log_file.file , MYF (MY_WME|MY_SYNC_FILESIZE)))
3526
3530
goto err;
3527
- mysql_mutex_lock (&LOCK_commit_ordered);
3528
- strmake_buf (last_commit_pos_file, log_file_name);
3529
- last_commit_pos_offset= my_b_tell (&log_file);
3530
- mysql_mutex_unlock (&LOCK_commit_ordered);
3531
+
3532
+ my_off_t offset= my_b_tell (&log_file);
3533
+
3534
+ if (!is_relay_log)
3535
+ {
3536
+ /* update binlog_end_pos so that it can be read by after sync hook */
3537
+ reset_binlog_end_pos (log_file_name, offset);
3538
+
3539
+ mysql_mutex_lock (&LOCK_commit_ordered);
3540
+ strmake_buf (last_commit_pos_file, log_file_name);
3541
+ last_commit_pos_offset= offset;
3542
+ mysql_mutex_unlock (&LOCK_commit_ordered);
3543
+ }
3531
3544
3532
3545
if (write_file_name_to_index_file)
3533
3546
{
@@ -3632,6 +3645,7 @@ int MYSQL_BIN_LOG::get_current_log(LOG_INFO* linfo)
3632
3645
3633
3646
int MYSQL_BIN_LOG::raw_get_current_log (LOG_INFO* linfo)
3634
3647
{
3648
+ mysql_mutex_assert_owner (&LOCK_log);
3635
3649
strmake_buf (linfo->log_file_name , log_file_name);
3636
3650
linfo->pos = my_b_tell (&log_file);
3637
3651
return 0 ;
@@ -4797,6 +4811,20 @@ void MYSQL_BIN_LOG::make_log_name(char* buf, const char* log_ident)
4797
4811
4798
4812
bool MYSQL_BIN_LOG::is_active (const char *log_file_name_arg)
4799
4813
{
4814
+ /* *
4815
+ * there should/must be mysql_mutex_assert_owner(&LOCK_log) here...
4816
+ * but code violates this! (scary monsters and super creeps!)
4817
+ *
4818
+ * example stacktrace:
4819
+ * #8 MYSQL_BIN_LOG::is_active
4820
+ * #9 MYSQL_BIN_LOG::can_purge_log
4821
+ * #10 MYSQL_BIN_LOG::purge_logs
4822
+ * #11 MYSQL_BIN_LOG::purge_first_log
4823
+ * #12 next_event
4824
+ * #13 exec_relay_log_event
4825
+ *
4826
+ * I didn't investigate if this is ligit...(i.e if my comment is wrong)
4827
+ */
4800
4828
return !strcmp (log_file_name, log_file_name_arg);
4801
4829
}
4802
4830
@@ -5359,6 +5387,7 @@ binlog_start_consistent_snapshot(handlerton *hton, THD *thd)
5359
5387
binlog_cache_mngr *const cache_mngr= thd->binlog_setup_trx_data ();
5360
5388
5361
5389
/* Server layer calls us with LOCK_commit_ordered locked, so this is safe. */
5390
+ mysql_mutex_assert_owner (&LOCK_commit_ordered);
5362
5391
strmake_buf (cache_mngr->last_commit_pos_file , mysql_bin_log.last_commit_pos_file );
5363
5392
cache_mngr->last_commit_pos_offset = mysql_bin_log.last_commit_pos_offset ;
5364
5393
@@ -6013,6 +6042,14 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
6013
6042
}
6014
6043
else
6015
6044
{
6045
+ /* update binlog_end_pos so it can be read by dump thread
6046
+ *
6047
+ * note: must be _after_ the RUN_HOOK(after_flush) or else
6048
+ * semi-sync-plugin might not have put the transaction into
6049
+ * it's list before dump-thread tries to send it
6050
+ */
6051
+ update_binlog_end_pos (offset);
6052
+
6016
6053
signal_update ();
6017
6054
if ((error= rotate (false , &check_purge)))
6018
6055
check_purge= false ;
@@ -6664,6 +6701,9 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd)
6664
6701
}
6665
6702
6666
6703
offset= my_b_tell (&log_file);
6704
+
6705
+ update_binlog_end_pos (offset);
6706
+
6667
6707
/*
6668
6708
Take mutex to protect against a reader seeing partial writes of 64-bit
6669
6709
offset on 32-bit CPUs.
@@ -6709,6 +6749,9 @@ MYSQL_BIN_LOG::write_binlog_checkpoint_event_already_locked(const char *name,
6709
6749
}
6710
6750
6711
6751
offset= my_b_tell (&log_file);
6752
+
6753
+ update_binlog_end_pos (offset);
6754
+
6712
6755
/*
6713
6756
Take mutex to protect against a reader seeing partial writes of 64-bit
6714
6757
offset on 32-bit CPUs.
@@ -7335,7 +7378,8 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
7335
7378
{
7336
7379
if (!current->error &&
7337
7380
RUN_HOOK (binlog_storage, after_flush,
7338
- (current->thd , log_file_name,
7381
+ (current->thd ,
7382
+ current->cache_mngr ->last_commit_pos_file ,
7339
7383
current->cache_mngr ->last_commit_pos_offset , synced)))
7340
7384
{
7341
7385
current->error = ER_ERROR_ON_WRITE;
@@ -7347,6 +7391,14 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
7347
7391
all_error= false ;
7348
7392
}
7349
7393
7394
+ /* update binlog_end_pos so it can be read by dump thread
7395
+ *
7396
+ * note: must be _after_ the RUN_HOOK(after_flush) or else
7397
+ * semi-sync-plugin might not have put the transaction into
7398
+ * it's list before dump-thread tries to send it
7399
+ */
7400
+ update_binlog_end_pos (commit_offset);
7401
+
7350
7402
if (any_error)
7351
7403
sql_print_error (" Failed to run 'after_flush' hooks" );
7352
7404
if (!all_error)
@@ -7387,6 +7439,10 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
7387
7439
7388
7440
DEBUG_SYNC (leader->thd , " commit_before_get_LOCK_commit_ordered" );
7389
7441
mysql_mutex_lock (&LOCK_commit_ordered);
7442
+ /* *
7443
+ * TODO(jonaso): Check with Kristian,
7444
+ * if we rotate:d above, this offset is "wrong"
7445
+ */
7390
7446
last_commit_pos_offset= commit_offset;
7391
7447
/*
7392
7448
We cannot unlock LOCK_log until we have locked LOCK_commit_ordered;
@@ -7625,6 +7681,7 @@ void MYSQL_BIN_LOG::wait_for_update_relay_log(THD* thd)
7625
7681
PSI_stage_info old_stage;
7626
7682
DBUG_ENTER (" wait_for_update_relay_log" );
7627
7683
7684
+ mysql_mutex_assert_owner (&LOCK_log);
7628
7685
thd->ENTER_COND (&update_cond, &LOCK_log,
7629
7686
&stage_slave_has_read_all_relay_log,
7630
7687
&old_stage);
@@ -7655,6 +7712,7 @@ int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd,
7655
7712
int ret= 0 ;
7656
7713
DBUG_ENTER (" wait_for_update_bin_log" );
7657
7714
7715
+ mysql_mutex_assert_owner (&LOCK_log);
7658
7716
if (!timeout)
7659
7717
mysql_cond_wait (&update_cond, &LOCK_log);
7660
7718
else
@@ -7663,6 +7721,21 @@ int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd,
7663
7721
DBUG_RETURN (ret);
7664
7722
}
7665
7723
7724
+ int MYSQL_BIN_LOG::wait_for_update_binlog_end_pos (THD* thd,
7725
+ struct timespec *timeout)
7726
+ {
7727
+ int ret= 0 ;
7728
+ DBUG_ENTER (" wait_for_update_binlog_end_pos" );
7729
+
7730
+ mysql_mutex_assert_owner (get_binlog_end_pos_lock ());
7731
+ if (!timeout)
7732
+ mysql_cond_wait (&update_cond, get_binlog_end_pos_lock ());
7733
+ else
7734
+ ret= mysql_cond_timedwait (&update_cond, get_binlog_end_pos_lock (),
7735
+ timeout);
7736
+ DBUG_RETURN (ret);
7737
+ }
7738
+
7666
7739
7667
7740
/* *
7668
7741
Close the log file.
@@ -9703,6 +9776,14 @@ TC_LOG_BINLOG::set_status_variables(THD *thd)
9703
9776
}
9704
9777
}
9705
9778
9779
+ void assert_LOCK_log_owner (bool owner)
9780
+ {
9781
+ if (owner)
9782
+ mysql_mutex_assert_owner (mysql_bin_log.get_log_lock ());
9783
+ else
9784
+ mysql_mutex_assert_not_owner (mysql_bin_log.get_log_lock ());
9785
+ }
9786
+
9706
9787
struct st_mysql_storage_engine binlog_storage_engine=
9707
9788
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
9708
9789
0 commit comments