Skip to content

Commit

Permalink
MDEV-21117 post-push to cover a "custom" xid format
Browse files Browse the repository at this point in the history
Due to wsrep uses its own xid format for its recovery,
the xid hashing has to be refined.
When a xid object is not in the server "mysql" format,
the hash record made to contain the xid also in the full format.
  • Loading branch information
andrelkin committed Jun 16, 2021
1 parent da65cb4 commit e95f78f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 15 deletions.
41 changes: 28 additions & 13 deletions sql/handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2399,15 +2399,22 @@ struct xarecover_st
or NULL.
*/
static xid_recovery_member*
xid_member_insert(HASH *hash_arg, my_xid xid_arg, MEM_ROOT *ptr_mem_root)
xid_member_insert(HASH *hash_arg, my_xid xid_arg, MEM_ROOT *ptr_mem_root,
XID *full_xid_arg)
{
xid_recovery_member *member= (xid_recovery_member *)
alloc_root(ptr_mem_root, sizeof(xid_recovery_member));
XID *xid_full= NULL;

if (!member)
if (full_xid_arg)
xid_full= (XID*) alloc_root(ptr_mem_root, sizeof(XID));

if (!member || (full_xid_arg && !xid_full))
return NULL;

*member= xid_recovery_member(xid_arg, 1, false);
if (full_xid_arg)
*xid_full= *full_xid_arg;
*member= xid_recovery_member(xid_arg, 1, false, xid_full);

return
my_hash_insert(hash_arg, (uchar*) member) ? NULL : member;
Expand All @@ -2421,14 +2428,15 @@ xid_member_insert(HASH *hash_arg, my_xid xid_arg, MEM_ROOT *ptr_mem_root)
true otherwise.
*/
static bool xid_member_replace(HASH *hash_arg, my_xid xid_arg,
MEM_ROOT *ptr_mem_root)
MEM_ROOT *ptr_mem_root,
XID *full_xid_arg)
{
xid_recovery_member* member;
if ((member= (xid_recovery_member *)
my_hash_search(hash_arg, (uchar *)& xid_arg, sizeof(xid_arg))))
member->in_engine_prepare++;
else
member= xid_member_insert(hash_arg, xid_arg, ptr_mem_root);
member= xid_member_insert(hash_arg, xid_arg, ptr_mem_root, full_xid_arg);

return member == NULL;
}
Expand Down Expand Up @@ -2479,7 +2487,10 @@ static void xarecover_do_commit_or_rollback(handlerton *hton,
xid_recovery_member *member= arg->member;
Binlog_offset *ptr_commit_max= arg->binlog_coord;

x.set(member->xid);
if (!member->full_xid)
x.set(member->xid);
else
x= *member->full_xid;

rc= xarecover_decide_to_commit(member, ptr_commit_max) ?
hton->commit_by_xid(hton, &x) : hton->rollback_by_xid(hton, &x);
Expand Down Expand Up @@ -2601,10 +2612,13 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,

for (int i=0; i < got; i ++)
{
my_xid x= IF_WSREP(wsrep_is_wsrep_xid(&info->list[i]) ?
wsrep_xid_seqno(&info->list[i]) :
info->list[i].get_my_xid(),
info->list[i].get_my_xid());
my_xid x= info->list[i].get_my_xid();
bool is_server_xid= x > 0;

#ifdef WITH_WSREP
if (!is_server_xid && wsrep_is_wsrep_xid(&info->list[i]))
x= wsrep_xid_seqno(&info->list[i]);
#endif
if (!x) // not "mine" - that is generated by external TM
{
DBUG_EXECUTE("info",{
Expand All @@ -2630,7 +2644,9 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
*/
if (info->mem_root)
{
if (xid_member_replace(info->commit_list, x, info->mem_root))
// remember "full" xid too when it's not in mysql format
if (xid_member_replace(info->commit_list, x, info->mem_root,
is_server_xid? NULL : &info->list[i]))
{
info->error= true;
sql_print_error("Error in memory allocation at xarecover_handlerton");
Expand All @@ -2651,8 +2667,7 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
});
}
}
else if (WSREP_ON ||
tc_heuristic_recover == TC_HEURISTIC_RECOVER_ROLLBACK)
else if (!info->mem_root)
{
int rc= hton->rollback_by_xid(hton, info->list+i);
if (rc == 0)
Expand Down
6 changes: 4 additions & 2 deletions sql/handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -956,10 +956,12 @@ struct xid_recovery_member
uint in_engine_prepare; // number of engines that have xid prepared
bool decided_to_commit;
Binlog_offset binlog_coord; // semisync recovery binlog offset
XID *full_xid; // needed by wsrep or past it recovery

xid_recovery_member(my_xid xid_arg, uint prepare_arg, bool decided_arg)
xid_recovery_member(my_xid xid_arg, uint prepare_arg, bool decided_arg,
XID *full_xid_arg)
: xid(xid_arg), in_engine_prepare(prepare_arg),
decided_to_commit(decided_arg) {};
decided_to_commit(decided_arg), full_xid(full_xid_arg) {};
};

/* for recover() handlerton call */
Expand Down

0 comments on commit e95f78f

Please sign in to comment.