diff --git a/src/gausskernel/storage/access/nbtree/nbtpage.cpp b/src/gausskernel/storage/access/nbtree/nbtpage.cpp index 33fae015450a81efd320bd91ca1d83218b415744..ae7023f349f6bdb0c9b9c9260dcd7fe45241e9ab 100644 --- a/src/gausskernel/storage/access/nbtree/nbtpage.cpp +++ b/src/gausskernel/storage/access/nbtree/nbtpage.cpp @@ -117,6 +117,44 @@ void btree_meta_version(Relation rel, bool *heapkeyspace, bool *allequalimage) *allequalimage = meta_data->btm_allequalimage; } +static Buffer _bt_getcachedrootbuf(Relation rel, BlockNumber rootblkno) +{ + if (!RelationIsSegmentTable(rel) || + IS_EXRTO_STANDBY_READ || + rel->rd_rootcache < 0) { + return _bt_getbuf(rel, rootblkno, BT_READ); + } + + Buffer rootbuf = rel->rd_rootcache; + if (rootbuf != InvalidBuffer) { + RelationOpenSmgr(rel); + + /* Make sure we will have room to remember the buffer pin */ + ResourceOwnerEnlargeBuffers(t_thrd.utils_cxt.CurrentResourceOwner); + BufferDesc *buf = GetBufferDescriptor(rootbuf - 1); + bool valid = PinBuffer(buf, NULL); + bool locked = false; + if (valid) { + locked = TryLockBuffer(rootbuf, BT_READ, false); + } + + if (valid && locked && (buf->tag.forkNum == MAIN_FORKNUM) && + RelFileNodeEquals(buf->tag.rnode, rel->rd_node) && + (buf->tag.blockNum == rootblkno)) { + return rootbuf; + } + + if (locked) { + LockBuffer(rootbuf, BUFFER_LOCK_UNLOCK); + } + + UnpinBuffer(buf, true); + } + rootbuf = _bt_getbuf(rel, rootblkno, BT_READ); + rel->rd_rootcache = rootbuf; + return rootbuf; +} + /* * _bt_getroot() -- Get the root page of the btree. * @@ -172,7 +210,8 @@ Buffer _bt_getroot(Relation rel, int access) Assert(rootblkno != P_NONE); rootlevel = metad->btm_fastlevel; - rootbuf = _bt_getbuf(rel, rootblkno, BT_READ); + rootbuf = _bt_getcachedrootbuf(rel, rootblkno); + //rootbuf = _bt_getbuf(rel, rootblkno, BT_READ); rootpage = BufferGetPage(rootbuf); rootopaque = (BTPageOpaqueInternal)PageGetSpecialPointer(rootpage); /* diff --git a/src/gausskernel/storage/buffer/bufmgr.cpp b/src/gausskernel/storage/buffer/bufmgr.cpp index cc71e990caa3bab7da3f5b3d10e5dbe2493c7374..11781a8dc0906ac67f79be8bbc420dba094151ff 100644 --- a/src/gausskernel/storage/buffer/bufmgr.cpp +++ b/src/gausskernel/storage/buffer/bufmgr.cpp @@ -257,12 +257,12 @@ PrivateRefCountEntry *GetPrivateRefCountEntry(Buffer buffer, bool do_move) * First search for references in the array, that'll be sufficient in the * majority of cases. */ + res = t_thrd.storage_cxt.PrivateRefCountArray; for (i = 0; i < REFCOUNT_ARRAY_ENTRIES; i++) { - res = &t_thrd.storage_cxt.PrivateRefCountArray[i]; - if (res->buffer == buffer) { return res; } + res++; } /* @@ -272,7 +272,7 @@ PrivateRefCountEntry *GetPrivateRefCountEntry(Buffer buffer, bool do_move) * Only look up the buffer in the hashtable if we've previously overflowed * into it. */ - if (t_thrd.storage_cxt.PrivateRefCountOverflowed == 0) + if (unlikely(t_thrd.storage_cxt.PrivateRefCountOverflowed == 0)) return NULL; res = (PrivateRefCountEntry*) hash_search(t_thrd.storage_cxt.PrivateRefCountHash, @@ -3972,7 +3972,7 @@ void UnpinBuffer(BufferDesc *buf, bool fixOwner) if (fixOwner) { ResourceOwnerForgetBuffer(t_thrd.utils_cxt.CurrentResourceOwner, b); } - if (ref->refcount <= 0) { + if (unlikely(ref->refcount <= 0)) { ereport(PANIC, (errmsg("[exception] private ref->refcount is %d in UnpinBuffer", ref->refcount))); } @@ -6482,8 +6482,7 @@ retry: * and the timeout time of the primary and standby servers is modified to open the unlocking * time window. */ - if (!dms_standby_retry_read && SS_STANDBY_MODE && - !g_instance.attr.attr_storage.dms_attr.enable_bcast_snapshot) { + if (!dms_standby_retry_read && SS_STANDBY_MODE) { dms_standby_retry_read = true; mode = BUFFER_LOCK_EXCLUSIVE; } diff --git a/src/gausskernel/storage/lmgr/lwlock.cpp b/src/gausskernel/storage/lmgr/lwlock.cpp index ced3e0bdaf2b163ad43177aa66c8f122395640d7..3e8e868b7e187d65bb9954a82b774042728af267 100644 --- a/src/gausskernel/storage/lmgr/lwlock.cpp +++ b/src/gausskernel/storage/lmgr/lwlock.cpp @@ -1315,6 +1315,19 @@ static bool LWLockConflictsWithVar(LWLock *lock, uint64 *valptr, uint64 oldval, const float NEED_UPDATE_LOCKID_QUEUE_SLOT = 0.6; +/* + * remember lwlock hold when success to acquire + * the lwlock. + */ +static inline void remember_lwlock_hold(LWLock *lock, LWLockMode mode) +{ + t_thrd.storage_cxt.held_lwlocks[t_thrd.storage_cxt.num_held_lwlocks].lock = lock; + t_thrd.storage_cxt.held_lwlocks[t_thrd.storage_cxt.num_held_lwlocks].mode = mode; + t_thrd.storage_cxt.lwlock_held_times[t_thrd.storage_cxt.num_held_lwlocks] = + (u_sess->attr.attr_common.pgstat_track_activities ? GetCurrentTimestamp() : (TimestampTz)0); + t_thrd.storage_cxt.num_held_lwlocks++; +} + /* * LWLockAcquire - acquire a lightweight lock in the specified mode * @@ -1354,7 +1367,7 @@ bool LWLockAcquire(LWLock *lock, LWLockMode mode, bool need_update_lockid) Assert(!(proc == NULL && IsUnderPostmaster)); /* Ensure we will have room to remember the lock */ - if (t_thrd.storage_cxt.num_held_lwlocks >= MAX_SIMUL_LWLOCKS) { + if (unlikely(t_thrd.storage_cxt.num_held_lwlocks >= MAX_SIMUL_LWLOCKS)) { ereport(ERROR, (errcode(ERRCODE_LOCK_NOT_AVAILABLE), errmsg("too many LWLocks taken"))); } diff --git a/src/gausskernel/storage/lmgr/lwlock_be.cpp b/src/gausskernel/storage/lmgr/lwlock_be.cpp index 31356170a8dd2ada81966accd924cb96984f3b4c..a1aadeaef4b2fbb749f9a1dfc5f1a41ca30b3fb9 100644 --- a/src/gausskernel/storage/lmgr/lwlock_be.cpp +++ b/src/gausskernel/storage/lmgr/lwlock_be.cpp @@ -63,21 +63,6 @@ void forget_lwlock_acquire(void) } } - -/* - * remember lwlock hold when success to acquire - * the lwlock. - */ -void remember_lwlock_hold(LWLock *lock, LWLockMode mode) -{ - t_thrd.storage_cxt.held_lwlocks[t_thrd.storage_cxt.num_held_lwlocks].lock = lock; - t_thrd.storage_cxt.held_lwlocks[t_thrd.storage_cxt.num_held_lwlocks].mode = mode; - t_thrd.storage_cxt.lwlock_held_times[t_thrd.storage_cxt.num_held_lwlocks] = - (u_sess->attr.attr_common.pgstat_track_activities ? GetCurrentTimestamp() : (TimestampTz)0); - t_thrd.storage_cxt.num_held_lwlocks++; -} - - /* * find lwlock we held and return the index. */ @@ -93,7 +78,7 @@ int find_lwlock_hold(LWLock *lock) } } - if (i < 0) { + if (unlikely(i < 0)) { ereport(ERROR, (errcode(ERRCODE_LOCK_NOT_AVAILABLE), errmsg("lock %s is not held", T_NAME(lock)))); } @@ -134,4 +119,4 @@ LWLockMode forget_lwlock_hold(LWLock *lock) } return mode; -} \ No newline at end of file +} diff --git a/src/include/storage/lock/lwlock_be.h b/src/include/storage/lock/lwlock_be.h index a71d4cbad684db545cfbdd35f0c99336d05fe0cd..5d4e41a1e4a306843fe0f97dd59c469f34bef812 100644 --- a/src/include/storage/lock/lwlock_be.h +++ b/src/include/storage/lock/lwlock_be.h @@ -32,7 +32,6 @@ extern void remember_lwlock_acquire(LWLock* lockid, LWLockMode mode); extern void forget_lwlock_acquire(void); -extern void remember_lwlock_hold(LWLock *lock, LWLockMode mode); extern int find_lwlock_hold(LWLock *lock); extern LWLockMode forget_lwlock_hold(LWLock *lock);