Почему переменная сеанса MySQL `gtid_owned` всегда пуста после совершения транзакции?
Я тестирую некоторую работу с MySQL Global Transaction ID (GTID), и мне трудно получить самый последний сеанс GTID. Я включил GTID (глобальный gtid_mode
установлен в ON_PERMISSIVE
). Согласно документации дляgtid_owned
:
Эта переменная только для чтения содержит список, содержимое которого зависит от области его действия. При использовании с областью сеанса список содержит все GTID, которые принадлежат этому клиенту; ...
Итак, я ожидаю после совершения транзакции, что эта переменная сеанса будет содержать GTID; но это всегда пусто, независимо от того, что я делаю. Тем не менее, глобальный gtid_executed
меняется каждый раз, когда я совершаю транзакцию, поэтому я знаю, что GTID работают.
Вот сеанс, который демонстрирует эту проблему:
mysql> SELECT @@global.gtid_executed;
| a1c32161-89c4-11e8-856e-0242ac12001d:1-4 |
mysql> SELECT @@session.gtid_next;
| AUTOMATIC |
mysql> SELECT @@session.gtid_owned;
| |
mysql> START TRANSACTION;
mysql> SELECT @@global.gtid_executed;
| a1c32161-89c4-11e8-856e-0242ac12001d:1-4 |
mysql> SELECT @@session.gtid_next;
| AUTOMATIC |
mysql> SELECT @@session.gtid_owned;
| |
mysql> INSERT INTO ........
mysql> SELECT @@global.gtid_executed;
| a1c32161-89c4-11e8-856e-0242ac12001d:1-4 |
mysql> SELECT @@session.gtid_next;
| AUTOMATIC |
mysql> SELECT @@session.gtid_owned;
| |
mysql> COMMIT;
mysql> SELECT @@global.gtid_executed;
| a1c32161-89c4-11e8-856e-0242ac12001d:1-5 |
mysql> SELECT @@session.gtid_next;
| AUTOMATIC |
mysql> SELECT @@session.gtid_owned;
| |
mysql> INSERT INTO ........
mysql> SELECT @@global.gtid_executed;
| a1c32161-89c4-11e8-856e-0242ac12001d:1-6 |
mysql> SELECT @@session.gtid_next;
| AUTOMATIC |
mysql> SELECT @@session.gtid_owned;
| |
Обратите внимание, что каждый раз, когда транзакция фиксируется (явно или неявно /autocommit), глобальный список выполненных GTID увеличивается, но сеанс gtid_owned
всегда пусто
Что я делаю неправильно / отсутствует? Или я нашел ошибку?
2 ответа
Клиент владеет только открытой транзакцией, поэтому gtid_owned
очищается после фиксации транзакции. Он также показывает значение, только если вы явно установили его для gtid_next
; с помощью gtid_next=automatic
не будет заселяться gtid_owned
, Использование gtid_owned
поэтому ограничен некоторыми внутренними операциями и случаями, такими как репликация, где GTID явно установлен в двоичном журнале.
Чтобы получить список gtids, установленных текущим сеансом, вы можете включить session_track_gtids
(см. https://dev.mysql.com/doc/en/server-system-variables.html).
Однако обратите внимание, что клиент командной строки 'mysql' не сообщает о значениях, возвращаемых трекером сеанса; вам нужен клиент, который позволяет вам вызывать функции C API mysql_session_track_get_first()
а также mysql_session_track_get_next()
(см. https://dev.mysql.com/doc/en/mysql-session-track-get-first.html).
Я тестирую его в MySQL 8.0.12, и <= 8.0.12 должен иметь те же результаты.
Личное мнение, могут быть ошибки!
а также
Gtid_executed
используются при создании нового GTID, чтобы избежать дублирования. И влияет на время использования.
Если есть
AUTOMATIC
, GTID генерируется, когда транзакция находится на стадии сброса в фазе фиксации и сохраняется в ; путь к исходному коду в binlog.cc
MYSQL_BIN_LOG :: ordered_commit() --> MYSQL_BIN_LOG::process_flush_stage_queue() --> assign_automatic_gtids_to_flush_group
;
И будет удален на этапе коммита, исходный код тоже есть в binlog.cc, путь
MYSQL_BIN_LOG::process_commit_stage_queue -> Gtid_state::update_commit_group -> update_gtids_impl_own_gtid_set
;
Таким образом, вы не можете получить в этой ситуации, потому что mysql генерирует его и очищает на заключительном этапе транзакции;
Чтобы получить значение , просто установите
Gtid_next
на точный gtid, поэтому он будет сохранен в
Gtid_owned
немедленно (без проверки исходного кода) , поэтому вы можете проверить эту переменную в обычном режиме, как показано на рисунке;
Еще одна картинка, т.
global gtid_owned
сохраните используемый gtid и thread_id клиента после #, на предыдущем рисунке также показан thread_id.