diff --git a/src/gausskernel/process/postmaster/postmaster.cpp b/src/gausskernel/process/postmaster/postmaster.cpp index 35bc500b06d449677ad9b97eaf0271d6335abdbd..a6faf400510d33c5fe635f95ee17bdca81a7708a 100644 --- a/src/gausskernel/process/postmaster/postmaster.cpp +++ b/src/gausskernel/process/postmaster/postmaster.cpp @@ -3349,6 +3349,22 @@ static void CheckExtremeRtoGUCConflicts(void) TRXN_REDO_MANAGER_NUM + TRXN_REDO_WORKER_NUM + XLOG_READER_NUM, MAX_RECOVERY_THREAD_NUM))); } #endif + + if (g_instance.attr.attr_storage.dms_attr.enable_ondemand_recovery) { + if (!g_instance.attr.attr_storage.dms_attr.enable_dms) { + ereport(ERROR, + (errcode(ERRCODE_SYSTEM_ERROR), + errmsg("ondemand extreme rto only support in shared storage mode."), + errhint("Either turn on ss_enable_dms, or turn off ss_enable_ondemand_recovery."))); + } + + if (g_instance.attr.attr_storage.recovery_parse_workers <= 1) { + ereport(ERROR, + (errcode(ERRCODE_SYSTEM_ERROR), + errmsg("extreme rto param should be set in ondemand extreme rto mode."), + errhint("Either turn off ss_enable_ondemand_recovery, or set extreme rto param."))); + } + } } static void CheckRecoveryParaConflict() { diff --git a/src/gausskernel/process/threadpool/knl_thread.cpp b/src/gausskernel/process/threadpool/knl_thread.cpp index 97e4ccd521362d96cebe647483d4590da1e74e18..af937063b0d09e150cdcc4a1cba33116c351df3f 100755 --- a/src/gausskernel/process/threadpool/knl_thread.cpp +++ b/src/gausskernel/process/threadpool/knl_thread.cpp @@ -1428,6 +1428,7 @@ static void knl_t_storage_init(knl_t_storage_context* storage_cxt) storage_cxt->max_userdatafiles = 8192 - 1000; storage_cxt->timeoutRemoteOpera = 0; storage_cxt->dmsBufCtl = NULL; + storage_cxt->ondemandXLogMem = NULL; } static void knl_t_port_init(knl_t_port_context* port_cxt) diff --git a/src/gausskernel/storage/access/transam/ondemand_extreme_rto/redo_utils.cpp b/src/gausskernel/storage/access/transam/ondemand_extreme_rto/redo_utils.cpp index 0bb706aca16303b2fbb81ac671b15d273cd4ae8b..7ba976b25c40451c1b758205cc8ceb7509bd2e7b 100644 --- a/src/gausskernel/storage/access/transam/ondemand_extreme_rto/redo_utils.cpp +++ b/src/gausskernel/storage/access/transam/ondemand_extreme_rto/redo_utils.cpp @@ -27,48 +27,46 @@ #include "access/ondemand_extreme_rto/redo_utils.h" #include "storage/lock/lwlock.h" +Size OndemandRecoveryShmemSize(void) +{ + Size size = 0; + + size = add_size(size, (Size)g_instance.attr.attr_storage.dms_attr.ondemand_recovery_mem_size << BITS_IN_KB); + + return size; +} + +void OndemandRecoveryShmemInit(void) +{ + bool found = false; + t_thrd.storage_cxt.ondemandXLogMem = + (char *)ShmemInitStruct("Ondemand Recovery HashMap", OndemandRecoveryShmemSize(), &found); + + if (!found) { + /* The memory of the memset sometimes exceeds 2 GB. so, memset_s cannot be used. */ + MemSet(t_thrd.storage_cxt.ondemandXLogMem, 0, OndemandRecoveryShmemSize()); + } +} + /* add for batch redo mem manager */ void *OndemandXLogMemCtlInit(RedoMemManager *memctl, Size itemsize, int itemnum) { - void *allocdata = NULL; - RedoMemSlot *nextfreeslot = NULL; - OndemandParseAllocCtrl *ctrl; - Assert(PARSEBUFFER_SIZE == itemsize); - - allocdata = (void *)palloc(sizeof(OndemandParseAllocCtrl)); - ctrl = (OndemandParseAllocCtrl *)allocdata; - ctrl->allocNum = itemnum / ONDEMAND_MAX_PARSEBUFF_PREPALLOC; - if ((int)(ctrl->allocNum * ONDEMAND_MAX_PARSEBUFF_PREPALLOC) != itemnum) { - ctrl->allocNum++; - } - ctrl->memslotEntry = (void *)palloc(sizeof(RedoMemSlot) * itemnum); - - // palloc all parse mem entry - for (int i = 0; i < ctrl->allocNum; i++) { - ctrl->allocEntry[i] = (void *)palloc(ONDEMAND_MAX_PARSESIZE_PREPALLOC); - if (ctrl->allocEntry[i] == NULL) { - ereport(PANIC, - (errmodule(MOD_REDO), errcode(ERRCODE_LOG), - errmsg("[SS] XLogMemCtlInit Allocated buffer failed!, totalblknum:%d, itemsize:%lu", - itemnum, itemsize))); - /* panic */ - } - errno_t rc = memset_s(ctrl->allocEntry[i], ONDEMAND_MAX_PARSESIZE_PREPALLOC, 0, - ONDEMAND_MAX_PARSESIZE_PREPALLOC); - securec_check(rc, "\0", "\0"); - } + Size dataSize = (itemsize + sizeof(RedoMemSlot)) * itemnum; + + Assert(t_thrd.storage_cxt.ondemandXLogMem != NULL); + Assert(dataSize <= OndemandRecoveryShmemSize()); + memctl->totalblknum = itemnum; memctl->usedblknum = 0; memctl->itemsize = itemsize; - memctl->memslot = (RedoMemSlot *)ctrl->memslotEntry; - nextfreeslot = memctl->memslot; + memctl->memslot = (RedoMemSlot *)(t_thrd.storage_cxt.ondemandXLogMem + (itemsize * itemnum)); for (int i = memctl->totalblknum; i > 0; --i) { memctl->memslot[i - 1].buf_id = i; /* start from 1 , 0 is invalidbuffer */ memctl->memslot[i - 1].freeNext = i - 1; } memctl->firstfreeslot = memctl->totalblknum; memctl->firstreleaseslot = InvalidBuffer; - return allocdata; + return (void *)t_thrd.storage_cxt.ondemandXLogMem; } RedoMemSlot *OndemandXLogMemAlloc(RedoMemManager *memctl) @@ -136,26 +134,11 @@ void OndemandXLogParseBufferInit(RedoParseManager *parsemanager, int buffernum, void OndemandXLogParseBufferDestory(RedoParseManager *parsemanager) { g_parseManager = NULL; - OndemandParseAllocCtrl *ctrl = (OndemandParseAllocCtrl *)parsemanager->parsebuffers; - - if (ctrl != NULL) { - for (int i = 0; i < ctrl->allocNum; i++) { - pfree(ctrl->allocEntry[i]); - } - pfree(ctrl->memslotEntry); - pfree(ctrl); - parsemanager->parsebuffers = NULL; - } + // do not free parsebuffers, which is managed in shared memory + parsemanager->parsebuffers = NULL; parsemanager->memctl.isInit = false; } -ParseBufferDesc *OndemandGetParseMemSlot(OndemandParseAllocCtrl *ctrl, int itemIndex) -{ - int entryIndex = itemIndex / ONDEMAND_MAX_PARSEBUFF_PREPALLOC; - int entryOffset = (itemIndex - (entryIndex * ONDEMAND_MAX_PARSEBUFF_PREPALLOC)) * PARSEBUFFER_SIZE; - return (ParseBufferDesc *)((char *)ctrl->allocEntry[entryIndex] + entryOffset); -} - XLogRecParseState *OndemandXLogParseBufferAllocList(RedoParseManager *parsemanager, XLogRecParseState *blkstatehead, void *record) { @@ -175,7 +158,7 @@ XLogRecParseState *OndemandXLogParseBufferAllocList(RedoParseManager *parsemanag pg_read_barrier(); Assert(allocslot->buf_id != InvalidBuffer); Assert(memctl->itemsize == (sizeof(XLogRecParseState) + sizeof(ParseBufferDesc))); - descstate = OndemandGetParseMemSlot((OndemandParseAllocCtrl *)parsemanager->parsebuffers, allocslot->buf_id - 1); + descstate = (ParseBufferDesc *)((char *)parsemanager->parsebuffers + memctl->itemsize * (allocslot->buf_id - 1)); descstate->buff_id = allocslot->buf_id; Assert(descstate->state == 0); descstate->state = 1; diff --git a/src/gausskernel/storage/ipc/ipci.cpp b/src/gausskernel/storage/ipc/ipci.cpp index d243ca461cd8c8a3d3772e2f410ccf6b46baa894..d40ed2e84012e0954e89d2a86ef0dd1e706055c7 100644 --- a/src/gausskernel/storage/ipc/ipci.cpp +++ b/src/gausskernel/storage/ipc/ipci.cpp @@ -30,6 +30,7 @@ #include "access/ustore/undo/knl_uundoapi.h" #include "access/ustore/knl_undoworker.h" #include "access/ustore/knl_undorequest.h" +#include "access/ondemand_extreme_rto/redo_utils.h" #include "commands/tablespace.h" #include "commands/async.h" #include "commands/matview.h" @@ -195,6 +196,10 @@ Size ComputeTotalSizeOfShmem() /* csf shrinker backend shared memory */ size = add_size(size, CfsShrinkerShmemSize()); + + if (g_instance.attr.attr_storage.dms_attr.enable_ondemand_recovery) { + size = add_size(size, OndemandRecoveryShmemSize()); + } return size; } @@ -444,6 +449,10 @@ void CreateSharedMemoryAndSemaphores(bool makePrivate, int port) FileRepairHashTblInit(); initRepairBadBlockStat(); + if (g_instance.attr.attr_storage.dms_attr.enable_ondemand_recovery) { + OndemandRecoveryShmemInit(); + } + if (g_instance.ckpt_cxt_ctl->prune_queue_lock == NULL) { g_instance.ckpt_cxt_ctl->prune_queue_lock = LWLockAssign(LWTRANCHE_PRUNE_DIRTY_QUEUE); } diff --git a/src/include/access/ondemand_extreme_rto/redo_utils.h b/src/include/access/ondemand_extreme_rto/redo_utils.h index 8b2775785e1ca58da523f2d2d852090b03a79cc7..a5a95a2b56ee56c249000f94b0e8ae7df7396a18 100644 --- a/src/include/access/ondemand_extreme_rto/redo_utils.h +++ b/src/include/access/ondemand_extreme_rto/redo_utils.h @@ -26,19 +26,8 @@ #include "access/xlogproc.h" -#define PARSEBUFFER_SIZE (sizeof(XLogRecParseState) + sizeof(ParseBufferDesc)) -#define ONDEMAND_MAX_PARSEBUFF_PREPALLOC ((1024 * 1024 * 1024 - 1) / PARSEBUFFER_SIZE) -#define ONDEMAND_MAX_PARSESIZE_PREPALLOC (ONDEMAND_MAX_PARSEBUFF_PREPALLOC * PARSEBUFFER_SIZE) -#define ONDEMAND_MAX_PARSEBUFF_ALLOCSIZE 100 // 100GB - -typedef struct -{ - int allocNum; - void *allocEntry[ONDEMAND_MAX_PARSEBUFF_ALLOCSIZE]; - void *memslotEntry; -} OndemandParseAllocCtrl; - - +Size OndemandRecoveryShmemSize(void); +void OndemandRecoveryShmemInit(void); void OndemandXLogParseBufferInit(RedoParseManager *parsemanager, int buffernum, RefOperate *refOperate, InterruptFunc interruptOperte); void OndemandXLogParseBufferDestory(RedoParseManager *parsemanager); diff --git a/src/include/knl/knl_thread.h b/src/include/knl/knl_thread.h index 0ebcd89461facc26b900eff638b9638cb9102dca..f58b2a0ca2c18c93f47c0b83f40cf0bdf642e60c 100755 --- a/src/include/knl/knl_thread.h +++ b/src/include/knl/knl_thread.h @@ -2805,6 +2805,7 @@ typedef struct knl_t_storage_context { int timeoutRemoteOpera; char* PcaBufferBlocks; dms_buf_ctrl_t* dmsBufCtl; + char* ondemandXLogMem; } knl_t_storage_context; typedef struct knl_t_port_context {