From c3339b5ba1fb2c48d2c99a310f5a46e682459901 Mon Sep 17 00:00:00 2001 From: openGaussDev Date: Thu, 10 Mar 2022 10:21:28 +0800 Subject: [PATCH] fix invalid memory in undo Offering: openGaussDev More detail: fix invalid memory in undo Match-id-496852205f7ba0be46bf71ec29580aeece9d50f5 --- .../storage/access/ustore/knl_undoaction.cpp | 18 ++++++++++-------- .../storage/access/ustore/knl_uundovec.cpp | 2 +- src/include/access/ustore/knl_undorequest.h | 3 +++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/gausskernel/storage/access/ustore/knl_undoaction.cpp b/src/gausskernel/storage/access/ustore/knl_undoaction.cpp index 0c285a90a..b82f02313 100644 --- a/src/gausskernel/storage/access/ustore/knl_undoaction.cpp +++ b/src/gausskernel/storage/access/ustore/knl_undoaction.cpp @@ -35,6 +35,14 @@ static UHeapDiskTuple CopyTupleFromUndoRecord(Relation relation, UndoRecord *und static void RestoreXactFromUndoRecord(UndoRecord *undorecord, Buffer buffer, UHeapDiskTuple tuple); static void LogUHeapUndoActions(UHeapUndoActionWALInfo *walInfo, Relation rel); +static int GetUndoApplySize() +{ + uint64 undoApplySize = (uint64)u_sess->attr.attr_memory.maintenance_work_mem * 1024L; + uint64 applySize = MAX_UNDO_APPLY_SIZE > undoApplySize ? undoApplySize : MAX_UNDO_APPLY_SIZE; + Assert(applySize <= MAX_UNDO_APPLY_SIZE); + return (int)applySize; +} + /* * execute_undo_actions - Execute the undo actions * @@ -49,10 +57,7 @@ void ExecuteUndoActions(TransactionId fullXid, UndoRecPtr fromUrecptr, UndoRecPt Assert(toUrecptr != INVALID_UNDO_REC_PTR && fromUrecptr != INVALID_UNDO_REC_PTR); Assert(slotPtr != INVALID_UNDO_REC_PTR); Assert(fullXid != InvalidTransactionId); - int undoApplySize = u_sess->attr.attr_memory.maintenance_work_mem * 1024L; - - /* setting maintenance_work_mem atleast 2GB will cause an overflow */ - undoApplySize = (undoApplySize < 0) ? INT_MAX : undoApplySize; + int undoApplySize = GetUndoApplySize(); UndoRecPtr urecPtr = fromUrecptr; UndoRecord *urec = New(CurrentMemoryContext)UndoRecord(); urec->SetUrp(toUrecptr); @@ -165,10 +170,7 @@ void ExecuteUndoActions(TransactionId fullXid, UndoRecPtr fromUrecptr, UndoRecPt void ExecuteUndoActionsPage(UndoRecPtr fromUrp, Relation rel, Buffer buffer, TransactionId xid) { UndoRecPtr urp = fromUrp; - int undoApplySize = u_sess->attr.attr_memory.maintenance_work_mem * 1024L; - - /* setting maintenance_work_mem atleast 2GB will cause an overflow */ - undoApplySize = (undoApplySize < 0) ? INT_MAX : undoApplySize; + int undoApplySize = GetUndoApplySize(); /* * Fetch the multiple undo records which can fit into undoApplySize; diff --git a/src/gausskernel/storage/access/ustore/knl_uundovec.cpp b/src/gausskernel/storage/access/ustore/knl_uundovec.cpp index 8d72ae7b5..e8e101a29 100644 --- a/src/gausskernel/storage/access/ustore/knl_uundovec.cpp +++ b/src/gausskernel/storage/access/ustore/knl_uundovec.cpp @@ -480,7 +480,7 @@ URecVector* FetchUndoRecordRange( __inout UndoRecPtr *startUrp, } totalSize += urec->MemoryRecordSize(); - if (totalSize > maxUndoApplySize) { + if (totalSize >= maxUndoApplySize) { *startUrp = currUrp; break; } diff --git a/src/include/access/ustore/knl_undorequest.h b/src/include/access/ustore/knl_undorequest.h index 6380b0249..a22f9f2c3 100644 --- a/src/include/access/ustore/knl_undorequest.h +++ b/src/include/access/ustore/knl_undorequest.h @@ -21,6 +21,9 @@ #include "access/ustore/knl_uundovec.h" #include "utils/rel.h" +/* Maximum size of the cache of undo records in a single rollback, 64M. */ +const uint64 MAX_UNDO_APPLY_SIZE = 64 * 1024 * 1024; + typedef struct RollbackRequestsHashKey { TransactionId xid; UndoRecPtr startUndoPtr;