From b1720fc88a14adb8dea854fe1b78896bb58513fe Mon Sep 17 00:00:00 2001 From: Onder Kalaci Date: Wed, 17 Aug 2022 11:31:35 +0200 Subject: [PATCH] acquire lock on a ref table --- .../distributed/utils/reference_table_utils.c | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/backend/distributed/utils/reference_table_utils.c b/src/backend/distributed/utils/reference_table_utils.c index f5720539b..d3a728bb3 100644 --- a/src/backend/distributed/utils/reference_table_utils.c +++ b/src/backend/distributed/utils/reference_table_utils.c @@ -114,13 +114,37 @@ EnsureReferenceTablesExistOnAllNodesExtended(char transferMode) /* * Don't let this table dropped, if dropped retry instead of - * erroring out unless we find 1 table. + * erroring out unless we find 1 table. Move this logic to + * a function where we can find at least 1 ref table and lock + * it, or return InvalidOid. + * + * If returns InvalidOid, we can consider LockColocationId + * on colocationId, because at that point there is not risk of + * deadlock as there are no reference tables to drop. */ - if (!ConditionalLockRelationOid(referenceTableId, AccessShareLock)) + bool foundOneRefTable = false; + foreach_oid(referenceTableId, referenceTableIdList) { - elog(ERROR, "table droppeed concurrently"); + Relation aRefTable = try_relation_open(referenceTableId, AccessShareLock); + if (!aRefTable) + { + /* dropped concurrently*/ + continue; + } + else + { + foundOneRefTable = true; + relation_close(aRefTable, NoLock); + } } + if (!foundOneRefTable) + { + /* no concern for deadlock with DROP ref table as there are no ref tables */ + LockColocationId(colocationId, ShareLock); + } + + /* * Most of the time this function should result in a conclusion where we do not need * to copy any reference tables. To prevent excessive locking the majority of the time