Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions bin/pg_repack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */

/*
Expand Down
35 changes: 24 additions & 11 deletions lib/repack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
{
Expand All @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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;
}

Expand Down