我正在测试MySQL全局事务I( 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;
| |注意,每次提交事务(显式或隐式/自动提交)时,执行的GTID的全局列表都会增加,但会话gtid_owned始终是空的。
我做错了什么?还是我找到窃听器了?
发布于 2018-09-14 14:12:34
客户端只拥有一个仍处于打开状态的事务,因此一旦事务提交,gtid_owned就会被清除。它还显示了一个值,如果您已经显式地为gtid_next设置了一个值;使用gtid_next=automatic不会填充gtid_owned。因此,gtid_owned的使用仅限于某些内部操作,以及在二进制日志中显式设置GTID的复制等情况。
要获得当前会话设置的gtid列表,可以启用session_track_gtids (参见gtids)。
但是,请注意,'mysql‘命令行客户端不报告会话跟踪器返回的值;您需要一个客户机来调用call函数mysql_session_track_get_first()和mysql_session_track_get_next() (参见https://dev.mysql.com/doc/en/mysql-session-track-get-first.html)。
发布于 2018-08-01 08:49:57
我在MySQL 8.0.12中测试它,<= 8.0.12应该有相同的结果。

个人意见,可能有一些错误!
在生成新的GTID以避免重复GTID时使用Gtid_owned和Gtid_executed。Gtid_next会影响使用Gtid_owned的时间。
如果Gtid_next为AUTOMATIC,则在提交阶段事务处于刷新阶段并保存在Gtid_owned中时生成GTID;binlog.cc中的源代码路径为MYSQL_BIN_LOG :: ordered_commit() --> MYSQL_BIN_LOG::process_flush_stage_queue() --> assign_automatic_gtids_to_flush_group;
而Gtid_owned在提交阶段将被删除,源代码也在binlog.cc中,路径是MYSQL_BIN_LOG::process_commit_stage_queue -> Gtid_state::update_commit_group -> update_gtids_impl_own_gtid_set;
因此,在这种情况下无法获得Gtid_owned,因为mysql生成它并在事务的最后阶段清除它;
要获得Gtid_owned的值,只需将Gtid_next设置为精确的gtid,就可以立即将其保存到中(无需源代码检查),这样您就可以正常地检查这个变量,如图所示;
另一张图片,global gtid_owned在#之后保存使用的gtid和客户端的thread_id,上面的图片也显示了thread_id。

https://stackoverflow.com/questions/51432247
复制相似问题