Транзакция со снимком данных (transaction snapshot) PostgreSQL
Транзакция со снимком данных - это набор данных, в котором хранится информация о том, все ли транзакции активны в определенный момент времени для отдельной транзакции. В данном случае активная транзакция означает, что она находится в процессе или еще не началась.
PostgreSQL внутренне определяет формат текстового представления транзакций со снимком данных как '100:100:'. Например, '100:100:' означает, что "txid, которые меньше 99, не активны, а txis, которые равны или больше 100, активны".
Встроенная функция pg_current_snapshot и формат ее текстового представления
Функция pg_current_snapshot отображает моментальный снимок текущей транзакции.
testdb=# SELECT pg_current_snapshot(); pg_current_snapshot ---------------------
100:104:100,102 (1 row)
В текстовом виде txid_snapshot представляется как xmin:xmax:xip_list, компоненты rjnjhjuj описываются следующим образом:
-
xmin
Минимальный номер активной транзакции на момент создания снимка .Все предыдущие транзакции будут либо выполнены и видны, либо откатаны назад и стунт «мертвыми». -
xmax
Максимальный (еще пока не выданный) номер транзакции Все txid, превышающие или равные этому значению, не запущены на момент моментального снимка и поэтому невидимы. -
xip_list
Список номеров транзакций, активных на момент создания снимка: В список включены только активные txid между xmin и xmax.
Например, в моментальном снимке '100:104:100,102' xmin равен '100', xmax '104', а xip_list '100,102'.
Примеры моментальных снимков (рис. 55)
Первый пример - '100:100:'. Этот снимок означает следующее (рис. 55a):
- txid, равные или меньше 99 не активны, потому что xmin равен 100.
- txid, равные или превышающие 100, активны, поскольку xmax равен 100.
Второй пример - '100:104:100,102'. Этот снимок означает следующее (рис. 55b):
- txid, равные или меньше 99, не активны.
- txid, равные 104 или более, активны.
- txid 100 и 102 активны, поскольку они есть в списке xip, в то время как txid 101 и 103 не активны.
С помощью менеджера транзакций можно получить моментальные снимки транзакций. На уровне изоляции Read Committed снимок создается в начале каждого оператора транзакции. Такой снимок активен, пока выполняется оператор. Снимок транзакции Repeatable Read фактически создается в начале первой команды запроса или изменения данных (SELECT, INSERT, UPDATE или DELETE). Полученный снимок транзакции используется для проверки видимости кортежей, которая подробно описана в разделе 5.7.
При использовании полученного снимка для проверки видимости активные транзакции в снимке должны рассматриваться как выполняющиеся, даже если на самом деле они были выполнены или прерваны.
Работа менеджера транзакций отображена на рисунке ниже.
Менеджер транзакций хранит информацию о текущих транзакциях. Предположим, что три транзакции происходят одна за другой, при этом уровень изоляции транзакций Транзакция_A и Транзакция_B - READ COMMITTED, а Транзакция_C - REPEATABLE READ.
- T1:
Транзакция_A запускает и выполняет первую команду SELECT. При выполнении первой команды Transaction_A запрашивает txid и снимок этого момента.
В этом сценарии менеджер транзакций присваивает транзакции txid 200 и возвращает моментальный снимок транзакции '200:200:'.
- T2:
Транзакция_B запускает и выполняет первую команду SELECT. Менеджер транзакций присваивает ей txid 201 и возвращает снимок транзакции '200:200:', поскольку транзакция_A (txid 200) находится в процессе выполнения. Таким образом, транзакция_A не видна транзакции_B.
- T3:
Транзакция_C запускает и выполняет первую команду SELECT. Менеджер транзакций присваивает ей txid 202 и возвращает моментальный снимок транзакции '200:200:', таким образом, транзакция_A и транзакция_B не видны транзакции_C.
- T4:
Транзакция_A выполнена. Менеджер транзакций удаляет всю информацию, касающуюся данной транзакции.
- T5:
Транзакция_B и Транзакция_C выполняют команды SELECT.
Транзакция_B требуется моментальный снимок, поскольку ее уровень изоляции - READ COMMITTED.
В данном случае Транзакция_B получает новый снимок '201:201:', потому что Транзакция_A (txid 200) была зафиксирована. Таким образом, Транзакция_A становится видимой для Транзакции_B. Транзакции_C не требуется снимок транзакции, поскольку ее уровень изоляции - REPEATABLE READ, ее моментальный снимок - '200:200:'. Таким образом, Транзакция_A по-прежнему не видна Транзакции_C.





