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

mysqldump --master-data does not work with GTID setups

Details

    Description

      mysqldump --master-data (or --dump-slave) is a usual way to provision a new
      slave from an existing master or slave. But this is not able to provision a
      GTID slave, as the GTID is not available in the output.

      Proposed solution is to add a --gtid option (old behaviour is preserved
      without --gtid, for backwards compatibility).

      With --gtid, the GTID position is output instead, while the old-style position
      is included but commented out.

      The GTID position is obtained from @@gtid_binlog_pos or @@gtid_slave_pos, if
      using table locking, or from BINLOG_GTID_POS() if using non-blocking
      consistent snapshot.

      Attachments

        Activity

          knielsen Kristian Nielsen added a comment - Patch: http://lists.askmonty.org/pipermail/commits/2014-June/006208.html
          monty Michael Widenius added a comment - - edited

          Hi!

          Here is the review:

          ------------------------------------------------------------
          revno: 4245
          revision-id: knielsen at knielsen-hq.org-20140616093803-gub60pda6t77ch3k
          parent: igor at askmonty.org-20140610223256-nqs0kkp7i45qzyvx
          committer: knielsen at knielsen-hq.org
          branch nick: work-10.0
          timestamp: Mon 2014-06-16 11:38:03 +0200
          message:
            MDEV-6336: mysqldump --master-data does not work with GTID setups
            MDEV-6344: mysqldump issues FLUSH TABLES, which gets written into binlog and replicated
            
            Add a --gtid option (for compatibility, the original behaviour is preserved
            when --gtid is not used).
            
            With --gtid, --master-data and --dump-slave output the GTID position (the
            old-style file/offset position is still output, but commented out). Also, a
            CHANGE MASTER TO master_use_gtid=slave_pos is output to ensure a provisioned
            slave is configured in GTID, as requested.
            
            Without --gtid, the GTID position is still output, if available, but commented
            out.
            
            Also fix MDEV-6344, to avoid FLUSH TABLES getting into the binlog. Otherwise a
            mysqldump on a slave server will silently inject a GTID which does not exist
            on the master, which is highly undesirable.

          <cut>

          === modified file 'client/mysqldump.c'
          --- a/client/mysqldump.c	2014-05-09 10:35:11 +0000
          +++ b/client/mysqldump.c	2014-06-16 09:38:03 +0000
          <cut>
          @@ -1177,7 +1185,7 @@ check_consistent_binlog_pos(char *binlog
           
             if (mysql_query_with_error_report(mysql, &res,
                                               "SHOW STATUS LIKE 'binlog_snapshot_%'"))
          -    return 1;
          +    return 0;
           
             found= 0;
             while ((row= mysql_fetch_row(res)))

          Apparently and old bug. Good to get it fixed.
          Would have been good to have this in the changelog too, but not required.

          <cut>

          +/*
          +  Get the GTID position on a master or slave.
          +  The parameter MASTER is non-zero to get the position on a master
          +  (@@gtid_binlog_pos) or zero for a slave (@@gtid_slave_pos).
          +
          +  This uses the @@gtid_binlog_pos or @@gtid_slave_pos, so requires FLUSH TABLES
          +  WITH READ LOCK or similar to be consistent.
          +
          +  Returns 0 if ok, non-zero for error.
          +*/
          +static int
          +get_gtid_pos(char *out_gtid_pos, int master)
          +{
          +  MYSQL_RES *res;
          +  MYSQL_ROW row;
          +  int found;
          +
          +  if (mysql_query_with_error_report(mysql, &res,
          +                                    (master ?
          +                                     "SELECT @@GLOBAL.gtid_binlog_pos" :
          +                                     "SELECT @@GLOBAL.gtid_slave_pos")))
          +    return 1;
          +
          +  found= 0;
          +  if ((row= mysql_fetch_row(res)))
          +  {
          +    strmake(out_gtid_pos, row[0], FN_REFLEN-1);

          I would use a different max-length for GTID that is not depending on
          FN_REFLEN. How about introducing MAX_GTID_LENGTH instead ?

          +    found++;
          +  }
          +  mysql_free_result(res);
          +
          +  return (found != 1);
          +}

          Otherwise ok to push

          monty Michael Widenius added a comment - - edited Hi! Here is the review: ------------------------------------------------------------ revno: 4245 revision-id: knielsen at knielsen-hq.org-20140616093803-gub60pda6t77ch3k parent: igor at askmonty.org-20140610223256-nqs0kkp7i45qzyvx committer: knielsen at knielsen-hq.org branch nick: work-10.0 timestamp: Mon 2014-06-16 11:38:03 +0200 message: MDEV-6336: mysqldump --master-data does not work with GTID setups MDEV-6344: mysqldump issues FLUSH TABLES, which gets written into binlog and replicated Add a --gtid option (for compatibility, the original behaviour is preserved when --gtid is not used). With --gtid, --master-data and --dump-slave output the GTID position (the old-style file/offset position is still output, but commented out). Also, a CHANGE MASTER TO master_use_gtid=slave_pos is output to ensure a provisioned slave is configured in GTID, as requested. Without --gtid, the GTID position is still output, if available, but commented out. Also fix MDEV-6344, to avoid FLUSH TABLES getting into the binlog. Otherwise a mysqldump on a slave server will silently inject a GTID which does not exist on the master, which is highly undesirable. <cut> === modified file 'client/mysqldump.c' --- a/client/mysqldump.c 2014-05-09 10:35:11 +0000 +++ b/client/mysqldump.c 2014-06-16 09:38:03 +0000 <cut> @@ -1177,7 +1185,7 @@ check_consistent_binlog_pos(char *binlog if (mysql_query_with_error_report(mysql, &res, "SHOW STATUS LIKE 'binlog_snapshot_%'")) - return 1; + return 0; found= 0; while ((row= mysql_fetch_row(res))) Apparently and old bug. Good to get it fixed. Would have been good to have this in the changelog too, but not required. <cut> +/* + Get the GTID position on a master or slave. + The parameter MASTER is non-zero to get the position on a master + (@@gtid_binlog_pos) or zero for a slave (@@gtid_slave_pos). + + This uses the @@gtid_binlog_pos or @@gtid_slave_pos, so requires FLUSH TABLES + WITH READ LOCK or similar to be consistent. + + Returns 0 if ok, non-zero for error. +*/ +static int +get_gtid_pos(char *out_gtid_pos, int master) +{ + MYSQL_RES *res; + MYSQL_ROW row; + int found; + + if (mysql_query_with_error_report(mysql, &res, + (master ? + "SELECT @@GLOBAL.gtid_binlog_pos" : + "SELECT @@GLOBAL.gtid_slave_pos"))) + return 1; + + found= 0; + if ((row= mysql_fetch_row(res))) + { + strmake(out_gtid_pos, row[0], FN_REFLEN-1); I would use a different max-length for GTID that is not depending on FN_REFLEN. How about introducing MAX_GTID_LENGTH instead ? + found++; + } + mysql_free_result(res); + + return (found != 1); +} Otherwise ok to push

          Pushed to 10.0.13

          knielsen Kristian Nielsen added a comment - Pushed to 10.0.13

          People

            knielsen Kristian Nielsen
            knielsen Kristian Nielsen
            Votes:
            0 Vote for this issue
            Watchers:
            4 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.