|
29 | 29 | #include "access/xlogutils.h"
|
30 | 30 | #include "backup/walsummary.h"
|
31 | 31 | #include "catalog/storage_xlog.h"
|
| 32 | +#include "commands/dbcommands_xlog.h" |
32 | 33 | #include "common/blkreftable.h"
|
33 | 34 | #include "libpq/pqsignal.h"
|
34 | 35 | #include "miscadmin.h"
|
@@ -146,6 +147,8 @@ static void HandleWalSummarizerInterrupts(void);
|
146 | 147 | static XLogRecPtr SummarizeWAL(TimeLineID tli, XLogRecPtr start_lsn,
|
147 | 148 | bool exact, XLogRecPtr switch_lsn,
|
148 | 149 | XLogRecPtr maximum_lsn);
|
| 150 | +static void SummarizeDbaseRecord(XLogReaderState *xlogreader, |
| 151 | + BlockRefTable *brtab); |
149 | 152 | static void SummarizeSmgrRecord(XLogReaderState *xlogreader,
|
150 | 153 | BlockRefTable *brtab);
|
151 | 154 | static void SummarizeXactRecord(XLogReaderState *xlogreader,
|
@@ -961,6 +964,9 @@ SummarizeWAL(TimeLineID tli, XLogRecPtr start_lsn, bool exact,
|
961 | 964 | /* Special handling for particular types of WAL records. */
|
962 | 965 | switch (XLogRecGetRmid(xlogreader))
|
963 | 966 | {
|
| 967 | + case RM_DBASE_ID: |
| 968 | + SummarizeDbaseRecord(xlogreader, brtab); |
| 969 | + break; |
964 | 970 | case RM_SMGR_ID:
|
965 | 971 | SummarizeSmgrRecord(xlogreader, brtab);
|
966 | 972 | break;
|
@@ -1074,6 +1080,75 @@ SummarizeWAL(TimeLineID tli, XLogRecPtr start_lsn, bool exact,
|
1074 | 1080 | return summary_end_lsn;
|
1075 | 1081 | }
|
1076 | 1082 |
|
| 1083 | +/* |
| 1084 | + * Special handling for WAL records with RM_DBASE_ID. |
| 1085 | + */ |
| 1086 | +static void |
| 1087 | +SummarizeDbaseRecord(XLogReaderState *xlogreader, BlockRefTable *brtab) |
| 1088 | +{ |
| 1089 | + uint8 info = XLogRecGetInfo(xlogreader) & ~XLR_INFO_MASK; |
| 1090 | + |
| 1091 | + /* |
| 1092 | + * We use relfilenode zero for a given database OID and tablespace OID |
| 1093 | + * to indicate that all relations with that pair of IDs have been |
| 1094 | + * recreated if they exist at all. Effectively, we're setting a limit |
| 1095 | + * block of 0 for all such relfilenodes. |
| 1096 | + * |
| 1097 | + * Technically, this special handling is only needed in the case of |
| 1098 | + * XLOG_DBASE_CREATE_FILE_COPY, because that can create a whole bunch |
| 1099 | + * of relation files in a directory without logging anything |
| 1100 | + * specific to each one. If we didn't mark the whole DB OID/TS OID |
| 1101 | + * combination in some way, then a tablespace that was dropped after |
| 1102 | + * the reference backup and recreated using the FILE_COPY method prior |
| 1103 | + * to the incremental backup would look just like one that was never |
| 1104 | + * touched at all, which would be catastrophic. |
| 1105 | + * |
| 1106 | + * But it seems best to adopt this treatment for all records that drop |
| 1107 | + * or create a DB OID/TS OID combination. That's similar to how we |
| 1108 | + * treat the limit block for individual relations, and it's an extra |
| 1109 | + * layer of safety here. We can never lose data by marking more stuff |
| 1110 | + * as needing to be backed up in full. |
| 1111 | + */ |
| 1112 | + if (info == XLOG_DBASE_CREATE_FILE_COPY) |
| 1113 | + { |
| 1114 | + xl_dbase_create_file_copy_rec *xlrec; |
| 1115 | + RelFileLocator rlocator; |
| 1116 | + |
| 1117 | + xlrec = |
| 1118 | + (xl_dbase_create_file_copy_rec *) XLogRecGetData(xlogreader); |
| 1119 | + rlocator.spcOid = xlrec->tablespace_id; |
| 1120 | + rlocator.dbOid = xlrec->db_id; |
| 1121 | + rlocator.relNumber = 0; |
| 1122 | + BlockRefTableSetLimitBlock(brtab, &rlocator, MAIN_FORKNUM, 0); |
| 1123 | + } |
| 1124 | + else if (info == XLOG_DBASE_CREATE_WAL_LOG) |
| 1125 | + { |
| 1126 | + xl_dbase_create_wal_log_rec *xlrec; |
| 1127 | + RelFileLocator rlocator; |
| 1128 | + |
| 1129 | + xlrec = (xl_dbase_create_wal_log_rec *) XLogRecGetData(xlogreader); |
| 1130 | + rlocator.spcOid = xlrec->tablespace_id; |
| 1131 | + rlocator.dbOid = xlrec->db_id; |
| 1132 | + rlocator.relNumber = 0; |
| 1133 | + BlockRefTableSetLimitBlock(brtab, &rlocator, MAIN_FORKNUM, 0); |
| 1134 | + } |
| 1135 | + else if (info == XLOG_DBASE_DROP) |
| 1136 | + { |
| 1137 | + xl_dbase_drop_rec *xlrec; |
| 1138 | + RelFileLocator rlocator; |
| 1139 | + int i; |
| 1140 | + |
| 1141 | + xlrec = (xl_dbase_drop_rec *) XLogRecGetData(xlogreader); |
| 1142 | + rlocator.dbOid = xlrec->db_id; |
| 1143 | + rlocator.relNumber = 0; |
| 1144 | + for (i = 0; i < xlrec->ntablespaces; ++i) |
| 1145 | + { |
| 1146 | + rlocator.spcOid = xlrec->tablespace_ids[i]; |
| 1147 | + BlockRefTableSetLimitBlock(brtab, &rlocator, MAIN_FORKNUM, 0); |
| 1148 | + } |
| 1149 | + } |
| 1150 | +} |
| 1151 | + |
1077 | 1152 | /*
|
1078 | 1153 | * Special handling for WAL records with RM_SMGR_ID.
|
1079 | 1154 | */
|
|
0 commit comments