Commit e95f78f4 authored by Andrei Elkin's avatar Andrei Elkin

MDEV-21117 post-push to cover a "custom" xid format

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.
parent da65cb4d
......@@ -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;
......@@ -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;
}
......@@ -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);
......@@ -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",{
......@@ -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");
......@@ -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)
......
......@@ -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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment