Как мне реализовать MVCC?

Я нашел много ресурсов в Интернете, дающих общие обзоры концепций MVCC (многоуровневое управление параллелизмом), но нет подробных технических ссылок о том, как именно это должно работать или реализовываться. Существуют ли какие-либо документы в Интернете или книги в автономном режиме, которые содержат достаточно теории (и, в идеале, немного практической помощи), на которой можно основывать реализацию? Я хочу более или менее подражать тому, что делает PostgreSQL.

(Для информации, я буду реализовывать его в SAS с использованием SAS /Share - который предоставляет некоторые блокирующие примитивы и одновременный доступ для чтения / записи к базовому хранилищу данных, но ничего в плане изоляции транзакций или надлежащих функций СУБД. Если кто-то знаком с SAS / поделитесь и считает это невыполнимой задачей, пожалуйста кричите!)

4 ответа

Решение

Я написал сообщение в блоге об этом:

https://elliot.silvrback.com/implementing-your-own-transactions-with-mvcc

Я написал сообщение в блоге о том, как MVCC работает в PostgreSQL. По сути, таблица в PostgreSQL может хранить несколько версий одной и той же строки.

Более того, есть две дополнительные колонки:

  • tmin - маркировка идентификатора транзакции, которая вставила строку
  • tmax - маркировка идентификатора транзакции, которая удалила строку

Обновление выполняется путем удаления и вставки новой записи, и процесс VACUUM собирает старые версии, которые больше не используются.

Я реализовал MVCC на Java. Смотрите транзакцию , бегун и код mvcc .

Представьте, что каждая транзакция получает числовую метку времени, которая увеличивается для каждой транзакции. В этом примере у нас есть транзакции 1 и 2.

Транзакция 1 читает A и записывает значение (A + 1). Изоляция снимка создает временную версию (A), которой владеет транзакция 1. Временная метка чтения A устанавливается на транзакцию 1.

Если транзакция 2 появится в то же время и прочитает A, она также прочитает зафиксированную A — она не увидит A + 1, потому что она не была зафиксирована. Транзакция 2 может видеть версии A, которые == lastCommittedA и <= transaction 2.

Когда транзакция 2 читает A, она также проверит метку времени чтения A и увидит, что транзакция 1 существует, и проверит метку времени транзакции 1 < метку времени транзакции 2. Поскольку 1 < 2, транзакция 2 будет прервана, поскольку она уже зависит от старого значения A.

Другие вопросы по тегам