[MDEV-18404] Setting gtid_binlog_state with non-local server_id does not update gtid_current_pos Created: 2019-01-28  Updated: 2019-10-25  Resolved: 2019-07-16

Status: Closed
Project: MariaDB Server
Component/s: Documentation, Replication
Affects Version/s: 10.1.37, 10.2.21, 10.3.12
Fix Version/s: N/A

Type: Bug Priority: Major
Reporter: Geoff Montee (Inactive) Assignee: Andrei Elkin
Resolution: Fixed Votes: 0
Labels: gtid

Issue Links:
Relates
relates to MDEV-18405 Add Mariabackup option to set gtid_sl... Stalled

 Description   

Currently, gtid_binlog_pos can be manually updated by changing gtid_binlog_state.

https://mariadb.com/kb/en/library/gtid/#gtid_binlog_state

Since gtid_current_pos is a union of gtid_binlog_pos and gtid_slave_pos, this also updates gtid_current_pos. For example:

MariaDB [db1]> SHOW GLOBAL VARIABLES WHERE Variable_name IN( 'log_bin', 'server_id', 'gtid_binlog_pos', 'gtid_binlog_state', 'gtid_slave_pos', 'gtid_current_pos' );
+-------------------+------------------+
| Variable_name     | Value            |
+-------------------+------------------+
| gtid_binlog_pos   | 1-1-101,2-1-2002 |
| gtid_binlog_state | 1-1-101,2-1-2002 |
| gtid_current_pos  | 1-1-101,2-1-2002 |
| gtid_slave_pos    |                  |
| log_bin           | ON               |
| server_id         | 1                |
+-------------------+------------------+
6 rows in set (0.001 sec)
 
MariaDB [db1]> RESET MASTER;
Query OK, 0 rows affected (0.005 sec)
 
MariaDB [db1]> SHOW GLOBAL VARIABLES WHERE Variable_name IN( 'log_bin', 'server_id', 'gtid_binlog_pos', 'gtid_binlog_state', 'gtid_slave_pos', 'gtid_current_pos' );
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| gtid_binlog_pos   |       |
| gtid_binlog_state |       |
| gtid_current_pos  |       |
| gtid_slave_pos    |       |
| log_bin           | ON    |
| server_id         | 1     |
+-------------------+-------+
6 rows in set (0.001 sec)
 
MariaDB [db1]> SET GLOBAL gtid_binlog_state='1-1-101,2-1-2002';
Query OK, 0 rows affected (0.005 sec)
 
MariaDB [db1]> SHOW GLOBAL VARIABLES WHERE Variable_name IN( 'log_bin', 'server_id', 'gtid_binlog_pos', 'gtid_binlog_state', 'gtid_slave_pos', 'gtid_current_pos' );
+-------------------+------------------+
| Variable_name     | Value            |
+-------------------+------------------+
| gtid_binlog_pos   | 1-1-101,2-1-2002 |
| gtid_binlog_state | 1-1-101,2-1-2002 |
| gtid_current_pos  | 1-1-101,2-1-2002 |
| gtid_slave_pos    |                  |
| log_bin           | ON               |
| server_id         | 1                |
+-------------------+------------------+
6 rows in set (0.001 sec)

However, there seems to be a bug where gtid_current_pos is not updated if gtid_binlog_state is updated with GTIDs that contain non-local server_id values. Compare the above behavior to the following:

MariaDB [db1]> SHOW GLOBAL VARIABLES WHERE Variable_name IN( 'log_bin', 'server_id', 'gtid_binlog_pos', 'gtid_binlog_state', 'gtid_slave_pos', 'gtid_current_pos' );
+-------------------+------------------+
| Variable_name     | Value            |
+-------------------+------------------+
| gtid_binlog_pos   | 1-1-101,2-1-2002 |
| gtid_binlog_state | 1-1-101,2-1-2002 |
| gtid_current_pos  | 1-1-101,2-1-2002 |
| gtid_slave_pos    |                  |
| log_bin           | ON               |
| server_id         | 1                |
+-------------------+------------------+
6 rows in set (0.001 sec)
 
MariaDB [db1]> RESET MASTER;
Query OK, 0 rows affected (0.005 sec)
 
