Многоверсионность в Postgresql
Многоверсионность
MVCC - обеспечивает изоляцию транзакций для каждого сеанса баз данных
Транзакция обращаясь к таблице , должна видеть только одну из версий каждой строки. В снимках данных видны последние версии зафиксированных данных, незафиксированные данные не видны.
Снимок - это номер последней зафиксированной транзакции на момент создания снимка и список активных транзакций на этот момент
Список нужен для того, чтобы исключить из снимка изменения тех транзакций, которые начались до создания снимка, но еще не были зафиксированы
Версия одной и той же строки таблицы различается временем действия
Например в первой версии эту строку добавили, во второй эту строку изменили, в третьей версии эту строку удалили
Если к одной и той же строке обращаются сразу две транзакции, тогда они выстраиваются в очередь и выполняют действия одна за другой
Читающая транзакция работает с одной версией строки, пишущая транзакция работает с другой версией строки
Каждая версия строки имеет метку времени и тип команды ( insert, delete )
Уровни изоляции транзакций - Read uncommited, Read committed, Repeatable read, Serializable
Для выбора нужного уровня изоляции транзакций используется команда SET TRANSACTION
Стандарт SQL определяет четыре уровня изоляции: чем строже уровень, тем меньше влияния оказывают параллельно работающие транзакции друг на друга.
Read Committed — уровень изоляции транзакции, выбираемый в PostgreSQL по умолчанию
В транзакции, работающей на этом уровне, запрос SELECT видит только те данные, которые были зафиксированы до начала запроса, Однако SELECT видит результаты изменений, внесённых ранее в этой же транзакции, даже если они ещё не зафиксированы.
Команды UPDATE, DELETE, SELECT FOR UPDATE и SELECT FOR SHARE ведут себя подобно SELECT при поиске целевых строк: они найдут только те целевые строки, которые были зафиксированы на момент начала команды. Однако к моменту, когда они будут найдены, эти целевые строки могут быть уже изменены (а также удалены или заблокированы) другой параллельной транзакцией. В этом случае запланированное изменение будет отложено до фиксирования или отката первой изменяющей данные транзакции (если она ещё выполняется).
Источник: https://postgrespro.ru/docs/postgresql/13/transaction-iso
Repeatable Read - снимок строится на момент начала первого оператора транзакциитранзакция может завершиться ошибкой сериализации
Serializable - полная изоляция, но дополнительные накладные расходытранзакция может завершиться ошибкой сериализации
--Создать таблицу
CREATE TABLE t(s text);
--Вставим строку, в данном случае изменения зафиксируются сразу
INSERT INTO t VALUES ('Первая версия');
--Начнем транзакцию и выведем ее номер:
testbase=# BEGIN;
BEGIN
testbase=*# SELECT pg_current_xact_id();
pg_current_xact_id
--------------------
15674
(1 row)
--Транзакция видит первую (и пока единственную) версию строки, xmax = 0 означает, что эта версия актуальна
testbase=*# select *, xmin, xmax from t;
s | xmin | xmax
---------------+-------+------
Первая версия | 15673 | 0
(1 row)
--Изменим строку во второй транзакции
testbase=*# update t SET s = 'Вторая версия';
UPDATE 1
--Вот что получилось
testbase=*# update t SET s = 'Вторая версия';
UPDATE 1
testbase=*# SELECT *, xmin, xmax from t;
s | xmin | xmax
---------------+-------+------
Вторая версия | 15674 | 0
(1 row)
--При этом первая транзакция видит это
testbase=# SELECT *, xmin, xmax FROM t;
s | xmin | xmax
---------------+-------+-------
Первая версия | 15673 | 15674
(1 row)
--Поскольку изменение не зафиксировано, первая транзакция продолжает видеть первую версию строки
--Зафиксируем изменения во второй транзакции
COMMIT;
--После фиксации изменений, первая и вторая транзакция будут видеть одинаковый результат
testbase=# SELECT *, xmin, xmax FROM t;
s | xmin | xmax
---------------+-------+------
Вторая версия | 15674 | 0
(1 row)
Источники
Связанные темы
Буферный кэш и журнал в Postgresql
Системный каталог в Postgresql
Табличные пространства в Postgresql
Определение данных в Postgresql
Основные команды psql и sql Postgresql
Агрегирование и группировка в Postgresql
Основные понятия реляционной модели
Создание и управление кластером postgresql
Системные каталоги в Postgresql