Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-18404

Setting gtid_binlog_state with non-local server_id does not update gtid_current_pos

Details

    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.

      Attachments

        Issue Links

          Activity

            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.

            knielsen Kristian Nielsen added a comment - 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.

            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.

            GeoffMontee Geoff Montee (Inactive) added a comment - 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.
            Elkin Andrei Elkin added a comment -

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

            Elkin Andrei Elkin added a comment - Fixed with improving documentation https://mariadb.com/kb/en/library/gtid/#gtid_current_pos . GeoffMontee , thanks.

            People

              Elkin Andrei Elkin
              GeoffMontee Geoff Montee (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.