1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +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:
Hugo Wen
2022-02-04 03:56:08 +00:00
committed by Otto Kekäläinen
parent 572e34304e
commit dafc5fb9c1
4 changed files with 85 additions and 11 deletions

View File

@ -900,12 +900,13 @@ struct xid_t {
if ((bqual_length= bl))
memcpy(data+gl, b, bl);
}
void set(ulonglong xid)
// Populate server_id if it's specified, otherwise use the current server_id
void set(ulonglong xid, decltype(::server_id) trx_server_id= server_id)
{
my_xid tmp;
formatID= 1;
set(MYSQL_XID_PREFIX_LEN, 0, MYSQL_XID_PREFIX);
memcpy(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id));
memcpy(data+MYSQL_XID_PREFIX_LEN, &trx_server_id, sizeof(trx_server_id));
tmp= xid;
memcpy(data+MYSQL_XID_OFFSET, &tmp, sizeof(tmp));
gtrid_length=MYSQL_XID_GTRID_LEN;
@ -931,6 +932,12 @@ struct xid_t {
!memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ?
quick_get_my_xid() : 0;
}
decltype(::server_id) get_trx_server_id()
{
decltype(::server_id) trx_server_id;
memcpy(&trx_server_id, data+MYSQL_XID_PREFIX_LEN, sizeof(trx_server_id));
return trx_server_id;
}
uint length()
{
return static_cast<uint>(sizeof(formatID)) + key_length();
@ -972,11 +979,12 @@ struct xid_recovery_member
bool decided_to_commit;
Binlog_offset binlog_coord; // semisync recovery binlog offset
XID *full_xid; // needed by wsrep or past it recovery
decltype(::server_id) server_id; // server id of orginal server
xid_recovery_member(my_xid xid_arg, uint prepare_arg, bool decided_arg,
XID *full_xid_arg)
XID *full_xid_arg, decltype(::server_id) server_id_arg)
: xid(xid_arg), in_engine_prepare(prepare_arg),
decided_to_commit(decided_arg), full_xid(full_xid_arg) {};
decided_to_commit(decided_arg), full_xid(full_xid_arg) , server_id(server_id_arg) {};
};
/* for recover() handlerton call */