Многоверсионность в Postgresql

MVCC — один из механизмов СУБД для обеспечения параллельного доступа к базам данных, заключающийся в предоставлении каждому пользователю «снимка» базы, обладающего тем свойством, что вносимые пользователем изменения невидимы другим пользователям до момента фиксации транзакции ( Википедия )

    Многоверсионность

    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)
    Источники
    Последнее изменение: 11.10.2024 11:50


    Связанные темы
    Здесь пока нет комментариев
    Добавлять комментарии могут только авторизованные пользователи

    Авторизоваться
    Я буду рекламой
    Я тоже буду рекламой
    И я
    ВВЕРХ