diff --git a/src/common/backend/utils/init/globals.cpp b/src/common/backend/utils/init/globals.cpp index 8946ce230..e363e82a2 100644 --- a/src/common/backend/utils/init/globals.cpp +++ b/src/common/backend/utils/init/globals.cpp @@ -59,7 +59,7 @@ bool open_join_children = true; bool will_shutdown = false; /* hard-wired binary version number */ -const uint32 GRAND_VERSION_NUM = 92604; +const uint32 GRAND_VERSION_NUM = 92605; const uint32 PREDPUSH_SAME_LEVEL_VERSION_NUM = 92522; const uint32 UPSERT_WHERE_VERSION_NUM = 92514; @@ -114,6 +114,8 @@ const uint32 SUPPORT_HASH_XLOG_VERSION_NUM = 92603; /* This variable indicates wheather the instance is in progress of upgrade as a whole */ uint32 volatile WorkingGrandVersionNum = GRAND_VERSION_NUM; +const uint32 INVALID_INVISIBLE_TUPLE_VERSION = 92605; + const uint32 ENHANCED_TUPLE_LOCK_VERSION_NUM = 92583; const uint32 TWOPHASE_FILE_VERSION = 92414; diff --git a/src/gausskernel/optimizer/commands/cluster.cpp b/src/gausskernel/optimizer/commands/cluster.cpp index 7d66f8509..57801a4e4 100755 --- a/src/gausskernel/optimizer/commands/cluster.cpp +++ b/src/gausskernel/optimizer/commands/cluster.cpp @@ -1920,6 +1920,15 @@ double CopyUHeapDataInternal(Relation oldHeap, Relation oldIndex, Relation newHe return tups_vacuumed; } +static inline bool tuple_invisible_not_hotupdate(HeapTuple tuple, Relation relation) +{ + if (HeapKeepInvisibleTuple(tuple, RelationGetDescr(relation)) && !HeapTupleIsHotUpdated(tuple)) { + return false; + } else { + return true; + } +} + double copy_heap_data_internal(Relation OldHeap, Relation OldIndex, Relation NewHeap, TransactionId OldestXmin, TransactionId FreezeXid, bool verbose, bool use_sort, AdaptMem* memUsage) { @@ -2071,7 +2080,7 @@ double copy_heap_data_internal(Relation OldHeap, Relation OldIndex, Relation New switch (HeapTupleSatisfiesVacuum(tuple, OldestXmin, buf)) { case HEAPTUPLE_DEAD: /* Definitely dead */ - isdead = true; + isdead = tuple_invisible_not_hotupdate(tuple, OldHeap); break; case HEAPTUPLE_RECENTLY_DEAD: tups_recently_dead += 1; diff --git a/src/gausskernel/optimizer/commands/vacuumlazy.cpp b/src/gausskernel/optimizer/commands/vacuumlazy.cpp index ebef225da..842b30741 100644 --- a/src/gausskernel/optimizer/commands/vacuumlazy.cpp +++ b/src/gausskernel/optimizer/commands/vacuumlazy.cpp @@ -1051,9 +1051,11 @@ static IndexBulkDeleteResult** lazy_scan_heap( OffsetNumber offnum, maxoff; bool tupgone = false; bool hastup = false; - bool keepThisInvisbleTuple = false; + bool keepThisInvisibleTuple = false; int prev_dead_count; + OffsetNumber invalid[MaxOffsetNumber]; OffsetNumber frozen[MaxOffsetNumber]; + int ninvalid = 0; int nfrozen; Size freespace; bool all_visible_according_to_vm = false; @@ -1335,7 +1337,7 @@ static IndexBulkDeleteResult** lazy_scan_heap( tuple.t_bucketId = RelationGetBktid(onerel); HeapTupleCopyBaseFromPage(&tuple, page); tupgone = false; - keepThisInvisbleTuple = false; + keepThisInvisibleTuple = false; if (u_sess->attr.attr_storage.enable_debug_vacuum) t_thrd.utils_cxt.pRelatedRel = onerel; @@ -1358,8 +1360,8 @@ static IndexBulkDeleteResult** lazy_scan_heap( * cheaper to get rid of it in the next pruning pass than * to treat it like an indexed tuple. */ - keepThisInvisbleTuple = HeapKeepInvisbleTuple(&tuple, RelationGetDescr(onerel)); - if (HeapTupleIsHotUpdated(&tuple) || HeapTupleIsHeapOnly(&tuple) || keepThisInvisbleTuple) { + keepThisInvisibleTuple = HeapKeepInvisibleTuple(&tuple, RelationGetDescr(onerel)); + if (HeapTupleIsHotUpdated(&tuple) || HeapTupleIsHeapOnly(&tuple) || keepThisInvisibleTuple) { nkeep += 1; } else { tupgone = true; /* we can delete the tuple */ @@ -1437,8 +1439,15 @@ static IndexBulkDeleteResult** lazy_scan_heap( tups_vacuumed += 1; has_dead_tuples = true; - } else if (keepThisInvisbleTuple) { - vacrelstats->hasKeepInvisbleTuples = true; + } else if (keepThisInvisibleTuple) { + if (t_thrd.proc->workingVersionNum >= INVALID_INVISIBLE_TUPLE_VERSION + && !HeapTupleIsHotUpdated(&tuple)) { + heap_invalid_invisible_tuple(&tuple); + Assert(tuple.t_tableOid == PartitionRelationId); + invalid[ninvalid++] = offnum; + } else { + vacrelstats->hasKeepInvisbleTuples = true; + } } else { num_tuples += 1; hastup = true; @@ -1478,6 +1487,23 @@ static IndexBulkDeleteResult** lazy_scan_heap( } } + if (ninvalid > 0) { + START_CRIT_SECTION(); + MarkBufferDirty(buf); + if (RelationNeedsWAL(onerel)) { + XLogRecPtr recptr; + + recptr = log_heap_invalid(onerel, buf, u_sess->cmd_cxt.FreezeLimit, + invalid, ninvalid); + PageSetLSN(page, recptr); + } + END_CRIT_SECTION(); + if (TransactionIdPrecedes(((HeapPageHeader)page)->pd_xid_base, u_sess->utils_cxt.RecentXmin)) { + if (u_sess->utils_cxt.RecentXmin - ((HeapPageHeader)page)->pd_xid_base > CHANGE_XID_BASE) + (void)heap_change_xidbase_after_freeze(onerel, buf); + } + } + /* * If there are no indexes then we can vacuum the page right now * instead of doing a second scan. diff --git a/src/gausskernel/storage/access/common/heaptuple.cpp b/src/gausskernel/storage/access/common/heaptuple.cpp index ba232aa0d..ccaa5203c 100644 --- a/src/gausskernel/storage/access/common/heaptuple.cpp +++ b/src/gausskernel/storage/access/common/heaptuple.cpp @@ -3401,7 +3401,7 @@ void heap_slot_store_heap_tuple(HeapTuple tuple, TupleTableSlot* slot, Buffer bu * * Note: Only the dead tuple of pg_partition needs to be verified in the current code. */ -bool HeapKeepInvisbleTuple(HeapTuple tuple, TupleDesc tupleDesc, KeepInvisbleTupleFunc checkKeepFunc) +bool HeapKeepInvisibleTuple(HeapTuple tuple, TupleDesc tupleDesc, KeepInvisbleTupleFunc checkKeepFunc) { static KeepInvisbleOpt keepInvisibleArray[] = { {PartitionRelationId, Anum_pg_partition_parttype, PartitionLocalIndexSkipping}, diff --git a/src/gausskernel/storage/access/heap/heapam.cpp b/src/gausskernel/storage/access/heap/heapam.cpp index d94a09803..fc477f152 100755 --- a/src/gausskernel/storage/access/heap/heapam.cpp +++ b/src/gausskernel/storage/access/heap/heapam.cpp @@ -3454,6 +3454,34 @@ static void HeapPageShiftBase(Buffer buffer, Page page, bool multi, int64 delta) } } +void heap_invalid_invisible_tuple(HeapTuple tuple) +{ + HeapTupleSetXmin(tuple, InvalidTransactionId); + HeapTupleSetXmax(tuple, InvalidTransactionId); + tuple->t_data->t_infomask &= ~HEAP_XMAX_BITS; + tuple->t_data->t_infomask &= ~HEAP_XMIN_COMMITTED; + tuple->t_data->t_infomask |= HEAP_XMIN_INVALID; + + Assert(!HeapTupleIsHotUpdated(tuple)); + + ereport(LOG, (errmsg("Dead and invisible tuple: t_ctid = { ip_blkid = { bi_hi = %hu, bi_lo = %hu }, " + "ip_posid = %hu }, t_xmin = %u, xmax = %u, infomask = %hu", + tuple->t_data->t_ctid.ip_blkid.bi_hi, + tuple->t_data->t_ctid.ip_blkid.bi_lo, + tuple->t_data->t_ctid.ip_posid, + tuple->t_data->t_choice.t_heap.t_xmin, + tuple->t_data->t_choice.t_heap.t_xmin, + tuple->t_data->t_infomask))); +} + +static inline bool heap_check_invalid_invisible_tuple(HeapTuple tuple, TupleDesc tupleDesc, + TransactionId cutoff_xid, Buffer buffer) +{ + return (t_thrd.proc->workingVersionNum >= INVALID_INVISIBLE_TUPLE_VERSION) + && !HeapTupleIsHotUpdated(tuple) && HeapKeepInvisibleTuple(tuple, tupleDesc) + && (HeapTupleSatisfiesVacuum(tuple, cutoff_xid, buffer) == HEAPTUPLE_DEAD); +} + /* * Freeze xids in the single heap page. Useful when we can't fit new xid even * with base shift. @@ -3466,7 +3494,9 @@ static int freeze_single_heap_page(Relation relation, Buffer buffer) OffsetNumber maxoff = InvalidOffsetNumber; HeapTupleData tuple; int nfrozen = 0; + int ninvalid = 0; OffsetNumber frozen[MaxOffsetNumber]; + OffsetNumber invalid[MaxOffsetNumber]; TransactionId latest_removed_xid = InvalidTransactionId; TransactionId oldest_xmin = InvalidTransactionId; TransactionId freeze_xid = InvalidTransactionId; @@ -3534,13 +3564,18 @@ static int freeze_single_heap_page(Relation relation, Buffer buffer) tuple.t_len = ItemIdGetLength(itemid); tuple.t_tableOid = RelationGetRelid(relation); tuple.t_bucketId = RelationGetBktid(relation); + ItemPointerSet(&(tuple.t_self), BufferGetBlockNumber(buffer), offnum); HeapTupleCopyBaseFromPage(&tuple, page); /* * Each non-removable tuple must be checked to see if it needs * freezing. Note we already have exclusive buffer lock. */ - if (heap_freeze_tuple(&tuple, freeze_xid, freeze_mxid, &changedMultiXid)) { + if (heap_check_invalid_invisible_tuple(&tuple, RelationGetDescr(relation), freeze_xid, buffer)) { + heap_invalid_invisible_tuple(&tuple); + Assert(tuple.t_tableOid == PartitionRelationId); + invalid[ninvalid++] = offnum; + } else if (heap_freeze_tuple(&tuple, freeze_xid, freeze_mxid, &changedMultiXid)) { frozen[nfrozen++] = offnum; } } /* scan along page */ @@ -3565,6 +3600,20 @@ static int freeze_single_heap_page(Relation relation, Buffer buffer) END_CRIT_SECTION(); } + if (ninvalid > 0) { + START_CRIT_SECTION(); + + MarkBufferDirty(buffer); + /* Now WAL-log freezing if necessary */ + if (RelationNeedsWAL(relation)) { + XLogRecPtr recptr = log_heap_invalid(relation, buffer, freeze_xid, + invalid, ninvalid); + PageSetLSN(page, recptr); + } + + END_CRIT_SECTION(); + } + gstrace_exit(GS_TRC_ID_freeze_single_heap_page); return nfrozen; } @@ -7976,7 +8025,7 @@ XLogRecPtr log_heap_freeze(Relation reln, Buffer buffer, TransactionId cutoff_xi OffsetNumber* offsets, int offcnt) { xl_heap_freeze xlrec; - XLogRecPtr recptr; + XLogRecPtr recptr = InvalidXLogRecPtr; bool useOldXlog = t_thrd.proc->workingVersionNum < ENHANCED_TUPLE_LOCK_VERSION_NUM || !MultiXactIdIsValid(cutoff_multi); #ifdef ENABLE_MULTIPLE_NODES @@ -8002,7 +8051,41 @@ XLogRecPtr log_heap_freeze(Relation reln, Buffer buffer, TransactionId cutoff_xi XLogRegisterBuffer(0, buffer, REGBUF_STANDARD); XLogRegisterBufData(0, (char*)offsets, offcnt * sizeof(OffsetNumber)); - recptr = XLogInsert(RM_HEAP2_ID, useOldXlog ? XLOG_HEAP2_FREEZE : XLOG_HEAP2_FREEZE | XLOG_TUPLE_LOCK_UPGRADE_FLAG); + recptr = XLogInsert(RM_HEAP2_ID, + useOldXlog ? XLOG_HEAP2_FREEZE : XLOG_HEAP2_FREEZE | XLOG_TUPLE_LOCK_UPGRADE_FLAG); + + return recptr; +} + +/* + * Perform XLogInsert for a heap-invalid operation. Caller must already + * have modified the buffer and marked it dirty. + */ +XLogRecPtr log_heap_invalid(Relation reln, Buffer buffer, TransactionId cutoff_xid, OffsetNumber* offsets, + int offcnt) +{ + xl_heap_invalid xlrecInvalid; + XLogRecPtr recptr = InvalidXLogRecPtr; + + /* Caller should not call me on a non-WAL-logged relation */ + Assert(RelationNeedsWAL(reln)); + /* nor when there are no tuples to invalid */ + Assert(offcnt > 0); + + xlrecInvalid.cutoff_xid = cutoff_xid; + + XLogBeginInsert(); + XLogRegisterData((char*)&xlrecInvalid, SizeOfHeapInvalid); + + /* + * The tuple-offsets array is not actually in the buffer, but pretend that + * it is. When XLogInsert stores the whole buffer, the offsets array need + * not be stored too. + */ + XLogRegisterBuffer(0, buffer, REGBUF_STANDARD); + XLogRegisterBufData(0, (char*)offsets, offcnt * sizeof(OffsetNumber)); + + recptr = XLogInsert(RM_HEAP3_ID, XLOG_HEAP3_INVALID); return recptr; } @@ -8665,6 +8748,37 @@ static void heap_xlog_freeze(XLogReaderState* record) } } +static void heap_xlog_invalid(XLogReaderState* record) +{ + xl_heap_invalid* xlrecInvalid = (xl_heap_invalid*)XLogRecGetData(record); + TransactionId cutoff_xid = xlrecInvalid->cutoff_xid; + RedoBufferInfo buffer; + + /* + * In Hot Standby mode, ensure that there's no queries running which still + * consider the frozen xids as running. + */ + if (InHotStandby && g_supportHotStandby) { + RelFileNode rnode; + + (void)XLogRecGetBlockTag(record, HEAP_FREEZE_ORIG_BLOCK_NUM, &rnode, NULL, NULL); + XLogRecPtr lsn = record->EndRecPtr; + ResolveRecoveryConflictWithSnapshot(cutoff_xid, rnode, lsn); + } + + if (XLogReadBufferForRedo(record, HEAP_FREEZE_ORIG_BLOCK_NUM, &buffer) == BLK_NEEDS_REDO) { + Size blkdatalen; + char* blkdata = XLogRecGetBlockData(record, HEAP_FREEZE_ORIG_BLOCK_NUM, &blkdatalen); + + HeapXlogInvalidOperatorPage(&buffer, (void*)blkdata, blkdatalen); + MarkBufferDirty(buffer.buf); + + } + if (BufferIsValid(buffer.buf)) { + UnlockReleaseBuffer(buffer.buf); + } +} + /* * Replay XLOG_HEAP2_VISIBLE record. * The critical integrity requirement here is that we must never end up with @@ -9289,6 +9403,9 @@ void heap3_redo(XLogReaderState* record) break; case XLOG_HEAP3_REWRITE: break; + case XLOG_HEAP3_INVALID: + heap_xlog_invalid(record); + break; default: ereport(PANIC, (errmsg("heap3_redo: unknown op code %hhu", info))); } diff --git a/src/gausskernel/storage/access/heap/pruneheap.cpp b/src/gausskernel/storage/access/heap/pruneheap.cpp index 964274ea0..be7da5975 100644 --- a/src/gausskernel/storage/access/heap/pruneheap.cpp +++ b/src/gausskernel/storage/access/heap/pruneheap.cpp @@ -344,6 +344,7 @@ static int heap_prune_chain(Relation relation, Buffer buffer, OffsetNumber rooto HeapTupleData tup; tup.t_tableOid = RelationGetRelid(relation); tup.t_bucketId = RelationGetBktid(relation); + bool keepInvisible = false; gstrace_entry(GS_TRC_ID_heap_prune_chain); @@ -389,7 +390,7 @@ static int heap_prune_chain(Relation relation, Buffer buffer, OffsetNumber rooto if (HeapTupleSatisfiesVacuum(&tup, oldest_xmin, buffer) == HEAPTUPLE_DEAD && !HeapTupleHeaderIsHotUpdated(htup)) { - if (HeapKeepInvisbleTuple(&tup, RelationGetDescr(relation))) { + if (HeapKeepInvisibleTuple(&tup, RelationGetDescr(relation))) { return ndeleted; } @@ -485,9 +486,8 @@ static int heap_prune_chain(Relation relation, Buffer buffer, OffsetNumber rooto } switch (HeapTupleSatisfiesVacuum(&tup, oldest_xmin, buffer)) { case HEAPTUPLE_DEAD: - if (!HeapKeepInvisbleTuple(&tup, RelationGetDescr(relation))) { - tupdead = true; - } + keepInvisible = HeapKeepInvisibleTuple(&tup, RelationGetDescr(relation)); + tupdead = true; break; case HEAPTUPLE_RECENTLY_DEAD: @@ -557,6 +557,11 @@ static int heap_prune_chain(Relation relation, Buffer buffer, OffsetNumber rooto prior_xmax = HeapTupleGetUpdateXid(&tup); } + /* There is only one dead tuple that needs to be retained and no processing is performed */ + if (keepInvisible && (nchain == 1)) { + latestdead = InvalidOffsetNumber; + } + /* * If we found a DEAD tuple in the chain, adjust the HOT chain so that all * the DEAD tuples at the start of the chain are removed and the root line @@ -571,6 +576,10 @@ static int heap_prune_chain(Relation relation, Buffer buffer, OffsetNumber rooto * right candidate for redirection. */ for (i = 1; (i < nchain) && (chainitems[i - 1] != latestdead); i++) { + // The entire chain is dead, but need to keep invisble tuple + if (keepInvisible && (i == nchain - 1)) { + break; + } heap_prune_record_unused(prstate, chainitems[i]); ndeleted++; } diff --git a/src/gausskernel/storage/access/redo/redo_heapam.cpp b/src/gausskernel/storage/access/redo/redo_heapam.cpp index b76ed0ae9..23fe139c0 100755 --- a/src/gausskernel/storage/access/redo/redo_heapam.cpp +++ b/src/gausskernel/storage/access/redo/redo_heapam.cpp @@ -151,6 +151,32 @@ void HeapXlogFreezeOperatorPage(RedoBufferInfo *buffer, void *recorddata, void * PageSetLSN(page, buffer->lsn); } +void HeapXlogInvalidOperatorPage(RedoBufferInfo *buffer, void *blkdata, Size datalen) +{ + Page page = buffer->pageinfo.page; + if (datalen > 0) { + OffsetNumber *offsets = (OffsetNumber *)blkdata; + OffsetNumber *offsets_end = (OffsetNumber *)((char *)offsets + datalen); + HeapTupleData tuple; + + while (offsets < offsets_end) { + /* offsets[] entries are one-based */ + ItemId lp = PageGetItemId(page, *offsets); + + tuple.t_data = (HeapTupleHeader)PageGetItem(page, lp); + tuple.t_len = ItemIdGetLength(lp); + HeapTupleCopyBaseFromPage(&tuple, page); + ItemPointerSet(&(tuple.t_self), buffer->blockinfo.blkno, *offsets); + + heap_invalid_invisible_tuple(&tuple); + + offsets++; + } + } + + PageSetLSN(page, buffer->lsn); +} + void HeapXlogVisibleOperatorPage(RedoBufferInfo *buffer, void *recorddata) { xl_heap_visible *xlrec = (xl_heap_visible *)recorddata; @@ -1083,6 +1109,45 @@ static XLogRecParseState *HeapXlogFreezeParseBlock(XLogReaderState *record, uint return recordstatehead; } +static XLogRecParseState *HeapXlogInvalidParseBlock(XLogReaderState *record, uint32 *blocknum) +{ + *blocknum = 1; + XLogRecParseState *blockstate = NULL; + XLogRecParseState *recordstatehead = NULL; + + XLogParseBufferAllocListFunc(record, &recordstatehead, NULL); + if (recordstatehead == NULL) { + return NULL; + } + XLogRecSetBlockDataState(record, HEAP_FREEZE_ORIG_BLOCK_NUM, recordstatehead); + + /* + * In Hot Standby mode, ensure that there's no queries running which still consider the + * invalid xids as running. + */ + if (g_supportHotStandby) { + (*blocknum)++; + /* need notify hot standby */ + XLogParseBufferAllocListFunc(record, &blockstate, recordstatehead); + if (blockstate == NULL) { + return NULL; + } + /* get cutoff xid */ + xl_heap_invalid *xlrecInvalid = (xl_heap_invalid *)XLogRecGetData(record); + TransactionId cutoff_xid = xlrecInvalid->cutoff_xid; + RelFileNode rnode; + + XLogRecGetBlockTag(record, HEAP_FREEZE_ORIG_BLOCK_NUM, &rnode, NULL, NULL); + + RelFileNodeForkNum filenode = + RelFileNodeForkNumFill(&rnode, InvalidBackendId, InvalidForkNumber, InvalidBlockNumber); + XLogRecSetBlockCommonState(record, BLOCK_DATA_INVALIDMSG_TYPE, filenode, blockstate); + XLogRecSetInvalidMsgState(&blockstate->blockparse.extra_rec.blockinvalidmsg, cutoff_xid); + } + + return recordstatehead; +} + static XLogRecParseState *HeapXlogCleanParseBlock(XLogReaderState *record, uint32 *blocknum) { xl_heap_clean *xlrec = (xl_heap_clean *)XLogRecGetData(record); @@ -1526,6 +1591,19 @@ static void HeapXlogFreezeBlock(XLogBlockHead *blockhead, XLogBlockDataParse *bl } } +static void HeapXlogInvalidBlock(XLogBlockHead *blockhead, XLogBlockDataParse *blockdatarec, RedoBufferInfo *bufferinfo) +{ + XLogBlockDataParse *datadecode = blockdatarec; + XLogRedoAction action = XLogCheckBlockDataRedoAction(datadecode, bufferinfo); + if (action == BLK_NEEDS_REDO) { + Size blkdatalen; + char *blkdata = XLogBlockDataGetBlockData(datadecode, &blkdatalen); + Assert(blkdata != NULL); + HeapXlogInvalidOperatorPage(bufferinfo, (void *)blkdata, blkdatalen); + MakeRedoBufferDirty(bufferinfo); + } +} + static void HeapXlogCleanBlock(XLogBlockHead *blockhead, XLogBlockDataParse *blockdatarec, RedoBufferInfo *bufferinfo) { XLogBlockDataParse *datadecode = blockdatarec; @@ -1638,6 +1716,9 @@ XLogRecParseState *Heap3RedoParseToBlock(XLogReaderState *record, uint32 *blockn break; case XLOG_HEAP3_REWRITE: break; + case XLOG_HEAP3_INVALID: + recordblockstate = HeapXlogInvalidParseBlock(record, blocknum); + break; default: ereport(PANIC, (errmsg("Heap3RedoParseToBlock: unknown op code %u", info))); } @@ -1654,6 +1735,9 @@ void Heap3RedoDataBlock(XLogBlockHead *blockhead, XLogBlockDataParse *blockdatar break; case XLOG_HEAP3_REWRITE: break; + case XLOG_HEAP3_INVALID: + HeapXlogInvalidBlock(blockhead, blockdatarec, bufferinfo); + break; default: ereport(PANIC, (errmsg("heap3_redo_block: unknown op code %u", info))); } diff --git a/src/gausskernel/storage/access/rmgrdesc/heapdesc.cpp b/src/gausskernel/storage/access/rmgrdesc/heapdesc.cpp index 00126e95e..f72e292e5 100644 --- a/src/gausskernel/storage/access/rmgrdesc/heapdesc.cpp +++ b/src/gausskernel/storage/access/rmgrdesc/heapdesc.cpp @@ -337,6 +337,8 @@ const char* heap3_type_name(uint8 subtype) return "heap3_new_cid"; } else if (info == XLOG_HEAP3_REWRITE) { return "heap3_rewrite"; + } else if (info == XLOG_HEAP3_INVALID) { + return "heap3_invalid"; } else { return "unkown_type"; } @@ -350,6 +352,26 @@ void heap3_desc(StringInfo buf, XLogReaderState *record) appendStringInfo(buf, "XLOG_HEAP_NEW_CID"); } else if (info == XLOG_HEAP3_REWRITE) { appendStringInfo(buf, "XLOG_HEAP2_REWRITE"); - } else + } else if (info == XLOG_HEAP3_INVALID) { + xl_heap_invalid *xlrecInvalid = (xl_heap_invalid *)XLogRecGetData(record); + + appendStringInfo(buf, "invalid: cutoff xid %lu", xlrecInvalid->cutoff_xid); + + if (!XLogRecHasBlockImage(record, 0)) { + Size datalen; + OffsetNumber *offsets = (OffsetNumber *)XLogRecGetBlockData(record, 0, &datalen); + if (datalen > 0) { + OffsetNumber *offsets_end = (OffsetNumber *)((char *)offsets + datalen); + + appendStringInfo(buf, " offsets: ["); + while (offsets < offsets_end) { + appendStringInfo(buf, " %d ", *offsets); + offsets++; + } + appendStringInfo(buf, "]"); + } + } + } else { appendStringInfo(buf, "UNKNOWN"); + } } diff --git a/src/gausskernel/storage/access/transam/extreme_rto/dispatcher.cpp b/src/gausskernel/storage/access/transam/extreme_rto/dispatcher.cpp index 5e9ef1415..a8adcb3ae 100755 --- a/src/gausskernel/storage/access/transam/extreme_rto/dispatcher.cpp +++ b/src/gausskernel/storage/access/transam/extreme_rto/dispatcher.cpp @@ -198,7 +198,7 @@ static const RmgrDispatchData g_dispatchTable[RM_MAX_ID + 1] = { { DispatchSeqRecord, RmgrRecordInfoValid, RM_SEQ_ID, XLOG_SEQ_LOG, XLOG_SEQ_LOG }, { DispatchSpgistRecord, RmgrRecordInfoValid, RM_SPGIST_ID, XLOG_SPGIST_CREATE_INDEX, XLOG_SPGIST_VACUUM_REDIRECT }, { DispatchRepSlotRecord, RmgrRecordInfoValid, RM_SLOT_ID, XLOG_SLOT_CREATE, XLOG_TERM_LOG }, - { DispatchHeap3Record, RmgrRecordInfoValid, RM_HEAP3_ID, XLOG_HEAP3_NEW_CID, XLOG_HEAP3_REWRITE }, + { DispatchHeap3Record, RmgrRecordInfoValid, RM_HEAP3_ID, XLOG_HEAP3_NEW_CID, XLOG_HEAP3_INVALID }, { DispatchBarrierRecord, RmgrRecordInfoValid, RM_BARRIER_ID, XLOG_BARRIER_CREATE, XLOG_BARRIER_SWITCHOVER }, #ifdef ENABLE_MOT {DispatchMotRecord, NULL, RM_MOT_ID, 0, 0}, @@ -867,7 +867,13 @@ static bool DispatchRepSlotRecord(XLogReaderState *record, List *expectedTLIs, T /* Run from the dispatcher thread. */ static bool DispatchHeap3Record(XLogReaderState *record, List *expectedTLIs, TimestampTz recordXTime) { - DispatchTxnRecord(record, expectedTLIs); + uint8 info = (XLogRecGetInfo(record) & (~XLR_INFO_MASK)); + + if (info == XLOG_HEAP3_INVALID) { + DispatchRecordWithPages(record, expectedTLIs); + } else { + DispatchTxnRecord(record, expectedTLIs); + } return false; } diff --git a/src/gausskernel/storage/access/transam/parallel_recovery/dispatcher.cpp b/src/gausskernel/storage/access/transam/parallel_recovery/dispatcher.cpp index 1224d926e..dda9d91b0 100755 --- a/src/gausskernel/storage/access/transam/parallel_recovery/dispatcher.cpp +++ b/src/gausskernel/storage/access/transam/parallel_recovery/dispatcher.cpp @@ -189,7 +189,7 @@ static const RmgrDispatchData g_dispatchTable[RM_MAX_ID + 1] = { { DispatchSeqRecord, RmgrRecordInfoValid, RM_SEQ_ID, XLOG_SEQ_LOG, XLOG_SEQ_LOG }, { DispatchSpgistRecord, RmgrRecordInfoValid, RM_SPGIST_ID, XLOG_SPGIST_CREATE_INDEX, XLOG_SPGIST_VACUUM_REDIRECT }, { DispatchRepSlotRecord, RmgrRecordInfoValid, RM_SLOT_ID, XLOG_SLOT_CREATE, XLOG_TERM_LOG }, - { DispatchHeap3Record, RmgrRecordInfoValid, RM_HEAP3_ID, XLOG_HEAP3_NEW_CID, XLOG_HEAP3_REWRITE }, + { DispatchHeap3Record, RmgrRecordInfoValid, RM_HEAP3_ID, XLOG_HEAP3_NEW_CID, XLOG_HEAP3_INVALID }, { DispatchBarrierRecord, RmgrRecordInfoValid, RM_BARRIER_ID, XLOG_BARRIER_CREATE, XLOG_BARRIER_SWITCHOVER }, #ifdef ENABLE_MOT @@ -720,7 +720,13 @@ static bool DispatchRepSlotRecord(XLogReaderState *record, List *expectedTLIs, T /* Run from the dispatcher thread. */ static bool DispatchHeap3Record(XLogReaderState *record, List *expectedTLIs, TimestampTz recordXTime) { - DispatchTxnRecord(record, expectedTLIs, recordXTime, false); + uint8 info = ((XLogRecGetInfo(record) & (~XLR_INFO_MASK)) & XLOG_HEAP_OPMASK); + + if (info == XLOG_HEAP3_INVALID) { + DispatchRecordWithPages(record, expectedTLIs, SUPPORT_FPAGE_DISPATCH); + } else { + DispatchTxnRecord(record, expectedTLIs, recordXTime, false); + } return false; } diff --git a/src/gausskernel/storage/replication/logical/decode.cpp b/src/gausskernel/storage/replication/logical/decode.cpp index 8d55420e3..189e8fe39 100644 --- a/src/gausskernel/storage/replication/logical/decode.cpp +++ b/src/gausskernel/storage/replication/logical/decode.cpp @@ -745,6 +745,8 @@ static void DecodeHeap3Op(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) SnapBuildProcessNewCid(builder, xid, buf->origptr, xlrec, bucket_id); break; } + case XLOG_HEAP3_INVALID: + break; case XLOG_HEAP3_REWRITE: break; default: diff --git a/src/gausskernel/storage/replication/logical/logical_parse.cpp b/src/gausskernel/storage/replication/logical/logical_parse.cpp index 7e5636477..502ed5217 100644 --- a/src/gausskernel/storage/replication/logical/logical_parse.cpp +++ b/src/gausskernel/storage/replication/logical/logical_parse.cpp @@ -479,6 +479,8 @@ void ParseHeap3Op(ParallelLogicalDecodingContext *ctx, XLogRecordBuffer *buf, Pa } case XLOG_HEAP3_REWRITE: break; + case XLOG_HEAP3_INVALID: + break; default: ereport(WARNING, (errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE), errmsg("unexpected RM_HEAP3_ID record type: %u", info))); diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index f04fdf90d..8419c9e2c 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -290,6 +290,8 @@ extern TableScanDesc heap_beginscan_sampling(Relation relation, Snapshot snapsho extern void heapgetpage(TableScanDesc scan, BlockNumber page); +extern void heap_invalid_invisible_tuple(HeapTuple tuple); + extern void heap_rescan(TableScanDesc sscan, ScanKey key); extern void heap_endscan(TableScanDesc scan); extern HeapTuple heap_getnext(TableScanDesc scan, ScanDirection direction); @@ -367,8 +369,10 @@ extern XLogRecPtr log_heap_cleanup_info(const RelFileNode* rnode, TransactionId extern XLogRecPtr log_heap_clean(Relation reln, Buffer buffer, OffsetNumber* redirected, int nredirected, OffsetNumber* nowdead, int ndead, OffsetNumber* nowunused, int nunused, TransactionId latestRemovedXid, bool repair_fragmentation); -extern XLogRecPtr log_heap_freeze( - Relation reln, Buffer buffer, TransactionId cutoff_xid, MultiXactId cutoff_multi, OffsetNumber* offsets, int offcnt); +extern XLogRecPtr log_heap_freeze(Relation reln, Buffer buffer, TransactionId cutoff_xid, MultiXactId cutoff_multi, + OffsetNumber* offsets, int offcnt); +extern XLogRecPtr log_heap_invalid(Relation reln, Buffer buffer, TransactionId cutoff_xid, OffsetNumber* offsets, + int offcnt); extern XLogRecPtr log_heap_visible(RelFileNode rnode, BlockNumber block, Buffer heap_buffer, Buffer vm_buffer, TransactionId cutoff_xid, bool free_dict); extern XLogRecPtr log_cu_bcm(const RelFileNode* rnode, int col, uint64 block, int status, int count); diff --git a/src/include/access/htup.h b/src/include/access/htup.h index c5094324b..4f175ec8a 100644 --- a/src/include/access/htup.h +++ b/src/include/access/htup.h @@ -748,6 +748,7 @@ inline HeapTuple heaptup_alloc(Size size) /* XLOG_HEAP_NEW_CID with 0x30 in heap is XLOGHEAP2_NEW_CID with 0x70 in heap2 in PG9.4 */ #define XLOG_HEAP3_NEW_CID 0x00 #define XLOG_HEAP3_REWRITE 0x10 +#define XLOG_HEAP3_INVALID 0x20 /* we used to put all xl_heap_* together, which made us run out of opcodes (quickly) * when trying to add a DELETE_IS_SUPER operation. Thus we split the codes carefully @@ -980,6 +981,12 @@ typedef struct xl_heap_freeze { #define SizeOfOldHeapFreeze (offsetof(xl_heap_freeze, cutoff_xid) + sizeof(TransactionId)) #define SizeOfHeapFreeze (offsetof(xl_heap_freeze, cutoff_multi) + sizeof(MultiXactId)) +typedef struct xl_heap_invalid { + TransactionId cutoff_xid; + /* TUPLE OFFSET NUMBERS FOLLOW AT THE END */ +} xl_heap_invalid; +#define SizeOfHeapInvalid (offsetof(xl_heap_invalid, cutoff_xid) + sizeof(TransactionId)) + typedef struct xl_heap_freeze_tuple { TransactionId xmax; OffsetNumber offset; @@ -1212,7 +1219,7 @@ typedef struct KeepInvisbleOpt { KeepInvisbleTupleFunc checkKeepFunc; } KeepInvisbleOpt; -bool HeapKeepInvisbleTuple(HeapTuple tuple, TupleDesc tupleDesc, KeepInvisbleTupleFunc checkKeepFunc = NULL); +bool HeapKeepInvisibleTuple(HeapTuple tuple, TupleDesc tupleDesc, KeepInvisbleTupleFunc checkKeepFunc = NULL); void HeapCopyTupleNoAlloc(HeapTuple dest, HeapTuple src); // for ut test diff --git a/src/include/access/xlogproc.h b/src/include/access/xlogproc.h index 9bf89ffe0..0a1807668 100755 --- a/src/include/access/xlogproc.h +++ b/src/include/access/xlogproc.h @@ -1,1240 +1,1241 @@ -/* - * Copyright (c) 2020 Huawei Technologies Co.,Ltd. - * - * openGauss is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * - * http://license.coscl.org.cn/MulanPSL2 - * - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - * --------------------------------------------------------------------------------------- - * - * xlogproc.h - * - * - * IDENTIFICATION - * src/include/access/xlogproc.h - * - * --------------------------------------------------------------------------------------- - */ - -#ifndef XLOG_PROC_H -#define XLOG_PROC_H -#include "postgres.h" -#include "knl/knl_variable.h" - -#include "access/xlogreader.h" -#include "storage/buf/bufmgr.h" -#include "storage/buf/buf_internals.h" -#include "access/xlog_basic.h" -#include "access/xlogutils.h" -#include "access/clog.h" -#include "access/ustore/knl_uredo.h" -#include "access/ustore/knl_utuple.h" -#include "access/ustore/undo/knl_uundotxn.h" -#include "access/ustore/undo/knl_uundoxlog.h" - -#ifndef byte -#define byte unsigned char -#endif - -typedef void (*relasexlogreadstate)(void* record); -/* **************define for parse end******************************* */ -#define MIN(_a, _b) ((_a) > (_b) ? (_b) : (_a)) - -/* for common blockhead begin */ - -#define XLogBlockHeadGetInfo(blockhead) ((blockhead)->xl_info) -#define XLogBlockHeadGetXid(blockhead) ((blockhead)->xl_xid) -#define XLogBlockHeadGetRmid(blockhead) ((blockhead)->xl_rmid) - -#define XLogBlockHeadGetLSN(blockhead) ((blockhead)->end_ptr) -#define XLogBlockHeadGetRelNode(blockhead) ((blockhead)->relNode) -#define XLogBlockHeadGetSpcNode(blockhead) ((blockhead)->spcNode) -#define XLogBlockHeadGetDbNode(blockhead) ((blockhead)->dbNode) -#define XLogBlockHeadGetForkNum(blockhead) ((blockhead)->forknum) -#define XLogBlockHeadGetBlockNum(blockhead) ((blockhead)->blkno) -#define XLogBlockHeadGetBucketId(blockhead) ((blockhead)->bucketNode) -#define XLogBlockHeadGetCompressOpt(blockhead) ((blockhead)->opt) -#define XLogBlockHeadGetValidInfo(blockhead) ((blockhead)->block_valid) -#define XLogBlockHeadGetPhysicalBlock(blockhead) ((blockhead)->pblk) -/* for common blockhead end */ - -/* for block data beging */ -#define XLogBlockDataHasBlockImage(blockdata) ((blockdata)->blockhead.has_image) -#define XLogBlockDataHasBlockData(blockdata) ((blockdata)->blockhead.has_data) -#define XLogBlockDataGetLastBlockLSN(_blockdata) ((_blockdata)->blockdata.last_lsn) -#define XLogBlockDataGetBlockFlags(blockdata) ((blockdata)->blockhead.flags) - -#define XLogBlockDataGetBlockId(blockdata) ((blockdata)->blockhead.cur_block_id) -#define XLogBlockDataGetAuxiBlock1(blockdata) ((blockdata)->blockhead.auxiblk1) -#define XLogBlockDataGetAuxiBlock2(blockdata) ((blockdata)->blockhead.auxiblk2) -/* for block data end */ - -typedef struct { - RelFileNode rnode; - ForkNumber forknum; - BlockNumber blkno; - XLogPhyBlock pblk; -} RedoBufferTag; - -typedef struct { - Page page; // pagepointer - Size pagesize; -#ifdef USE_ASSERT_CHECKING - bool ignorecheck; -#endif -} RedoPageInfo; - -typedef struct { - XLogRecPtr lsn; /* block cur lsn */ - Buffer buf; - RedoBufferTag blockinfo; - RedoPageInfo pageinfo; - int dirtyflag; /* true if the buffer changed */ -} RedoBufferInfo; - -extern void GetFlushBufferInfo(void *buf, RedoBufferInfo *bufferinfo, uint32 *buf_state, ReadBufferMethod flushmethod); - -#define MakeRedoBufferDirty(bufferinfo) ((bufferinfo)->dirtyflag = true) -#define RedoBufferDirtyClear(bufferinfo) ((bufferinfo)->dirtyflag = false) -#define IsRedoBufferDirty(bufferinfo) ((bufferinfo)->dirtyflag == true) - -#define RedoMemIsValid(memctl, bufferid) (((bufferid) > InvalidBuffer) && ((bufferid) <= (memctl->totalblknum))) - -typedef struct { - RedoBufferTag blockinfo; - pg_atomic_uint32 state; -} RedoBufferDesc; - -typedef struct { - Buffer buff_id; - pg_atomic_uint32 state; -} ParseBufferDesc; - -#define RedoBufferSlotGetBuffer(bslot) ((bslot)->buf_id) - -#define EnalbeWalLsnCheck true - -#pragma pack(push, 1) - -#define INVALID_BLOCK_ID (XLR_MAX_BLOCK_ID + 2) - -#define LOW_BLOKNUMBER_BITS (32) -#define LOW_BLOKNUMBER_MASK (((uint64)1 << 32) - 1) - - -/* ********BLOCK COMMON HEADER BEGIN ***************** */ -typedef enum { - BLOCK_DATA_MAIN_DATA_TYPE = 0, /* BLOCK DATA */ - BLOCK_DATA_VM_TYPE, /* VM */ - BLOCK_DATA_UNDO_TYPE, /* UNDO */ - BLOCK_DATA_FSM_TYPE, /* FSM */ - BLOCK_DATA_DDL_TYPE, /* DDL */ - BLOCK_DATA_BCM_TYPE, /* bcm */ - BLOCK_DATA_NEWCU_TYPE, /* cu newlog */ - BLOCK_DATA_CLOG_TYPE, /* CLog */ - BLOCK_DATA_MULITACT_OFF_TYPE, /* MultiXact */ - BLOCK_DATA_MULITACT_MEM_TYPE, - BLOCK_DATA_CSNLOG_TYPE, /* CSNLog */ - /* *****xact don't need sent to dfv */ - BLOCK_DATA_MULITACT_UPDATEOID_TYPE, - BLOCK_DATA_XACTDATA_TYPE, /* XACT */ - BLOCK_DATA_RELMAP_TYPE, /* RELMAP */ - BLOCK_DATA_SLOT_TYPE, - BLOCK_DATA_BARRIER_TYPE, - BLOCK_DATA_PREPARE_TYPE, /* prepare */ - BLOCK_DATA_INVALIDMSG_TYPE, /* INVALIDMSG */ - BLOCK_DATA_INCOMPLETE_TYPE, - BLOCK_DATA_VACUUM_PIN_TYPE, - BLOCK_DATA_XLOG_COMMON_TYPE, - BLOCK_DATA_CREATE_DATABASE_TYPE, - BLOCK_DATA_DROP_DATABASE_TYPE, - BLOCK_DATA_CREATE_TBLSPC_TYPE, - BLOCK_DATA_DROP_TBLSPC_TYPE, - BLOCK_DATA_DROP_SLICE_TYPE, - BLOCK_DATA_SEG_FILE_EXTEND_TYPE, - BLOCK_DATA_SEG_SPACE_DROP, - BLOCK_DATA_SEG_SPACE_SHRINK, - BLOCK_DATA_SEG_FULL_SYNC_TYPE, - BLOCK_DATA_SEG_EXTEND, -} XLogBlockParseEnum; - -/* ********BLOCK COMMON HEADER END ***************** */ - -/* **************define for parse begin ******************************* */ - -/* ********BLOCK DATE BEGIN ***************** */ - -typedef struct { - uint8 cur_block_id; /* blockid */ - uint8 flags; - uint8 has_image; - uint8 has_data; - BlockNumber auxiblk1; - BlockNumber auxiblk2; -} XLogBlocDatakHead; - -#define XLOG_BLOCK_DATAHEAD_LEN sizeof(XLogBlocDatakHead) - -typedef struct { - uint16 extra_flag; - uint16 hole_offset; - uint16 hole_length; /* image position */ - uint16 data_len; /* data length */ - XLogRecPtr last_lsn; - char* bkp_image; - char* data; -} XLogBlockData; - -#define XLOG_BLOCK_DATA_LEN sizeof(XLogBlockData) - -typedef struct { - XLogBlocDatakHead blockhead; - XLogBlockData blockdata; - uint32 main_data_len; /* main data portion's length */ - char* main_data; /* point to XLogReaderState's main_data */ -} XLogBlockDataParse; -/* ********BLOCK DATE END ***************** */ -#define XLOG_BLOCK_DATA_PARSE_LEN sizeof(XLogBlockDataParse) - -/* ********BLOCK DDL BEGIN ***************** */ -typedef enum { - BLOCK_DDL_TYPE_NONE = 0, - BLOCK_DDL_CREATE_RELNODE, - BLOCK_DDL_DROP_RELNODE, - BLOCK_DDL_EXTEND_RELNODE, - BLOCK_DDL_TRUNCATE_RELNODE, - BLOCK_DDL_CLOG_ZERO, - BLOCK_DDL_CLOG_TRUNCATE, - BLOCK_DDL_MULTIXACT_OFF_ZERO, - BLOCK_DDL_MULTIXACT_MEM_ZERO, -} XLogBlockDdlInfoEnum; - -typedef struct { - uint32 blockddltype; - int rels; - char *mainData; -} XLogBlockDdlParse; - -/* ********BLOCK DDL END ***************** */ - -/* ********BLOCK CLOG BEGIN ***************** */ - -#define MAX_BLOCK_XID_NUMS (28) -typedef struct { - TransactionId topxid; - uint16 status; - uint16 xidnum; - uint16 xidsarry[MAX_BLOCK_XID_NUMS]; -} XLogBlockCLogParse; - -/* ********BLOCK CLOG END ***************** */ - -/* ********BLOCK CSNLOG BEGIN ***************** */ -typedef struct { - TransactionId topxid; - CommitSeqNo cslseq; - uint32 xidnum; - uint16 xidsarry[MAX_BLOCK_XID_NUMS]; -} XLogBlockCSNLogParse; - -/* ********BLOCK CSNLOG END ***************** */ - -/* ********BLOCK prepare BEGIN ***************** */ -struct TwoPhaseFileHeader; - -typedef struct { - TransactionId maxxid; - Size maindatalen; - char* maindata; -} XLogBlockPrepareParse; - -/* ********BLOCK prepare END ***************** */ - -/* ********BLOCK Bcm BEGIN ***************** */ -typedef struct { - uint64 startblock; - int count; - int status; -} XLogBlockBcmParse; - -/* ********BLOCK Bcm END ***************** */ - -/* ********BLOCK Vm BEGIN ***************** */ -typedef struct { - BlockNumber heapBlk; -} XLogBlockVmParse; - -#define XLOG_BLOCK_VM_PARSE_LEN sizeof(XLogBlockVmParse) -/* ********BLOCK Vm END ***************** */ - -/* ********BLOCK Undo BEGIN ***************** */ -struct insertUndoParse { - TransactionId recxid; - BlockNumber blkno; - Oid spcNode; - Oid relNode; - XLogRecPtr lsn; - XlUndoHeader xlundohdr; - XlUndoHeaderExtra xlundohdrextra; - undo::XlogUndoMeta xlundometa; - OffsetNumber offnum; -}; - -struct deleteUndoParse { - TransactionId recxid; - TransactionId oldxid; - BlockNumber blkno; - Oid spcNode; - Oid relNode; - XLogRecPtr lsn; - XlUndoHeader xlundohdr; - XlUndoHeaderExtra xlundohdrextra; - undo::XlogUndoMeta xlundometa; - UHeapTupleData utup; - OffsetNumber offnum; -}; - -struct updateUndoParse { - bool inplaceUpdate; - TransactionId recxid; - TransactionId oldxid; - Oid spcNode; - Oid relNode; - OffsetNumber new_offnum; - OffsetNumber old_offnum; - XLogRecPtr lsn; - XlUndoHeader xlundohdr; - XlUndoHeaderExtra xlundohdrextra; - XlUndoHeader xlnewundohdr; - XlUndoHeaderExtra xlnewundohdrextra; - undo::XlogUndoMeta xlundometa; - int undoXorDeltaSize; - char *xlogXorDelta; - BlockNumber newblk; - BlockNumber oldblk; -}; - -struct multiInsertUndoParse { - TransactionId recxid; - BlockNumber blkno; - Oid spcNode; - Oid relNode; - XLogRecPtr lsn; - bool isinit; - bool skipUndo; - XlUndoHeader xlundohdr; - XlUndoHeaderExtra xlundohdrextra; - UndoRecPtr last_urecptr; - undo::XlogUndoMeta xlundometa; -}; - -struct rollbackFinishParse { - UndoSlotPtr slotPtr; - XLogRecPtr lsn; -}; - -struct undoDiscardParse { - int zoneId; - UndoSlotPtr endSlot; - UndoSlotPtr startSlot; - UndoRecPtr endUndoPtr; - TransactionId recycledXid; - XLogRecPtr lsn; -}; - -struct undoUnlinkParse { - int zoneId; - UndoLogOffset headOffset; - XLogRecPtr unlinkLsn; -}; - -struct undoExtendParse { - int zoneId; - UndoLogOffset tailOffset; - XLogRecPtr extendLsn; -}; - -struct undoCleanParse { - int zoneId; - UndoLogOffset tailOffset; - XLogRecPtr cleanLsn; -}; - -typedef struct { - char *maindata; - Size recordlen; - union { - struct insertUndoParse insertUndoParse; - struct deleteUndoParse deleteUndoParse; - struct updateUndoParse updateUndoParse; - struct undoDiscardParse undoDiscardParse; - struct undoUnlinkParse undoUnlinkParse; - struct undoExtendParse undoExtendParse; - struct undoCleanParse undoCleanParse; - struct rollbackFinishParse rollbackFinishParse; - struct multiInsertUndoParse multiInsertUndoParse; - }; -} XLogBlockUndoParse; -/* ********BLOCK Undo END ***************** */ - -/* ********BLOCK NewCu BEGIN ***************** */ -typedef struct { - uint32 main_data_len; /* main data portion's length */ - char* main_data; /* point to XLogReaderState's main_data */ -} XLogBlockNewCuParse; - - -/* ********BLOCK NewCu END ***************** */ - -/* ********BLOCK InvalidMsg BEGIN ***************** */ -typedef struct { - TransactionId cutoffxid; -} XLogBlockInvalidParse; - -/* ********BLOCK InvalidMsg END ***************** */ - -/* ********BLOCK Incomplete BEGIN ***************** */ - -typedef enum { - INCOMPLETE_ACTION_LOG = 0, - INCOMPLETE_ACTION_FORGET -} XLogBlockIncompleteEnum; - -typedef struct { - uint16 action; /* split or delete */ - bool issplit; - bool isroot; - BlockNumber downblk; - BlockNumber leftblk; - BlockNumber rightblk; -} XLogBlockIncompleteParse; - -/* ********BLOCK Incomplete END ***************** */ - -/* ********BLOCK VacuumPin BEGIN ***************** */ -typedef struct { - BlockNumber lastBlockVacuumed; -} XLogBlockVacuumPinParse; - -/* ********BLOCK XLOG Common BEGIN ***************** */ -typedef struct { - XLogRecPtr readrecptr; - Size maindatalen; - char* maindata; -} XLogBlockXLogComParse; - -/* ********BLOCK XLOG Common END ***************** */ - -/* ********BLOCK DataBase BEGIN ***************** */ -typedef struct { - Oid src_db_id; - Oid src_tablespace_id; -} XLogBlockDataBaseParse; - -/* ********BLOCK DataBase Common END ***************** */ - -/* ********BLOCK table spc BEGIN ***************** */ -typedef struct { - char* tblPath; - bool isRelativePath; -} XLogBlockTblSpcParse; - -/* ********BLOCK table spc END ***************** */ - -/* ********BLOCK Multi Xact Offset BEGIN ***************** */ -typedef struct { - MultiXactId multi; - MultiXactOffset moffset; -} XLogBlockMultiXactOffParse; - -/* ********BLOCK Multi Xact Offset END ***************** */ - -/* ********BLOCK Multi Xact Mem BEGIN ***************** */ -typedef struct { - MultiXactId multi; - MultiXactOffset startoffset; - uint64 xidnum; - TransactionId xidsarry[MAX_BLOCK_XID_NUMS]; -} XLogBlockMultiXactMemParse; -/* ********BLOCK Multi Xact Mem END ***************** */ - -/* ********BLOCK Multi Xact update oid BEGIN ***************** */ -typedef struct { - MultiXactId nextmulti; - MultiXactOffset nextoffset; - TransactionId maxxid; -} XLogBlockMultiUpdateParse; -/* ********BLOCK Multi Xact update oid END ***************** */ - -/* ********BLOCK rel map BEGIN ***************** */ -typedef struct { - Size maindatalen; - char* maindata; -} XLogBlockRelMapParse; -/* ********BLOCK rel map END ***************** */ - -typedef struct { - uint32 xl_term; -} XLogBlockRedoHead; - -#define XLogRecRedoHeadEncodeSize (offsetof(XLogBlockRedoHead, refrecord)) -typedef struct { - XLogRecPtr start_ptr; - XLogRecPtr end_ptr; /* copy from XLogReaderState's EndRecPtr */ - BlockNumber blkno; - Oid relNode; /* relation */ - uint16 block_valid; /* block data validinfo see XLogBlockInfoEnum */ - uint8 xl_info; /* flag bits, see below */ - RmgrId xl_rmid; /* resource manager for this record */ - ForkNumber forknum; - TransactionId xl_xid; /* xact id */ - Oid spcNode; /* tablespace */ - Oid dbNode; /* database */ - int2 bucketNode; /* bucket */ - uint2 opt; - XLogPhyBlock pblk; -} XLogBlockHead; - -#define XLogBlockHeadEncodeSize (sizeof(XLogBlockHead)) - -#define BYTE_NUM_BITS (8) -#define BYTE_MASK (0xFF) -#define U64_BYTES_NUM (8) -#define U32_BYTES_NUM (4) -#define U16_BYTES_NUM (2) -#define U8_BYTES_NUM (1) - -#define U32_BITS_NUM (BYTE_NUM_BITS * U32_BYTES_NUM) - -extern uint64 XLog_Read_N_Bytes(char* buffer, Size buffersize, Size readbytes); - -#define XLog_Read_1_Bytes(buffer, buffersize) XLog_Read_N_Bytes(buffer, buffersize, U8_BYTES_NUM) -#define XLog_Read_2_Bytes(buffer, buffersize) XLog_Read_N_Bytes(buffer, buffersize, U16_BYTES_NUM) -#define XLog_Read_4_Bytes(buffer, buffersize) XLog_Read_N_Bytes(buffer, buffersize, U32_BYTES_NUM) -#define XLog_Read_8_Bytes(buffer, buffersize) XLog_Read_N_Bytes(buffer, buffersize, U64_BYTES_NUM) - -extern bool XLog_Write_N_bytes(uint64 values, Size writebytes, byte* buffer); - -#define XLog_Write_1_Bytes(values, buffer) XLog_Write_N_bytes(values, U8_BYTES_NUM, buffer) -#define XLog_Write_2_Bytes(values, buffer) XLog_Write_N_bytes(values, U16_BYTES_NUM, buffer) -#define XLog_Write_4_Bytes(values, buffer) XLog_Write_N_bytes(values, U32_BYTES_NUM, buffer) -#define XLog_Write_8_Bytes(values, buffer) XLog_Write_N_bytes(values, U64_BYTES_NUM, buffer) - -typedef struct XLogBlockEnCode { - bool (*xlog_encodefun)(byte* buffer, Size buffersize, Size* encodesize, void* xlogbody); - uint16 block_valid; -} XLogBlockEnCode; - -typedef struct XLogBlockRedoCode { - void (*xlog_redofun)(char* buffer, Size buffersize, XLogBlockHead* blockhead, XLogBlockRedoHead* redohead, - void* page, Size pagesize); - uint16 block_valid; -} XLogBlockRedoCode; - -#pragma pack(pop) - -/* ********BLOCK Xact BEGIN ***************** */ -typedef struct { - uint8 delayddlflag; - uint8 updateminrecovery; - uint16 committype; - int invalidmsgnum; - int nrels; /* delete rels */ - int nlibs; /* delete libs */ - uint64 xinfo; - TimestampTz xact_time; - TransactionId maxxid; - CommitSeqNo maxcommitseq; - void* invalidmsg; - void* xnodes; - void* libfilename; -} XLogBlockXactParse; - -typedef struct { - Size maindatalen; - char* maindata; -} XLogBlockSlotParse; -/* ********BLOCK slot END ***************** */ - -/* ********BLOCK barrier BEGIN ***************** */ -typedef struct { - char* maindata; - Size maindatalen; -} XLogBlockBarrierParse; - -/* ********BLOCK Xact END ***************** */ - -/* ********BLOCK VacuumPin END ***************** */ - -/* ********BLOCK Segfile Extend Begin */ -typedef struct { - BlockNumber target_blocks; -} XLogSegFileExtendParse; -/* ********BLOCK Segfile Extend END */ - -/* ********BLOCK Segment Truncate Begin */ -typedef struct { - XLogBlockDdlParse blockddlrec; - XLogBlockDataParse blockdatarec; -} XLogBlockSegDdlParse; -/* ********BLOCK Segment Truncate END */ - -typedef struct { - void *childState; -} XLogBlockSegFullSyncParse; - -typedef struct { - char *mainData; - Size dataLen; -} XLogBlockSegNewPage; - -typedef struct { - XLogBlockHead blockhead; - XLogBlockRedoHead redohead; - union { - XLogBlockDataParse blockdatarec; - XLogBlockVmParse blockvmrec; - XLogBlockUndoParse blockundorec; - XLogBlockDdlParse blockddlrec; - XLogBlockBcmParse blockbcmrec; - XLogBlockNewCuParse blocknewcu; - XLogBlockCLogParse blockclogrec; - XLogBlockCSNLogParse blockcsnlogrec; - XLogBlockXactParse blockxact; - XLogBlockPrepareParse blockprepare; - XLogBlockInvalidParse blockinvalidmsg; - // XLogBlockIncompleteParse blockincomplete; - XLogBlockVacuumPinParse blockvacuumpin; - XLogBlockXLogComParse blockxlogcommon; - XLogBlockDataBaseParse blockdatabase; - XLogBlockTblSpcParse blocktblspc; - XLogBlockMultiXactOffParse blockmultixactoff; - XLogBlockMultiXactMemParse blockmultixactmem; - XLogBlockMultiUpdateParse blockmultiupdate; - XLogBlockRelMapParse blockrelmap; - XLogBlockSlotParse blockslot; - XLogBlockBarrierParse blockbarrier; - XLogSegFileExtendParse segfileExtend; - XLogBlockSegDdlParse blocksegddlrec; - XLogBlockSegFullSyncParse blocksegfullsyncrec; - XLogBlockSegNewPage blocksegnewpageinfo; - } extra_rec; -} XLogBlockParse; - -#define XLogBlockParseGetDdlParse(blockdatarec, ddlrecparse) \ - do \ - { \ - Assert((blockdatarec)->blockparse.blockhead.block_valid == BLOCK_DATA_DDL_TYPE); \ - if (blockdatarec->blockparse.blockhead.bucketNode != InvalidBktId) { \ - ddlrecparse = &blockdatarec->blockparse.extra_rec.blocksegddlrec.blockddlrec; \ - } else { \ - ddlrecparse = &blockdatarec->blockparse.extra_rec.blockddlrec; \ - } \ - } while (0); - -typedef struct -{ - Buffer buf_id; - Buffer freeNext; -} RedoMemSlot; - -typedef void (*InterruptFunc)(); - -typedef struct -{ - int totalblknum; /* total slot */ - int usedblknum; /* used slot */ - Size itemsize; - Buffer firstfreeslot; /* first free slot */ - Buffer firstreleaseslot; /* first release slot */ - RedoMemSlot *memslot; /* slot itme */ - bool isInit; - InterruptFunc doInterrupt; -}RedoMemManager; - -typedef void (*RefOperateFunc)(void *record); -#ifdef USE_ASSERT_CHECKING -typedef void (*RecordCheckFunc)(void *record, XLogRecPtr curPageLsn, uint32 blockId, bool replayed); -#endif -typedef void (*AddReadBlockFunc)(void *record, uint32 readblocks); - -typedef struct { - RefOperateFunc refCount; - RefOperateFunc DerefCount; -#ifdef USE_ASSERT_CHECKING - RecordCheckFunc checkFunc; -#endif - AddReadBlockFunc addReadBlock; -}RefOperate; - -typedef struct -{ - void *BufferBlockPointers; /* RedoBufferDesc + block */ - RedoMemManager memctl; - RefOperate *refOperate; -}RedoBufferManager; - - - -typedef struct -{ - void *parsebuffers; /* ParseBufferDesc + XLogRecParseState */ - RedoMemManager memctl; - RefOperate *refOperate; -}RedoParseManager; - - - -typedef struct { - void* nextrecord; - XLogBlockParse blockparse; /* block data */ - RedoParseManager* manager; - void* refrecord; /* origin dataptr, for mem release */ - bool isFullSync; -} XLogRecParseState; - -typedef struct XLogBlockRedoExtreRto { - void (*xlog_redoextrto)(XLogBlockHead* blockhead, void* blockrecbody, RedoBufferInfo* bufferinfo); - uint16 block_valid; -} XLogBlockRedoExtreRto; - -typedef struct XLogParseBlock { - XLogRecParseState* (*xlog_parseblock)(XLogReaderState* record, uint32* blocknum); - RmgrId rmid; -} XLogParseBlock; - -typedef enum { - HEAP_INSERT_ORIG_BLOCK_NUM = 0 -} XLogHeapInsertBlockEnum; - -typedef enum { - HEAP_DELETE_ORIG_BLOCK_NUM = 0 -} XLogHeapDeleteBlockEnum; - -typedef enum { - HEAP_UPDATE_NEW_BLOCK_NUM = 0, - HEAP_UPDATE_OLD_BLOCK_NUM -} XLogHeapUpdateBlockEnum; - -typedef enum { - HEAP_BASESHIFT_ORIG_BLOCK_NUM = 0 -} XLogHeapBaeShiftBlockEnum; - -typedef enum { - HEAP_NEWPAGE_ORIG_BLOCK_NUM = 0 -} XLogHeapNewPageBlockEnum; - -typedef enum { - HEAP_LOCK_ORIG_BLOCK_NUM = 0 -} XLogHeapLockBlockEnum; - -typedef enum { - HEAP_INPLACE_ORIG_BLOCK_NUM = 0 -} XLogHeapInplaceBlockEnum; - -typedef enum { - HEAP_FREEZE_ORIG_BLOCK_NUM = 0 -} XLogHeapFreezeBlockEnum; - -typedef enum { - HEAP_CLEAN_ORIG_BLOCK_NUM = 0 -} XLogHeapCleanBlockEnum; - -typedef enum { - HEAP_VISIBLE_VM_BLOCK_NUM = 0, - HEAP_VISIBLE_DATA_BLOCK_NUM -} XLogHeapVisibleBlockEnum; - -typedef enum { - HEAP_MULTI_INSERT_ORIG_BLOCK_NUM = 0 -} XLogHeapMultiInsertBlockEnum; - -typedef enum { - UHEAP_INSERT_ORIG_BLOCK_NUM = 0 -} XLogUHeapInsertBlockEnum; - -typedef enum { - UHEAP_DELETE_ORIG_BLOCK_NUM = 0 -} XLogUHeapDeleteBlockEnum; - -typedef enum { - UHEAP_UPDATE_NEW_BLOCK_NUM = 0, - UHEAP_UPDATE_OLD_BLOCK_NUM -} XLogUHeapUpdateBlockEnum; - -typedef enum { - UHEAP_MULTI_INSERT_ORIG_BLOCK_NUM = 0 -} XLogUHeapMultiInsertBlockEnum; - -typedef enum { - UHEAP_FREEZE_TD_ORIG_BLOCK_NUM = 0 -} XLogUHeapFreezeTDBlockEnum; - -typedef enum { - UHEAP_INVALID_TD_ORIG_BLOCK_NUM = 0 -} XLogUHeapInvalidTDBlockEnum; - -typedef enum { - UHEAP_CLEAN_ORIG_BLOCK_NUM = 0 -} XLogUHeapCleanBlockEnum; - -typedef enum { - UHEAP2_ORIG_BLOCK_NUM = 0 -} XLogUHeap2BlockEnum; - -typedef enum { - UHEAP_UNDO_ORIG_BLOCK_NUM = 0 -} XLogUHeapUndoBlockEnum; - -typedef enum { - UHEAP_UNDOACTION_ORIG_BLOCK_NUM = 0 -} XLogUheapUndoActionBlockEnum; - -extern THR_LOCAL RedoParseManager* g_parseManager; -extern THR_LOCAL RedoBufferManager* g_bufferManager; - -extern void* XLogMemCtlInit(RedoMemManager* memctl, Size itemsize, int itemnum); -extern RedoMemSlot* XLogMemAlloc(RedoMemManager* memctl); -extern void XLogMemRelease(RedoMemManager* memctl, Buffer bufferid); - -extern void XLogRedoBufferInit(RedoBufferManager* buffermanager, int buffernum, RefOperate *refOperate, - InterruptFunc interruptOperte); -extern void XLogRedoBufferDestory(RedoBufferManager* buffermanager); -extern RedoMemSlot* XLogRedoBufferAlloc( - RedoBufferManager* buffermanager, RelFileNode relnode, ForkNumber forkNum, BlockNumber blockNum); -extern bool XLogRedoBufferIsValid(RedoBufferManager* buffermanager, Buffer bufferid); -extern void XLogRedoBufferRelease(RedoBufferManager* buffermanager, Buffer bufferid); -extern BlockNumber XLogRedoBufferGetBlkNumber(RedoBufferManager* buffermanager, Buffer bufferid); -extern Block XLogRedoBufferGetBlk(RedoBufferManager* buffermanager, RedoMemSlot* bufferslot); -extern Block XLogRedoBufferGetPage(RedoBufferManager* buffermanager, Buffer bufferid); -extern void XLogRedoBufferSetState(RedoBufferManager* buffermanager, RedoMemSlot* bufferslot, uint32 state); - -#define XLogRedoBufferInitFunc(bufferManager, buffernum, defOperate, interruptOperte) do { \ - XLogRedoBufferInit(bufferManager, buffernum, defOperate, interruptOperte); \ -} while (0) -#define XLogRedoBufferDestoryFunc(bufferManager) do { \ - XLogRedoBufferDestory(bufferManager); \ -} while (0) -#define XLogRedoBufferAllocFunc(relnode, forkNum, blockNum, bufferslot) do { \ - *bufferslot = XLogRedoBufferAlloc(g_bufferManager, relnode, forkNum, blockNum); \ -} while (0) -#define XLogRedoBufferIsValidFunc(bufferid, isvalid) do { \ - *isvalid = XLogRedoBufferIsValid(g_bufferManager, bufferid); \ -} while (0) -#define XLogRedoBufferReleaseFunc(bufferid) do { \ - XLogRedoBufferRelease(g_bufferManager, bufferid); \ -} while (0) - -#define XLogRedoBufferGetBlkNumberFunc(bufferid, blknumber) do { \ - *blknumber = XLogRedoBufferGetBlkNumber(g_bufferManager, bufferid); \ -} while (0) - -#define XLogRedoBufferGetBlkFunc(bufferslot, blockdata) do { \ - *blockdata = XLogRedoBufferGetBlk(g_bufferManager, bufferslot); \ -} while (0) - -#define XLogRedoBufferGetPageFunc(bufferid, blockdata) do { \ - *blockdata = (Page)XLogRedoBufferGetPage(g_bufferManager, bufferid); \ -} while (0) -#define XLogRedoBufferSetStateFunc(bufferslot, state) do { \ - XLogRedoBufferSetState(g_bufferManager, bufferslot, state); \ -} while (0) - -extern void XLogParseBufferInit(RedoParseManager* parsemanager, int buffernum, RefOperate *refOperate, - InterruptFunc interruptOperte); -extern void XLogParseBufferDestory(RedoParseManager* parsemanager); -extern void XLogParseBufferRelease(XLogRecParseState* recordstate); -extern XLogRecParseState* XLogParseBufferAllocList(RedoParseManager* parsemanager, XLogRecParseState* blkstatehead, void *record); -extern XLogRedoAction XLogReadBufferForRedo(XLogReaderState* record, uint8 buffer_id, RedoBufferInfo* bufferinfo); -extern void XLogInitBufferForRedo(XLogReaderState* record, uint8 block_id, RedoBufferInfo* bufferinfo); -extern XLogRedoAction XLogReadBufferForRedoExtended(XLogReaderState* record, uint8 buffer_id, ReadBufferMode mode, - bool get_cleanup_lock, RedoBufferInfo* bufferinfo, ReadBufferMethod readmethod = WITH_NORMAL_CACHE); -#define XLogParseBufferInitFunc(parseManager, buffernum, defOperate, interruptOperte) do { \ - XLogParseBufferInit(parseManager, buffernum, defOperate, interruptOperte); \ -} while (0) - -#define XLogParseBufferDestoryFunc(parseManager) do { \ - XLogParseBufferDestory(parseManager); \ -} while (0) - -#define XLogParseBufferReleaseFunc(recordstate) do { \ - XLogParseBufferRelease(recordstate); \ -} while (0) - -#define XLogParseBufferAllocListFunc(record, newblkstate, blkstatehead) do { \ - *newblkstate = XLogParseBufferAllocList(g_parseManager, blkstatehead, record); \ -} while (0) - -#define XLogParseBufferAllocListStateFunc(record, newblkstate, blkstatehead) do { \ - if (*blkstatehead == NULL) { \ - *newblkstate = XLogParseBufferAllocList(g_parseManager, NULL, record); \ - *blkstatehead = *newblkstate; \ - } else { \ - *newblkstate = XLogParseBufferAllocList(g_parseManager, *blkstatehead, record); \ - } \ -} while (0) - - - - -#ifdef EXTREME_RTO_DEBUG_AB -typedef void (*AbnormalProcFunc)(void); -typedef enum { - A_THREAD_EXIT, - ALLOC_FAIL, - OPEN_FILE_FAIL, - WAIT_LONG, - ABNORMAL_NUM, -}AbnormalType; -extern AbnormalProcFunc g_AbFunList[ABNORMAL_NUM]; - - -#define ADD_ABNORMAL_POSITION(pos) do { \ - static int __count##pos = 0; \ - __count##pos++; \ - if (g_instance.attr.attr_storage.extreme_rto_ab_pos == pos) { \ - if (g_instance.attr.attr_storage.extreme_rto_ab_count == __count##pos) { \ - ereport(LOG, (errmsg("extreme rto debug abnormal stop pos:%d, type:%d, count:%d", pos, \ - g_instance.attr.attr_storage.extreme_rto_ab_type, __count##pos))); \ - g_AbFunList[g_instance.attr.attr_storage.extreme_rto_ab_type % ABNORMAL_NUM](); \ - } \ - } \ -} while(0) -#else -#define ADD_ABNORMAL_POSITION(pos) -#endif - - - -void HeapXlogCleanOperatorPage( - RedoBufferInfo* buffer, void* recorddata, void* blkdata, Size datalen, Size* freespace, bool repairFragmentation); -void HeapXlogFreezeOperatorPage(RedoBufferInfo* buffer, void* recorddata, void* blkdata, Size datalen, - bool isTupleLockUpgrade); -void HeapXlogVisibleOperatorPage(RedoBufferInfo* buffer, void* recorddata); -void HeapXlogVisibleOperatorVmpage(RedoBufferInfo* vmbuffer, void* recorddata); -void HeapXlogDeleteOperatorPage(RedoBufferInfo* buffer, void* recorddata, TransactionId recordxid, - bool isTupleLockUpgrade); -void HeapXlogInsertOperatorPage(RedoBufferInfo* buffer, void* recorddata, bool isinit, void* blkdata, Size datalen, - TransactionId recxid, Size* freespace, bool tde = false); -void HeapXlogMultiInsertOperatorPage(RedoBufferInfo* buffer, const void* recoreddata, bool isinit, const void* blkdata, - Size len, TransactionId recordxid, Size* freespace, bool tde = false); -void HeapXlogUpdateOperatorOldpage(RedoBufferInfo* buffer, void* recoreddata, bool hot_update, bool isnewinit, - BlockNumber newblk, TransactionId recordxid, bool isTupleLockUpgrade); -void HeapXlogUpdateOperatorNewpage(RedoBufferInfo* buffer, void* recorddata, bool isinit, void* blkdata, - Size datalen, TransactionId recordxid, Size* freespace, bool isTupleLockUpgrade, bool tde = false); -void HeapXlogLockOperatorPage(RedoBufferInfo* buffer, void* recorddata, bool isTupleLockUpgrade); -void HeapXlogInplaceOperatorPage(RedoBufferInfo* buffer, void* recorddata, void* blkdata, Size newlen); -void HeapXlogBaseShiftOperatorPage(RedoBufferInfo* buffer, void* recorddata); - -void BtreeRestorePage(Page page, char* from, int len); -void BtreeXlogMarkDeleteOperatorPage(RedoBufferInfo* buffer, void* recorddata); -void BtreeXlogPrunePageOperatorPage(RedoBufferInfo* buffer, void* recorddata); -void Btree2XlogShiftBaseOperatorPage(RedoBufferInfo* buffer, void* recorddata); - -void BtreeRestoreMetaOperatorPage(RedoBufferInfo* metabuf, void* recorddata, Size datalen); -void BtreeXlogInsertOperatorPage(RedoBufferInfo* buffer, void* recorddata, void* data, Size datalen); -void BtreeXlogSplitOperatorRightpage( - RedoBufferInfo* rbuf, void* recorddata, BlockNumber leftsib, BlockNumber rnext, void* blkdata, Size datalen); -void BtreeXlogSplitOperatorNextpage(RedoBufferInfo* buffer, BlockNumber rightsib); -void BtreeXlogSplitOperatorLeftpage( - RedoBufferInfo* lbuf, void* recorddata, BlockNumber rightsib, bool onleft, void* blkdata, Size datalen); -void BtreeXlogVacuumOperatorPage(RedoBufferInfo* redobuffer, void* recorddata, void* blkdata, Size len); -void BtreeXlogDeleteOperatorPage(RedoBufferInfo* buffer, void* recorddata, Size recorddatalen); -void btreeXlogDeletePageOperatorRightpage(RedoBufferInfo* buffer, void* recorddata); - -void BtreeXlogDeletePageOperatorLeftpage(RedoBufferInfo* buffer, void* recorddata); - -void BtreeXlogDeletePageOperatorCurrentpage(RedoBufferInfo* buffer, void* recorddata); - -void BtreeXlogNewrootOperatorPage(RedoBufferInfo* buffer, void* record, void* blkdata, Size len, BlockNumber* downlink); -void BtreeXlogHalfdeadPageOperatorParentpage( - RedoBufferInfo* pbuf, void* recorddata); -void BtreeXlogHalfdeadPageOperatorLeafpage( - RedoBufferInfo* lbuf, void* recorddata); -void BtreeXlogUnlinkPageOperatorRightpage(RedoBufferInfo* rbuf, void* recorddata); -void BtreeXlogUnlinkPageOperatorLeftpage(RedoBufferInfo* lbuf, void* recorddata); -void BtreeXlogUnlinkPageOperatorCurpage(RedoBufferInfo* buf, void* recorddata); -void BtreeXlogUnlinkPageOperatorChildpage(RedoBufferInfo* cbuf, void* recorddata); - -void BtreeXlogClearIncompleteSplit(RedoBufferInfo* buffer); - -/* UBTree */ -extern void UBTreeRestorePage(Page page, char* from, int len); -extern void UBTreeXlogMarkDeleteOperatorPage(RedoBufferInfo* buffer, void* recorddata); -extern void UBTreeXlogPrunePageOperatorPage(RedoBufferInfo* buffer, void* recorddata); -extern void UBTree2XlogShiftBaseOperatorPage(RedoBufferInfo* buffer, void* recorddata); -extern void UBTree2XlogRecycleQueueInitPageOperatorCurrPage(RedoBufferInfo* buffer, void* recorddata); -extern void UBTree2XlogRecycleQueueInitPageOperatorAdjacentPage(RedoBufferInfo* buffer, void* recorddata, bool isLeft); -extern void UBTree2XlogRecycleQueueEndpointOperatorLeftPage(RedoBufferInfo* buffer, void* recorddata); -extern void UBTree2XlogRecycleQueueEndpointOperatorRightPage(RedoBufferInfo* buffer, void* recorddata); -extern void UBTree2XlogRecycleQueueModifyOperatorPage(RedoBufferInfo* buffer, void* recorddata); -extern void UBTree2XlogFreezeOperatorPage(RedoBufferInfo* buffer, void* recorddata); - -extern void UBTreeRestoreMetaOperatorPage(RedoBufferInfo* metabuf, void* recorddata, Size datalen); -extern void UBTreeXlogInsertOperatorPage(RedoBufferInfo* buffer, void* recorddata, void* data, Size datalen); -extern void UBTreeXlogSplitOperatorRightPage(RedoBufferInfo* rbuf, void* recorddata, BlockNumber leftsib, - BlockNumber rnext, void* blkdata, Size datalen, bool hasOpaque = true); -extern void UBTreeXlogSplitOperatorNextpage(RedoBufferInfo* buffer, BlockNumber rightsib); -extern void UBTreeXlogSplitOperatorLeftpage(RedoBufferInfo* lbuf, void* recorddata, BlockNumber rightsib, - bool onleft, void* blkdata, Size datalen, bool hasOpaque = true); -extern void UBTreeXlogVacuumOperatorPage(RedoBufferInfo* redobuffer, void* recorddata, void* blkdata, Size len); -extern void UBTreeXlogDeleteOperatorPage(RedoBufferInfo* buffer, void* recorddata, Size recorddatalen); -extern void UBTreeXlogDeletePageOperatorRightpage(RedoBufferInfo* buffer, void* recorddata); - -extern void UBTreeXlogDeletePageOperatorLeftpage(RedoBufferInfo* buffer, void* recorddata); - -extern void UBTreeXlogDeletePageOperatorCurrentpage(RedoBufferInfo* buffer, void* recorddata); - -extern void UBTreeXlogNewrootOperatorPage(RedoBufferInfo *buffer, void *record, void *blkdata, Size len, - BlockNumber *downlink); -extern void UBTreeXlogHalfdeadPageOperatorParentpage( - RedoBufferInfo* pbuf, void* recorddata); -extern void UBTreeXlogHalfdeadPageOperatorLeafpage( - RedoBufferInfo* lbuf, void* recorddata); -extern void UBTreeXlogUnlinkPageOperatorRightpage(RedoBufferInfo* rbuf, void* recorddata); -extern void UBTreeXlogUnlinkPageOperatorLeftpage(RedoBufferInfo* lbuf, void* recorddata); -extern void UBTreeXlogUnlinkPageOperatorCurpage(RedoBufferInfo* buf, void* recorddata); -extern void UBTreeXlogUnlinkPageOperatorChildpage(RedoBufferInfo* cbuf, void* recorddata); - -extern void UBTreeXlogClearIncompleteSplit(RedoBufferInfo* buffer); - -void HashRedoInitMetaPageOperatorPage(RedoBufferInfo *metabuf, void *recorddata); - -void HashRedoInitBitmapPageOperatorBitmapPage(RedoBufferInfo *bitmapbuf, void *recorddata); -void HashRedoInitBitmapPageOperatorMetaPage(RedoBufferInfo *metabuf); - -void HashRedoInsertOperatorPage(RedoBufferInfo *buffer, void *recorddata, void *data, Size datalen); -void HashRedoInsertOperatorMetaPage(RedoBufferInfo *metabuf); - -void HashRedoAddOvflPageOperatorOvflPage(RedoBufferInfo *ovflbuf, BlockNumber leftblk, void *data, Size datalen); -void HashRedoAddOvflPageOperatorLeftPage(RedoBufferInfo *ovflbuf, BlockNumber rightblk); -void HashRedoAddOvflPageOperatorMapPage(RedoBufferInfo *mapbuf, void *data); -void HashRedoAddOvflPageOperatorNewmapPage(RedoBufferInfo *newmapbuf, void *recorddata); -void HashRedoAddOvflPageOperatorMetaPage(RedoBufferInfo *metabuf, void *recorddata, void *data, Size datalen); - -void HashRedoSplitAllocatePageOperatorObukPage(RedoBufferInfo *oldbukbuf, void *recorddata); -void HashRedoSplitAllocatePageOperatorNbukPage(RedoBufferInfo *newbukbuf, void *recorddata); -void HashRedoSplitAllocatePageOperatorMetaPage(RedoBufferInfo *metabuf, void *recorddata, void *blkdata); - -void HashRedoSplitCompleteOperatorObukPage(RedoBufferInfo *oldbukbuf, void *recorddata); -void HashRedoSplitCompleteOperatorNbukPage(RedoBufferInfo *newbukbuf, void *recorddata); - -void HashXlogMoveAddPageOperatorPage(RedoBufferInfo *redobuffer, void *recorddata, void *blkdata, Size len); -void HashXlogMoveDeleteOvflPageOperatorPage(RedoBufferInfo *redobuffer, void *blkdata, Size len); - -void HashXlogSqueezeAddPageOperatorPage(RedoBufferInfo *redobuffer, void *recorddata, void *blkdata, Size len); -void HashXlogSqueezeInitOvflbufOperatorPage(RedoBufferInfo *redobuffer, void *recorddata); -void HashXlogSqueezeUpdatePrevPageOperatorPage(RedoBufferInfo *redobuffer, void *recorddata); -void HashXlogSqueezeUpdateNextPageOperatorPage(RedoBufferInfo *redobuffer, void *recorddata); -void HashXlogSqueezeUpdateBitmapOperatorPage(RedoBufferInfo *redobuffer, void *blkdata); -void HashXlogSqueezeUpdateMateOperatorPage(RedoBufferInfo *redobuffer, void *blkdata); - -void HashXlogDeleteBlockOperatorPage(RedoBufferInfo *redobuffer, void *recorddata, void *blkdata, Size len); - -void HashXlogSplitCleanupOperatorPage(RedoBufferInfo *redobuffer); - -void HashXlogUpdateMetaOperatorPage(RedoBufferInfo *redobuffer, void *recorddata); - -void HashXlogVacuumOnePageOperatorPage(RedoBufferInfo *redobuffer, void *recorddata, Size len); - -void HashXlogVacuumMateOperatorPage(RedoBufferInfo *redobuffer, void *recorddata); - -void XLogRecSetBlockCommonState(XLogReaderState* record, XLogBlockParseEnum blockvalid, - RelFileNodeForkNum filenode, XLogRecParseState* recordblockstate, XLogPhyBlock *pblk = NULL); - -void XLogRecSetBlockCLogState( - XLogBlockCLogParse* blockclogstate, TransactionId topxid, uint16 status, uint16 xidnum, uint16* xidsarry); - -void XLogRecSetBlockCSNLogState( - XLogBlockCSNLogParse* blockcsnlogstate, TransactionId topxid, CommitSeqNo csnseq, uint16 xidnum, uint16* xidsarry); -void XLogRecSetXactRecoveryState(XLogBlockXactParse* blockxactstate, TransactionId maxxid, CommitSeqNo maxcsnseq, - uint8 delayddlflag, uint8 updateminrecovery); -void XLogRecSetXactDdlState(XLogBlockXactParse* blockxactstate, int nrels, void* xnodes, int invalidmsgnum, - void* invalidmsg, int nlibs, void* libfilename); -void XLogRecSetXactCommonState( - XLogBlockXactParse* blockxactstate, uint16 committype, uint64 xinfo, TimestampTz xact_time); -void XLogRecSetBcmState(XLogBlockBcmParse* blockbcmrec, uint64 startblock, int count, int status); -void XLogRecSetNewCuState(XLogBlockNewCuParse* blockcudata, char* main_data, uint32 main_data_len); -void XLogRecSetInvalidMsgState(XLogBlockInvalidParse* blockinvalid, TransactionId cutoffxid); -void XLogRecSetIncompleteMsgState(XLogBlockIncompleteParse* blockincomplete, uint16 action, bool issplit, bool isroot, - BlockNumber downblk, BlockNumber leftblk, BlockNumber rightblk); -void XLogRecSetPinVacuumState(XLogBlockVacuumPinParse* blockvacuum, BlockNumber lastblknum); -void XLogRecSetSegFullSyncState(XLogBlockSegFullSyncParse *state, void *childState); -void XLogRecSetSegNewPageInfo(XLogBlockSegNewPage *state, char *mainData, Size len); -void XLogRecSetAuxiBlkNumState(XLogBlockDataParse* blockdatarec, BlockNumber auxilaryblkn1, BlockNumber auxilaryblkn2); -void XLogRecSetBlockDataStateContent(XLogReaderState *record, uint32 blockid, XLogBlockDataParse *blockdatarec); -void XLogRecSetBlockDataState(XLogReaderState* record, uint32 blockid, XLogRecParseState* recordblockstate, - XLogBlockParseEnum type = BLOCK_DATA_MAIN_DATA_TYPE); -extern char* XLogBlockDataGetBlockData(XLogBlockDataParse* datadecode, Size* len); -void Heap2RedoDataBlock(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); -extern void HeapRedoDataBlock( - XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); -void SegPageRedoDataBlock(XLogBlockHead *blockhead, XLogBlockDataParse *blockdatarec, RedoBufferInfo *bufferinfo); -extern void xlog_redo_data_block( - XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); -extern void XLogRecSetBlockDdlState(XLogBlockDdlParse* blockddlstate, uint32 blockddltype, char *mainData, - int rels = 1); -XLogRedoAction XLogCheckBlockDataRedoAction(XLogBlockDataParse* datadecode, RedoBufferInfo* bufferinfo); - -void BtreeRedoDataBlock(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); -void Btree2RedoDataBlock(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); - -/* UBTree */ -extern void UBTreeRedoDataBlock(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); -extern void UBTree2RedoDataBlock(XLogBlockHead *blockhead, XLogBlockDataParse *blockdatarec, - RedoBufferInfo *bufferinfo); - -extern void HashRedoDataBlock(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); -XLogRecParseState* XactXlogCsnlogParseToBlock(XLogReaderState* record, uint32* blocknum, TransactionId xid, - int nsubxids, TransactionId* subxids, CommitSeqNo csn, XLogRecParseState* recordstatehead); -extern void XLogRecSetVmBlockState(XLogReaderState* record, uint32 blockid, XLogRecParseState* recordblockstate); -extern void XLogRecSetUHeapUndoBlockState(XLogReaderState* record, uint32 blockid, XLogRecParseState* recordundostate); -extern void XLogRecSetUndoBlockState(XLogReaderState* record, uint32 blockid, XLogRecParseState* recordundostate); -extern void XLogRecSetRollbackFinishBlockState(XLogReaderState *record, uint32 blockid, - XLogRecParseState *recordundostate); -extern bool DoLsnCheck(const RedoBufferInfo* bufferinfo, bool willInit, XLogRecPtr lastLsn, - const XLogPhyBlock *pblk, bool *needRepair); -char* XLogBlockDataGetMainData(XLogBlockDataParse* datadecode, Size* len); -void HeapRedoVmBlock(XLogBlockHead* blockhead, XLogBlockVmParse* blockvmrec, RedoBufferInfo* bufferinfo); -void Heap2RedoVmBlock(XLogBlockHead* blockhead, XLogBlockVmParse* blockvmrec, RedoBufferInfo* bufferinfo); -XLogRecParseState* xlog_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); -XLogRecParseState* smgr_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); -XLogRecParseState* segpage_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); -void ProcSegPageCommonRedo(XLogRecParseState *parseState); -void ProcSegPageJustFreeChildState(XLogRecParseState *parseState); -XLogRecParseState* XactXlogClogParseToBlock(XLogReaderState* record, XLogRecParseState* recordstatehead, - uint32* blocknum, TransactionId xid, int nsubxids, TransactionId* subxids, CLogXidStatus status); -XLogRecParseState* xact_xlog_commit_parse_to_block(XLogReaderState* record, XLogRecParseState* recordstatehead, - uint32* blocknum, TransactionId maxxid, CommitSeqNo maxseqnum); -void visibilitymap_clear_buffer(RedoBufferInfo* bufferinfo, BlockNumber heapBlk); -XLogRecParseState* xact_xlog_abort_parse_to_block(XLogReaderState* record, XLogRecParseState* recordstatehead, - uint32* blocknum, TransactionId maxxid, CommitSeqNo maxseqnum); -XLogRecParseState* xact_xlog_prepare_parse_to_block( - XLogReaderState* record, XLogRecParseState* recordstatehead, uint32* blocknum, TransactionId maxxid); -XLogRecParseState* xact_xlog_parse_to_block(XLogReaderState* record, uint32* blocknum); -XLogRecParseState* ClogRedoParseToBlock(XLogReaderState* record, uint32* blocknum); - -XLogRecParseState* DbaseRedoParseToBlock(XLogReaderState* record, uint32* blocknum); - -XLogRecParseState* Heap2RedoParseIoBlock(XLogReaderState* record, uint32* blocknum); -extern XLogRecParseState* HeapRedoParseToBlock(XLogReaderState* record, uint32* blocknum); -extern XLogRecParseState* BtreeRedoParseToBlock(XLogReaderState* record, uint32* blocknum); -/* UBTree */ -extern XLogRecParseState* UBTreeRedoParseToBlock(XLogReaderState* record, uint32* blocknum); -extern XLogRecParseState* UBTree2RedoParseToBlock(XLogReaderState* record, uint32* blocknum); - -extern XLogRecParseState* Heap3RedoParseToBlock(XLogReaderState* record, uint32* blocknum); - -extern Size SalEncodeXLogBlock(void* recordblockstate, byte* buffer, void* sliceinfo); - -extern XLogRecParseState* XLogParseToBlockForDfv(XLogReaderState* record, uint32* blocknum); -extern Size getBlockSize(XLogRecParseState* recordblockstate); -extern XLogRecParseState* GistRedoParseToBlock(XLogReaderState* record, uint32* blocknum); -extern XLogRecParseState* GinRedoParseToBlock(XLogReaderState* record, uint32* blocknum); - -extern void GistRedoClearFollowRightOperatorPage(RedoBufferInfo* buffer); -extern void GistRedoPageUpdateOperatorPage(RedoBufferInfo* buffer, void* recorddata, void* blkdata, Size datalen); -extern void GistRedoPageSplitOperatorPage( - RedoBufferInfo* buffer, void* recorddata, void* data, Size datalen, bool Markflag, BlockNumber rightlink); -extern void GistRedoCreateIndexOperatorPage(RedoBufferInfo* buffer); - -extern void GinRedoCreateIndexOperatorMetaPage(RedoBufferInfo* MetaBuffer); -extern void GinRedoCreateIndexOperatorRootPage(RedoBufferInfo* RootBuffer); -extern void GinRedoCreatePTreeOperatorPage(RedoBufferInfo* buffer, void* recordData); -extern void GinRedoClearIncompleteSplitOperatorPage(RedoBufferInfo* buffer); -extern void GinRedoVacuumDataOperatorLeafPage(RedoBufferInfo* buffer, void* recorddata); -extern void GinRedoDeletePageOperatorCurPage(RedoBufferInfo* dbuffer); -extern void GinRedoDeletePageOperatorParentPage(RedoBufferInfo* pbuffer, void* recorddata); -extern void GinRedoDeletePageOperatorLeftPage(RedoBufferInfo* lbuffer, void* recorddata); -extern void GinRedoUpdateOperatorMetapage(RedoBufferInfo* metabuffer, void* recorddata); -extern void GinRedoUpdateOperatorTailPage(RedoBufferInfo* buffer, void* payload, Size totaltupsize, int32 ntuples); -extern void GinRedoInsertListPageOperatorPage( - RedoBufferInfo* buffer, void* recorddata, void* payload, Size totaltupsize); -extern void GinRedoUpdateAddNewTail(RedoBufferInfo* buffer, BlockNumber newRightlink); -extern void GinRedoInsertData(RedoBufferInfo* buffer, bool isLeaf, BlockNumber rightblkno, void* rdata); -extern void GinRedoInsertEntry(RedoBufferInfo* buffer, bool isLeaf, BlockNumber rightblkno, void* rdata); - -extern void GinRedoDeleteListPagesOperatorPage(RedoBufferInfo* metabuffer, const void* recorddata); -extern void GinRedoDeleteListPagesMarkDelete(RedoBufferInfo* buffer); - -extern void spgRedoCreateIndexOperatorMetaPage(RedoBufferInfo* buffer); -extern void spgRedoCreateIndexOperatorRootPage(RedoBufferInfo* buffer); -extern void spgRedoCreateIndexOperatorLeafPage(RedoBufferInfo* buffer); -extern void spgRedoAddLeafOperatorPage(RedoBufferInfo* bufferinfo, void* recorddata); -extern void spgRedoAddLeafOperatorParent(RedoBufferInfo* bufferinfo, void* recorddata, BlockNumber blknoLeaf); -extern void spgRedoMoveLeafsOpratorDstPage(RedoBufferInfo* buffer, void* recorddata, void* insertdata, void* tupledata); -extern void spgRedoMoveLeafsOpratorSrcPage( - RedoBufferInfo* buffer, void* recorddata, void* insertdata, void* deletedata, BlockNumber blknoDst, int nInsert); -extern void spgRedoMoveLeafsOpratorParentPage( - RedoBufferInfo* buffer, void* recorddata, void* insertdata, BlockNumber blknoDst, int nInsert); -extern void spgRedoAddNodeUpdateSrcPage(RedoBufferInfo* buffer, void* recorddata, void* tuple, void* tupleheader); -extern void spgRedoAddNodeOperatorSrcPage(RedoBufferInfo* buffer, void* recorddata, BlockNumber blknoNew); -extern void spgRedoAddNodeOperatorDestPage( - RedoBufferInfo* buffer, void* recorddata, void* tuple, void* tupleheader, BlockNumber blknoNew); -extern void spgRedoAddNodeOperatorParentPage(RedoBufferInfo* buffer, void* recorddata, BlockNumber blknoNew); -extern void spgRedoSplitTupleOperatorDestPage(RedoBufferInfo* buffer, void* recorddata, void* tuple); -extern void spgRedoSplitTupleOperatorSrcPage(RedoBufferInfo* buffer, void* recorddata, void* pretuple, void* posttuple); -extern void spgRedoPickSplitRestoreLeafTuples( - RedoBufferInfo* buffer, void* recorddata, bool destflag, void* pageselect, void* insertdata); -extern void spgRedoPickSplitOperatorSrcPage(RedoBufferInfo* srcBuffer, void* recorddata, void* deleteoffset, - BlockNumber blknoInner, void* pageselect, void* insertdata); -extern void spgRedoPickSplitOperatorDestPage( - RedoBufferInfo* destBuffer, void* recorddata, void* pageselect, void* insertdata); -extern void spgRedoPickSplitOperatorInnerPage( - RedoBufferInfo* innerBuffer, void* recorddata, void* tuple, void* tupleheader, BlockNumber blknoInner); -extern void spgRedoPickSplitOperatorParentPage(RedoBufferInfo* parentBuffer, void* recorddata, BlockNumber blknoInner); -extern void spgRedoVacuumLeafOperatorPage(RedoBufferInfo* buffer, void* recorddata); -extern void spgRedoVacuumRootOperatorPage(RedoBufferInfo* buffer, void* recorddata); -extern void spgRedoVacuumRedirectOperatorPage(RedoBufferInfo* buffer, void* recorddata); - -extern XLogRecParseState* SpgRedoParseToBlock(XLogReaderState* record, uint32* blocknum); - -extern void seqRedoOperatorPage(RedoBufferInfo* buffer, void* itmedata, Size itemsz); -extern void seq_redo_data_block(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); - -extern void Heap3RedoDataBlock( - XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); - -extern XLogRecParseState* xact_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); - -extern bool XLogBlockRedoForExtremeRTO(XLogRecParseState* redoblocktate, RedoBufferInfo *bufferinfo, - bool notfound, RedoTimeCost &readBufCost, RedoTimeCost &redoCost); -void XLogBlockParseStateRelease_debug(XLogRecParseState* recordstate, const char *func, uint32 line); -#define XLogBlockParseStateRelease(recordstate) XLogBlockParseStateRelease_debug(recordstate, __FUNCTION__, __LINE__) -#ifdef USE_ASSERT_CHECKING -extern void DoRecordCheck(XLogRecParseState *recordstate, XLogRecPtr pageLsn, bool replayed); -#endif -extern XLogRecParseState* XLogParseBufferCopy(XLogRecParseState *srcState); -extern XLogRecParseState* XLogParseToBlockForExtermeRTO(XLogReaderState* record, uint32* blocknum); -extern XLogRedoAction XLogReadBufferForRedoBlockExtend(RedoBufferTag *redoblock, ReadBufferMode mode, - bool get_cleanup_lock, RedoBufferInfo *redobufferinfo, - XLogRecPtr xloglsn, XLogRecPtr last_lsn, bool willinit, - ReadBufferMethod readmethod, bool tde = false); -extern XLogRecParseState* tblspc_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); -extern XLogRecParseState* relmap_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); -extern XLogRecParseState* HashRedoParseToBlock(XLogReaderState* record, uint32* blocknum); -extern XLogRecParseState* seq_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); -extern XLogRecParseState* slot_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); -extern XLogRecParseState* barrier_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); -extern XLogRecParseState* multixact_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); -extern void ExtremeRtoFlushBuffer(RedoBufferInfo *bufferinfo, bool updateFsm); -extern void XLogForgetDDLRedo(XLogRecParseState* redoblockstate); -void XLogDropSpaceShrink(XLogRecParseState *redoblockstate); -extern void SyncOneBufferForExtremRto(RedoBufferInfo *bufferinfo); -extern void XLogBlockInitRedoBlockInfo(XLogBlockHead* blockhead, RedoBufferTag* blockinfo); -extern void XLogBlockDdlDoSmgrAction(XLogBlockHead* blockhead, void* blockrecbody, RedoBufferInfo* bufferinfo); -extern void XLogBlockSegDdlDoRealAction(XLogBlockHead* blockhead, void* blockrecbody, RedoBufferInfo* bufferinfo); -extern void GinRedoDataBlock(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); -extern void GistRedoDataBlock(XLogBlockHead *blockhead, XLogBlockDataParse *blockdatarec, RedoBufferInfo *bufferinfo); -extern bool IsCheckPoint(const XLogRecParseState *parseState); - -void redo_atomic_xlog_dispatch(uint8 opCode, RedoBufferInfo *redo_buf, const char *data); -void seg_redo_new_page_copy_and_flush(BufferTag *tag, char *data, XLogRecPtr lsn); - -#endif +/* + * Copyright (c) 2020 Huawei Technologies Co.,Ltd. + * + * openGauss is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * --------------------------------------------------------------------------------------- + * + * xlogproc.h + * + * + * IDENTIFICATION + * src/include/access/xlogproc.h + * + * --------------------------------------------------------------------------------------- + */ + +#ifndef XLOG_PROC_H +#define XLOG_PROC_H +#include "postgres.h" +#include "knl/knl_variable.h" + +#include "access/xlogreader.h" +#include "storage/buf/bufmgr.h" +#include "storage/buf/buf_internals.h" +#include "access/xlog_basic.h" +#include "access/xlogutils.h" +#include "access/clog.h" +#include "access/ustore/knl_uredo.h" +#include "access/ustore/knl_utuple.h" +#include "access/ustore/undo/knl_uundotxn.h" +#include "access/ustore/undo/knl_uundoxlog.h" + +#ifndef byte +#define byte unsigned char +#endif + +typedef void (*relasexlogreadstate)(void* record); +/* **************define for parse end******************************* */ +#define MIN(_a, _b) ((_a) > (_b) ? (_b) : (_a)) + +/* for common blockhead begin */ + +#define XLogBlockHeadGetInfo(blockhead) ((blockhead)->xl_info) +#define XLogBlockHeadGetXid(blockhead) ((blockhead)->xl_xid) +#define XLogBlockHeadGetRmid(blockhead) ((blockhead)->xl_rmid) + +#define XLogBlockHeadGetLSN(blockhead) ((blockhead)->end_ptr) +#define XLogBlockHeadGetRelNode(blockhead) ((blockhead)->relNode) +#define XLogBlockHeadGetSpcNode(blockhead) ((blockhead)->spcNode) +#define XLogBlockHeadGetDbNode(blockhead) ((blockhead)->dbNode) +#define XLogBlockHeadGetForkNum(blockhead) ((blockhead)->forknum) +#define XLogBlockHeadGetBlockNum(blockhead) ((blockhead)->blkno) +#define XLogBlockHeadGetBucketId(blockhead) ((blockhead)->bucketNode) +#define XLogBlockHeadGetCompressOpt(blockhead) ((blockhead)->opt) +#define XLogBlockHeadGetValidInfo(blockhead) ((blockhead)->block_valid) +#define XLogBlockHeadGetPhysicalBlock(blockhead) ((blockhead)->pblk) +/* for common blockhead end */ + +/* for block data beging */ +#define XLogBlockDataHasBlockImage(blockdata) ((blockdata)->blockhead.has_image) +#define XLogBlockDataHasBlockData(blockdata) ((blockdata)->blockhead.has_data) +#define XLogBlockDataGetLastBlockLSN(_blockdata) ((_blockdata)->blockdata.last_lsn) +#define XLogBlockDataGetBlockFlags(blockdata) ((blockdata)->blockhead.flags) + +#define XLogBlockDataGetBlockId(blockdata) ((blockdata)->blockhead.cur_block_id) +#define XLogBlockDataGetAuxiBlock1(blockdata) ((blockdata)->blockhead.auxiblk1) +#define XLogBlockDataGetAuxiBlock2(blockdata) ((blockdata)->blockhead.auxiblk2) +/* for block data end */ + +typedef struct { + RelFileNode rnode; + ForkNumber forknum; + BlockNumber blkno; + XLogPhyBlock pblk; +} RedoBufferTag; + +typedef struct { + Page page; // pagepointer + Size pagesize; +#ifdef USE_ASSERT_CHECKING + bool ignorecheck; +#endif +} RedoPageInfo; + +typedef struct { + XLogRecPtr lsn; /* block cur lsn */ + Buffer buf; + RedoBufferTag blockinfo; + RedoPageInfo pageinfo; + int dirtyflag; /* true if the buffer changed */ +} RedoBufferInfo; + +extern void GetFlushBufferInfo(void *buf, RedoBufferInfo *bufferinfo, uint32 *buf_state, ReadBufferMethod flushmethod); + +#define MakeRedoBufferDirty(bufferinfo) ((bufferinfo)->dirtyflag = true) +#define RedoBufferDirtyClear(bufferinfo) ((bufferinfo)->dirtyflag = false) +#define IsRedoBufferDirty(bufferinfo) ((bufferinfo)->dirtyflag == true) + +#define RedoMemIsValid(memctl, bufferid) (((bufferid) > InvalidBuffer) && ((bufferid) <= (memctl->totalblknum))) + +typedef struct { + RedoBufferTag blockinfo; + pg_atomic_uint32 state; +} RedoBufferDesc; + +typedef struct { + Buffer buff_id; + pg_atomic_uint32 state; +} ParseBufferDesc; + +#define RedoBufferSlotGetBuffer(bslot) ((bslot)->buf_id) + +#define EnalbeWalLsnCheck true + +#pragma pack(push, 1) + +#define INVALID_BLOCK_ID (XLR_MAX_BLOCK_ID + 2) + +#define LOW_BLOKNUMBER_BITS (32) +#define LOW_BLOKNUMBER_MASK (((uint64)1 << 32) - 1) + + +/* ********BLOCK COMMON HEADER BEGIN ***************** */ +typedef enum { + BLOCK_DATA_MAIN_DATA_TYPE = 0, /* BLOCK DATA */ + BLOCK_DATA_VM_TYPE, /* VM */ + BLOCK_DATA_UNDO_TYPE, /* UNDO */ + BLOCK_DATA_FSM_TYPE, /* FSM */ + BLOCK_DATA_DDL_TYPE, /* DDL */ + BLOCK_DATA_BCM_TYPE, /* bcm */ + BLOCK_DATA_NEWCU_TYPE, /* cu newlog */ + BLOCK_DATA_CLOG_TYPE, /* CLog */ + BLOCK_DATA_MULITACT_OFF_TYPE, /* MultiXact */ + BLOCK_DATA_MULITACT_MEM_TYPE, + BLOCK_DATA_CSNLOG_TYPE, /* CSNLog */ + /* *****xact don't need sent to dfv */ + BLOCK_DATA_MULITACT_UPDATEOID_TYPE, + BLOCK_DATA_XACTDATA_TYPE, /* XACT */ + BLOCK_DATA_RELMAP_TYPE, /* RELMAP */ + BLOCK_DATA_SLOT_TYPE, + BLOCK_DATA_BARRIER_TYPE, + BLOCK_DATA_PREPARE_TYPE, /* prepare */ + BLOCK_DATA_INVALIDMSG_TYPE, /* INVALIDMSG */ + BLOCK_DATA_INCOMPLETE_TYPE, + BLOCK_DATA_VACUUM_PIN_TYPE, + BLOCK_DATA_XLOG_COMMON_TYPE, + BLOCK_DATA_CREATE_DATABASE_TYPE, + BLOCK_DATA_DROP_DATABASE_TYPE, + BLOCK_DATA_CREATE_TBLSPC_TYPE, + BLOCK_DATA_DROP_TBLSPC_TYPE, + BLOCK_DATA_DROP_SLICE_TYPE, + BLOCK_DATA_SEG_FILE_EXTEND_TYPE, + BLOCK_DATA_SEG_SPACE_DROP, + BLOCK_DATA_SEG_SPACE_SHRINK, + BLOCK_DATA_SEG_FULL_SYNC_TYPE, + BLOCK_DATA_SEG_EXTEND, +} XLogBlockParseEnum; + +/* ********BLOCK COMMON HEADER END ***************** */ + +/* **************define for parse begin ******************************* */ + +/* ********BLOCK DATE BEGIN ***************** */ + +typedef struct { + uint8 cur_block_id; /* blockid */ + uint8 flags; + uint8 has_image; + uint8 has_data; + BlockNumber auxiblk1; + BlockNumber auxiblk2; +} XLogBlocDatakHead; + +#define XLOG_BLOCK_DATAHEAD_LEN sizeof(XLogBlocDatakHead) + +typedef struct { + uint16 extra_flag; + uint16 hole_offset; + uint16 hole_length; /* image position */ + uint16 data_len; /* data length */ + XLogRecPtr last_lsn; + char* bkp_image; + char* data; +} XLogBlockData; + +#define XLOG_BLOCK_DATA_LEN sizeof(XLogBlockData) + +typedef struct { + XLogBlocDatakHead blockhead; + XLogBlockData blockdata; + uint32 main_data_len; /* main data portion's length */ + char* main_data; /* point to XLogReaderState's main_data */ +} XLogBlockDataParse; +/* ********BLOCK DATE END ***************** */ +#define XLOG_BLOCK_DATA_PARSE_LEN sizeof(XLogBlockDataParse) + +/* ********BLOCK DDL BEGIN ***************** */ +typedef enum { + BLOCK_DDL_TYPE_NONE = 0, + BLOCK_DDL_CREATE_RELNODE, + BLOCK_DDL_DROP_RELNODE, + BLOCK_DDL_EXTEND_RELNODE, + BLOCK_DDL_TRUNCATE_RELNODE, + BLOCK_DDL_CLOG_ZERO, + BLOCK_DDL_CLOG_TRUNCATE, + BLOCK_DDL_MULTIXACT_OFF_ZERO, + BLOCK_DDL_MULTIXACT_MEM_ZERO, +} XLogBlockDdlInfoEnum; + +typedef struct { + uint32 blockddltype; + int rels; + char *mainData; +} XLogBlockDdlParse; + +/* ********BLOCK DDL END ***************** */ + +/* ********BLOCK CLOG BEGIN ***************** */ + +#define MAX_BLOCK_XID_NUMS (28) +typedef struct { + TransactionId topxid; + uint16 status; + uint16 xidnum; + uint16 xidsarry[MAX_BLOCK_XID_NUMS]; +} XLogBlockCLogParse; + +/* ********BLOCK CLOG END ***************** */ + +/* ********BLOCK CSNLOG BEGIN ***************** */ +typedef struct { + TransactionId topxid; + CommitSeqNo cslseq; + uint32 xidnum; + uint16 xidsarry[MAX_BLOCK_XID_NUMS]; +} XLogBlockCSNLogParse; + +/* ********BLOCK CSNLOG END ***************** */ + +/* ********BLOCK prepare BEGIN ***************** */ +struct TwoPhaseFileHeader; + +typedef struct { + TransactionId maxxid; + Size maindatalen; + char* maindata; +} XLogBlockPrepareParse; + +/* ********BLOCK prepare END ***************** */ + +/* ********BLOCK Bcm BEGIN ***************** */ +typedef struct { + uint64 startblock; + int count; + int status; +} XLogBlockBcmParse; + +/* ********BLOCK Bcm END ***************** */ + +/* ********BLOCK Vm BEGIN ***************** */ +typedef struct { + BlockNumber heapBlk; +} XLogBlockVmParse; + +#define XLOG_BLOCK_VM_PARSE_LEN sizeof(XLogBlockVmParse) +/* ********BLOCK Vm END ***************** */ + +/* ********BLOCK Undo BEGIN ***************** */ +struct insertUndoParse { + TransactionId recxid; + BlockNumber blkno; + Oid spcNode; + Oid relNode; + XLogRecPtr lsn; + XlUndoHeader xlundohdr; + XlUndoHeaderExtra xlundohdrextra; + undo::XlogUndoMeta xlundometa; + OffsetNumber offnum; +}; + +struct deleteUndoParse { + TransactionId recxid; + TransactionId oldxid; + BlockNumber blkno; + Oid spcNode; + Oid relNode; + XLogRecPtr lsn; + XlUndoHeader xlundohdr; + XlUndoHeaderExtra xlundohdrextra; + undo::XlogUndoMeta xlundometa; + UHeapTupleData utup; + OffsetNumber offnum; +}; + +struct updateUndoParse { + bool inplaceUpdate; + TransactionId recxid; + TransactionId oldxid; + Oid spcNode; + Oid relNode; + OffsetNumber new_offnum; + OffsetNumber old_offnum; + XLogRecPtr lsn; + XlUndoHeader xlundohdr; + XlUndoHeaderExtra xlundohdrextra; + XlUndoHeader xlnewundohdr; + XlUndoHeaderExtra xlnewundohdrextra; + undo::XlogUndoMeta xlundometa; + int undoXorDeltaSize; + char *xlogXorDelta; + BlockNumber newblk; + BlockNumber oldblk; +}; + +struct multiInsertUndoParse { + TransactionId recxid; + BlockNumber blkno; + Oid spcNode; + Oid relNode; + XLogRecPtr lsn; + bool isinit; + bool skipUndo; + XlUndoHeader xlundohdr; + XlUndoHeaderExtra xlundohdrextra; + UndoRecPtr last_urecptr; + undo::XlogUndoMeta xlundometa; +}; + +struct rollbackFinishParse { + UndoSlotPtr slotPtr; + XLogRecPtr lsn; +}; + +struct undoDiscardParse { + int zoneId; + UndoSlotPtr endSlot; + UndoSlotPtr startSlot; + UndoRecPtr endUndoPtr; + TransactionId recycledXid; + XLogRecPtr lsn; +}; + +struct undoUnlinkParse { + int zoneId; + UndoLogOffset headOffset; + XLogRecPtr unlinkLsn; +}; + +struct undoExtendParse { + int zoneId; + UndoLogOffset tailOffset; + XLogRecPtr extendLsn; +}; + +struct undoCleanParse { + int zoneId; + UndoLogOffset tailOffset; + XLogRecPtr cleanLsn; +}; + +typedef struct { + char *maindata; + Size recordlen; + union { + struct insertUndoParse insertUndoParse; + struct deleteUndoParse deleteUndoParse; + struct updateUndoParse updateUndoParse; + struct undoDiscardParse undoDiscardParse; + struct undoUnlinkParse undoUnlinkParse; + struct undoExtendParse undoExtendParse; + struct undoCleanParse undoCleanParse; + struct rollbackFinishParse rollbackFinishParse; + struct multiInsertUndoParse multiInsertUndoParse; + }; +} XLogBlockUndoParse; +/* ********BLOCK Undo END ***************** */ + +/* ********BLOCK NewCu BEGIN ***************** */ +typedef struct { + uint32 main_data_len; /* main data portion's length */ + char* main_data; /* point to XLogReaderState's main_data */ +} XLogBlockNewCuParse; + + +/* ********BLOCK NewCu END ***************** */ + +/* ********BLOCK InvalidMsg BEGIN ***************** */ +typedef struct { + TransactionId cutoffxid; +} XLogBlockInvalidParse; + +/* ********BLOCK InvalidMsg END ***************** */ + +/* ********BLOCK Incomplete BEGIN ***************** */ + +typedef enum { + INCOMPLETE_ACTION_LOG = 0, + INCOMPLETE_ACTION_FORGET +} XLogBlockIncompleteEnum; + +typedef struct { + uint16 action; /* split or delete */ + bool issplit; + bool isroot; + BlockNumber downblk; + BlockNumber leftblk; + BlockNumber rightblk; +} XLogBlockIncompleteParse; + +/* ********BLOCK Incomplete END ***************** */ + +/* ********BLOCK VacuumPin BEGIN ***************** */ +typedef struct { + BlockNumber lastBlockVacuumed; +} XLogBlockVacuumPinParse; + +/* ********BLOCK XLOG Common BEGIN ***************** */ +typedef struct { + XLogRecPtr readrecptr; + Size maindatalen; + char* maindata; +} XLogBlockXLogComParse; + +/* ********BLOCK XLOG Common END ***************** */ + +/* ********BLOCK DataBase BEGIN ***************** */ +typedef struct { + Oid src_db_id; + Oid src_tablespace_id; +} XLogBlockDataBaseParse; + +/* ********BLOCK DataBase Common END ***************** */ + +/* ********BLOCK table spc BEGIN ***************** */ +typedef struct { + char* tblPath; + bool isRelativePath; +} XLogBlockTblSpcParse; + +/* ********BLOCK table spc END ***************** */ + +/* ********BLOCK Multi Xact Offset BEGIN ***************** */ +typedef struct { + MultiXactId multi; + MultiXactOffset moffset; +} XLogBlockMultiXactOffParse; + +/* ********BLOCK Multi Xact Offset END ***************** */ + +/* ********BLOCK Multi Xact Mem BEGIN ***************** */ +typedef struct { + MultiXactId multi; + MultiXactOffset startoffset; + uint64 xidnum; + TransactionId xidsarry[MAX_BLOCK_XID_NUMS]; +} XLogBlockMultiXactMemParse; +/* ********BLOCK Multi Xact Mem END ***************** */ + +/* ********BLOCK Multi Xact update oid BEGIN ***************** */ +typedef struct { + MultiXactId nextmulti; + MultiXactOffset nextoffset; + TransactionId maxxid; +} XLogBlockMultiUpdateParse; +/* ********BLOCK Multi Xact update oid END ***************** */ + +/* ********BLOCK rel map BEGIN ***************** */ +typedef struct { + Size maindatalen; + char* maindata; +} XLogBlockRelMapParse; +/* ********BLOCK rel map END ***************** */ + +typedef struct { + uint32 xl_term; +} XLogBlockRedoHead; + +#define XLogRecRedoHeadEncodeSize (offsetof(XLogBlockRedoHead, refrecord)) +typedef struct { + XLogRecPtr start_ptr; + XLogRecPtr end_ptr; /* copy from XLogReaderState's EndRecPtr */ + BlockNumber blkno; + Oid relNode; /* relation */ + uint16 block_valid; /* block data validinfo see XLogBlockInfoEnum */ + uint8 xl_info; /* flag bits, see below */ + RmgrId xl_rmid; /* resource manager for this record */ + ForkNumber forknum; + TransactionId xl_xid; /* xact id */ + Oid spcNode; /* tablespace */ + Oid dbNode; /* database */ + int2 bucketNode; /* bucket */ + uint2 opt; + XLogPhyBlock pblk; +} XLogBlockHead; + +#define XLogBlockHeadEncodeSize (sizeof(XLogBlockHead)) + +#define BYTE_NUM_BITS (8) +#define BYTE_MASK (0xFF) +#define U64_BYTES_NUM (8) +#define U32_BYTES_NUM (4) +#define U16_BYTES_NUM (2) +#define U8_BYTES_NUM (1) + +#define U32_BITS_NUM (BYTE_NUM_BITS * U32_BYTES_NUM) + +extern uint64 XLog_Read_N_Bytes(char* buffer, Size buffersize, Size readbytes); + +#define XLog_Read_1_Bytes(buffer, buffersize) XLog_Read_N_Bytes(buffer, buffersize, U8_BYTES_NUM) +#define XLog_Read_2_Bytes(buffer, buffersize) XLog_Read_N_Bytes(buffer, buffersize, U16_BYTES_NUM) +#define XLog_Read_4_Bytes(buffer, buffersize) XLog_Read_N_Bytes(buffer, buffersize, U32_BYTES_NUM) +#define XLog_Read_8_Bytes(buffer, buffersize) XLog_Read_N_Bytes(buffer, buffersize, U64_BYTES_NUM) + +extern bool XLog_Write_N_bytes(uint64 values, Size writebytes, byte* buffer); + +#define XLog_Write_1_Bytes(values, buffer) XLog_Write_N_bytes(values, U8_BYTES_NUM, buffer) +#define XLog_Write_2_Bytes(values, buffer) XLog_Write_N_bytes(values, U16_BYTES_NUM, buffer) +#define XLog_Write_4_Bytes(values, buffer) XLog_Write_N_bytes(values, U32_BYTES_NUM, buffer) +#define XLog_Write_8_Bytes(values, buffer) XLog_Write_N_bytes(values, U64_BYTES_NUM, buffer) + +typedef struct XLogBlockEnCode { + bool (*xlog_encodefun)(byte* buffer, Size buffersize, Size* encodesize, void* xlogbody); + uint16 block_valid; +} XLogBlockEnCode; + +typedef struct XLogBlockRedoCode { + void (*xlog_redofun)(char* buffer, Size buffersize, XLogBlockHead* blockhead, XLogBlockRedoHead* redohead, + void* page, Size pagesize); + uint16 block_valid; +} XLogBlockRedoCode; + +#pragma pack(pop) + +/* ********BLOCK Xact BEGIN ***************** */ +typedef struct { + uint8 delayddlflag; + uint8 updateminrecovery; + uint16 committype; + int invalidmsgnum; + int nrels; /* delete rels */ + int nlibs; /* delete libs */ + uint64 xinfo; + TimestampTz xact_time; + TransactionId maxxid; + CommitSeqNo maxcommitseq; + void* invalidmsg; + void* xnodes; + void* libfilename; +} XLogBlockXactParse; + +typedef struct { + Size maindatalen; + char* maindata; +} XLogBlockSlotParse; +/* ********BLOCK slot END ***************** */ + +/* ********BLOCK barrier BEGIN ***************** */ +typedef struct { + char* maindata; + Size maindatalen; +} XLogBlockBarrierParse; + +/* ********BLOCK Xact END ***************** */ + +/* ********BLOCK VacuumPin END ***************** */ + +/* ********BLOCK Segfile Extend Begin */ +typedef struct { + BlockNumber target_blocks; +} XLogSegFileExtendParse; +/* ********BLOCK Segfile Extend END */ + +/* ********BLOCK Segment Truncate Begin */ +typedef struct { + XLogBlockDdlParse blockddlrec; + XLogBlockDataParse blockdatarec; +} XLogBlockSegDdlParse; +/* ********BLOCK Segment Truncate END */ + +typedef struct { + void *childState; +} XLogBlockSegFullSyncParse; + +typedef struct { + char *mainData; + Size dataLen; +} XLogBlockSegNewPage; + +typedef struct { + XLogBlockHead blockhead; + XLogBlockRedoHead redohead; + union { + XLogBlockDataParse blockdatarec; + XLogBlockVmParse blockvmrec; + XLogBlockUndoParse blockundorec; + XLogBlockDdlParse blockddlrec; + XLogBlockBcmParse blockbcmrec; + XLogBlockNewCuParse blocknewcu; + XLogBlockCLogParse blockclogrec; + XLogBlockCSNLogParse blockcsnlogrec; + XLogBlockXactParse blockxact; + XLogBlockPrepareParse blockprepare; + XLogBlockInvalidParse blockinvalidmsg; + // XLogBlockIncompleteParse blockincomplete; + XLogBlockVacuumPinParse blockvacuumpin; + XLogBlockXLogComParse blockxlogcommon; + XLogBlockDataBaseParse blockdatabase; + XLogBlockTblSpcParse blocktblspc; + XLogBlockMultiXactOffParse blockmultixactoff; + XLogBlockMultiXactMemParse blockmultixactmem; + XLogBlockMultiUpdateParse blockmultiupdate; + XLogBlockRelMapParse blockrelmap; + XLogBlockSlotParse blockslot; + XLogBlockBarrierParse blockbarrier; + XLogSegFileExtendParse segfileExtend; + XLogBlockSegDdlParse blocksegddlrec; + XLogBlockSegFullSyncParse blocksegfullsyncrec; + XLogBlockSegNewPage blocksegnewpageinfo; + } extra_rec; +} XLogBlockParse; + +#define XLogBlockParseGetDdlParse(blockdatarec, ddlrecparse) \ + do \ + { \ + Assert((blockdatarec)->blockparse.blockhead.block_valid == BLOCK_DATA_DDL_TYPE); \ + if (blockdatarec->blockparse.blockhead.bucketNode != InvalidBktId) { \ + ddlrecparse = &blockdatarec->blockparse.extra_rec.blocksegddlrec.blockddlrec; \ + } else { \ + ddlrecparse = &blockdatarec->blockparse.extra_rec.blockddlrec; \ + } \ + } while (0); + +typedef struct +{ + Buffer buf_id; + Buffer freeNext; +} RedoMemSlot; + +typedef void (*InterruptFunc)(); + +typedef struct +{ + int totalblknum; /* total slot */ + int usedblknum; /* used slot */ + Size itemsize; + Buffer firstfreeslot; /* first free slot */ + Buffer firstreleaseslot; /* first release slot */ + RedoMemSlot *memslot; /* slot itme */ + bool isInit; + InterruptFunc doInterrupt; +}RedoMemManager; + +typedef void (*RefOperateFunc)(void *record); +#ifdef USE_ASSERT_CHECKING +typedef void (*RecordCheckFunc)(void *record, XLogRecPtr curPageLsn, uint32 blockId, bool replayed); +#endif +typedef void (*AddReadBlockFunc)(void *record, uint32 readblocks); + +typedef struct { + RefOperateFunc refCount; + RefOperateFunc DerefCount; +#ifdef USE_ASSERT_CHECKING + RecordCheckFunc checkFunc; +#endif + AddReadBlockFunc addReadBlock; +}RefOperate; + +typedef struct +{ + void *BufferBlockPointers; /* RedoBufferDesc + block */ + RedoMemManager memctl; + RefOperate *refOperate; +}RedoBufferManager; + + + +typedef struct +{ + void *parsebuffers; /* ParseBufferDesc + XLogRecParseState */ + RedoMemManager memctl; + RefOperate *refOperate; +}RedoParseManager; + + + +typedef struct { + void* nextrecord; + XLogBlockParse blockparse; /* block data */ + RedoParseManager* manager; + void* refrecord; /* origin dataptr, for mem release */ + bool isFullSync; +} XLogRecParseState; + +typedef struct XLogBlockRedoExtreRto { + void (*xlog_redoextrto)(XLogBlockHead* blockhead, void* blockrecbody, RedoBufferInfo* bufferinfo); + uint16 block_valid; +} XLogBlockRedoExtreRto; + +typedef struct XLogParseBlock { + XLogRecParseState* (*xlog_parseblock)(XLogReaderState* record, uint32* blocknum); + RmgrId rmid; +} XLogParseBlock; + +typedef enum { + HEAP_INSERT_ORIG_BLOCK_NUM = 0 +} XLogHeapInsertBlockEnum; + +typedef enum { + HEAP_DELETE_ORIG_BLOCK_NUM = 0 +} XLogHeapDeleteBlockEnum; + +typedef enum { + HEAP_UPDATE_NEW_BLOCK_NUM = 0, + HEAP_UPDATE_OLD_BLOCK_NUM +} XLogHeapUpdateBlockEnum; + +typedef enum { + HEAP_BASESHIFT_ORIG_BLOCK_NUM = 0 +} XLogHeapBaeShiftBlockEnum; + +typedef enum { + HEAP_NEWPAGE_ORIG_BLOCK_NUM = 0 +} XLogHeapNewPageBlockEnum; + +typedef enum { + HEAP_LOCK_ORIG_BLOCK_NUM = 0 +} XLogHeapLockBlockEnum; + +typedef enum { + HEAP_INPLACE_ORIG_BLOCK_NUM = 0 +} XLogHeapInplaceBlockEnum; + +typedef enum { + HEAP_FREEZE_ORIG_BLOCK_NUM = 0 +} XLogHeapFreezeBlockEnum; + +typedef enum { + HEAP_CLEAN_ORIG_BLOCK_NUM = 0 +} XLogHeapCleanBlockEnum; + +typedef enum { + HEAP_VISIBLE_VM_BLOCK_NUM = 0, + HEAP_VISIBLE_DATA_BLOCK_NUM +} XLogHeapVisibleBlockEnum; + +typedef enum { + HEAP_MULTI_INSERT_ORIG_BLOCK_NUM = 0 +} XLogHeapMultiInsertBlockEnum; + +typedef enum { + UHEAP_INSERT_ORIG_BLOCK_NUM = 0 +} XLogUHeapInsertBlockEnum; + +typedef enum { + UHEAP_DELETE_ORIG_BLOCK_NUM = 0 +} XLogUHeapDeleteBlockEnum; + +typedef enum { + UHEAP_UPDATE_NEW_BLOCK_NUM = 0, + UHEAP_UPDATE_OLD_BLOCK_NUM +} XLogUHeapUpdateBlockEnum; + +typedef enum { + UHEAP_MULTI_INSERT_ORIG_BLOCK_NUM = 0 +} XLogUHeapMultiInsertBlockEnum; + +typedef enum { + UHEAP_FREEZE_TD_ORIG_BLOCK_NUM = 0 +} XLogUHeapFreezeTDBlockEnum; + +typedef enum { + UHEAP_INVALID_TD_ORIG_BLOCK_NUM = 0 +} XLogUHeapInvalidTDBlockEnum; + +typedef enum { + UHEAP_CLEAN_ORIG_BLOCK_NUM = 0 +} XLogUHeapCleanBlockEnum; + +typedef enum { + UHEAP2_ORIG_BLOCK_NUM = 0 +} XLogUHeap2BlockEnum; + +typedef enum { + UHEAP_UNDO_ORIG_BLOCK_NUM = 0 +} XLogUHeapUndoBlockEnum; + +typedef enum { + UHEAP_UNDOACTION_ORIG_BLOCK_NUM = 0 +} XLogUheapUndoActionBlockEnum; + +extern THR_LOCAL RedoParseManager* g_parseManager; +extern THR_LOCAL RedoBufferManager* g_bufferManager; + +extern void* XLogMemCtlInit(RedoMemManager* memctl, Size itemsize, int itemnum); +extern RedoMemSlot* XLogMemAlloc(RedoMemManager* memctl); +extern void XLogMemRelease(RedoMemManager* memctl, Buffer bufferid); + +extern void XLogRedoBufferInit(RedoBufferManager* buffermanager, int buffernum, RefOperate *refOperate, + InterruptFunc interruptOperte); +extern void XLogRedoBufferDestory(RedoBufferManager* buffermanager); +extern RedoMemSlot* XLogRedoBufferAlloc( + RedoBufferManager* buffermanager, RelFileNode relnode, ForkNumber forkNum, BlockNumber blockNum); +extern bool XLogRedoBufferIsValid(RedoBufferManager* buffermanager, Buffer bufferid); +extern void XLogRedoBufferRelease(RedoBufferManager* buffermanager, Buffer bufferid); +extern BlockNumber XLogRedoBufferGetBlkNumber(RedoBufferManager* buffermanager, Buffer bufferid); +extern Block XLogRedoBufferGetBlk(RedoBufferManager* buffermanager, RedoMemSlot* bufferslot); +extern Block XLogRedoBufferGetPage(RedoBufferManager* buffermanager, Buffer bufferid); +extern void XLogRedoBufferSetState(RedoBufferManager* buffermanager, RedoMemSlot* bufferslot, uint32 state); + +#define XLogRedoBufferInitFunc(bufferManager, buffernum, defOperate, interruptOperte) do { \ + XLogRedoBufferInit(bufferManager, buffernum, defOperate, interruptOperte); \ +} while (0) +#define XLogRedoBufferDestoryFunc(bufferManager) do { \ + XLogRedoBufferDestory(bufferManager); \ +} while (0) +#define XLogRedoBufferAllocFunc(relnode, forkNum, blockNum, bufferslot) do { \ + *bufferslot = XLogRedoBufferAlloc(g_bufferManager, relnode, forkNum, blockNum); \ +} while (0) +#define XLogRedoBufferIsValidFunc(bufferid, isvalid) do { \ + *isvalid = XLogRedoBufferIsValid(g_bufferManager, bufferid); \ +} while (0) +#define XLogRedoBufferReleaseFunc(bufferid) do { \ + XLogRedoBufferRelease(g_bufferManager, bufferid); \ +} while (0) + +#define XLogRedoBufferGetBlkNumberFunc(bufferid, blknumber) do { \ + *blknumber = XLogRedoBufferGetBlkNumber(g_bufferManager, bufferid); \ +} while (0) + +#define XLogRedoBufferGetBlkFunc(bufferslot, blockdata) do { \ + *blockdata = XLogRedoBufferGetBlk(g_bufferManager, bufferslot); \ +} while (0) + +#define XLogRedoBufferGetPageFunc(bufferid, blockdata) do { \ + *blockdata = (Page)XLogRedoBufferGetPage(g_bufferManager, bufferid); \ +} while (0) +#define XLogRedoBufferSetStateFunc(bufferslot, state) do { \ + XLogRedoBufferSetState(g_bufferManager, bufferslot, state); \ +} while (0) + +extern void XLogParseBufferInit(RedoParseManager* parsemanager, int buffernum, RefOperate *refOperate, + InterruptFunc interruptOperte); +extern void XLogParseBufferDestory(RedoParseManager* parsemanager); +extern void XLogParseBufferRelease(XLogRecParseState* recordstate); +extern XLogRecParseState* XLogParseBufferAllocList(RedoParseManager* parsemanager, XLogRecParseState* blkstatehead, void *record); +extern XLogRedoAction XLogReadBufferForRedo(XLogReaderState* record, uint8 buffer_id, RedoBufferInfo* bufferinfo); +extern void XLogInitBufferForRedo(XLogReaderState* record, uint8 block_id, RedoBufferInfo* bufferinfo); +extern XLogRedoAction XLogReadBufferForRedoExtended(XLogReaderState* record, uint8 buffer_id, ReadBufferMode mode, + bool get_cleanup_lock, RedoBufferInfo* bufferinfo, ReadBufferMethod readmethod = WITH_NORMAL_CACHE); +#define XLogParseBufferInitFunc(parseManager, buffernum, defOperate, interruptOperte) do { \ + XLogParseBufferInit(parseManager, buffernum, defOperate, interruptOperte); \ +} while (0) + +#define XLogParseBufferDestoryFunc(parseManager) do { \ + XLogParseBufferDestory(parseManager); \ +} while (0) + +#define XLogParseBufferReleaseFunc(recordstate) do { \ + XLogParseBufferRelease(recordstate); \ +} while (0) + +#define XLogParseBufferAllocListFunc(record, newblkstate, blkstatehead) do { \ + *newblkstate = XLogParseBufferAllocList(g_parseManager, blkstatehead, record); \ +} while (0) + +#define XLogParseBufferAllocListStateFunc(record, newblkstate, blkstatehead) do { \ + if (*blkstatehead == NULL) { \ + *newblkstate = XLogParseBufferAllocList(g_parseManager, NULL, record); \ + *blkstatehead = *newblkstate; \ + } else { \ + *newblkstate = XLogParseBufferAllocList(g_parseManager, *blkstatehead, record); \ + } \ +} while (0) + + + + +#ifdef EXTREME_RTO_DEBUG_AB +typedef void (*AbnormalProcFunc)(void); +typedef enum { + A_THREAD_EXIT, + ALLOC_FAIL, + OPEN_FILE_FAIL, + WAIT_LONG, + ABNORMAL_NUM, +}AbnormalType; +extern AbnormalProcFunc g_AbFunList[ABNORMAL_NUM]; + + +#define ADD_ABNORMAL_POSITION(pos) do { \ + static int __count##pos = 0; \ + __count##pos++; \ + if (g_instance.attr.attr_storage.extreme_rto_ab_pos == pos) { \ + if (g_instance.attr.attr_storage.extreme_rto_ab_count == __count##pos) { \ + ereport(LOG, (errmsg("extreme rto debug abnormal stop pos:%d, type:%d, count:%d", pos, \ + g_instance.attr.attr_storage.extreme_rto_ab_type, __count##pos))); \ + g_AbFunList[g_instance.attr.attr_storage.extreme_rto_ab_type % ABNORMAL_NUM](); \ + } \ + } \ +} while(0) +#else +#define ADD_ABNORMAL_POSITION(pos) +#endif + + + +void HeapXlogCleanOperatorPage( + RedoBufferInfo* buffer, void* recorddata, void* blkdata, Size datalen, Size* freespace, bool repairFragmentation); +void HeapXlogFreezeOperatorPage(RedoBufferInfo* buffer, void* recorddata, void* blkdata, Size datalen, + bool isTupleLockUpgrade); +void HeapXlogInvalidOperatorPage(RedoBufferInfo* buffer, void* blkdata, Size datalen); +void HeapXlogVisibleOperatorPage(RedoBufferInfo* buffer, void* recorddata); +void HeapXlogVisibleOperatorVmpage(RedoBufferInfo* vmbuffer, void* recorddata); +void HeapXlogDeleteOperatorPage(RedoBufferInfo* buffer, void* recorddata, TransactionId recordxid, + bool isTupleLockUpgrade); +void HeapXlogInsertOperatorPage(RedoBufferInfo* buffer, void* recorddata, bool isinit, void* blkdata, Size datalen, + TransactionId recxid, Size* freespace, bool tde = false); +void HeapXlogMultiInsertOperatorPage(RedoBufferInfo* buffer, const void* recoreddata, bool isinit, const void* blkdata, + Size len, TransactionId recordxid, Size* freespace, bool tde = false); +void HeapXlogUpdateOperatorOldpage(RedoBufferInfo* buffer, void* recoreddata, bool hot_update, bool isnewinit, + BlockNumber newblk, TransactionId recordxid, bool isTupleLockUpgrade); +void HeapXlogUpdateOperatorNewpage(RedoBufferInfo* buffer, void* recorddata, bool isinit, void* blkdata, + Size datalen, TransactionId recordxid, Size* freespace, bool isTupleLockUpgrade, bool tde = false); +void HeapXlogLockOperatorPage(RedoBufferInfo* buffer, void* recorddata, bool isTupleLockUpgrade); +void HeapXlogInplaceOperatorPage(RedoBufferInfo* buffer, void* recorddata, void* blkdata, Size newlen); +void HeapXlogBaseShiftOperatorPage(RedoBufferInfo* buffer, void* recorddata); + +void BtreeRestorePage(Page page, char* from, int len); +void BtreeXlogMarkDeleteOperatorPage(RedoBufferInfo* buffer, void* recorddata); +void BtreeXlogPrunePageOperatorPage(RedoBufferInfo* buffer, void* recorddata); +void Btree2XlogShiftBaseOperatorPage(RedoBufferInfo* buffer, void* recorddata); + +void BtreeRestoreMetaOperatorPage(RedoBufferInfo* metabuf, void* recorddata, Size datalen); +void BtreeXlogInsertOperatorPage(RedoBufferInfo* buffer, void* recorddata, void* data, Size datalen); +void BtreeXlogSplitOperatorRightpage( + RedoBufferInfo* rbuf, void* recorddata, BlockNumber leftsib, BlockNumber rnext, void* blkdata, Size datalen); +void BtreeXlogSplitOperatorNextpage(RedoBufferInfo* buffer, BlockNumber rightsib); +void BtreeXlogSplitOperatorLeftpage( + RedoBufferInfo* lbuf, void* recorddata, BlockNumber rightsib, bool onleft, void* blkdata, Size datalen); +void BtreeXlogVacuumOperatorPage(RedoBufferInfo* redobuffer, void* recorddata, void* blkdata, Size len); +void BtreeXlogDeleteOperatorPage(RedoBufferInfo* buffer, void* recorddata, Size recorddatalen); +void btreeXlogDeletePageOperatorRightpage(RedoBufferInfo* buffer, void* recorddata); + +void BtreeXlogDeletePageOperatorLeftpage(RedoBufferInfo* buffer, void* recorddata); + +void BtreeXlogDeletePageOperatorCurrentpage(RedoBufferInfo* buffer, void* recorddata); + +void BtreeXlogNewrootOperatorPage(RedoBufferInfo* buffer, void* record, void* blkdata, Size len, BlockNumber* downlink); +void BtreeXlogHalfdeadPageOperatorParentpage( + RedoBufferInfo* pbuf, void* recorddata); +void BtreeXlogHalfdeadPageOperatorLeafpage( + RedoBufferInfo* lbuf, void* recorddata); +void BtreeXlogUnlinkPageOperatorRightpage(RedoBufferInfo* rbuf, void* recorddata); +void BtreeXlogUnlinkPageOperatorLeftpage(RedoBufferInfo* lbuf, void* recorddata); +void BtreeXlogUnlinkPageOperatorCurpage(RedoBufferInfo* buf, void* recorddata); +void BtreeXlogUnlinkPageOperatorChildpage(RedoBufferInfo* cbuf, void* recorddata); + +void BtreeXlogClearIncompleteSplit(RedoBufferInfo* buffer); + +/* UBTree */ +extern void UBTreeRestorePage(Page page, char* from, int len); +extern void UBTreeXlogMarkDeleteOperatorPage(RedoBufferInfo* buffer, void* recorddata); +extern void UBTreeXlogPrunePageOperatorPage(RedoBufferInfo* buffer, void* recorddata); +extern void UBTree2XlogShiftBaseOperatorPage(RedoBufferInfo* buffer, void* recorddata); +extern void UBTree2XlogRecycleQueueInitPageOperatorCurrPage(RedoBufferInfo* buffer, void* recorddata); +extern void UBTree2XlogRecycleQueueInitPageOperatorAdjacentPage(RedoBufferInfo* buffer, void* recorddata, bool isLeft); +extern void UBTree2XlogRecycleQueueEndpointOperatorLeftPage(RedoBufferInfo* buffer, void* recorddata); +extern void UBTree2XlogRecycleQueueEndpointOperatorRightPage(RedoBufferInfo* buffer, void* recorddata); +extern void UBTree2XlogRecycleQueueModifyOperatorPage(RedoBufferInfo* buffer, void* recorddata); +extern void UBTree2XlogFreezeOperatorPage(RedoBufferInfo* buffer, void* recorddata); + +extern void UBTreeRestoreMetaOperatorPage(RedoBufferInfo* metabuf, void* recorddata, Size datalen); +extern void UBTreeXlogInsertOperatorPage(RedoBufferInfo* buffer, void* recorddata, void* data, Size datalen); +extern void UBTreeXlogSplitOperatorRightPage(RedoBufferInfo* rbuf, void* recorddata, BlockNumber leftsib, + BlockNumber rnext, void* blkdata, Size datalen, bool hasOpaque = true); +extern void UBTreeXlogSplitOperatorNextpage(RedoBufferInfo* buffer, BlockNumber rightsib); +extern void UBTreeXlogSplitOperatorLeftpage(RedoBufferInfo* lbuf, void* recorddata, BlockNumber rightsib, + bool onleft, void* blkdata, Size datalen, bool hasOpaque = true); +extern void UBTreeXlogVacuumOperatorPage(RedoBufferInfo* redobuffer, void* recorddata, void* blkdata, Size len); +extern void UBTreeXlogDeleteOperatorPage(RedoBufferInfo* buffer, void* recorddata, Size recorddatalen); +extern void UBTreeXlogDeletePageOperatorRightpage(RedoBufferInfo* buffer, void* recorddata); + +extern void UBTreeXlogDeletePageOperatorLeftpage(RedoBufferInfo* buffer, void* recorddata); + +extern void UBTreeXlogDeletePageOperatorCurrentpage(RedoBufferInfo* buffer, void* recorddata); + +extern void UBTreeXlogNewrootOperatorPage(RedoBufferInfo *buffer, void *record, void *blkdata, Size len, + BlockNumber *downlink); +extern void UBTreeXlogHalfdeadPageOperatorParentpage( + RedoBufferInfo* pbuf, void* recorddata); +extern void UBTreeXlogHalfdeadPageOperatorLeafpage( + RedoBufferInfo* lbuf, void* recorddata); +extern void UBTreeXlogUnlinkPageOperatorRightpage(RedoBufferInfo* rbuf, void* recorddata); +extern void UBTreeXlogUnlinkPageOperatorLeftpage(RedoBufferInfo* lbuf, void* recorddata); +extern void UBTreeXlogUnlinkPageOperatorCurpage(RedoBufferInfo* buf, void* recorddata); +extern void UBTreeXlogUnlinkPageOperatorChildpage(RedoBufferInfo* cbuf, void* recorddata); + +extern void UBTreeXlogClearIncompleteSplit(RedoBufferInfo* buffer); + +void HashRedoInitMetaPageOperatorPage(RedoBufferInfo *metabuf, void *recorddata); + +void HashRedoInitBitmapPageOperatorBitmapPage(RedoBufferInfo *bitmapbuf, void *recorddata); +void HashRedoInitBitmapPageOperatorMetaPage(RedoBufferInfo *metabuf); + +void HashRedoInsertOperatorPage(RedoBufferInfo *buffer, void *recorddata, void *data, Size datalen); +void HashRedoInsertOperatorMetaPage(RedoBufferInfo *metabuf); + +void HashRedoAddOvflPageOperatorOvflPage(RedoBufferInfo *ovflbuf, BlockNumber leftblk, void *data, Size datalen); +void HashRedoAddOvflPageOperatorLeftPage(RedoBufferInfo *ovflbuf, BlockNumber rightblk); +void HashRedoAddOvflPageOperatorMapPage(RedoBufferInfo *mapbuf, void *data); +void HashRedoAddOvflPageOperatorNewmapPage(RedoBufferInfo *newmapbuf, void *recorddata); +void HashRedoAddOvflPageOperatorMetaPage(RedoBufferInfo *metabuf, void *recorddata, void *data, Size datalen); + +void HashRedoSplitAllocatePageOperatorObukPage(RedoBufferInfo *oldbukbuf, void *recorddata); +void HashRedoSplitAllocatePageOperatorNbukPage(RedoBufferInfo *newbukbuf, void *recorddata); +void HashRedoSplitAllocatePageOperatorMetaPage(RedoBufferInfo *metabuf, void *recorddata, void *blkdata); + +void HashRedoSplitCompleteOperatorObukPage(RedoBufferInfo *oldbukbuf, void *recorddata); +void HashRedoSplitCompleteOperatorNbukPage(RedoBufferInfo *newbukbuf, void *recorddata); + +void HashXlogMoveAddPageOperatorPage(RedoBufferInfo *redobuffer, void *recorddata, void *blkdata, Size len); +void HashXlogMoveDeleteOvflPageOperatorPage(RedoBufferInfo *redobuffer, void *blkdata, Size len); + +void HashXlogSqueezeAddPageOperatorPage(RedoBufferInfo *redobuffer, void *recorddata, void *blkdata, Size len); +void HashXlogSqueezeInitOvflbufOperatorPage(RedoBufferInfo *redobuffer, void *recorddata); +void HashXlogSqueezeUpdatePrevPageOperatorPage(RedoBufferInfo *redobuffer, void *recorddata); +void HashXlogSqueezeUpdateNextPageOperatorPage(RedoBufferInfo *redobuffer, void *recorddata); +void HashXlogSqueezeUpdateBitmapOperatorPage(RedoBufferInfo *redobuffer, void *blkdata); +void HashXlogSqueezeUpdateMateOperatorPage(RedoBufferInfo *redobuffer, void *blkdata); + +void HashXlogDeleteBlockOperatorPage(RedoBufferInfo *redobuffer, void *recorddata, void *blkdata, Size len); + +void HashXlogSplitCleanupOperatorPage(RedoBufferInfo *redobuffer); + +void HashXlogUpdateMetaOperatorPage(RedoBufferInfo *redobuffer, void *recorddata); + +void HashXlogVacuumOnePageOperatorPage(RedoBufferInfo *redobuffer, void *recorddata, Size len); + +void HashXlogVacuumMateOperatorPage(RedoBufferInfo *redobuffer, void *recorddata); + +void XLogRecSetBlockCommonState(XLogReaderState* record, XLogBlockParseEnum blockvalid, + RelFileNodeForkNum filenode, XLogRecParseState* recordblockstate, XLogPhyBlock *pblk = NULL); + +void XLogRecSetBlockCLogState( + XLogBlockCLogParse* blockclogstate, TransactionId topxid, uint16 status, uint16 xidnum, uint16* xidsarry); + +void XLogRecSetBlockCSNLogState( + XLogBlockCSNLogParse* blockcsnlogstate, TransactionId topxid, CommitSeqNo csnseq, uint16 xidnum, uint16* xidsarry); +void XLogRecSetXactRecoveryState(XLogBlockXactParse* blockxactstate, TransactionId maxxid, CommitSeqNo maxcsnseq, + uint8 delayddlflag, uint8 updateminrecovery); +void XLogRecSetXactDdlState(XLogBlockXactParse* blockxactstate, int nrels, void* xnodes, int invalidmsgnum, + void* invalidmsg, int nlibs, void* libfilename); +void XLogRecSetXactCommonState( + XLogBlockXactParse* blockxactstate, uint16 committype, uint64 xinfo, TimestampTz xact_time); +void XLogRecSetBcmState(XLogBlockBcmParse* blockbcmrec, uint64 startblock, int count, int status); +void XLogRecSetNewCuState(XLogBlockNewCuParse* blockcudata, char* main_data, uint32 main_data_len); +void XLogRecSetInvalidMsgState(XLogBlockInvalidParse* blockinvalid, TransactionId cutoffxid); +void XLogRecSetIncompleteMsgState(XLogBlockIncompleteParse* blockincomplete, uint16 action, bool issplit, bool isroot, + BlockNumber downblk, BlockNumber leftblk, BlockNumber rightblk); +void XLogRecSetPinVacuumState(XLogBlockVacuumPinParse* blockvacuum, BlockNumber lastblknum); +void XLogRecSetSegFullSyncState(XLogBlockSegFullSyncParse *state, void *childState); +void XLogRecSetSegNewPageInfo(XLogBlockSegNewPage *state, char *mainData, Size len); +void XLogRecSetAuxiBlkNumState(XLogBlockDataParse* blockdatarec, BlockNumber auxilaryblkn1, BlockNumber auxilaryblkn2); +void XLogRecSetBlockDataStateContent(XLogReaderState *record, uint32 blockid, XLogBlockDataParse *blockdatarec); +void XLogRecSetBlockDataState(XLogReaderState* record, uint32 blockid, XLogRecParseState* recordblockstate, + XLogBlockParseEnum type = BLOCK_DATA_MAIN_DATA_TYPE); +extern char* XLogBlockDataGetBlockData(XLogBlockDataParse* datadecode, Size* len); +void Heap2RedoDataBlock(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); +extern void HeapRedoDataBlock( + XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); +void SegPageRedoDataBlock(XLogBlockHead *blockhead, XLogBlockDataParse *blockdatarec, RedoBufferInfo *bufferinfo); +extern void xlog_redo_data_block( + XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); +extern void XLogRecSetBlockDdlState(XLogBlockDdlParse* blockddlstate, uint32 blockddltype, char *mainData, + int rels = 1); +XLogRedoAction XLogCheckBlockDataRedoAction(XLogBlockDataParse* datadecode, RedoBufferInfo* bufferinfo); + +void BtreeRedoDataBlock(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); +void Btree2RedoDataBlock(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); + +/* UBTree */ +extern void UBTreeRedoDataBlock(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); +extern void UBTree2RedoDataBlock(XLogBlockHead *blockhead, XLogBlockDataParse *blockdatarec, + RedoBufferInfo *bufferinfo); + +extern void HashRedoDataBlock(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); +XLogRecParseState* XactXlogCsnlogParseToBlock(XLogReaderState* record, uint32* blocknum, TransactionId xid, + int nsubxids, TransactionId* subxids, CommitSeqNo csn, XLogRecParseState* recordstatehead); +extern void XLogRecSetVmBlockState(XLogReaderState* record, uint32 blockid, XLogRecParseState* recordblockstate); +extern void XLogRecSetUHeapUndoBlockState(XLogReaderState* record, uint32 blockid, XLogRecParseState* recordundostate); +extern void XLogRecSetUndoBlockState(XLogReaderState* record, uint32 blockid, XLogRecParseState* recordundostate); +extern void XLogRecSetRollbackFinishBlockState(XLogReaderState *record, uint32 blockid, + XLogRecParseState *recordundostate); +extern bool DoLsnCheck(const RedoBufferInfo* bufferinfo, bool willInit, XLogRecPtr lastLsn, + const XLogPhyBlock *pblk, bool *needRepair); +char* XLogBlockDataGetMainData(XLogBlockDataParse* datadecode, Size* len); +void HeapRedoVmBlock(XLogBlockHead* blockhead, XLogBlockVmParse* blockvmrec, RedoBufferInfo* bufferinfo); +void Heap2RedoVmBlock(XLogBlockHead* blockhead, XLogBlockVmParse* blockvmrec, RedoBufferInfo* bufferinfo); +XLogRecParseState* xlog_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); +XLogRecParseState* smgr_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); +XLogRecParseState* segpage_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); +void ProcSegPageCommonRedo(XLogRecParseState *parseState); +void ProcSegPageJustFreeChildState(XLogRecParseState *parseState); +XLogRecParseState* XactXlogClogParseToBlock(XLogReaderState* record, XLogRecParseState* recordstatehead, + uint32* blocknum, TransactionId xid, int nsubxids, TransactionId* subxids, CLogXidStatus status); +XLogRecParseState* xact_xlog_commit_parse_to_block(XLogReaderState* record, XLogRecParseState* recordstatehead, + uint32* blocknum, TransactionId maxxid, CommitSeqNo maxseqnum); +void visibilitymap_clear_buffer(RedoBufferInfo* bufferinfo, BlockNumber heapBlk); +XLogRecParseState* xact_xlog_abort_parse_to_block(XLogReaderState* record, XLogRecParseState* recordstatehead, + uint32* blocknum, TransactionId maxxid, CommitSeqNo maxseqnum); +XLogRecParseState* xact_xlog_prepare_parse_to_block( + XLogReaderState* record, XLogRecParseState* recordstatehead, uint32* blocknum, TransactionId maxxid); +XLogRecParseState* xact_xlog_parse_to_block(XLogReaderState* record, uint32* blocknum); +XLogRecParseState* ClogRedoParseToBlock(XLogReaderState* record, uint32* blocknum); + +XLogRecParseState* DbaseRedoParseToBlock(XLogReaderState* record, uint32* blocknum); + +XLogRecParseState* Heap2RedoParseIoBlock(XLogReaderState* record, uint32* blocknum); +extern XLogRecParseState* HeapRedoParseToBlock(XLogReaderState* record, uint32* blocknum); +extern XLogRecParseState* BtreeRedoParseToBlock(XLogReaderState* record, uint32* blocknum); +/* UBTree */ +extern XLogRecParseState* UBTreeRedoParseToBlock(XLogReaderState* record, uint32* blocknum); +extern XLogRecParseState* UBTree2RedoParseToBlock(XLogReaderState* record, uint32* blocknum); + +extern XLogRecParseState* Heap3RedoParseToBlock(XLogReaderState* record, uint32* blocknum); + +extern Size SalEncodeXLogBlock(void* recordblockstate, byte* buffer, void* sliceinfo); + +extern XLogRecParseState* XLogParseToBlockForDfv(XLogReaderState* record, uint32* blocknum); +extern Size getBlockSize(XLogRecParseState* recordblockstate); +extern XLogRecParseState* GistRedoParseToBlock(XLogReaderState* record, uint32* blocknum); +extern XLogRecParseState* GinRedoParseToBlock(XLogReaderState* record, uint32* blocknum); + +extern void GistRedoClearFollowRightOperatorPage(RedoBufferInfo* buffer); +extern void GistRedoPageUpdateOperatorPage(RedoBufferInfo* buffer, void* recorddata, void* blkdata, Size datalen); +extern void GistRedoPageSplitOperatorPage( + RedoBufferInfo* buffer, void* recorddata, void* data, Size datalen, bool Markflag, BlockNumber rightlink); +extern void GistRedoCreateIndexOperatorPage(RedoBufferInfo* buffer); + +extern void GinRedoCreateIndexOperatorMetaPage(RedoBufferInfo* MetaBuffer); +extern void GinRedoCreateIndexOperatorRootPage(RedoBufferInfo* RootBuffer); +extern void GinRedoCreatePTreeOperatorPage(RedoBufferInfo* buffer, void* recordData); +extern void GinRedoClearIncompleteSplitOperatorPage(RedoBufferInfo* buffer); +extern void GinRedoVacuumDataOperatorLeafPage(RedoBufferInfo* buffer, void* recorddata); +extern void GinRedoDeletePageOperatorCurPage(RedoBufferInfo* dbuffer); +extern void GinRedoDeletePageOperatorParentPage(RedoBufferInfo* pbuffer, void* recorddata); +extern void GinRedoDeletePageOperatorLeftPage(RedoBufferInfo* lbuffer, void* recorddata); +extern void GinRedoUpdateOperatorMetapage(RedoBufferInfo* metabuffer, void* recorddata); +extern void GinRedoUpdateOperatorTailPage(RedoBufferInfo* buffer, void* payload, Size totaltupsize, int32 ntuples); +extern void GinRedoInsertListPageOperatorPage( + RedoBufferInfo* buffer, void* recorddata, void* payload, Size totaltupsize); +extern void GinRedoUpdateAddNewTail(RedoBufferInfo* buffer, BlockNumber newRightlink); +extern void GinRedoInsertData(RedoBufferInfo* buffer, bool isLeaf, BlockNumber rightblkno, void* rdata); +extern void GinRedoInsertEntry(RedoBufferInfo* buffer, bool isLeaf, BlockNumber rightblkno, void* rdata); + +extern void GinRedoDeleteListPagesOperatorPage(RedoBufferInfo* metabuffer, const void* recorddata); +extern void GinRedoDeleteListPagesMarkDelete(RedoBufferInfo* buffer); + +extern void spgRedoCreateIndexOperatorMetaPage(RedoBufferInfo* buffer); +extern void spgRedoCreateIndexOperatorRootPage(RedoBufferInfo* buffer); +extern void spgRedoCreateIndexOperatorLeafPage(RedoBufferInfo* buffer); +extern void spgRedoAddLeafOperatorPage(RedoBufferInfo* bufferinfo, void* recorddata); +extern void spgRedoAddLeafOperatorParent(RedoBufferInfo* bufferinfo, void* recorddata, BlockNumber blknoLeaf); +extern void spgRedoMoveLeafsOpratorDstPage(RedoBufferInfo* buffer, void* recorddata, void* insertdata, void* tupledata); +extern void spgRedoMoveLeafsOpratorSrcPage( + RedoBufferInfo* buffer, void* recorddata, void* insertdata, void* deletedata, BlockNumber blknoDst, int nInsert); +extern void spgRedoMoveLeafsOpratorParentPage( + RedoBufferInfo* buffer, void* recorddata, void* insertdata, BlockNumber blknoDst, int nInsert); +extern void spgRedoAddNodeUpdateSrcPage(RedoBufferInfo* buffer, void* recorddata, void* tuple, void* tupleheader); +extern void spgRedoAddNodeOperatorSrcPage(RedoBufferInfo* buffer, void* recorddata, BlockNumber blknoNew); +extern void spgRedoAddNodeOperatorDestPage( + RedoBufferInfo* buffer, void* recorddata, void* tuple, void* tupleheader, BlockNumber blknoNew); +extern void spgRedoAddNodeOperatorParentPage(RedoBufferInfo* buffer, void* recorddata, BlockNumber blknoNew); +extern void spgRedoSplitTupleOperatorDestPage(RedoBufferInfo* buffer, void* recorddata, void* tuple); +extern void spgRedoSplitTupleOperatorSrcPage(RedoBufferInfo* buffer, void* recorddata, void* pretuple, void* posttuple); +extern void spgRedoPickSplitRestoreLeafTuples( + RedoBufferInfo* buffer, void* recorddata, bool destflag, void* pageselect, void* insertdata); +extern void spgRedoPickSplitOperatorSrcPage(RedoBufferInfo* srcBuffer, void* recorddata, void* deleteoffset, + BlockNumber blknoInner, void* pageselect, void* insertdata); +extern void spgRedoPickSplitOperatorDestPage( + RedoBufferInfo* destBuffer, void* recorddata, void* pageselect, void* insertdata); +extern void spgRedoPickSplitOperatorInnerPage( + RedoBufferInfo* innerBuffer, void* recorddata, void* tuple, void* tupleheader, BlockNumber blknoInner); +extern void spgRedoPickSplitOperatorParentPage(RedoBufferInfo* parentBuffer, void* recorddata, BlockNumber blknoInner); +extern void spgRedoVacuumLeafOperatorPage(RedoBufferInfo* buffer, void* recorddata); +extern void spgRedoVacuumRootOperatorPage(RedoBufferInfo* buffer, void* recorddata); +extern void spgRedoVacuumRedirectOperatorPage(RedoBufferInfo* buffer, void* recorddata); + +extern XLogRecParseState* SpgRedoParseToBlock(XLogReaderState* record, uint32* blocknum); + +extern void seqRedoOperatorPage(RedoBufferInfo* buffer, void* itmedata, Size itemsz); +extern void seq_redo_data_block(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); + +extern void Heap3RedoDataBlock( + XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); + +extern XLogRecParseState* xact_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); + +extern bool XLogBlockRedoForExtremeRTO(XLogRecParseState* redoblocktate, RedoBufferInfo *bufferinfo, + bool notfound, RedoTimeCost &readBufCost, RedoTimeCost &redoCost); +void XLogBlockParseStateRelease_debug(XLogRecParseState* recordstate, const char *func, uint32 line); +#define XLogBlockParseStateRelease(recordstate) XLogBlockParseStateRelease_debug(recordstate, __FUNCTION__, __LINE__) +#ifdef USE_ASSERT_CHECKING +extern void DoRecordCheck(XLogRecParseState *recordstate, XLogRecPtr pageLsn, bool replayed); +#endif +extern XLogRecParseState* XLogParseBufferCopy(XLogRecParseState *srcState); +extern XLogRecParseState* XLogParseToBlockForExtermeRTO(XLogReaderState* record, uint32* blocknum); +extern XLogRedoAction XLogReadBufferForRedoBlockExtend(RedoBufferTag *redoblock, ReadBufferMode mode, + bool get_cleanup_lock, RedoBufferInfo *redobufferinfo, + XLogRecPtr xloglsn, XLogRecPtr last_lsn, bool willinit, + ReadBufferMethod readmethod, bool tde = false); +extern XLogRecParseState* tblspc_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); +extern XLogRecParseState* relmap_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); +extern XLogRecParseState* HashRedoParseToBlock(XLogReaderState* record, uint32* blocknum); +extern XLogRecParseState* seq_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); +extern XLogRecParseState* slot_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); +extern XLogRecParseState* barrier_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); +extern XLogRecParseState* multixact_redo_parse_to_block(XLogReaderState* record, uint32* blocknum); +extern void ExtremeRtoFlushBuffer(RedoBufferInfo *bufferinfo, bool updateFsm); +extern void XLogForgetDDLRedo(XLogRecParseState* redoblockstate); +void XLogDropSpaceShrink(XLogRecParseState *redoblockstate); +extern void SyncOneBufferForExtremRto(RedoBufferInfo *bufferinfo); +extern void XLogBlockInitRedoBlockInfo(XLogBlockHead* blockhead, RedoBufferTag* blockinfo); +extern void XLogBlockDdlDoSmgrAction(XLogBlockHead* blockhead, void* blockrecbody, RedoBufferInfo* bufferinfo); +extern void XLogBlockSegDdlDoRealAction(XLogBlockHead* blockhead, void* blockrecbody, RedoBufferInfo* bufferinfo); +extern void GinRedoDataBlock(XLogBlockHead* blockhead, XLogBlockDataParse* blockdatarec, RedoBufferInfo* bufferinfo); +extern void GistRedoDataBlock(XLogBlockHead *blockhead, XLogBlockDataParse *blockdatarec, RedoBufferInfo *bufferinfo); +extern bool IsCheckPoint(const XLogRecParseState *parseState); + +void redo_atomic_xlog_dispatch(uint8 opCode, RedoBufferInfo *redo_buf, const char *data); +void seg_redo_new_page_copy_and_flush(BufferTag *tag, char *data, XLogRecPtr lsn); + +#endif diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index f0890a0ac..02e605df4 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -80,6 +80,7 @@ extern const uint32 TWOPHASE_FILE_VERSION; extern const uint32 CLIENT_ENCRYPTION_PROC_VERSION_NUM; extern const uint32 PRIVS_DIRECTORY_VERSION_NUM; extern const uint32 COMMENT_RECORD_PARAM_VERSION_NUM; +extern const uint32 INVALID_INVISIBLE_TUPLE_VERSION; extern const uint32 ENHANCED_TUPLE_LOCK_VERSION_NUM; extern const uint32 HASUID_VERSION_NUM; extern const uint32 CREATE_INDEX_CONCURRENTLY_DIST_VERSION_NUM;