MDEV-37602: Phase 1 & 2 - Session-scoped rgi and Master_info registration in index#5159
MDEV-37602: Phase 1 & 2 - Session-scoped rgi and Master_info registration in index#5159bodyhedia44 wants to merge 1 commit into
Conversation
…tion in index Phase 1: Persist rpl_group_info per connection instead of per BINLOG statement Phase 2: Create session Master_info and register in master_info_index with unique names This enables proper cross-event context and visibility in SHOW SLAVE STATUS.
There was a problem hiding this comment.
Code Review
This pull request introduces a session-scoped Master_info (mi_fake) for BINLOG replay statements to eliminate the overhead of creating and deleting throwaway Master_info instances per query event. The session-scoped instance is registered in master_info_index and cleaned up during connection teardown. Feedback highlights two critical issues: first, master_info_index can be NULL on standalone servers and its modification requires holding the LOCK_active_mi mutex to avoid race conditions; second, the allocation of rpl_group_info lacks a NULL check, which could lead to a server crash if memory is exhausted.
| if (master_info_index->add_master_info(mi, FALSE)) | ||
| { | ||
| delete mi; | ||
| my_error(ER_OUTOFMEMORY, MYF(ME_FATAL), 1); | ||
| goto end; | ||
| } |
There was a problem hiding this comment.
The global master_info_index can be NULL on standalone servers where replication is not initialized or disabled. Dereferencing it directly will cause a server crash when executing BINLOG statements. Additionally, modifying master_info_index requires holding the LOCK_active_mi mutex to prevent race conditions with other threads (e.g., concurrent SHOW STATUS or administrative commands).
Please add a NULL check for master_info_index and wrap the registration in LOCK_active_mi.
if (master_info_index)
{
mysql_mutex_lock(&LOCK_active_mi);
if (master_info_index->add_master_info(mi, FALSE))
{
mysql_mutex_unlock(&LOCK_active_mi);
delete mi;
my_error(ER_OUTOFMEMORY, MYF(ME_FATAL), 1);
goto end;
}
mysql_mutex_unlock(&LOCK_active_mi);
}| if (!rgi) | ||
| rgi= thd->rgi_fake= new rpl_group_info(rli); | ||
| rgi->thd= thd; |
There was a problem hiding this comment.
If new rpl_group_info(rli) fails and returns NULL due to an out-of-memory condition, dereferencing rgi on the next line (rgi->thd = thd;) will cause a server crash. We should check if rgi is NULL and handle the error gracefully.
if (!rgi)
{
if (!(rgi= thd->rgi_fake= new rpl_group_info(rli)))
{
my_error(ER_OUTOFMEMORY, MYF(ME_FATAL), 1);
goto end;
}
}
rgi->thd= thd;
Phase 1: Persist rpl_group_info per connection instead of per BINLOG statement
Phase 2: Create session Master_info and register in master_info_index with unique names