mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-27342: Fix issue of recovery failure using new server id
Commit 6c39eaeb1
made the crash recovery dependent on server_id.
The crash recovery could fail when restoring a new instance from
original crashed data directory USING A NEW SERVER ID.
The issue doesn't exist in previous major versions before 10.6.
Root cause is when generating the input XID to be searched in the hash,
server id is populated with the current server id.
So if the server id changed when recovering, the XID couldn't be found
in the hash due to server id doesn't match.
This fix is to use original server id when creating the input XID
object in function `xarecover_do_commit_or_rollback`.
All new code of the whole pull request, including one or several files
that are either new files or modified ones, are contributed under the
BSD-new license. I am contributing on behalf of my employer Amazon Web
Services, Inc.
This commit is contained in:
committed by
Otto Kekäläinen
parent
572e34304e
commit
dafc5fb9c1
@ -2414,7 +2414,7 @@ struct xarecover_st
|
||||
*/
|
||||
static xid_recovery_member*
|
||||
xid_member_insert(HASH *hash_arg, my_xid xid_arg, MEM_ROOT *ptr_mem_root,
|
||||
XID *full_xid_arg)
|
||||
XID *full_xid_arg, decltype(::server_id) server_id_arg)
|
||||
{
|
||||
xid_recovery_member *member= (xid_recovery_member *)
|
||||
alloc_root(ptr_mem_root, sizeof(xid_recovery_member));
|
||||
@ -2428,7 +2428,7 @@ xid_member_insert(HASH *hash_arg, my_xid xid_arg, MEM_ROOT *ptr_mem_root,
|
||||
|
||||
if (full_xid_arg)
|
||||
*xid_full= *full_xid_arg;
|
||||
*member= xid_recovery_member(xid_arg, 1, false, xid_full);
|
||||
*member= xid_recovery_member(xid_arg, 1, false, xid_full, server_id_arg);
|
||||
|
||||
return
|
||||
my_hash_insert(hash_arg, (uchar*) member) ? NULL : member;
|
||||
@ -2443,14 +2443,15 @@ xid_member_insert(HASH *hash_arg, my_xid xid_arg, MEM_ROOT *ptr_mem_root,
|
||||
*/
|
||||
static bool xid_member_replace(HASH *hash_arg, my_xid xid_arg,
|
||||
MEM_ROOT *ptr_mem_root,
|
||||
XID *full_xid_arg)
|
||||
XID *full_xid_arg,
|
||||
decltype(::server_id) server_id_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, full_xid_arg);
|
||||
member= xid_member_insert(hash_arg, xid_arg, ptr_mem_root, full_xid_arg, server_id_arg);
|
||||
|
||||
return member == NULL;
|
||||
}
|
||||
@ -2502,7 +2503,8 @@ static void xarecover_do_commit_or_rollback(handlerton *hton,
|
||||
Binlog_offset *ptr_commit_max= arg->binlog_coord;
|
||||
|
||||
if (!member->full_xid)
|
||||
x.set(member->xid);
|
||||
// Populate xid using the server_id from original transaction
|
||||
x.set(member->xid, member->server_id);
|
||||
else
|
||||
x= *member->full_xid;
|
||||
|
||||
@ -2658,9 +2660,12 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
|
||||
*/
|
||||
if (info->mem_root)
|
||||
{
|
||||
// remember "full" xid too when it's not in mysql format
|
||||
// remember "full" xid too when it's not in mysql format.
|
||||
// Also record the transaction's original server_id. It will be used for
|
||||
// populating the input XID to be searched in hash.
|
||||
if (xid_member_replace(info->commit_list, x, info->mem_root,
|
||||
is_server_xid? NULL : &info->list[i]))
|
||||
is_server_xid? NULL : &info->list[i],
|
||||
is_server_xid? info->list[i].get_trx_server_id() : server_id))
|
||||
{
|
||||
info->error= true;
|
||||
sql_print_error("Error in memory allocation at xarecover_handlerton");
|
||||
|
Reference in New Issue
Block a user