Bug #116789 gtid tags docs don't match actual server behavior
Submitted: 26 Nov 2024 20:44 Modified: 8 Mar 9:30
Reporter: Daniël van Eeden (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Documentation Severity:S1 (Critical)
Version:9.1.0 OS:Any
Assigned to: CPU Architecture:Any
Tags: GTID, gtids, uuid_set

[26 Nov 2024 20:44] Daniël van Eeden
Description:
Page: https://dev.mysql.com/doc/refman/9.1/en/replication-gtids-concepts.html

-------------------------------------------------
GTIDs originating from the same server but having different tags are treated in a manner similar to those originating from different servers, like this:

3E11FA47-71CA-11E1-9E33-C80AA9429562:Domain_1:1-3:15-21, 3E11FA47-71CA-11E1-9E33-C80AA9429562:Domain_2:8-52
-------------------------------------------------

-------------------------------------------------
mysql-9.1.0> reset binary logs and gtids;
Query OK, 0 rows affected (0.03 sec)

mysql-9.1.0> set global gtid_purged='3E11FA47-71CA-11E1-9E33-C80AA9429562:Domain_1:1-3:15-21, 
    '> 3E11FA47-71CA-11E1-9E33-C80AA9429562:Domain_2:8-52';
Query OK, 0 rows affected (0.02 sec)

mysql-9.1.0> show global variables like 'gtid%';
+----------------------------------+-----------------------------------------------------------------------+
| Variable_name                    | Value                                                                 |
+----------------------------------+-----------------------------------------------------------------------+
| gtid_executed                    | 3e11fa47-71ca-11e1-9e33-c80aa9429562:domain_1:1-3:15-21:domain_2:8-52 |
| gtid_executed_compression_period | 0                                                                     |
| gtid_mode                        | ON                                                                    |
| gtid_owned                       |                                                                       |
| gtid_purged                      | 3e11fa47-71ca-11e1-9e33-c80aa9429562:domain_1:1-3:15-21:domain_2:8-52 |
+----------------------------------+-----------------------------------------------------------------------+
5 rows in set (0.00 sec)
-------------------------------------------------

The text from the docs show the UUID part twice, once for each tag. This doesn't match the way this is displayed in gtid_executed as that uses one UUID.

How to repeat:
See description
[27 Nov 2024 5:24] MySQL Verification Team
Hello Daniël,

Thank you for the report and feedback.

regards,
Umesh
[7 Mar 14:46] Daniël van Eeden
This is also not correct:

```
uuid_set:
    uuid:[tag:]interval[:interval]...
```

This should probably be:

```
uuid_set:
    uuid:[[tag:]interval][[tag:]:interval]...
```

Observed from a MySQL v8.4.7 server: `40eb4bee-1972-11f1-acc9-324f96ede8f2:1-3:foobar:1-2`.
This doesn't match the current `uuid_set` definition on https://dev.mysql.com/doc/refman/8.4/en/replication-gtids-concepts.html
[7 Mar 14:53] Daniël van Eeden
Probably more correct: 

uuid_set:
    uuid:[tag:]interval[[tag:]:interval]...
[7 Mar 15:20] Daniël van Eeden
Also wrong:

On https://dev.mysql.com/doc/refman/8.4/en/replication-gtids-concepts.html

```
tag:
    [a-z_][a-z0-9_]{0,31}
```

On https://dev.mysql.com/doc/refman/8.4/en/replication-options-gtids.html#sysvar_gtid_next

```
 The tag must match the regular expression [a-z_][a-z0-9_]{0,7}; in other words, it must conform to the following rules:

    The tag must consist of 1-8 characters (inclusive).

    The first character can be any letter a through z, or an underscore (_).

    Each of the remaining characters can be any of the letters a through z, the digits 0 through 9, or an underscore (_). 

```

32 character tags are accepted on MySQL Server 8.4.7 and with 33 or more I get a `ERROR 1774 (HY000): Malformed GTID specification '%s'.`.
[8 Mar 9:13] Daniël van Eeden
Note that the `Domain_1` and `Domain_2` tags in the documentation don't follow the syntax specification that's on the same page as they contain uppercase letters.

```
$ ipython
Python 3.14.3 (main, Feb  4 2026, 00:00:00) [GCC 15.2.1 20260123 (Red Hat 15.2.1-7)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.37.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import re

In [2]: re.match(r'[a-z_][a-z0-9_]{0,31}','Domain_1')

In [3]: re.match(r'[a-z_][a-z0-9_]{0,31}','domain_1')
Out[3]: <re.Match object; span=(0, 8), match='domain_1'>
```
[8 Mar 9:30] Daniël van Eeden
https://github.com/mysql/mysql-server/blob/447eb26e094b444a88c532028647e48228c3c04f/libs/m...

```
/// @class Tag
/// @brief Representation of the GTID tag
/// @details Tag format: [a-z_]{a-z0-9_}{0,31}
/// Tag may be created from a given text. Text may contain leading and
/// trailing spaces which will be omitted during Tag creation. Text may also
/// contain uppercase characters. Acceptable format for text is as follows:
/// [:space:][a-zA-Z_][a-zA-Z0-9_]{0,31}[:space:]
```

So a tag must match `[a-z_]{a-z0-9_}{0,31}` but can be created from `[:space:][a-zA-Z_][a-zA-Z0-9_]{0,31}[:space:]` by converting it to lowercase and removing leading and trailing whitespace.

Note that multiple spaces or tabs as leading or trailing whitespace seems to be accepted.