Логическая расшифровка текста двухфазной фиксации в 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 и является одним из направлений дальнейшего улучшения.
Ссылки: