Skip to content

Commit 67ccc24

Browse files
committed
The concluding commit prior to collapse the branch.
- renaming - function header comments added - hyperoptimization of `wfc->parent_commit_started` is removed for the reason of not having been proved safe - the size of the XAP sliding window is doubled to account a possibility of XAP_k -> XAP_k+2|W|-1 dependency. Say k=1, and the # of Workers is 4. Transaction are distributed RR, then it's possible to have T^*_1 -> T^*_8. It's seen from worker queues. The queue depelops downward: W1 ... W4 1^* 2 3 4 5 6 7 8^* Worker # 1 has assigned with T_1 and T_5. Worker #4 can take on its T_8 when T_1 is yet at the beginning of its processing, so even before XA START of that XAP. This analysis was done couple of weeks ago, but I have not found a commit planned to cover it.
1 parent 6716800 commit 67ccc24

File tree

9 files changed

+42
-32
lines changed

9 files changed

+42
-32
lines changed

sql/log.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7944,7 +7944,7 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry)
79447944
it.
79457945
*/
79467946
if ((loc_waitee= wfc->waitee.load(std::memory_order_relaxed)) &&
7947-
!(wfc->parent_commit_started= loc_waitee->commit_started))
7947+
!loc_waitee->commit_started)
79487948
{
79497949
PSI_stage_info old_stage;
79507950

@@ -8336,7 +8336,7 @@ MYSQL_BIN_LOG::write_transaction_to_binlog_events(group_commit_entry *entry)
83368336
}
83378337

83388338
if (likely(!entry->error))
8339-
return (entry->thd->wait_for_commit_ptr && entry->thd->wait_for_commit_ptr->parent_commit_started) ? 0 : entry->thd->wait_for_prior_commit();
8339+
return entry->thd->wait_for_prior_commit();
83408340

83418341
switch (entry->error)
83428342
{

sql/mysqld.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,7 @@ PSI_cond_key key_BINLOG_COND_xid_list,
10551055
key_BINLOG_COND_queue_busy;
10561056
PSI_cond_key key_RELAYLOG_COND_relay_log_updated,
10571057
key_RELAYLOG_COND_bin_log_updated, key_COND_wakeup_ready,
1058-
key_COND_wait_commit, key_COND_wait_xa_commit;
1058+
key_COND_wait_commit, key_COND_wait_commit_dep;
10591059
PSI_cond_key key_RELAYLOG_COND_queue_busy;
10601060
PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy;
10611061
PSI_cond_key key_COND_rpl_thread_queue, key_COND_rpl_thread,
@@ -1083,7 +1083,7 @@ static PSI_cond_info all_server_conds[]=
10831083
{ &key_RELAYLOG_COND_queue_busy, "MYSQL_RELAY_LOG::COND_queue_busy", 0},
10841084
{ &key_COND_wakeup_ready, "THD::COND_wakeup_ready", 0},
10851085
{ &key_COND_wait_commit, "wait_for_commit::COND_wait_commit", 0},
1086-
{ &key_COND_wait_commit, "wait_for_commit::COND_wait_xa_commit", 0},
1086+
{ &key_COND_wait_commit, "wait_for_commit::COND_wait_commit_dep", 0},
10871087
{ &key_COND_cache_status_changed, "Query_cache::COND_cache_status_changed", 0},
10881088
{ &key_COND_manager, "COND_manager", PSI_FLAG_GLOBAL},
10891089
{ &key_COND_server_started, "COND_server_started", PSI_FLAG_GLOBAL},

sql/mysqld.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ extern PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond,
376376
key_COND_start_thread;
377377
extern PSI_cond_key key_RELAYLOG_COND_relay_log_updated,
378378
key_RELAYLOG_COND_bin_log_updated, key_COND_wakeup_ready,
379-
key_COND_wait_commit, key_COND_wait_xa_commit;
379+
key_COND_wait_commit, key_COND_wait_commit_dep;
380380
extern PSI_cond_key key_RELAYLOG_COND_queue_busy;
381381
extern PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy;
382382
extern PSI_cond_key key_COND_rpl_thread, key_COND_rpl_thread_queue,

sql/rpl_parallel.cc

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2521,7 +2521,7 @@ rpl_parallel::find(uint32 domain_id)
25212521

25222522
e->concurrent_xaps_window.init((PSI_memory_key) PSI_INSTRUMENT_ME,
25232523
max((decltype(e->rpl_thread_max)) 2,
2524-
e->rpl_thread_max));
2524+
2*e->rpl_thread_max));
25252525
e->cxap_lhs= e->cxap_rhs= 0;
25262526

