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

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

commit 4bd589dc8f461598a06514f786ffe1b59c6a28c1
Author: Ashwin Agrawal <[email protected]>
AuthorDate: Thu May 9 16:56:13 2024 -0700

    Resolve Deadlock: Allow Concurrent Creation of Non-First Index on AO
    
    AlterTableCreateAoBlkdirTable() is being called unconditionally, it
    upgrades ShareLock to ShareRowExclusiveLock hence may result in
    deadlock for concurrent index creation even if block directory is
    present on the append-optimized table. This is regression in 7X
    compared to 6X. As a fix avoiding call to
    AlterTableCreateAoBlkdirTable() if block directory is present which is
    checked already in DefineIndex() with ShareLock held.
    
    Just note: the deadlock case for concurrent index creations in absence
    of block directory (which is initial index) still exists, as in
    absence of block directory, lock upgrade from ShareLock to
    ShareRowExclusiveLock in DefineIndex() still exists and is hard to
    resolve. Existing test concurrent_index_creation_should_not_deadlock
    wasn't testing the scenario correctly. Hence modifying that test to
    only validate for now non-first index creation case.
    
    Reviewed-by: Brent Doil <[email protected]>
---
 src/backend/commands/indexcmds.c                               |  7 +++++--
 .../sql/concurrent_index_creation_should_not_deadlock.sql      | 10 ++++++----
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 09e6ffe253..87d0f5ec2f 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -814,6 +814,8 @@ DefineIndex(Oid relationId,
                                 errmsg("cannot use more than %d columns in an 
index",
                                                INDEX_MAX_KEYS)));
 
+       SIMPLE_FAULT_INJECTOR("defineindex_before_acquire_lock");
+
        /*
         * Only SELECT ... FOR UPDATE/SHARE are allowed while doing a standard
         * index build; but for concurrent builds we allow INSERT/UPDATE/DELETE
@@ -1490,9 +1492,10 @@ DefineIndex(Oid relationId,
 
        /*
         * Create block directory if this is an appendoptimized
-        * relation
+        * relation and one not present currently
         */
-       AlterTableCreateAoBlkdirTable(RelationGetRelid(rel));
+       if (!OidIsValid(blkdirrelid))
+               AlterTableCreateAoBlkdirTable(RelationGetRelid(rel));
 
        /*
         * Make the catalog entries for the index, including constraints. This
diff --git 
a/src/test/isolation2/sql/concurrent_index_creation_should_not_deadlock.sql 
b/src/test/isolation2/sql/concurrent_index_creation_should_not_deadlock.sql
index 1174660c4a..a478ad7c9b 100644
--- a/src/test/isolation2/sql/concurrent_index_creation_should_not_deadlock.sql
+++ b/src/test/isolation2/sql/concurrent_index_creation_should_not_deadlock.sql
@@ -1,15 +1,17 @@
+-- Test to make sure non-first concurrent index creations don't deadlock
 -- Create an append only table, popluated with data
 CREATE TABLE index_deadlocking_test_table (value int) WITH (appendonly=true);
+CREATE INDEX index_deadlocking_test_table_initial_index on 
index_deadlocking_test_table (value);
 
--- Setup a fault to ensure that the first session pauses while creating an 
index,
+-- Setup a fault to ensure that both sessions pauses while creating an index,
 -- ensuring a concurrent index creation.
-SELECT gp_inject_fault('before_acquire_lock_during_create_ao_blkdir_table', 
'suspend', 1);
+SELECT gp_inject_fault('defineindex_before_acquire_lock', 'suspend', 1);
 
 -- Attempt to concurrently create an index
 1>: CREATE INDEX index_deadlocking_test_table_idx1 ON 
index_deadlocking_test_table (value);
-SELECT 
gp_wait_until_triggered_fault('before_acquire_lock_during_create_ao_blkdir_table',
 1, 1);
 2>: CREATE INDEX index_deadlocking_test_table_idx2 ON 
index_deadlocking_test_table (value);
-SELECT gp_inject_fault('before_acquire_lock_during_create_ao_blkdir_table', 
'reset', 1);
+SELECT gp_wait_until_triggered_fault('defineindex_before_acquire_lock', 2, 1);
+SELECT gp_inject_fault('defineindex_before_acquire_lock', 'reset', 1);
 
 -- Both index creation attempts should succeed
 1<:


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to