This is an automated email from the ASF dual-hosted git repository. yjhjstz pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit 843d90dd117292f31693c50321e7f3309c2b5ede Author: Jianghua Yang <[email protected]> AuthorDate: Wed Mar 18 03:15:50 2026 +0800 Fix session lock leak in ALTER DATABASE SET TABLESPACE for utility mode movedb() acquires a session-level AccessExclusiveLock on the database via MoveDbSessionLockAcquire(). The release in CommitTransaction() only checked for GP_ROLE_DISPATCH and IS_SINGLENODE(), missing GP_ROLE_UTILITY. This caused the lock to leak in standalone backends (e.g. TAP tests), triggering a proc.c assertion failure at exit: FailedAssertion("SHMQueueEmpty(&(MyProc->myProcLocks[i]))") Add GP_ROLE_UTILITY to the release condition. Also fix a spurious "could not read symbolic link" log message when dropping in-place tablespaces: readlink() on a directory returns EINVAL, which is expected and can be safely skipped. Fixes https://github.com/apache/cloudberry/issues/1626 --- src/backend/access/transam/xact.c | 16 +++++++++------- src/backend/commands/tablespace.c | 15 ++++++++++----- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index ed655baf989..f8bfa78b28e 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -3036,13 +3036,15 @@ CommitTransaction(void) DoPendingDbDeletes(true); /* - * Only QD holds the session level lock this long for a movedb operation. - * This is to prevent another transaction from moving database objects into - * the source database oid directory while it is being deleted. We don't - * worry about aborts as we release session level locks automatically during - * an abort as opposed to a commit. - */ - if(Gp_role == GP_ROLE_DISPATCH || IS_SINGLENODE()) + * Release the session level lock held for a movedb operation. This is to + * prevent another transaction from moving database objects into the source + * database oid directory while it is being deleted. We don't worry about + * aborts as we release session level locks automatically during an abort + * as opposed to a commit. We must also release in utility mode (e.g. + * standalone backends used in TAP tests). + */ + if (Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_UTILITY || + IS_SINGLENODE()) MoveDbSessionLockRelease(); /* diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 00fa8bcfb2a..e6822521694 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -1230,14 +1230,19 @@ remove_symlink: linkloc = pstrdup(linkloc_with_version_dir); get_parent_directory(linkloc); - /* Remove the symlink target directory if it exists or is valid. */ + /* + * Remove the symlink target directory if it exists or is valid. + * If linkloc is a directory (e.g. in-place tablespace), readlink() + * will fail with EINVAL, which we can safely skip. + */ rllen = readlink(linkloc, link_target_dir, sizeof(link_target_dir)); if(rllen < 0) { - ereport(redo ? LOG : ERROR, - (errcode_for_file_access(), - errmsg("could not read symbolic link \"%s\": %m", - linkloc))); + if (errno != EINVAL) + ereport(redo ? LOG : ERROR, + (errcode_for_file_access(), + errmsg("could not read symbolic link \"%s\": %m", + linkloc))); } else if(rllen >= sizeof(link_target_dir)) { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
