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]

Reply via email to