Логическая расшифровка текста двухфазной фиксации в PostgreSQL 14

Обновление: 2 июля 2023 г.

Логическая расшифровка текста двухфазной фиксации в PostgreSQL 14

Команда Fujitsu OSS и сообщество с открытым исходным кодом PostgreSQL объединили усилия, чтобы добавить в PG14 функцию дешифрования двухфазной фиксации при логической репликации. Давайте посмотрим, что это за функция?

фон

Двухфазная фиксация - это механизм, в котором транзакции совершаются в два этапа. Обычно используется в распределенных базах данных для обеспечения согласованности. Две фазы транзакции - это фаза PREPARE и фаза COMMIT / ROLLBACK. Команды, представленные в PG в два этапа:

ПОДГОТОВИТЬ СДЕЛКУ

ОБЯЗАТЕЛЬНО ПОДГОТОВЛЕНО

ОТКАТ ПОДГОТОВЛЕН

PG уже поддерживает двухфазную фиксацию в версии 8.0, а версия 10.0 поддерживает логическую репликацию. Однако двухэтапная фиксация никогда не поддерживалась при логической репликации. Команды PREPARE TRANSACTION, COMMIT PREPARED и ROLLBACK PREPARED поддерживаются в единственном экземпляре, но когда эти команды необходимо логически скопировать на резервную машину, они больше не сохраняют исходное значение. Команда PREPARE TRANSACTION обрабатывается как NOP и вообще не декодируется. Команда COMMIT PREPARED рассматривается как COMMIT, а команда ROLLBACK PREPARED рассматривается как ABORT.

Что такое двухфазная фиксация

Двухфазная фиксация - это протокол атомарной фиксации, который помогает поддерживать согласованность между распределенными базами данных. Обычных коммитов, обеспечивающих атомарность в базе данных, недостаточно для обеспечения согласованности транзакций между базами данных. Чтобы проиллюстрировать эту проблему, приведем пример:

1) У Джона 300 долларов в банке А

2) У Марка 100 $ в банке B

3) Джон хочет перевести 100 $ Марку

Во время транзакции вам необходимо вывести 100 долларов из банка A в банк B. В конце транзакции должно быть 200 долларов. Если какая-либо транзакция не удалась в любой момент во время процесса передачи, статус учетной записи должен быть восстановлен до состояния, которое было до начала передачи. Транзакция может завершиться неудачей по разным причинам. Если какое-либо прерывание произойдет до фиксации транзакции, транзакция будет отменена. В нашем примере, если прерывание происходит, когда счет Джона списывается, то счет Джона порта прерывания не должен уменьшаться. Вот как простая фиксация поддерживает согласованность в базе данных.

Но мы рассматриваем такую ​​ситуацию, то есть транзакция, которая вычитает 100 долларов из учетной записи Джона, является успешной за одну отправку, но транзакция, которая добавляет 100 долларов на счет Марка в банке B, терпит неудачу и откатывается. После завершения этой операции, хотя счет Джона был списан, Марк не получит эту сумму. 100 $ исчезли. При работе с распределенными транзакциями простая фиксация может завершиться ошибкой.

Пошаговое выполнение распределенных транзакций

При двухфазной фиксации одна из баз данных выступает в роли координатора распределенных транзакций.

Этап 1

База данных начинает применять транзакции, а затем готовиться. Он отправляет подготовленные транзакции в другие базы данных в виде подготовленных сообщений. Вторая база данных получает сообщение Prepare, а затем готовит транзакцию. Prepare включает изменения в транзакцию, но не фиксирует. Грязные данные записываются на диск для сохранения. После того, как все базы данных подготовили транзакцию и вся информация о транзакции сохранена на диске, этап подготовки завершен.

Этап 2

Затем арбитр начинает фазу фиксации. Если второй базе данных по какой-либо причине не удается подготовить транзакцию, арбитр начинает фазу отката. Следовательно, в зависимости от того, успешна ли подготовка, транзакция либо фиксируется, либо откатывается. Прерывание на этапе финальной фиксации может быть восстановлено, поскольку требуемая транзакция подготовки была записана на диск и может быть применена повторно.

Двухэтапная фиксация не связана с базами данных с одним экземпляром, но актуальна, когда данные реплицируются в нескольких экземплярах базы данных.

Очень важно поддерживать двухфазную фиксацию при логической репликации.

Функциональный обзор

До версии PG14 транзакции логической репликации декодировались и реплицировались только после фиксации транзакции. Это сделано для того, чтобы избежать прерывания транзакции репликации.

Расшифровать транзакцию при фиксации

Логическая репликация PG14 поддерживает команды PREPARE TRANSACTION, COMMIT PREPARED и ROOLBACK PREPARED. Когда команда PREPARE TRANSACTION декодируется, транзакция декодируется и копируется. PREPARE TRANSACTION запускает воспроизведение и декодирование транзакции так же, как COMMIT в WAL SENDER.

