diff --git a/bin/pg_repack.c b/bin/pg_repack.c index 03d344a2..97335b5e 100644 --- a/bin/pg_repack.c +++ b/bin/pg_repack.c @@ -1613,7 +1613,7 @@ repack_one_table(repack_table *table, const char *orderby) /* * 5. Swap: will be done with conn2, since it already holds an - * ShareUpdateExclusiveLock lock. + * ShareUpdateExclusiveLock lock. */ elog(DEBUG2, "---- swap ----"); /* Bump our existing ShareUpdateExclusive lock to AccessExclusive */ @@ -1646,22 +1646,16 @@ repack_one_table(repack_table *table, const char *orderby) pgut_command(conn2, "COMMIT", 0, NULL); /* - * 6. Drop. + * 6. Drop temporary objects. We don't need to acquire ACCESS EXCLUSIVE + * lock here since repack_swap() already dropped the repack_trigger trigger. */ elog(DEBUG2, "---- drop ----"); command("BEGIN ISOLATION LEVEL READ COMMITTED", 0, NULL); - if (!(lock_exclusive(connection, utoa(table->target_oid, buffer), - table->lock_table, false))) - { - elog(WARNING, "lock_exclusive() failed in connection for %s", - table->target_name); - goto cleanup; - } - params[1] = utoa(temp_obj_num, indexbuffer); command("SELECT repack.repack_drop($1, $2)", 2, params); command("COMMIT", 0, NULL); + temp_obj_num = 0; /* reset temporary object counter after cleanup */ /* diff --git a/lib/repack.c b/lib/repack.c index a36a0b2c..6aa519b3 100644 --- a/lib/repack.c +++ b/lib/repack.c @@ -1056,6 +1056,7 @@ repack_drop(PG_FUNCTION_ARGS) int numobj = PG_GETARG_INT32(1); const char *relname = get_quoted_relname(oid); const char *nspname = get_quoted_nspname(oid); + bool trigger_exists = true; if (!(relname && nspname)) { @@ -1069,6 +1070,22 @@ repack_drop(PG_FUNCTION_ARGS) /* connect to SPI manager */ repack_init(); + if (numobj > 0) + { + Oid argtypes[1] = { OIDOID }; + bool nulls[1] = { 0 }; + Datum values[1]; + + values[0] = ObjectIdGetDatum(oid); + execute_with_args(SPI_OK_SELECT, + "SELECT tgname" + " FROM pg_trigger" + " WHERE tgrelid = $1 AND tgname = 'repack_trigger'", + 1, argtypes, values, nulls); + + trigger_exists = SPI_processed > 0; + } + /* * To prevent concurrent lockers of the repack target table from causing * deadlocks, take an exclusive lock on it. Consider that the following @@ -1086,14 +1103,9 @@ repack_drop(PG_FUNCTION_ARGS) * * Fixes deadlock mentioned in the Github issue #55. * - * Skip the lock if we are not going to do anything. - * Otherwise, if repack gets accidentally run twice for the same table - * at the same time, the second repack, in order to perform - * a pointless cleanup, has to wait until the first one completes. - * This adds an ACCESS EXCLUSIVE lock request into the queue - * making the table effectively inaccessible for any other backend. + * Skip the lock if we are not going to drop the trigger. */ - if (numobj > 0) + if (numobj > 0 && trigger_exists) { execute_with_format( SPI_OK_UTILITY, @@ -1130,10 +1142,11 @@ repack_drop(PG_FUNCTION_ARGS) */ if (numobj > 0) { - execute_with_format( - SPI_OK_UTILITY, - "DROP TRIGGER IF EXISTS repack_trigger ON %s.%s CASCADE", - nspname, relname); + if (trigger_exists) + execute_with_format( + SPI_OK_UTILITY, + "DROP TRIGGER IF EXISTS repack_trigger ON %s.%s CASCADE", + nspname, relname); --numobj; }