You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudberry.apache.org by re...@apache.org on 2025/01/23 14:13:30 UTC

(cloudberry) 10/16: Fix incorrect behavior of gp_toolkit.gp_move_orphaned_files

This is an automated email from the ASF dual-hosted git repository.

reshke pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit 91f0710c21637bdb429c3d09197fa5d60546180d
Author: wuchengwen <dr...@gmail.com>
AuthorDate: Tue Feb 20 10:40:56 2024 +0800

    Fix incorrect behavior of gp_toolkit.gp_move_orphaned_files
    
    In function `gp_toolkit.gp_move_orphaned_files`, the following
    SQL will call `pg_file_rename` to move orphaned files:
    
    ```
    WITH OrphanedFiles AS (
        xxxxx
        xxxxx
    )
    SELECT
       OrphanedFiles.gp_segment_id,
       OrphanedFiles.oldpath,
       OrphanedFiles.newpath,
       pg_file_rename(OrphanedFiles.oldpath, OrphanedFiles.newpath,
    NULL) AS move_success
     FROM OrphanedFiles
    ```
    
    However, `pg_file_rename` will only be called by coordinator, which
    means, in a distributed environment, segments' files can't be moved
    as expected.
---
 gpcontrib/gp_toolkit/Makefile                 |  3 +-
 gpcontrib/gp_toolkit/gp_toolkit--1.4--1.5.sql | 72 +++++++++++++++++++++++++++
 gpcontrib/gp_toolkit/gp_toolkit.control       |  2 +-
 3 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/gpcontrib/gp_toolkit/Makefile b/gpcontrib/gp_toolkit/Makefile
index 2e7705463a..baa96cf1ea 100644
--- a/gpcontrib/gp_toolkit/Makefile
+++ b/gpcontrib/gp_toolkit/Makefile
@@ -1,6 +1,7 @@
 EXTENSION = gp_toolkit
 DATA = gp_toolkit--1.1--1.2.sql gp_toolkit--1.0--1.1.sql gp_toolkit--1.0.sql \
-		gp_toolkit--1.2--1.3.sql gp_toolkit--1.3.sql gp_toolkit--1.3--1.4.sql
+		gp_toolkit--1.2--1.3.sql gp_toolkit--1.3.sql gp_toolkit--1.3--1.4.sql \
+		gp_toolkit--1.4--1.5.sql
 MODULE_big = gp_toolkit
 ifeq ($(shell uname -s), Linux)
 OBJS = resgroup.o gp_partition_maint.o
diff --git a/gpcontrib/gp_toolkit/gp_toolkit--1.4--1.5.sql b/gpcontrib/gp_toolkit/gp_toolkit--1.4--1.5.sql
new file mode 100644
index 0000000000..740bba26d0
--- /dev/null
+++ b/gpcontrib/gp_toolkit/gp_toolkit--1.4--1.5.sql
@@ -0,0 +1,72 @@
+/* gpcontrib/gp_toolkit/gp_toolkit--1.4--1.5.sql */
+
+-- complain if script is sourced in psql, rather than via ALTER EXTENSION
+\echo Use "ALTER EXTENSION gp_toolkit UPDATE TO '1.5" to load this file. \quit
+
+-- Function to move orphaned files to a designated location.
+-- NOTE: this function does the same lock and checks as gp_toolkit.__gp_check_orphaned_files_func(), and it needs to be that way. 
+CREATE OR REPLACE FUNCTION gp_toolkit.gp_move_orphaned_files(target_location TEXT) RETURNS TABLE (
+    gp_segment_id INT,
+    move_success BOOL,
+    oldpath TEXT,
+    newpath TEXT
+)
+LANGUAGE plpgsql AS $$
+BEGIN
+    -- lock pg_class so that no one will be adding/altering relfilenodes
+    LOCK TABLE pg_class IN SHARE MODE NOWAIT;
+
+    -- make sure no other active/idle transaction is running
+    IF EXISTS (
+        SELECT 1
+        FROM gp_stat_activity
+        WHERE
+        sess_id <> -1 AND backend_type IN ('client backend', 'unknown process type') -- exclude background worker types
+        AND sess_id <> current_setting('gp_session_id')::int -- Exclude the current session
+    ) THEN
+        RAISE EXCEPTION 'There is a client session running on one or more segment. Aborting...';
+    END IF;
+
+    -- force checkpoint to make sure we do not include files that are normally pending delete
+    CHECKPOINT;
+
+    RETURN QUERY
+    SELECT
+        q.gp_segment_id,
+        q.move_success,
+        q.oldpath,
+        q.newpath
+    FROM (
+        SELECT s1.gp_segment_id, s1.oldpath, s1.newpath, pg_file_rename(s1.oldpath, s1.newpath, NULL) AS move_success
+        FROM
+        (
+            SELECT
+                o.gp_segment_id,
+                s.setting || '/' || o.filepath as oldpath,
+                target_location || '/seg' || o.gp_segment_id::text || '_' || REPLACE(o.filepath, '/', '_') as newpath
+            FROM gp_toolkit.__check_orphaned_files o
+            JOIN gp_settings s on o.gp_segment_id = s.gp_segment_id
+            WHERE s.name = 'data_directory'
+        ) s1
+        UNION ALL
+        -- Segments
+        SELECT s2.gp_segment_id, s2.oldpath, s2.newpath, pg_file_rename(s2.oldpath, s2.newpath, NULL) AS move_success
+        FROM
+        (
+            SELECT
+                o.gp_segment_id,
+                s.setting || '/' || o.filepath as oldpath,
+                target_location || '/seg' || o.gp_segment_id::text || '_' || REPLACE(o.filepath, '/', '_') as newpath
+            FROM gp_dist_random('gp_toolkit.__check_orphaned_files') o
+            JOIN gp_settings s on o.gp_segment_id = s.gp_segment_id
+            WHERE s.name = 'data_directory'
+        ) s2
+    ) q
+    ORDER BY q.gp_segment_id, q.oldpath;
+EXCEPTION
+    WHEN lock_not_available THEN
+        RAISE EXCEPTION 'cannot obtain SHARE lock on pg_class';
+    WHEN OTHERS THEN
+        RAISE;
+END;
+$$;
diff --git a/gpcontrib/gp_toolkit/gp_toolkit.control b/gpcontrib/gp_toolkit/gp_toolkit.control
index b6a2ba832b..8cd45c172d 100644
--- a/gpcontrib/gp_toolkit/gp_toolkit.control
+++ b/gpcontrib/gp_toolkit/gp_toolkit.control
@@ -1,5 +1,5 @@
 # gp_toolkit extension
 
 comment = 'various GPDB administrative views/functions'
-default_version = '1.4'
+default_version = '1.5'
 schema = gp_toolkit


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cloudberry.apache.org
For additional commands, e-mail: commits-help@cloudberry.apache.org