Skip to content

Commit

Permalink
[BACKPORT 2024.1][#21635] YSQL: Allow YbInitPinnedCacheIfNeeded to on…
Browse files Browse the repository at this point in the history
…ly load shared pinned cache.

Summary:
In order to support concurrent non-global-impact DDLs across different
databases, we call YbInitPinnedCacheIfNeeded before entering the separate DDL
transaction. Calling YbInitPinnedCacheIfNeeded triggers a scan of both
pg_shdepend and pg_depend. This ensure that the scan of pg_shdepend and
pg_depend is done without using a read time of the DDL transaction so that
yb-master can retry read restarts error automatically in case a concurrent DDL
in a separate database might have updated pg_shdepend that triggers a read
restarts error. Otherwise, a read restart error is returned to the PG backend the DDL
statement will fail because DDLs cannot be restarted.

However we only support cross-database concurrent DDL and therefore we only
need to call YbInitPinnedCacheIfNeeded to scan pg_shdepend. The scan of
pg_depend can be delayed into the DDL transaction until it is really needed
because we do not support a concurrent DDL in the same database from another
connection. Unconditionally loading pg_depend has a performance hit for DDL
statements that do not need to call YbInitPinnedCacheIfNeeded and it does not
help to solve any problem.

This diff made an API change of YbInitPinnedCacheIfNeeded to allow it to only
load pg_shdepend.
Jira: DB-10530

Original commit: 8487e59 / D33445

Test Plan: ./yb_build.sh --cxx-test pg_catalog_version-test

Reviewers: jason

Reviewed By: jason

Subscribers: yql

Tags: #jenkins-ready

Differential Revision: https://phorge.dev.yugabyte.com/D33480
  • Loading branch information
myang2021 committed Mar 23, 2024
1 parent a38b33e commit 35bf011
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 39 deletions.
48 changes: 18 additions & 30 deletions src/postgres/src/backend/utils/cache/syscache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1271,38 +1271,26 @@ YbBuildPinnedObjectCache(const char *name,
return cache;
}

static void
YbLoadPinnedObjectsCache()
{
YbPinnedObjectsCacheData cache = {
.shared = YbBuildPinnedObjectCache("Shared pinned objects cache",
20, /* Number of pinned objects in pg_shdepend is 9 */
SharedDependRelationId,
Anum_pg_shdepend_deptype,
SHARED_DEPENDENCY_PIN,
YbFetchPinnedObjectKeyFromPgShdepend),
.regular = YbBuildPinnedObjectCache("Pinned objects cache",
6500, /* Number of pinned object is pg_depend 6179 */
DependRelationId,
Anum_pg_depend_deptype,
DEPENDENCY_PIN,
YbFetchPinnedObjectKeyFromPgDepend)};
YbPinnedObjectsCache = cache;
}

/* Build the cache in case it is not yet ready. */
void
YbInitPinnedCacheIfNeeded()
YbInitPinnedCacheIfNeeded(bool shared_only)
{
/*
* Both 'regular' and 'shared' fields are set at same time.
* Checking any of them is enough.
*/
if (!YbPinnedObjectsCache.regular)
{
Assert(!YbPinnedObjectsCache.shared);
YbLoadPinnedObjectsCache();
}
if (!YbPinnedObjectsCache.shared)
YbPinnedObjectsCache.shared =
YbBuildPinnedObjectCache("Shared pinned objects cache",
20, /* Number of pinned objects in pg_shdepend is 9 */
SharedDependRelationId,
Anum_pg_shdepend_deptype,
SHARED_DEPENDENCY_PIN,
YbFetchPinnedObjectKeyFromPgShdepend);
if (!shared_only && !YbPinnedObjectsCache.regular)
YbPinnedObjectsCache.regular =
YbBuildPinnedObjectCache("Pinned objects cache",
6500, /* Number of pinned object is pg_depend 6179 */
DependRelationId,
Anum_pg_depend_deptype,
DEPENDENCY_PIN,
YbFetchPinnedObjectKeyFromPgDepend);
}

void
Expand All @@ -1325,7 +1313,7 @@ YbResetPinnedCache()
bool
YbIsObjectPinned(Oid classId, Oid objectId, bool shared_dependency)
{
YbInitPinnedCacheIfNeeded();
YbInitPinnedCacheIfNeeded(false /* shared_only */);

HTAB *cache = shared_dependency ? YbPinnedObjectsCache.shared
: YbPinnedObjectsCache.regular;
Expand Down
13 changes: 5 additions & 8 deletions src/postgres/src/backend/utils/misc/pg_yb_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -2138,20 +2138,17 @@ YBTxnDdlProcessUtility(
/*
* In order to support concurrent non-global-impact DDLs
* across different databases, call YbInitPinnedCacheIfNeeded
* now which triggers a scan of pg_shdepend and pg_depend.
* This ensure that the scan is done without using a read time
* of the DDL transaction so that yb-master can retry read
* restarts automatically. Otherwise, a read restart error is
* now which triggers a scan of pg_shdepend. This ensure that
* the scan is done without using a read time of the DDL
* transaction so that yb-master can retry read restarts
* automatically. Otherwise, a read restart error is
* returned to the PG backend the DDL statement will fail
* because DDLs cannot be restarted.
*
* YB NOTE: this implies a performance hit for DDL statements
* that do not need to call YbInitPinnedCacheIfNeeded.
*
* TODO(myang): we can optimize to only read pg_shdepend here
* to reduce its performance penalty.
*/
YbInitPinnedCacheIfNeeded();
YbInitPinnedCacheIfNeeded(true /* shared_only */);

YBIncrementDdlNestingLevel(ddl_mode.value);
}
Expand Down
2 changes: 1 addition & 1 deletion src/postgres/src/include/utils/syscache.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ enum SysCacheIdentifier
/* Used in IsYugaByteEnabled() mode only */
extern void YbSetSysCacheTuple(Relation rel, HeapTuple tup);
extern void YbPreloadCatalogCache(int cache_id, int idx_cache_id);
extern void YbInitPinnedCacheIfNeeded();
extern void YbInitPinnedCacheIfNeeded(bool shared_only);
extern void YbResetPinnedCache();
extern bool YbIsObjectPinned(Oid classId, Oid objectId, bool shared_dependency);
extern void YbPinObjectIfNeeded(Oid classId, Oid objectId, bool shared_dependency);
Expand Down

0 comments on commit 35bf011

Please sign in to comment.