There was a long-running transaction consisting of two queries:

    CREATE TEMPORARY TABLE abc AS SELECT * FROM def_view;
    INSERT INTO xyz_table SELECT * FROM abc;

When I ran VACUUM FULL pg_class, it waited for ShareLock on that
transaction:

postgres=# select * from pg_locks where pid = 29563;
   locktype    | database |  relation  | page | tuple | virtualxid |
transactionid | classid | objid | objsubid | virtualtransaction |  pid  |
     mode         | granted | fastpath
---------------+----------+------------+------+-------+------------+---------------+---------+-------+----------+--------------------+-------+---------------------+---------+----------
 virtualxid    |          |            |      |       | 414/5739   |
        |         |       |          | 414/5739           | 29563 |
ExclusiveLock       | t       | t
 relation      |    16517 |       1259 |      |       |            |
        |         |       |          | 414/5739           | 29563 |
ShareLock           | t       | f
 relation      |    16517 |       1259 |      |       |            |
        |         |       |          | 414/5739           | 29563 |
AccessExclusiveLock | t       | f
 relation      |    16517 | 1325035831 |      |       |            |
        |         |       |          | 414/5739           | 29563 |
AccessExclusiveLock | t       | f
 transactionid |          |            |      |       |            |
113559773 |         |       |          | 414/5739           | 29563 |
ExclusiveLock       | t       | f
 transactionid |          |            |      |       |            |
113551212 |         |       |          | 414/5739           | 29563 |
ShareLock           | f       | f
 relation      |    16517 |       2662 |      |       |            |
        |         |       |          | 414/5739           | 29563 |
AccessExclusiveLock | t       | f
(7 rows)

Why?
What's more interesting is that from time to time vacuum succeeded despite
the fact that the long-running transaction was still running.

I tried to reproduce it by simulating the long-running transaction, and
running VACUUM FULL pg_class in another transaction, but to no avail:

psql #1:
q=# CREATE TABLE demo AS SELECT generate_series(1, 1000);
SELECT 1000
q=# CREATE VIEW demo_view AS SELECT * FROM demo;
CREATE VIEW
q=# CREATE TABLE result (val BIGINT);
CREATE TABLE

q=# BEGIN;
BEGIN
q=*# CREATE TEMP TABLE abc AS SELECT * FROM demo_view;
SELECT 1000
q=*# INSERT INTO result SELECT * FROM abc;
INSERT 0 1000
q=*#

psql #2:
q=# VACUUM FULL pg_class;
VACUUM

--
Regards,
Marcin Barczynski

Reply via email to