I'm testing some work with MySQL Global Transaction IDs (GTIDs) and I'm having a hard time getting the most-recent session GTID. I've enabled GTIDs (global gtid_mode is set to ON_PERMISSIVE). According to the documentation for gtid_owned:
This read-only variable holds a list whose contents depend on its scope. When used with session scope, the list holds all GTIDs that are owned by this client; ...
So, I expect, after committing a transaction, that this session variable would contain GTIDs; but it is always empty, no matter what I do. However, the global gtid_executed changes every time I commit a transaction, so I know that GTIDs are working.
Here's a session that demonstrates this issue:
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;
| |
Notice that each time a transaction is committed (explicitly or implicitly/autocommit), the global list of executed GTIDs is incremented, but the session gtid_owned is always empty.
What am I doing wrong/missing? Or have I found a bug?
I test it in MySQL 8.0.12, and <= 8.0.12 should have the same results.
Personal opinions, may have some mistakes!
Gtid_ownedandGtid_executedare used when generate a new GTID to avoid a duplicate one. AndGtid_nextaffects the timing to useGtid_owned.If
Gtid_nextisAUTOMATIC, GTID is generated when the transaction is in flush stage in commit phase and saved inGtid_owned; source code path in binlog.cc isMYSQL_BIN_LOG :: ordered_commit() --> MYSQL_BIN_LOG::process_flush_stage_queue() --> assign_automatic_gtids_to_flush_group;And
Gtid_ownedwill be removed in commit stage, source code is in binlog.cc too, the path isMYSQL_BIN_LOG::process_commit_stage_queue -> Gtid_state::update_commit_group -> update_gtids_impl_own_gtid_set;So you can't get the
Gtid_ownedin this situation because mysql generate it and clear it at the final phase of transaction;To get the value of
Gtid_owned, just setGtid_nextto a precise gtid, so it will be saved inGtid_ownedimmediately(without source code checks), so you can check this variable normally as the pic shows;Another pic, the
global gtid_ownedsave the used gtid and the client's thread_id after #, the previous pic shows the thread_id too.