Особенности Pangolin в сравнении с Oracle Database
Счетчик транзакций
Емкость счетчика номеров-идентификаторов транзакций в Pangolin — всего 32 бита, поэтому количество номеров отслеживаемых транзакций ограничено. Доступно примерно четыре миллиарда значений, порядка двух миллиардов транзакций до текущего номера и порядка двух миллиардов - после. Если не «переносить в историю» активности транзакций, то сервер примет примерно два миллиарда транзакций и перейдет в READ ONLY
по всему кластеру баз.
Процесс «перехода в историю» транзакций (freezing) описан в разделе Заморозка (перенос в историю) транзакций. Его цель – высвободить номер транзакции, делая старый идентификатор доступным для новых транзакций.
Не получится «заморозить» любую из транзакций в «горизонте событий». Пока есть хотя бы одна транзакция старше рассматриваемой, требуется в остальных транзакциях отслеживать видимость данных, измененных рассматриваемой транзакцией. Старшие транзакции должны видеть данные «до» нее, а младшие — «после». Для отслеживания видимости данных номера должны сохраняться при всех транзакциях горизонта вне зависимости от статуса – активны они, бездействуют, приняты или отменены.
Поскольку номера транзакций — ценный ресурс, рекомендуется всегда избегать длительных и бездействующих транзакций. Крайне рекомендуется исключить длительные транзакции в те пиковые моменты, когда выполняется большое количество транзакций, быстро меняющих данные. Самая старая из активных транзакций, пока она существует, удерживает нижнюю границу горизонта событий базы, «растягивает» пространство используемых идентификаторов. Ни одна из транзакций младше нее не может «уйти в историю» (быть заморожена). Накопление двух миллиардов не замороженных транзакций приводит к переполнению счетчика транзакций («оборот» или wraparound). По базе в состоянии wraparound невозможно добавить транзакцию, она доступна только на чтение.
Борьба с продолжительными транзакциями
В Pangolin и PostgreSQL нет знакомого по Oracle отдельного пространства для хранения истории модификаций, UNDO tablespace. Механизмы, похожие на Automatic Undo Management (AUM) — намного сложнее. Единый параметр, подобный undo_retention
– есть, но действует он по-другому.
Зато в руках АБД Pangolin есть четыре параметра, которые помогают бороться с длительными и бездействующими транзакциями, а также с длительными запросами. Помогают они в том случае, когда разработка приложения помочь не в состоянии.
old_snapshot_threshold
— максимальное астрономическое время удержания снимка операции, в часах, минутах, секундах. Если снимок существует дольше указанного времени, то сервер считает приемлемой очистку тех версий истории записей, которые могли бы понадобиться этому снимку. Если длительная транзакция все-таки попробует к ним обратиться, то она получит ошибкуsnapshot too old
. Причины и эффект этой ошибки будут такими же, как у знакомой по Oracle ORA-01555. Поэтому параметр очень похож наundo_retention
— и по размерности (время), и по эффектам.idle_in_transaction_session_timeout
— максимальная продолжительность бездействия транзакции. По истечению заданного времени транзакция будет отменена.statement_timeout
— максимальная длительность выполнения оператора, при превышении которой оператор будет прерван.lock_timeout
— максимальная длительность ожидания получения блокировки таблицы, индекса, строки или другого объекта базы данных, при превышении которой оператор будет прерван.
Индексы
Индексы в Pangolin не хранят информацию о сроке действия и видимости записей таблицы. В них записаны равноправные ссылки на каждую из версий записи, хранимых в таблице. Среди этих версий есть как действующие, так и устаревшие, причем различить их можно только при посещении таблицы. Частный случай — когда вся страница (бл ок) таблицы отмечена в карте видимости таблицы как полностью видимая, тогда по ссылкам на эту страницу все записи точно действительны. Эта особенность используется для строгого индексного сканирования таблицы.
А где же Flashback?
Архитектурное решение, выбранное в PostgreSQL и Pangolin для хранения снимков операций, отодвигает на границы возможного реализации знакомых по Oracle технологий семейства Flashback. Эти технологии позволяют осмотреть историю версий данных по транзакциям (Flashback Transaction Query), получить снимок произвольно выбранной по номеру транзакции и выполнить «с ее точки зрения» произвольный запрос (Flashback Query), восстановить историческое состояние на любую транзакцию для таблицы (Flashback Table) и для БД (Flashback Database). Здесь, даже если история версий данных на последний миллиард транзакций еще доступна, крайне сложно осмотреть массив снимков (они хранятся вместе с транзакциями в процессах-сессиях) и сконструировать снимок данных с точки зрения произвольной транзакции (не хранится история списков активных транзакций на произвольный момент в прошлом).
В широком доступе реализации возможностей Flashback для PostgreSQL неизвестны.
Есть два исключения из общего правила:
- Параллельные потоки
pg_dump
выгружают согласованный образ базы благодаря возможности экспортировать снимок из транзакции потока-координатора и импортировать его в транзакциях потоков-исполнителях. Эти возможности открыты и доступны разработчикам приложений через документированный интерфейс pg_export_snapshot. - Процессы-обработчики параллельного шага в плане запроса клонируют снимок операции из вызывающей сессии, после чего по копии снимка выбирают данные, согласованные с вызывающей сессией.
Однако, в обоих случаях копируются заранее подготовленные снимки. Появление возможности для получения снимков с точки зрения произвольных транзакций – возможное направление для развития PostgreSQL.
Идентификация транзакций
В отличие от Oracle, Pangolin не имеет подобного SCN единого идентификатора транзакции, действительного одновременно в памяти экземпляра, в объектах на диске и в журнале повтора (предзаписи). Здесь номер транзакции XID никак не связан с адресом изменений транзакции в журнале WAL. Указатель на позицию в журнале WAL - другой идентификатор, Log Sequence Number или LSN, он же – последовательный номер транзакции в журнале. Искусственно связать идентификатор xid (транзакция MVCC) с LSN (запись журнала WAL) можно только при запуске логической репликации.
XID не связан и с астрономическим временем. Постоянной таблицы соответствия между XID и временем в секундах тоже нет.
Есть параметр сервера track_commit_timestamp
, который включает запись астрономического времени. Но записывается здесь только момент фиксации транзакции. Подробное описание в разделе «20.6. Репликация» в стандартной документации.
Только при включенном track_commit_timestamp
можно использовать аналоги функций SCN_TO_TIMESTAMP()
и TIMESTAMP_TO_SCN()
:
pg_xact_commit_timestamp ( xid ) → timestamp with time zone
– выдает время фиксации транзакции.pg_last_committed_xact () → record ( xid xid, timestamp timestamp with time zone )
– выдает идентификатор и время фиксации транзакции, зафиксированной последней.
Вторая функция может показать только последнюю зафиксированную транзакцию – произвольный момент времени не указать.