MariaDB [db1]> SHOW GLOBAL VARIABLES WHERE Variable_name IN( 'log_bin', 'server_id', 'gtid_binlog_pos', 'gtid_binlog_state', 'gtid_slave_pos', 'gtid_current_pos' );
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| gtid_binlog_pos   |       |
| gtid_binlog_state |       |
| gtid_current_pos  |       |
| gtid_slave_pos    |       |
| log_bin           | ON    |
| server_id         | 1     |
+-------------------+-------+
6 rows in set (0.001 sec)
 
MariaDB [db1]> SET GLOBAL gtid_binlog_state='1-2-101,2-2-2002';
Query OK, 0 rows affected (0.005 sec)
 
MariaDB [db1]> SHOW GLOBAL VARIABLES WHERE Variable_name IN( 'log_bin', 'server_id', 'gtid_binlog_pos', 'gtid_binlog_state', 'gtid_slave_pos', 'gtid_current_pos' );
+-------------------+------------------+
| Variable_name     | Value            |
+-------------------+------------------+
| gtid_binlog_pos   | 1-2-101,2-2-2002 |
| gtid_binlog_state | 1-2-101,2-2-2002 |
| gtid_current_pos  |                  |
| gtid_slave_pos    |                  |
| log_bin           | ON               |
| server_id         | 1                |
+-------------------+------------------+
6 rows in set (0.001 sec)

I think that if an update to gtid_binlog_state causes gtid_binlog_pos to be updated, then gtid_current_pos should also be updated--even if the GTIDs didn't contain the local server_id.



 Comments   
Comment by Kristian Nielsen [ 2019-07-15 ]

No, this is wrong. See the documentation of @@gtid_current_pos:

https://mariadb.com/kb/en/library/gtid/#gtid_current_pos

gtid_current_pos is documented to only take from the binlog position those GTIDs with the server's own server_id.

If you want GTIDs from a different server to affect the slave position, just update the gtid_slave_pos at the same time as updating gtid_binlog_state.

Comment by Geoff Montee (Inactive) [ 2019-07-15 ]

Hi knielsen,

No, this is wrong. See the documentation of @@gtid_current_pos:

https://mariadb.com/kb/en/library/gtid/#gtid_current_pos

gtid_current_pos is documented to only take from the binlog position those GTIDs with the server's own server_id.

To be specific, it says this:

For each replication domain, if the server ID of the corresponding GTID in @@gtid_binlog_pos is equal to the servers own server_id, and the sequence number is higher than the corresponding GTID in @@gtid_slave_pos, then the GTID from @@gtid_binlog_pos will be used. Otherwise the GTID from @@gtid_slave_pos will be used for that domain.

Based on this, it wasn't entirely clear what gtid_current_pos would contain for a given domain if gtid_binlog_pos contained a GTID from a different server for that domain, and if gtid_slave_pos contained no GTID for that domain. I assumed that gtid_current_pos would use the GTID from gtid_binlog_pos for that domain. I just did a test, and I can see that gtid_current_pos actually does not use any GTID for that domain.

For example:

MariaDB [(none)]> SHOW GLOBAL VARIABLES WHERE Variable_name IN('server_id', 'gtid_binlog_pos', 'gtid_slave_pos', 'gtid_current_pos');
+------------------+--------------+
| Variable_name    | Value        |
+------------------+--------------+
| gtid_binlog_pos  | 1-1-95,3-1-1 |
| gtid_current_pos |              |
| gtid_slave_pos   |              |
| server_id        | 2            |
+------------------+--------------+
4 rows in set (0.001 sec)

So I've clarified the documentation by adding this:

GTIDs from gtid_binlog_pos in which the server_id of the GTID is not equal to the server's own server_id are effectively ignored. If gtid_binlog_pos contains a GTID for a given replication domain, but the server_id of the GTID is not equal to the server's own server_id, and gtid_slave_pos does not contain a GTID for that given replication domain, then gtid_current_pos will not contain any GTID for that replication domain.

Comment by Andrei Elkin [ 2019-07-16 ]

Fixed with improving documentation https://mariadb.com/kb/en/library/gtid/#gtid_current_pos. GeoffMontee, thanks.

Generated at Thu Feb 08 08:43:50 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.