Расшифровка транзакции во время подготовки

Мы также определили новый обратный вызов подключаемого модуля, чтобы подключаемые модули логического декодирования поддерживали двухфазную отправку.

Обратный звонок

описывать

фильтровать_подготовить_кб

Разрешить плагину фильтровать транзакции, которые не нужно декодировать при подготовке, в соответствии с GID, используемым в команде PREPARE TRANSACTION

начать_подготовить_cb

Начало подготовки транзакции

подготовить_cb

Вызывается при декодировании команды PREPARE TRANSACTION

зафиксировать_подготовлено_cb

Вызывается при декодировании команды COMMIT PREPARED

откатподготовлено_cb

Вызывается при декодировании команды ROLLBACK PREPARED

Модификация плагина

тест декодирование

Подключаемый модуль представляет собой подключаемый модуль вывода логического декодирования, в качестве примера, помогающего пользователям разработать собственный подключаемый модуль логического декодирования. test_decoding получает WAL через механизм логического декодирования и декодирует его в текстовое представление выполненной операции.

Он был изменен, чтобы иметь возможность использовать новую двухэтапную функцию обратного вызова и декодировать транзакцию во время подготовки.

Модификация API

pg_create_logical_replication_slot ()

API добавляет новую опцию, чтобы указать, поддерживает ли слот двухфазную фиксацию. Плагин вывода может использовать слот репликации с двухфазной опцией для поддержки двухфазной фиксации.

pg_create_logical_replication_slot (slot_name name , plugin name [временное логическое , двухфазное логическое])

Пример

Давайте посмотрим, как определить декодированный вывод двухфазной транзакции фиксации:

1) Создайте слот репликации

Используйте test_decoding в качестве модуля вывода и передайте значение true, чтобы слот поддерживал двухэтапную отправку и декодирование.

postgres = # SELECT * FROM pg_create_logical_replication_slot ('regression_slot' , test_decoding 'false , true) ;

slot_name | lsn

----------------- + -----------

регрессия слот | 0 / 16B1970

(1 ряд)

2) Создайте таблицу

postgres = # СОЗДАТЬ данные ТАБЛИЦЫ (идентификатор серийного первичного ключа , текст данных) ;

СОЗДАТЬ ТАБЛИЦУ

3) Обнаружение декодированного выходного содержимого транзакции подготовки и фиксации транзакции

postgres = # НАЧАТЬ ;

postgres = * # ВСТАВИТЬ В данные (данные) ЗНАЧЕНИЯ ('5') ;

postgres = * # ПОДГОТОВИТЬ ТРАНЗАКЦИЮ 'test_prepared1' ;

postgres = # ВЫБРАТЬ * ИЗ pg_logical_slot_get_changes ('regression_slot' , NULL , NULL) ;

lsn | xid | данные

----------- + ----- + -----------------

0 / 1689DC 0 | 529 | НАЧАЛО 529

0 / 1689DC0 | 529 | общедоступные данные таблицы : INSERT : id [целое число] : 3 данные [текст] : '5'

0 / 1689FC0 | 529 | PREPARE TRANSACTION 'test_prepared1' , txid 529

(3 ряда)

postgres = # COMMIT PREPARED 'test_prepared1' ;

postgres = # выберите * из pg_logical_slot_get_changes ('regression_slot' , NULL , NULL) ;

lsn | xid | данные

----------- + ----- + ------------------

0 / 168A060 | 529 | COMMIT PREPARED 'test_prepared1' , txid 529

(4 ряда)

postgres = # выбрать * из данных ;

id | данные

---- + ------

1 | 5

(1 ряд)

будущее

Изменение этой функции PG14 имеет инфраструктуру на стороне декодера, которая позволяет двухэтапную подачу декодирования во время подготовки. Мы также изменили плагин test_decoding, чтобы использовать преимущества этой инфраструктуры.

Следующим шагом является реализация двухэтапной поддержки самого большого плагина логического декодирования в PG - плагина pgoutput. Этот плагин поддерживает режим логической репликации ИЗДАТЕЛЬ / ПОДПИСЧИК. Это наиболее широко используемый плагин для логической репликации. Команда Fujitsu OSS работает с сообществом разработчиков ПО с открытым исходным кодом, чтобы добавить эту функцию в PG15.

Для двухфазной транзакции в распределенной базе данных PG также необходимо поддерживать: резервная машина сообщает хосту о сбое PREPARE и инициирует откат. Этот механизм обратной связи не поддерживается в PG и является одним из направлений дальнейшего улучшения.

  Ссылки:

6мби25л-120

м500уз-2ч