提交事务后,为什么MySQL`gtid_owned`会话变量总是为空?

Nic*_*ams 7 mysql gtid

我正在使用MySQL全局事务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;
|                      |
Run Code Online (Sandbox Code Playgroud)

请注意,每次提交事务(显式或隐式/自动提交)时,执行的GTID的全局列表都会递增,但会话gtid_owned始终为空.

我做错了什么/错过了什么?或者我发现了一个错误?

Wan*_*'an -1

我在 MySQL 8.0.12 中测试它,<= 8.0.12 应该有相同的结果。

gtid_拥有

个人观点,可能有错误!

Gtid_ownedGtid_executed在生成新 GTID 时使用以避免重复。并且Gtid_next影响使用时机Gtid_owned

如果Gtid_nextAUTOMATIC,则在提交阶段事务处于flush阶段时生成GTID并保存在Gtid_owned;binlog.cc 中的源代码路径是MYSQL_BIN_LOG :: ordered_commit() --> MYSQL_BIN_LOG::process_flush_stage_queue() --> assign_automatic_gtids_to_flush_group

并且Gtid_owned会在commit阶段被删除,源代码也在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,这样它就会Gtid_owned立即保存在 中(无需检查源代码),这样您就可以正常检查该变量,如图所示;

另一张图片,global gtid_owned在#后面保存使用的gtid和客户端的thread_id,上一张图片也显示了thread_id。 gti_owned_global