|
86 | 86 | #include "access/xlog.h"
|
87 | 87 | #include "access/xloginsert.h"
|
88 | 88 | #include "access/xlogreader.h"
|
| 89 | +#include "access/xlogrecovery.h" |
89 | 90 | #include "access/xlogutils.h"
|
90 | 91 | #include "catalog/pg_type.h"
|
91 | 92 | #include "catalog/storage.h"
|
@@ -2477,6 +2478,38 @@ PrepareRedoAdd(char *buf, XLogRecPtr start_lsn,
|
2477 | 2478 | * that it got added in the redo phase
|
2478 | 2479 | */
|
2479 | 2480 |
|
| 2481 | + /* |
| 2482 | + * In the event of a crash while a checkpoint was running, it may be |
| 2483 | + * possible that some two-phase data found its way to disk while its |
| 2484 | + * corresponding record needs to be replayed in the follow-up recovery. |
| 2485 | + * As the 2PC data was on disk, it has already been restored at the |
| 2486 | + * beginning of recovery with restoreTwoPhaseData(), so skip this record |
| 2487 | + * to avoid duplicates in TwoPhaseState. If a consistent state has been |
| 2488 | + * reached, the record is added to TwoPhaseState and it should have no |
| 2489 | + * corresponding file in pg_twophase. |
| 2490 | + */ |
| 2491 | + if (!XLogRecPtrIsInvalid(start_lsn)) |
| 2492 | + { |
| 2493 | + char path[MAXPGPATH]; |
| 2494 | + |
| 2495 | + TwoPhaseFilePath(path, hdr->xid); |
| 2496 | + |
| 2497 | + if (access(path, F_OK) == 0) |
| 2498 | + { |
| 2499 | + ereport(reachedConsistency ? ERROR : WARNING, |
| 2500 | + (errmsg("could not recover two-phase state file for transaction %u", |
| 2501 | + hdr->xid), |
| 2502 | + errdetail("Two-phase state file has been found in WAL record %X/%X, but this transaction has already been restored from disk.", |
| 2503 | + LSN_FORMAT_ARGS(start_lsn)))); |
| 2504 | + return; |
| 2505 | + } |
| 2506 | + |
| 2507 | + if (errno != ENOENT) |
| 2508 | + ereport(ERROR, |
| 2509 | + (errcode_for_file_access(), |
| 2510 | + errmsg("could not access file \"%s\": %m", path))); |
| 2511 | + } |
| 2512 | + |
2480 | 2513 | /* Get a free gxact from the freelist */
|
2481 | 2514 | if (TwoPhaseState->freeGXacts == NULL)
|
2482 | 2515 | ereport(ERROR,
|
|
0 commit comments