提交 b05f0920 编写于 作者: A Ashwin Agrawal

Avoid aborting based on PT entry without consulting clog.

High level theory of the issue if checkpoint happens after recording
COMMIT to clog, xactHashTable won't know the status of the xact during
recovery, since no REDO records corresponding to the same would be
looked into. But its incorrect without consulting CLOG to ABORT the xact
based on having CREATE_PENDING entry in PT. Hence should check CLOG to
verify if it was COMMITTED. If we don't perform this check, the recovery
would try to mark COMMITED Xact Aborted, seeing Create-Pending entry
associated with the Xact and double fault.
Do not have repro as wasn't able to find scenario in which this can
happen, but was seen in field and hence better to add protection to
avoid double fault.
上级 974c13d4
......@@ -39,6 +39,7 @@
#include "cdb/cdbmirroredfilesysobj.h"
#include "cdb/cdbresynchronizechangetracking.h"
#include "access/twophase.h"
#include "access/clog.h"
static bool
PersistentRecovery_RedoRelationExists(
......@@ -1573,6 +1574,54 @@ PersistentRecovery_CrashAbort(void)
continue;
}
/* If checkpoint happened after Recording COMMIT, xactHashTable won't know the Status of the xact,
* since no REDO records corresponding to the same would be looked into.
* But its incorrect without consulting CLOG to consider ABORTing the xact based on having CREATE_PENDING entry in PT
* Hence should check CLOG to verify if it was COMMITTED.
* If we don't perform this step, the recovery later would try to mark COMMITED Xact Aborted,
* seeing Create-Pending entry associated with the Xact.
*/
bool validStatus = false;
XidStatus status = InRecoveryTransactionIdGetStatus(xactEntry->xid, &validStatus);
if ((validStatus == true) && (status != 0) && (status == TRANSACTION_STATUS_COMMITTED))
{
xactEntry->infoKind = XACT_INFOKIND_COMMIT;
if (Debug_persistent_recovery_print)
elog(PersistentRecovery_DebugPrintLevel(),
"PersistentRecovery_CrashAbort: Found transaction as COMMITTED in clog, transaction %u (state '%s')",
xactEntry->xid,
XactInfoKind_Name(xactEntry->infoKind));
fsObjEntry =
(FsObjEntry) DoublyLinkedHead_First(
offsetof(FsObjEntryData, xactLinks),
&xactEntry->fsObjEntryList);
while (fsObjEntry != NULL)
{
if (fsObjEntry->state == PersistentFileSysState_BulkLoadCreatePending ||
fsObjEntry->state == PersistentFileSysState_CreatePending)
{
if (Debug_persistent_recovery_print)
elog(PersistentRecovery_DebugPrintLevel(),
"PersistentRecovery_CrashAbort: Set state of %s to 'Created'",
FsObjEntryToString(fsObjEntry));
fsObjEntry->updateNeeded = true;
fsObjEntry->state = PersistentFileSysState_Created;
}
fsObjEntry =
(FsObjEntry) DoublyLinkedHead_Next(
offsetof(FsObjEntryData, xactLinks),
&xactEntry->fsObjEntryList,
fsObjEntry);
}
continue;
}
/*
* We don't know the status of the transaction until we examine the
* persistent node states.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册