25272527
/*
@@ -2809,8 +2809,17 @@ abandon_worker_thread(THD *thd, rpl_parallel_thread *cur_thread,
28092809
}
28102810

28112811
/**
2812-
@return true when there exists a duplicate xid hash value,
2813-
otherwise false.
2812+
Check the concurrency status of @c xid with ones in progress.
2813+
Any new @c xid of XA-prepare (@c is_xap is true then) is appended to
2814+
a sliding window designed as circular buffer. Through search in the window
2815+
the return result is computed.
2816+
2817+
@param e parallel entry pointer
2818+
@param xid a pointer to the xid of either XA-prepare of XA-"complete"
2819+
@param is_xap
2820+
true when xid belongs to XA-prepare
2821+
@return true when there exists a duplicate xid hash value,
2822+
false otherwise.
28142823
*/
28152824
static bool
28162825
handle_xa_prepera_duplicate_xid(rpl_parallel_entry *e, XID *xid, bool is_xap)
@@ -2832,8 +2841,9 @@ handle_xa_prepera_duplicate_xid(rpl_parallel_entry *e, XID *xid, bool is_xap)
28322841
of the window.
28332842
Otherwise RHS always points to a free cell of which one at least must
28342843
exist at this point.
2835-
Potential conflicts with the current input xid can come only from
2836-
the preceeding |W| - 1 xids, the |W|th in the past is safe.
2844+
While transaction disribution is Round-robin, potential conflicts with
2845+
the current input xid can come only from
2846+
the preceeding 2*|W| - 1 xids, the 2*|W|th in the past is safe.
28372847
*/
28382848
for (i= e->cxap_lhs; i != e->cxap_rhs;
28392849
i= (i+1) % (e->concurrent_xaps_window.max_size()))
@@ -3132,7 +3142,9 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
31323142
gco= e->current_gco;
31333143
/*
31343144
Take care of duplicate xids in XA-prepare, XA-"complete" should not
3135-
race its XA-prepare parent either.
3145+
race its XA-prepare parent either. When the current transaction's xid
3146+
was seen and its transaction may still be in process this event group
3147+
gets flagged to wait for prior commits at the start of execution.
31363148
*/
31373149
if ((gtid_flags & (Gtid_log_event::FL_PREPARED_XA |
31383150
Gtid_log_event::FL_COMPLETED_XA)) &&

sql/rpl_parallel.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,12 +428,9 @@ struct rpl_parallel_entry {
428428
group_commit_orderer *current_gco;
429429

430430
/*
431-
Circular buffer of size slave_parallel_threads to hold XIDs which may
432-
prepare concurrently along with the one that the SQL thread is currently
433-
processing.
434-
435-
For each queued event, the last element in the index is reset, and if the
436-
new event is an XAP, the xid will be saved in the spot of the last element.
431+
Circular buffer of size slave_parallel_threads to hold XIDs of XA-prepare
432+
group of events which may be processed concurrently.
433+
See how handle_xa_prepera_duplicate_xid operates on it.
437434
*/
438435
Dynamic_array<std::pair<std::size_t, uint32>> concurrent_xaps_window;
439436
uint32 cxap_lhs, cxap_rhs;

sql/rpl_rli.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -838,9 +838,8 @@ struct rpl_group_info
838838
/*
839839
When true indicates that the user xa transaction is going to
840840
complete (with COMMIT or ROLLBACK) by the worker thread,
841-
*while* another worker is preparing it to eventually release
842-
the xid for the former terminator one.
843-
Upon that followed by the xid acquisition the value flips to false.
841+
*while* another worker is still preparing it. Once the latter is done
842+
the xid will be acquired and the flag gets reset.
844843
*/
845844
bool is_async_xac;
846845

sql/sql_class.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7933,7 +7933,6 @@ wait_for_commit::reinit()
79337933
wakeup_subsequent_commits_running= false;
79347934
commit_started= false;
79357935
wakeup_blocked= false;
7936-
parent_commit_started= false;
79377936
#ifdef SAFE_MUTEX
79387937
/*
79397938
When using SAFE_MUTEX, the ordering between taking the LOCK_wait_commit
@@ -7959,7 +7958,7 @@ wait_for_commit::wait_for_commit()
79597958
{
79607959
mysql_mutex_init(key_LOCK_wait_commit, &LOCK_wait_commit, MY_MUTEX_INIT_FAST);
79617960
mysql_cond_init(key_COND_wait_commit, &COND_wait_commit, 0);
7962-
mysql_cond_init(key_COND_wait_xa_commit, &COND_wait_xa_commit, 0);
7961+
mysql_cond_init(key_COND_wait_commit_dep, &COND_wait_commit_dep, 0);
79637962
reinit();
79647963
}
79657964

@@ -7989,7 +7988,7 @@ wait_for_commit::~wait_for_commit()
79897988

79907989
mysql_mutex_destroy(&LOCK_wait_commit);
79917990
mysql_cond_destroy(&COND_wait_commit);
7992-
mysql_cond_destroy(&COND_wait_xa_commit);
7991+
mysql_cond_destroy(&COND_wait_commit_dep);
79937992
}
79947993

79957994

sql/sql_class.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2354,11 +2354,15 @@ struct wait_for_commit
23542354
event group is fully done.
23552355
*/
23562356
bool wakeup_blocked;
2357-
mysql_cond_t COND_wait_xa_commit;
2357+
/*
2358+
The condition variable servers as a part of facilities to handle various
2359+
commit time additional dependency between groups of replication events, e.g
2360+
XA-Prepare -> XA-Commit, or XA-Prepare -> XA-Prepare all with the same xid.
2361+
*/
2362+
mysql_cond_t COND_wait_commit_dep;
23582363
#ifndef DBUG_OFF
23592364
bool debug_done;
23602365
#endif
2361-
bool parent_commit_started;
23622366

23632367
void register_wait_for_prior_commit(wait_for_commit *waitee);
23642368
int wait_for_prior_commit(THD *thd, bool allow_kill=true)

sql/xa.cc

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -343,15 +343,15 @@ bool xid_cache_insert_maybe_wait(THD* thd)
343343
if (waiter) // notifier was not seen
344344
{
345345
mysql_mutex_lock(&waiter->LOCK_wait_commit);
346-
thd->ENTER_COND(&waiter->COND_wait_xa_commit, &waiter->LOCK_wait_commit,
346+
thd->ENTER_COND(&waiter->COND_wait_commit_dep, &waiter->LOCK_wait_commit,
347347
&stage_waiting_for_prior_xa_transaction,
348348
&old_stage);
349349
if ((element=
350350
(XID_cache_element*) lf_hash_search(&xid_cache, thd->xid_hash_pins,
351351
xid->key(), xid->key_length())))
352352
{
353353
lf_hash_search_unpin(thd->xid_hash_pins);
354-
mysql_cond_wait(&waiter->COND_wait_xa_commit,
354+
mysql_cond_wait(&waiter->COND_wait_commit_dep,
355355
&waiter->LOCK_wait_commit);
356356

357357
DBUG_ASSERT(waiter->debug_done || thd->check_killed(1));
@@ -440,12 +440,12 @@ XID_cache_element * xid_cache_search_maybe_wait(THD* thd)
440440
{
441441
PSI_stage_info old_stage;
442442
mysql_mutex_lock(&waiter->LOCK_wait_commit);
443-
thd->ENTER_COND(&waiter->COND_wait_xa_commit, &waiter->LOCK_wait_commit,
443+
thd->ENTER_COND(&waiter->COND_wait_commit_dep, &waiter->LOCK_wait_commit,
444444
&stage_waiting_for_prior_xa_transaction,
445445
&old_stage);
446446
if (element->c_waiter.load(std::memory_order_relaxed) &&
447447
likely(!thd->check_killed(1)))
448-
mysql_cond_wait(&waiter->COND_wait_xa_commit,
448+
mysql_cond_wait(&waiter->COND_wait_commit_dep,
449449
&waiter->LOCK_wait_commit);
450450

451451
if (element->c_waiter.load(std::memory_order_relaxed))
@@ -552,7 +552,7 @@ static void xid_cache_delete(THD *thd, XID_cache_element *&element)
552552
#ifndef DBUG_OFF
553553
waiter->debug_done= true;
554554
#endif
555-
mysql_cond_signal(&waiter->COND_wait_xa_commit);
555+
mysql_cond_signal(&waiter->COND_wait_commit_dep);
556556
mysql_mutex_unlock(&waiter->LOCK_wait_commit);
557557
}
558558
}
@@ -1445,9 +1445,8 @@ static bool slave_applier_reset_xa_trans(THD *thd)
14451445
// unmark and signal
14461446
mysql_mutex_lock(&xac_waiter->LOCK_wait_commit);
14471447
element->c_waiter.store(NULL, std::memory_order_relaxed);
1448-
mysql_cond_signal(&xac_waiter->COND_wait_xa_commit);
1448+
mysql_cond_signal(&xac_waiter->COND_wait_commit_dep);
14491449
mysql_mutex_unlock(&xac_waiter->LOCK_wait_commit);
1450-
sql_print_information("Notified XA COMMIT");
14511450
}
14521451
thd->transaction->cleanup();
14531452
thd->transaction->all.reset();

0 commit comments

Comments
 (0)