Skip to content

Commit 61bf8ac

Browse files
committed
Use our own namespace for advisory locks.
Switch to using the two-input form of pg_advisory_lock(), so as to avoid impacting other applications which might happen to lock just the OID of the table. The REPACK_LOCK_PREFIX_STR is a decimal version of the first three bytes of echo -n "pg_repack" | sha1sum
1 parent bebe6ff commit 61bf8ac

File tree

1 file changed

+16
-15
lines changed

1 file changed

+16
-15
lines changed

bin/pg_repack.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ const char *PROGRAM_VERSION = "unknown";
126126
" AND granted = false AND relation = %u"\
127127
" AND mode = 'AccessExclusiveLock' AND pid <> pg_backend_pid()"
128128

129+
/* Will be used as a unique prefix for advisory locks. */
130+
#define REPACK_LOCK_PREFIX_STR "16185446"
131+
129132
/*
130133
* per-table information
131134
*/
@@ -1300,8 +1303,10 @@ repack_one_table(const repack_table *table, const char *orderby)
13001303
}
13011304

13021305
/* Release advisory lock on table. */
1303-
res = pgut_execute(connection, "SELECT pg_advisory_unlock($1::bigint)",
1304-
1, params);
1306+
params[0] = REPACK_LOCK_PREFIX_STR;
1307+
params[1] = buffer;
1308+
res = pgut_execute(connection, "SELECT pg_advisory_unlock($1, $2)",
1309+
2, params);
13051310
ret = true;
13061311

13071312
cleanup:
@@ -1452,26 +1457,22 @@ lock_access_share(PGconn *conn, Oid relid, const char *target_name)
14521457
}
14531458

14541459

1455-
/* XXX: Make sure that repack_one_table() also obtains an advisory
1456-
* lock on the table, so that we can't have a table-wide repack running
1457-
* along with an indexes-only repack. Also, since advisory locks are
1458-
* 8 bytes wide and OIDs are only 4 bytes, consider using our own prefix
1459-
* rather than just the table OID, to avoid inadvertent conflict with
1460-
* other applications using advisory locks.
1461-
*/
1462-
14631460
/* Obtain an advisory lock on the table's OID, to make sure no other
14641461
* pg_repack is working on the table. This is not so much a concern with
14651462
* full-table repacks, but mainly so that index-only repacks don't interfere
14661463
* with each other or a full-table repack.
14671464
*/
14681465
static bool advisory_lock(PGconn *conn, const char *relid)
14691466
{
1470-
PGresult *res = NULL;
1471-
bool ret = false;
1467+
PGresult *res = NULL;
1468+
bool ret = false;
1469+
const char *params[2];
1470+
1471+
params[0] = REPACK_LOCK_PREFIX_STR;
1472+
params[1] = relid;
14721473

1473-
res = pgut_execute(conn, "SELECT pg_try_advisory_lock($1::bigint)",
1474-
1, &relid);
1474+
res = pgut_execute(conn, "SELECT pg_try_advisory_lock($1, $2)",
1475+
2, params);
14751476

14761477
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
14771478
elog(ERROR, "%s", PQerrorMessage(connection));
@@ -1790,7 +1791,7 @@ repack_all_indexes(char *errbuf, size_t errsize)
17901791
* table.
17911792
*/
17921793
if (!advisory_lock(connection, utoa(getoid(res, 0, 3), buffer))) {
1793-
snprintf(errbuf, errsize, "Unable to obtain advisory lock on %s",
1794+
snprintf(errbuf, errsize, "Unable to obtain advisory lock on \"%s\"",
17941795
table_name);
17951796
goto cleanup;
17961797
}

0 commit comments

Comments
 (0)