@@ -3133,6 +3133,7 @@ void MYSQL_BIN_LOG::cleanup()
31333133 mysql_mutex_destroy (&LOCK_index);
31343134 mysql_mutex_destroy (&LOCK_xid_list);
31353135 mysql_mutex_destroy (&LOCK_binlog_background_thread);
3136+ mysql_mutex_destroy (&LOCK_binlog_end_pos);
31363137 mysql_cond_destroy (&update_cond);
31373138 mysql_cond_destroy (&COND_queue_busy);
31383139 mysql_cond_destroy (&COND_xid_list);
@@ -3178,6 +3179,9 @@ void MYSQL_BIN_LOG::init_pthread_objects()
31783179 &COND_binlog_background_thread, 0 );
31793180 mysql_cond_init (key_BINLOG_COND_binlog_background_thread_end,
31803181 &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);
31813185}
31823186
31833187
@@ -3524,10 +3528,19 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
35243528 if (flush_io_cache (&log_file) ||
35253529 mysql_file_sync (log_file.file , MYF (MY_WME|MY_SYNC_FILESIZE)))
35263530 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+ }
35313544
35323545 if (write_file_name_to_index_file)
35333546 {
@@ -3632,6 +3645,7 @@ int MYSQL_BIN_LOG::get_current_log(LOG_INFO* linfo)
36323645
36333646int MYSQL_BIN_LOG::raw_get_current_log (LOG_INFO* linfo)
36343647{
3648+ mysql_mutex_assert_owner (&LOCK_log);
36353649 strmake_buf (linfo->log_file_name , log_file_name);
36363650 linfo->pos = my_b_tell (&log_file);
36373651 return 0 ;
@@ -4797,6 +4811,20 @@ void MYSQL_BIN_LOG::make_log_name(char* buf, const char* log_ident)
47974811
47984812bool MYSQL_BIN_LOG::is_active (const char *log_file_name_arg)
47994813{
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+ */
48004828 return !strcmp (log_file_name, log_file_name_arg);
48014829}
48024830
@@ -5359,6 +5387,7 @@ binlog_start_consistent_snapshot(handlerton *hton, THD *thd)
53595387 binlog_cache_mngr *const cache_mngr= thd->binlog_setup_trx_data ();
53605388
53615389 /* Server layer calls us with LOCK_commit_ordered locked, so this is safe. */
5390+ mysql_mutex_assert_owner (&LOCK_commit_ordered);
53625391 strmake_buf (cache_mngr->last_commit_pos_file , mysql_bin_log.last_commit_pos_file );
53635392 cache_mngr->last_commit_pos_offset = mysql_bin_log.last_commit_pos_offset ;
53645393
@@ -6013,6 +6042,14 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
60136042 }
60146043 else
60156044 {
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+
60166053 signal_update ();
60176054 if ((error= rotate (false , &check_purge)))
60186055 check_purge= false ;
@@ -6664,6 +6701,9 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd)
66646701 }
66656702
66666703 offset= my_b_tell (&log_file);
6704+
6705+ update_binlog_end_pos (offset);
6706+
66676707 /*
66686708 Take mutex to protect against a reader seeing partial writes of 64-bit
66696709 offset on 32-bit CPUs.
@@ -6709,6 +6749,9 @@ MYSQL_BIN_LOG::write_binlog_checkpoint_event_already_locked(const char *name,
67096749 }
67106750
67116751 offset= my_b_tell (&log_file);
6752+
6753+ update_binlog_end_pos (offset);
6754+
67126755 /*
67136756 Take mutex to protect against a reader seeing partial writes of 64-bit
67146757 offset on 32-bit CPUs.
@@ -7335,7 +7378,8 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
73357378 {
73367379 if (!current->error &&
73377380 RUN_HOOK (binlog_storage, after_flush,
7338- (current->thd , log_file_name,
7381+ (current->thd ,
7382+ current->cache_mngr ->last_commit_pos_file ,
73397383 current->cache_mngr ->last_commit_pos_offset , synced)))
73407384 {
73417385 current->error = ER_ERROR_ON_WRITE;
@@ -7347,6 +7391,14 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
73477391 all_error= false ;
73487392 }
73497393
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+
73507402 if (any_error)
73517403 sql_print_error (" Failed to run 'after_flush' hooks" );
73527404 if (!all_error)
@@ -7387,6 +7439,10 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader)
73877439
73887440 DEBUG_SYNC (leader->thd , " commit_before_get_LOCK_commit_ordered" );
73897441 mysql_mutex_lock (&LOCK_commit_ordered);
7442+ /* *
7443+ * TODO(jonaso): Check with Kristian,
7444+ * if we rotate:d above, this offset is "wrong"
7445+ */
73907446 last_commit_pos_offset= commit_offset;
73917447 /*
73927448 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)
76257681 PSI_stage_info old_stage;
76267682 DBUG_ENTER (" wait_for_update_relay_log" );
76277683
7684+ mysql_mutex_assert_owner (&LOCK_log);
76287685 thd->ENTER_COND (&update_cond, &LOCK_log,
76297686 &stage_slave_has_read_all_relay_log,
76307687 &old_stage);
@@ -7655,6 +7712,7 @@ int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd,
76557712 int ret= 0 ;
76567713 DBUG_ENTER (" wait_for_update_bin_log" );
76577714
7715+ mysql_mutex_assert_owner (&LOCK_log);
76587716 if (!timeout)
76597717 mysql_cond_wait (&update_cond, &LOCK_log);
76607718 else
@@ -7663,6 +7721,21 @@ int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd,
76637721 DBUG_RETURN (ret);
76647722}
76657723
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+
76667739
76677740/* *
76687741 Close the log file.
@@ -9703,6 +9776,14 @@ TC_LOG_BINLOG::set_status_variables(THD *thd)
97039776 }
97049777}
97059778
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+
97069787struct st_mysql_storage_engine binlog_storage_engine=
97079788{ MYSQL_HANDLERTON_INTERFACE_VERSION };
97089789
0 commit comments