diff --git a/src/gausskernel/process/postmaster/postmaster.cpp b/src/gausskernel/process/postmaster/postmaster.cpp index 54dee947059731e15269e0a244815a043c8e41eb..c44f8fd552e283690d9c06403a0ac88aee0e111b 100644 --- a/src/gausskernel/process/postmaster/postmaster.cpp +++ b/src/gausskernel/process/postmaster/postmaster.cpp @@ -3028,10 +3028,9 @@ int PostmasterMain(int argc, char* argv[]) ereport(LOG, (errmsg("[SS reform] Success: node:%d wait for PRIMARY:%d to finish 1st reform", g_instance.attr.attr_storage.dms_attr.instance_id, src_id))); - while (SS_OFFICIAL_RECOVERY_NODE && SS_CLUSTER_NOT_NORAML) { - pg_usleep(SLEEP_ONE_SEC); - SSReadControlFile(REFORM_CTRL_PAGE); - ereport(WARNING, (errmsg("[on-demand] node%d is last primary node, waiting for on-demand recovery done", + if (SS_OFFICIAL_RECOVERY_NODE && SS_CLUSTER_ONDEMAND_NOT_NORAML) { + ereport(FATAL, (errmsg( + "[on-demand] node%d is last primary node, do not allow join cluster until on-demand recovery done", g_instance.attr.attr_storage.dms_attr.instance_id))); } } diff --git a/src/gausskernel/storage/access/transam/extreme_rto_redo_api.cpp b/src/gausskernel/storage/access/transam/extreme_rto_redo_api.cpp index 65e449757d1a19ea994fc8cec0ac3e26bdb681fc..bc5ca2582ac3d36cabc7472e3f31bfbf25f73589 100644 --- a/src/gausskernel/storage/access/transam/extreme_rto_redo_api.cpp +++ b/src/gausskernel/storage/access/transam/extreme_rto_redo_api.cpp @@ -114,14 +114,14 @@ static const f_extreme_rto_redo extreme_rto_redosw[] = { ondemand_extreme_rto::WaitAllReplayWorkerIdle, ondemand_extreme_rto::DispatchCleanInvalidPageMarkToAllRedoWorker, ondemand_extreme_rto::DispatchClosefdMarkToAllRedoWorker, - NULL, + ondemand_extreme_rto::RecordBadBlockAndPushToRemote, ondemand_extreme_rto::CheckCommittingCsnList, ondemand_extreme_rto::ReadNextXLogRecord, ondemand_extreme_rto::ExtremeRtoStopHere, ondemand_extreme_rto::WaitAllRedoWorkerQueueEmpty, ondemand_extreme_rto::GetSafeMinCheckPoint, - NULL, - NULL, + ondemand_extreme_rto::ClearRecoveryThreadHashTbl, + ondemand_extreme_rto::BatchClearRecoveryThreadHashTbl, ondemand_extreme_rto::RedoWorkerIsUndoSpaceWorker, ondemand_extreme_rto::StartRecoveryWorkers, ondemand_extreme_rto::DispatchRedoRecordToFile, diff --git a/src/gausskernel/storage/access/transam/ondemand_extreme_rto/dispatcher.cpp b/src/gausskernel/storage/access/transam/ondemand_extreme_rto/dispatcher.cpp index 73e31ac0722b5c1b9e84173dd890418607f8731c..c5bcc4e0adfa179e83f1ae8f1c4206052354ec61 100644 --- a/src/gausskernel/storage/access/transam/ondemand_extreme_rto/dispatcher.cpp +++ b/src/gausskernel/storage/access/transam/ondemand_extreme_rto/dispatcher.cpp @@ -439,7 +439,6 @@ void StartRecoveryWorkers(XLogReaderState *xlogreader, uint32 privateLen) ALLOCSET_DEFAULT_MAXSIZE, SHARED_CONTEXT); g_instance.comm_cxt.predo_cxt.redoItemHash = PRRedoItemHashInitialize(g_instance.comm_cxt.redoItemCtx); - g_dispatcher->maxItemNum = ((get_batch_redo_num() + 4) * PAGE_WORK_QUEUE_SIZE) * ITEM_QUQUE_SIZE_RATIO; uint32 maxParseBufNum = (uint32)((uint64)g_instance.attr.attr_storage.dms_attr.ondemand_recovery_mem_size * 1024 / (sizeof(XLogRecParseState) + sizeof(ParseBufferDesc) + sizeof(RedoMemSlot))); g_dispatcher->maxItemNum = 4 * PAGE_WORK_QUEUE_SIZE * ITEM_QUQUE_SIZE_RATIO + maxParseBufNum; diff --git a/src/gausskernel/storage/access/transam/ondemand_extreme_rto/page_redo.cpp b/src/gausskernel/storage/access/transam/ondemand_extreme_rto/page_redo.cpp index 4ec868350f37e198eb89549109743d2663c41c99..4b5a6415aaa28797bdfba81556616ae5461b2bf9 100644 --- a/src/gausskernel/storage/access/transam/ondemand_extreme_rto/page_redo.cpp +++ b/src/gausskernel/storage/access/transam/ondemand_extreme_rto/page_redo.cpp @@ -634,6 +634,7 @@ void RedoPageManagerDistributeToAllOneBlock(XLogRecParseState *ddlParseState) for (uint32 i = 0; i < WorkerNumPerMng; ++i) { XLogRecParseState *newState = XLogParseBufferCopy(ddlParseState); + newState->distributeStatus = XLOG_HEAD_DISTRIBUTE; AddPageRedoItem(myRedoLine->redoThd[i], newState); } } @@ -940,6 +941,7 @@ void PageManagerDistributeBcmBlock(XLogRecParseState *preState) PageRedoPipeline *myRedoLine = &g_dispatcher->pageLines[g_redoWorker->slotId]; const uint32 WorkerNumPerMng = myRedoLine->redoThdNum; uint32 workId = GetWorkerId((uint32)preState->blockparse.blockhead.forknum, WorkerNumPerMng); + preState->distributeStatus = XLOG_HEAD_DISTRIBUTE; AddPageRedoItem(myRedoLine->redoThd[workId], preState); } @@ -2931,4 +2933,34 @@ bool XactHasSegpageRelFiles(XLogReaderState *record) return false; } +/* RecordBadBlockAndPushToRemote + * If the bad page has been stored, record the xlog. If the bad page + * has not been stored, need push to page repair thread hash table and record to + * recovery thread hash table. + */ +void RecordBadBlockAndPushToRemote(XLogBlockDataParse *datadecode, PageErrorType error_type, + XLogRecPtr old_lsn, XLogPhyBlock pblk) +{ + return; +} + +/* ClearPageRepairHashTbl + * drop table, or truncate table, need clear the page repair hashTbl, if the + * repair page Filenode match need remove. + */ +void ClearRecoveryThreadHashTbl(const RelFileNode &node, ForkNumber forknum, BlockNumber minblkno, + bool segment_shrink) +{ + return; +} + +/* BatchClearPageRepairHashTbl + * drop database, or drop segmentspace, need clear the page repair hashTbl, + * if the repair page key dbNode match and spcNode match, need remove. + */ +void BatchClearRecoveryThreadHashTbl(Oid spcNode, Oid dbNode) +{ + return; +} + } // namespace ondemand_extreme_rto \ No newline at end of file diff --git a/src/gausskernel/storage/access/transam/xlog.cpp b/src/gausskernel/storage/access/transam/xlog.cpp index 3d6dc1d2421f44a08a5073f82d9ae972a736b867..6302fcafd1e3273c23f7b3a465091ac11994f0da 100755 --- a/src/gausskernel/storage/access/transam/xlog.cpp +++ b/src/gausskernel/storage/access/transam/xlog.cpp @@ -8734,6 +8734,7 @@ void StartupXLOG(void) bool RecoveryByPending = false; /* recovery caused by pending mode */ bool ArchiveRecoveryByPending = false; /* archive recovery caused by pending mode */ bool AbnormalShutdown = true; + bool SSOndemandRecoveryExitNormal = true; /* status of last ondemand recovery */ struct stat st; errno_t rcm = 0; TransactionId latestCompletedXid; @@ -8805,15 +8806,15 @@ void StartupXLOG(void) if (ENABLE_DMS && ENABLE_DSS) { int src_id = INVALID_INSTANCEID; SSReadControlFile(REFORM_CTRL_PAGE); - if ((SS_CLUSTER_ONDEMAND_BUILD || SS_CLUSTER_ONDEMAND_RECOVERY) && SS_PRIMARY_MODE) { + if (SS_CLUSTER_ONDEMAND_NOT_NORAML && SS_PRIMARY_MODE) { if (SS_STANDBY_PROMOTING) { ereport(FATAL, (errmsg("Do not allow switchover if on-demand recovery is not finish"))); } - Assert(g_instance.dms_cxt.SSReformerControl.recoveryInstId != INVALID_INSTANCEID); src_id = g_instance.dms_cxt.SSReformerControl.recoveryInstId; ereport(LOG, (errmsg("[on-demand]: On-demand recovery do not finish in last reform, " "reading control file of original primary:%d", src_id))); + SSOndemandRecoveryExitNormal = false; } else { if (SS_STANDBY_FAILOVER || SS_STANDBY_PROMOTING) { src_id = SSGetPrimaryInstId(); @@ -9479,19 +9480,20 @@ void StartupXLOG(void) t_thrd.xlog_cxt.InRecovery = false; } - if (SS_PRIMARY_MODE) { - if (ENABLE_ONDEMAND_RECOVERY && (SS_STANDBY_FAILOVER || SS_PRIMARY_NORMAL_REFORM) && - t_thrd.xlog_cxt.InRecovery == true) { + if (SS_PRIMARY_MODE && ENABLE_ONDEMAND_RECOVERY && (SS_STANDBY_FAILOVER || SS_PRIMARY_NORMAL_REFORM) && + t_thrd.xlog_cxt.InRecovery == true) { + if (SSOndemandRecoveryExitNormal) { g_instance.dms_cxt.SSRecoveryInfo.in_ondemand_recovery = true; /* for other nodes in cluster and ondeamnd recovery failed */ g_instance.dms_cxt.SSReformerControl.clusterStatus = CLUSTER_IN_ONDEMAND_BUILD; g_instance.dms_cxt.SSReformerControl.recoveryInstId = g_instance.dms_cxt.SSRecoveryInfo.recovery_inst_id; + SSSaveReformerCtrl(); SetOndemandExtremeRtoMode(); ereport(LOG, (errmsg("[On-demand] replayed in extreme rto ondemand recovery mode"))); } else { - g_instance.dms_cxt.SSReformerControl.clusterStatus = CLUSTER_NORMAL; + ereport(LOG, (errmsg("[On-demand] do not allow replay in ondemand recovery if last ondemand recovery " + "crash, replayed in extreme rto recovery mode"))); } - SSSaveReformerCtrl(); } ReadRemainSegsFile(); @@ -10543,10 +10545,13 @@ void StartupXLOG(void) state->start = state->end; (void)LWLockRelease(state->recovery_queue_lock); } + g_instance.dms_cxt.SSRecoveryInfo.in_ondemand_recovery = false; + } + + if (SS_PRIMARY_MODE) { /* for other nodes in cluster */ g_instance.dms_cxt.SSReformerControl.clusterStatus = CLUSTER_NORMAL; SSSaveReformerCtrl(); - g_instance.dms_cxt.SSRecoveryInfo.in_ondemand_recovery = false; } ereport(LOG, (errmsg("redo done, nextXid: " XID_FMT ", startupMaxXid: " XID_FMT ", recentLocalXmin: " XID_FMT diff --git a/src/include/access/ondemand_extreme_rto/page_redo.h b/src/include/access/ondemand_extreme_rto/page_redo.h index 9d55e598c2cf3679e4797b16d909aa5d5a3bd842..005d76a9daa632e2e6cbaddf3c35d6b8818bb33a 100644 --- a/src/include/access/ondemand_extreme_rto/page_redo.h +++ b/src/include/access/ondemand_extreme_rto/page_redo.h @@ -242,7 +242,11 @@ void WaitAllRedoWorkerQueueEmpty(); void WaitAllReplayWorkerIdle(); void DispatchClosefdMarkToAllRedoWorker(); void DispatchCleanInvalidPageMarkToAllRedoWorker(RepairFileKey key); - +void ClearRecoveryThreadHashTbl(const RelFileNode &node, ForkNumber forknum, BlockNumber minblkno, + bool segment_shrink); +void BatchClearRecoveryThreadHashTbl(Oid spcNode, Oid dbNode); +void RecordBadBlockAndPushToRemote(XLogBlockDataParse *datadecode, PageErrorType error_type, + XLogRecPtr old_lsn, XLogPhyBlock pblk); const char *RedoWokerRole2Str(RedoRole role); } // namespace ondemand_extreme_rto diff --git a/src/include/ddes/dms/ss_common_attr.h b/src/include/ddes/dms/ss_common_attr.h index 9cd0bc02df14eb06a80de7ca8abe38836c521685..c56b1978a6b18762251bd2d91de3938e5c86b225 100644 --- a/src/include/ddes/dms/ss_common_attr.h +++ b/src/include/ddes/dms/ss_common_attr.h @@ -145,7 +145,8 @@ #define SS_PRIMARY_STANDBY_CLUSTER_NORMAL_STANDBY \ (SS_NORMAL_STANDBY && (g_instance.attr.attr_storage.xlog_file_path != 0)) -#define SS_CLUSTER_NOT_NORAML (ENABLE_DMS && (g_instance.dms_cxt.SSReformerControl.clusterStatus != CLUSTER_NORMAL)) +#define SS_CLUSTER_ONDEMAND_NOT_NORAML \ + (ENABLE_DMS && (g_instance.dms_cxt.SSReformerControl.clusterStatus != CLUSTER_NORMAL)) #define SS_CLUSTER_ONDEMAND_BUILD \ (ENABLE_DMS && (g_instance.dms_cxt.SSReformerControl.clusterStatus == CLUSTER_IN_ONDEMAND_BUILD)) #define SS_CLUSTER_ONDEMAND_RECOVERY \