F.44. pgrowlocks
Модуль pgrowlocks предоставляет функцию, показывающую информацию о блокировке строк для заданной таблицы.
По умолчанию его использование разрешено суперпользователям, членам роли pg_stat_scan_tables и пользователям с правом SELECT в заданной таблице.
F.44.1. Обзор
pgrowlocks(text) returns setof record
В параметре передаётся имя таблицы. В результате возвращается набор записей, в котором строка соответствует строке, заблокированной в таблице. Столбцы результата показаны в Таблице F.32.
Таблица F.32. Столбцы результата pgrowlocks
| Имя | Тип | Описание |
|---|---|---|
locked_row | tid | Идентификатор кортежа (TID) блокированной строки |
locker | xid | Идентификатор блокирующей транзакции или идентификатор мультитранзакции, если это мультитранзакция |
multi | boolean | True, если блокирующий субъект — мультитранзакция |
xids | xid[] | Идентификаторы блокирующих транзакций (больше одной для мультитранзакции) |
modes | text[] | Режим блокирования (больше одного для мультитранзакции), массив со значениями Key Share, Share, For No Key Update, No Key Update, For Update, Update. |
pids | integer[] | Идентификаторы блокирующих обслуживающих процессов (больше одного для мультитранзакции) |
Функция pgrowlocks запрашивает блокировку AccessShareLock для целевой таблицы и считывает строку за строкой для сбора информации о блокировке строк. Это происходит небыстро для большой таблицы. Заметьте, что:
Если таблица заблокирована в режиме
ACCESS EXCLUSIVE, функцияpgrowlocksбудет блокироваться.Функция
pgrowlocksне гарантирует внутреннюю согласованность результатов. В ходе её выполнения могут быть установлены новые блокировки строк, либо освобождены старые.
Функция pgrowlocks не показывает содержимое заблокированных строк. Если вы хотите параллельно взглянуть на содержимое строк, можно проделать примерно следующее:
SELECT * FROM accounts AS a, pgrowlocks('accounts') AS p
WHERE p.locked_row = a.ctid;Однако учтите, что такой запрос будет очень неэффективным.
F.44.2. Пример вывода
=# SELECT * FROM pgrowlocks('t1');
locked_row | locker | multi | xids | modes | pids
------------+--------+-------+-------+----------------+--------
(0,1) | 609 | f | {609} | {"For Share"} | {3161}
(0,2) | 609 | f | {609} | {"For Share"} | {3161}
(0,3) | 607 | f | {607} | {"For Update"} | {3107}
(0,4) | 607 | f | {607} | {"For Update"} | {3107}
(4 rows)F.44.3. Автор
Тацуо Исии
F.44. pgrowlocks
The pgrowlocks module provides a function to show row locking information for a specified table.
By default use is restricted to superusers, members of the pg_stat_scan_tables role, and users with SELECT permissions on the table.
F.44.1. Overview
pgrowlocks(text) returns setof record
The parameter is the name of a table. The result is a set of records, with one row for each locked row within the table. The output columns are shown in Table F.32.
Table F.32. pgrowlocks Output Columns
| Name | Type | Description |
|---|---|---|
locked_row | tid | Tuple ID (TID) of locked row |
locker | xid | Transaction ID of locker, or multixact ID if multitransaction |
multi | boolean | True if locker is a multitransaction |
xids | xid[] | Transaction IDs of lockers (more than one if multitransaction) |
modes | text[] | Lock mode of lockers (more than one if multitransaction), an array of Key Share, Share, For No Key Update, No Key Update, For Update, Update. |
pids | integer[] | Process IDs of locking backends (more than one if multitransaction) |
pgrowlocks takes AccessShareLock for the target table and reads each row one by one to collect the row locking information. This is not very speedy for a large table. Note that:
If an
ACCESS EXCLUSIVElock is taken on the table,pgrowlockswill be blocked.pgrowlocksis not guaranteed to produce a self-consistent snapshot. It is possible that a new row lock is taken, or an old lock is freed, during its execution.
pgrowlocks does not show the contents of locked rows. If you want to take a look at the row contents at the same time, you could do something like this:
SELECT * FROM accounts AS a, pgrowlocks('accounts') AS p
WHERE p.locked_row = a.ctid;
Be aware however that such a query will be very inefficient.
F.44.2. Sample Output
=# SELECT * FROM pgrowlocks('t1');
locked_row | locker | multi | xids | modes | pids
------------+--------+-------+-------+----------------+--------
(0,1) | 609 | f | {609} | {"For Share"} | {3161}
(0,2) | 609 | f | {609} | {"For Share"} | {3161}
(0,3) | 607 | f | {607} | {"For Update"} | {3107}
(0,4) | 607 | f | {607} | {"For Update"} | {3107}
(4 rows)
F.44.3. Author
Tatsuo Ishii