XA Transactions
Обзор
Реализация XA в MariaDB основана на документе X/Open CAE Distributed Transaction Processing: The XA Specification. Этот документ опубликован The Open Group и доступен по адресу http://www.opengroup.org/public/pubs/catalog/c193.htm.
Транзакции XA предназначены для поддержки распределённых транзакций, где менеджер транзакций (приложение) контролирует транзакцию, включающую несколько ресурсов. Такие ресурсы обычно представляют собой СУБД, но могут быть и любого другого типа. Совокупность необходимых транзакционных операций называется глобальной транзакцией. Каждая подгруппа операций, относящихся к одному ресурсу, называется локальной транзакцией. XA использует двухфазный протокол подтверждения (2PC). Во время первой фазы менеджер транзакций запрашивает от каждого ресурса подготовку к подтверждению, ожидая подтверждения. Изменения в этом пункте ещё не выполняются. Если какой-либо из ресурсов обнаружит ошибку, менеджер транзакций откатит глобальную транзакцию. Если все ресурсы сообщают об успешном завершении первой фазы, менеджер транзакций может запустить вторую фазу, которая делает изменения действительными.
В MariaDB транзакции XA могут использоваться только с хранилищами данных, которые их поддерживают. Их поддерживают, по крайней мере, InnoDB, TokuDB, SPIDER и MyRocks. Для InnoDB до версии MariaDB 10.2, транзакции XA можно было отключить, установив системную переменную сервера innodb_support_xa в 0. Начиная с MariaDB 10.3, транзакции XA всегда поддерживаются.
Как и обычные транзакции, транзакции XA создают блокировки метаданных на используемых таблицах.
Транзакции XA требуют REPEATABLE READ как минимальный уровень изоляции. Однако для распределённых транзакций всегда следует использовать SERIALIZABLE.
Попытка начать более одной XA транзакции одновременно приводит к ошибке 1400 (SQLSTATE 'XAE09'). Такая же ошибка возникает при попытке начать XA транзакцию, когда уже выполняется обычная транзакция. Попытка начать обычную транзакцию, когда активна XA транзакция, приводит к ошибке 1399 (SQLSTATE 'XAE07').
Выполнение операций, вызывающих неявное подтверждение COMMIT для обычных транзакций приводит к ошибке 1400 (SQLSTATE 'XAE09'), если активна XA транзакция.
Внутреннее XA против внешнего XA
Термин "XA транзакции" в MariaDB многозначен. Если хранилище данных поддерживает XA, это может означать одно или оба из следующего:
- Поддержка внутреннего двухфазного протокола подтверждения MariaDB. Это прозрачно для пользователя. Иногда это называют "внутренним XA", так как внутренний журнал координатора транзакций MariaDB может обрабатывать координацию этих транзакций.
- Поддержка XA транзакций с использованием операторов
XA START,XA PREPARE,XA COMMIT, и т.д. Иногда это называют "внешним XA", так как для правильного использования этой функции требуется внешний координатор транзакций.
Журнал координатора транзакций
Если у вас включено два или более хранилищ данных, поддерживающих XA, должен быть доступен журнал координатора транзакций.
В настоящее время существуют две реализации журнала координатора транзакций:
- Журнал координатора транзакций на основе бинарного лога
- Журнал координатора транзакций на основе файлов с памятью-мапой
Если на сервере включён бинарный лог, сервер будет использовать журнал координатора транзакций на основе бинарного лога. В противном случае будет использоваться журнал координатора транзакций на основе файлов с памятью-мапой.
См. Журнал координатора транзакций для получения дополнительной информации.
Синтаксис
XA {START|BEGIN} xid [JOIN|RESUME]
XA END xid [SUSPEND [FOR MIGRATE]]
XA PREPARE xid
XA COMMIT xid [ONE PHASE]
XA ROLLBACK xid
XA RECOVER [FORMAT=['RAW'|'SQL']]
xid: gtrid [, bqual [, formatID ]]
Интерфейс для XA транзакций — это набор SQL-команд, начинающихся с XA. Каждая команда изменяет состояние транзакции, определяя, какие действия она может выполнять. Транзакция, которая не существует, находится в состоянии NON-EXISTING.
XA START (или BEGIN ) запускает транзакцию и определяет её xid (идентификатор транзакции). Ключевые слова JOIN или RESUME не имеют эффекта. Новая транзакция будет находиться в состоянии ACTIVE.
xid может состоять из 3 компонентов, хотя только первый является обязательным. gtrid — это строка в кавычках, представляющая глобальный идентификатор транзакции. bqual — это строка в кавычках, представляющая локальный идентификатор транзакции. formatID — это целое без знака, указывающее формат, используемый для первых двух компонентов; если не указано, по умолчанию равно 1. MariaDB никак не интерпретирует эти компоненты и использует их только для идентификации транзакции. xid транзакций, находящихся в активном состоянии, должны быть уникальными.
XA END объявляет, что указанная ACTIVE транзакция завершена, и изменяет её состояние на IDLE. SUSPEND [FOR MIGRATE] не имеет эффекта.
XA PREPARE подготавливает IDLE транзакцию к подтверждению, изменяя её состояние на PREPARED. Это первая фаза подтверждения.
XA COMMIT окончательно подтверждает и завершает транзакцию, которая уже PREPARED. Если указан ONE PHASE параметр, эта команда выполняет однофазное подтверждение IDLE транзакции.
XA ROLLBACK откатывает и завершает IDLE или PREPARED транзакцию.
XA RECOVER отображает информацию обо всех PREPARED транзакциях.
При попытке выполнить операцию, запрещённую для текущего состояния транзакции, возникает ошибка:
XA COMMIT 'test' ONE PHASE; ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state XA COMMIT 'test2'; ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the NON-EXISTING state
XA ВОССТАНОВЛЕНИЕ
Команда XA RECOVER отображает информацию о всех транзакциях, которые находятся в состоянии PREPARED. Неважно, какая соединение создало транзакцию: если она была PREPARED, она отображается. Но это не означает, что соединение может подтвердить или отменить транзакцию, начатую другим соединением. Обратите внимание, что транзакции, использующие однофазное подтверждение, никогда не находятся в состоянии PREPARED, поэтому их невозможно отобразить с помощью XA RECOVER.
XA RECOVER выводит четыре столбца:
XA RECOVER; +----------+--------------+--------------+------+ | formatID | gtrid_length | bqual_length | data | +----------+--------------+--------------+------+ | 1 | 4 | 0 | test | +----------+--------------+--------------+------+
Вы можете использовать XA RECOVER FORMAT='SQL' для получения данных в удобочитаемом формате, который можно скопировать и вставить в XA COMMIT или XA ROLLBACK. Это особенно полезно для бинарных xid, созданных некоторыми координаторами транзакций.
formatID — formatID часть xid.
data — это gtrid и bqual части xid, конкатенированные.
gtrid_length и bqual_length — длины gtrid и bqual, соответственно.
Примеры
Двухфазное подтверждение:
XA START 'test'; INSERT INTO t VALUES (1,2); XA END 'test'; XA PREPARE 'test'; XA COMMIT 'test';
Однофазное подтверждение:
XA START 'test'; INSERT INTO t VALUES (1,2); XA END 'test'; XA COMMIT 'test' ONE PHASE;
Удобный для чтения формат:
xa start '12\r34\t67\v78', 'abc\ndef', 3; insert t1 values (40); xa end '12\r34\t67\v78', 'abc\ndef', 3; xa prepare '12\r34\t67\v78', 'abc\ndef', 3; xa recover format='RAW'; +----------+--------------+--------------+--------------------+ | formatID | gtrid_length | bqual_length | data | +----------+--------------+--------------+--------------------+ 34 67v78abc 11 | 7 | 12 def | +----------+--------------+--------------+--------------------+ xa recover format='SQL'; +----------+--------------+--------------+-----------------------------------------------+ | formatID | gtrid_length | bqual_length | data | +----------+--------------+--------------+-----------------------------------------------+ | 3 | 11 | 7 | X'31320d3334093637763738',X'6162630a646566',3 | +----------+--------------+--------------+-----------------------------------------------+ xa rollback X'31320d3334093637763738',X'6162630a646566',3;
Известные проблемы
Кластер MariaDB Galera
Кластер MariaDB Galera не поддерживает транзакции XA.
Однако сборки MariaDB Galera Cluster включают встроенный плагин под названием wsrep. До MariaDB 10.4.3 этот плагин внутренне считался хранилищем данных, поддерживающим XA. Вследствие этого, эти сборки MariaDB Galera Cluster по умолчанию имеют несколько хранилищ данных, поддерживающих XA, даже если единственным «настоящим» хранилищем данных, поддерживающим внешние XA транзакции, включённым по умолчанию в эти сборки, является InnoDB. Таким образом, при использовании одной из этих сборок MariaDB по умолчанию будет принудительно использовать журнал координатора транзакций, что может повлиять на производительность.
См. Обзор журнала координатора транзакций: MariaDB Galera Cluster для получения дополнительной информации.
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/xa-transactions/