Global SysCache

Offering: openGaussDev

More detail:
修复initsession时缓存命中,但是u_sess->proc_cxt.MyDatabaseId为0导致cache无法刷新问题

Match-id-eba30ce5fb121c33b1dccbcd127624fafe5cb83f
This commit is contained in:
openGaussDev 2022-03-02 19:34:19 +08:00 committed by yanghao
parent 9e59584896
commit 039aff4f64
4 changed files with 52 additions and 18 deletions

View File

@ -432,7 +432,6 @@ Size *GetSizeVfdCachePtr()
}
}
int GetVfdNfile()
{
if (EnableLocalSysCache()) {
@ -524,19 +523,49 @@ bool LocalSysDBCache::LocalSysDBCacheNeedClearMyDB(Oid db_id, const char *db_nam
strcmp(t_thrd.proc_cxt.MyProgName, "BootStrap") == 0
));
}
/* it is a weird design that we need access mydatabaseid before initsession.
* but for GSC mode, we do need aquire lock when cache hit and there are invalid msgs
* with session uninited and so u_sess->proc_cxt.MyDatabaseId is InvalidOid.
* 1 the publication feature will send all rels' invalmsgs even no refered ddl.
* 2 relations may have refcount leak, so we must rebuild them if cache hit.
* when we rebuild a relation, the session may be not uninited,
* and so u_sess->proc_cxt.MyDatabaseId is InvalidOid,
* so we use t_thrd.lsc_cxt.lsc->my_database_id on GSC mode */
Assert(CheckMyDatabaseMatch());
Assert(m_global_db != NULL);
/* if u_sess->proc_cxt.MyDatabaseId is InvalidOid, the session's status is uninit
* we will call SetDatabase to rewrite it.
* but beofre SetDatabase, we need the dbid to Accept Invalid msg */
bool lock_db_advance = u_sess->proc_cxt.MyDatabaseId == InvalidOid && IS_THREAD_POOL_WORKER;
/* cache hit, when initsession, we lock db to avoid alter db */
Oid old_db_id = t_thrd.proc->databaseId;
if (u_sess->proc_cxt.MyDatabaseId == InvalidOid && IS_THREAD_POOL_WORKER) {
LockSharedObject(DatabaseRelationId, my_database_id, 0, RowExclusiveLock);
if (lock_db_advance) {
Assert(u_sess->proc_cxt.MyDatabaseTableSpace == InvalidOid);
Assert(u_sess->proc_cxt.DatabasePath == NULL);
Assert(t_thrd.proc->databaseId == InvalidOid);
u_sess->proc_cxt.MyDatabaseId = my_database_id;
u_sess->proc_cxt.MyDatabaseTableSpace = my_database_tablespace;
/* use refer not copy, it will be rewritten when initsession */
u_sess->proc_cxt.DatabasePath = my_database_path;
/* we dont want to accept inval msg here, so use LockSharedObjectForSession to avoid it. */
LockSharedObjectForSession(DatabaseRelationId, my_database_id, 0, RowExclusiveLock);
t_thrd.proc->databaseId = my_database_id;
UnlockSharedObject(DatabaseRelationId, my_database_id, 0, RowExclusiveLock);
}
Assert(m_global_db != NULL);
if (m_global_db->m_isDead) {
t_thrd.proc->databaseId = old_db_id;
UnlockSharedObjectForSession(DatabaseRelationId, my_database_id, 0, RowExclusiveLock);
/* when we acquired the dblock, alter db transaction happened, and we should clear cache of mydb. */
if (m_global_db->m_isDead) {
t_thrd.proc->databaseId = InvalidOid;
u_sess->proc_cxt.MyDatabaseId = InvalidOid;
u_sess->proc_cxt.MyDatabaseTableSpace = InvalidOid;
u_sess->proc_cxt.DatabasePath = NULL;
return true;
}
} else if (m_global_db->m_isDead) {
return true;
}
return false;
}

View File

@ -816,8 +816,9 @@ void LocalTabDefCache::RememberToFreeTupleDescAtEOX(TupleDesc td)
{
if (EOXactTupleDescArray == NULL) {
MemoryContext oldcxt = MemoryContextSwitchTo(LocalMyDBCacheMemCxt());
EOXactTupleDescArrayLen = 16;
EOXactTupleDescArray = (TupleDesc *)palloc(EOXactTupleDescArrayLen * sizeof(TupleDesc));
const int default_len = 16;
EOXactTupleDescArray = (TupleDesc *)palloc(default_len * sizeof(TupleDesc));
EOXactTupleDescArrayLen = default_len;
NextEOXactTupleDescNum = 0;
MemoryContextSwitchTo(oldcxt);
} else if (NextEOXactTupleDescNum >= EOXactTupleDescArrayLen) {

View File

@ -66,6 +66,7 @@
#include "storage/ipc.h"
#include "storage/smgr/knl_usync.h"
#include "storage/lmgr.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/procsignal.h"
@ -2031,7 +2032,6 @@ void PostgresInitializer::InitThread()
on_shmem_exit(ShutdownXLOG, 0);
}
}
void PostgresInitializer::InitLoadLocalSysCache(Oid db_oid, const char *db_name)
{
if(!EnableLocalSysCache()) {
@ -2068,6 +2068,11 @@ void PostgresInitializer::InitLoadLocalSysCache(Oid db_oid, const char *db_name)
ResourceOwnerRelease(t_thrd.lsc_cxt.lsc->local_sysdb_resowner, RESOURCE_RELEASE_LOCKS, false, true);
ResourceOwnerRelease(t_thrd.lsc_cxt.lsc->local_sysdb_resowner, RESOURCE_RELEASE_AFTER_LOCKS, false, true);
/* we are not in transaction, so resowner cannot help us release proclocks and predicatelocks.
* we do nothing above except init and load syscache, so no undowork need. ProcReleaseLocks always need
* */
ProcReleaseLocks(false);
ReleasePredicateLocks(false);
/* lwlocks arre released at sigsetjmp */
/* recovery CurrentResourceOwner */
@ -2590,8 +2595,9 @@ void PostgresInitializer::SetDatabasePath()
ValidatePgVersion(m_fullpath);
/* This should happen only once per process */
Assert(!u_sess->proc_cxt.DatabasePath);
/* This should happen only once per process, for gsc, it may equal the pointer belongs to lsc */
Assert(!u_sess->proc_cxt.DatabasePath ||
(EnableLocalSysCache() && u_sess->proc_cxt.DatabasePath == t_thrd.lsc_cxt.lsc->my_database_path));
u_sess->proc_cxt.DatabasePath = MemoryContextStrdup(
SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_EXECUTOR), m_fullpath);
if (EnableLocalSysCache()) {

View File

@ -1399,12 +1399,10 @@ void instr_stmt_report_basic_info()
}
if (to_update_db_name || to_update_user_name || to_update_client_addr) {
ResourceOwner old_cur_owner = t_thrd.utils_cxt.CurrentResourceOwner;
MemoryContext old_ctx = MemoryContextSwitchTo(t_thrd.mem_cxt.msg_mem_cxt);
t_thrd.utils_cxt.CurrentResourceOwner = ResourceOwnerCreate(NULL, "Full/Slow SQL",
t_thrd.utils_cxt.CurrentResourceOwner = ResourceOwnerCreate(old_cur_owner, "Full/Slow SQL",
THREAD_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_DFX));
(void)MemoryContextSwitchTo(old_ctx);
old_ctx = MemoryContextSwitchTo(u_sess->statement_cxt.stmt_stat_cxt);
MemoryContext old_ctx = MemoryContextSwitchTo(u_sess->statement_cxt.stmt_stat_cxt);
if (to_update_db_name) {
u_sess->statement_cxt.db_name = get_database_name(beentry->st_databaseid);
}