Почему переменная сеанса 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.

Другие вопросы по тегам