diff --git a/src/gausskernel/storage/buffer/bufmgr.cpp b/src/gausskernel/storage/buffer/bufmgr.cpp index e062afafd..d5d15f30b 100644 --- a/src/gausskernel/storage/buffer/bufmgr.cpp +++ b/src/gausskernel/storage/buffer/bufmgr.cpp @@ -4764,6 +4764,29 @@ int GetThreadBufferLeakNum(void) return refCountErrors; } +bool CheckForBufferPin(void) +{ + PrivateRefCountEntry *res = NULL; + + for (int i = 0; i < REFCOUNT_ARRAY_ENTRIES; i++) { + res = &t_thrd.storage_cxt.PrivateRefCountArray[i]; + + if (res->buffer != InvalidBuffer) { + return true; + } + } + + if (t_thrd.storage_cxt.PrivateRefCountOverflowed) { + HASH_SEQ_STATUS hstat; + hash_seq_init(&hstat, t_thrd.storage_cxt.PrivateRefCountHash); + while ((res = (PrivateRefCountEntry *)hash_seq_search(&hstat)) != NULL) { + hash_seq_term(&hstat); + return true; + } + } + return false; +} + /* * CheckForBufferLeaks - ensure this backend holds no buffer pins * diff --git a/src/gausskernel/storage/ipc/procarray.cpp b/src/gausskernel/storage/ipc/procarray.cpp index d55df5110..4f012ce0a 100755 --- a/src/gausskernel/storage/ipc/procarray.cpp +++ b/src/gausskernel/storage/ipc/procarray.cpp @@ -2120,6 +2120,8 @@ RETRY: bool retry_get = false; uint64 retry_count = 0; const static uint64 WAIT_COUNT = 0x7FFFF; + bool get_snapshot_by_self = CheckForBufferPin() || forHSFeedBack; + /* reset xmin before acquiring lwlock, in case blocking redo */ t_thrd.pgxact->xmin = InvalidTransactionId; RETRY_GET: @@ -2184,7 +2186,7 @@ RETRY_GET: goto RETRY_GET; } #ifndef ENABLE_MULTIPLE_NODES - } else if (forHSFeedBack) { + } else if (get_snapshot_by_self) { LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); if ((t_thrd.xact_cxt.ShmemVariableCache->standbyXmin <= t_thrd.xact_cxt.ShmemVariableCache->standbyRedoCleanupXmin) diff --git a/src/include/storage/buf/bufmgr.h b/src/include/storage/buf/bufmgr.h index 63a8f9bce..2c0f6da63 100644 --- a/src/include/storage/buf/bufmgr.h +++ b/src/include/storage/buf/bufmgr.h @@ -410,6 +410,7 @@ extern void RangeForgetBuffer(RelFileNode node, ForkNumber forkNum, BlockNumber extern void DropSegRelNodeSharedBuffer(RelFileNode node, ForkNumber forkNum); extern int GetThreadBufferLeakNum(void); +extern bool CheckForBufferPin(void); extern void flush_all_buffers(Relation rel, Oid db_id, HTAB *hashtbl = NULL); /* in localbuf.c */ extern void ForgetLocalBuffer(RelFileNode rnode, ForkNumber forkNum, BlockNumber blockNum);