diff --git a/client/mysqldump.c b/client/mysqldump.c index 42309647c8c..6828a99c7b6 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -198,6 +198,8 @@ static CHARSET_INFO *charset_info= &my_charset_latin1; const char *default_dbug_option="d:t:o,/tmp/mysqldump.trace"; /* have we seen any VIEWs during table scanning? */ my_bool seen_views= 0; +static DYNAMIC_STRING gtid_executed_buffer; +static my_bool gtid_executed_buffer_inited= 0; const char *compatible_mode_names[]= { "MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2", @@ -1594,6 +1596,8 @@ static void free_resources() if (opt_ignore_error) my_free(opt_ignore_error); delete_dynamic(&ignore_error); + if(gtid_executed_buffer_inited) + dynstr_free(>id_executed_buffer); my_end(my_end_arg); } @@ -5895,22 +5899,22 @@ static my_bool add_set_gtid_purged(MYSQL *mysql_con) /* Proceed only if gtid_purged_res is non empty */ if ((num_sets= mysql_num_rows(gtid_purged_res)) > 0) { + gtid_executed_buffer_inited= 1; + init_dynamic_string_checked(>id_executed_buffer, "", 1024, 1024); if (opt_comments) - fprintf(md_result_file, - "\n--\n-- GTID state at the end of the backup \n--\n\n"); + dynstr_append_checked(>id_executed_buffer, + "\n--\n-- GTID state at the end of the backup \n--\n\n"); - fprintf(md_result_file,"SET @@GLOBAL.GTID_PURGED='"); + dynstr_append_checked(>id_executed_buffer,"SET @@GLOBAL.GTID_PURGED='"); /* formatting is not required, even for multiple gtid sets */ - for (idx= 0; idx< num_sets-1; idx++) + for (idx= 0; idx< num_sets; idx++) { gtid_set= mysql_fetch_row(gtid_purged_res); - fprintf(md_result_file,"%s,", (char*)gtid_set[0]); + dynstr_append_checked(>id_executed_buffer, (char*)gtid_set[0]); } - /* for the last set */ - gtid_set= mysql_fetch_row(gtid_purged_res); - /* close the SET expression */ - fprintf(md_result_file,"%s';\n", (char*)gtid_set[0]); + /* for the last set close the SET expression */ + dynstr_append_checked(>id_executed_buffer, "';\n"); } mysql_free_result(gtid_purged_res); @@ -5985,7 +5989,11 @@ static my_bool process_set_gtid_purged(MYSQL* mysql_con, my_bool flag) being AUTO or ON, add GTID_PURGED in the output. */ if (!flag) + { set_session_binlog(); + if (add_set_gtid_purged(mysql_con)) + return TRUE; + } else { if (flag && (opt_databases || !opt_alldbs || !opt_dump_triggers @@ -5999,8 +6007,7 @@ static my_bool process_set_gtid_purged(MYSQL* mysql_con, my_bool flag) "--all-databases --triggers --routines --events. \n"); } - if (add_set_gtid_purged(mysql_con)) - return TRUE; + fputs(gtid_executed_buffer.str,md_result_file); } } else /* gtid_mode is off */ diff --git a/mysql-test/r/mysqldump_gtid_state.result b/mysql-test/r/mysqldump_gtid_state.result index 050aa31c1ea..c82e89519b1 100644 --- a/mysql-test/r/mysqldump_gtid_state.result +++ b/mysql-test/r/mysqldump_gtid_state.result @@ -66,7 +66,34 @@ innodb_table_stats CREATE TABLE `innodb_table_stats` ( `sum_of_other_index_sizes` bigint(20) unsigned NOT NULL, PRIMARY KEY (`database_name`,`table_name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0 +# +# Bug#105761: mysqldump make a non-consistent backup +# with --single-transaction option +# +# Restart server. +# restart: --enforce-gtid-consistency=ON --gtid-mode=ON --log-bin +CREATE PROCEDURE test_data() +BEGIN +DECLARE v_max_rows INT UNSIGNED DEFAULT 1000; +DECLARE v_counter INT UNSIGNED DEFAULT 1; +while v_counter <= v_max_rows do +INSERT INTO t VALUES (v_counter, 1); +SET v_counter=v_counter+1; +end while; +end | +TRUNCATE TABLE t; +RESET MASTER; +USE test; +call test_data;; +# Waiting for until background bash has executed some inserts +# Waiting for until background bash has executed all inserts +# RESET +RESET MASTER; +# DUMP RESTORE WITH THE DUMP FILE HAVING DATA WRITTEN IN BACKGROUND. +# Checking rows vs gtid seqno +include/assert.inc [Committed rows vs gtid seqno] #CLEANUP DROP TABLE t; +DROP PROCEDURE test_data; RESET MASTER; -# restart +# restart: --enforce-gtid-consistency=ON --gtid-mode=ON --log-bin diff --git a/mysql-test/t/mysqldump_gtid_state.test b/mysql-test/t/mysqldump_gtid_state.test index 997676a825e..6c7a265a72b 100644 --- a/mysql-test/t/mysqldump_gtid_state.test +++ b/mysql-test/t/mysqldump_gtid_state.test @@ -107,7 +107,68 @@ CALL mtr.add_suppression(".*InnoDB: Table `mysql`.`innodb_table_stats` not found SHOW CREATE TABLE `mysql`.`innodb_table_stats`; +--echo # +--echo # Bug#105761: mysqldump make a non-consistent backup +--echo # with --single-transaction option +--echo # + +--echo # Restart server. +--let $restart_parameters= restart: --enforce-gtid-consistency=ON --gtid-mode=ON --log-bin +--source include/restart_mysqld.inc + + +DELIMITER |; +CREATE PROCEDURE test_data() +BEGIN + +DECLARE v_max_rows INT UNSIGNED DEFAULT 1000; +DECLARE v_counter INT UNSIGNED DEFAULT 1; + +while v_counter <= v_max_rows do + INSERT INTO t VALUES (v_counter, 1); + SET v_counter=v_counter+1; +end while; +end | + +DELIMITER ;| + +TRUNCATE TABLE t; +RESET MASTER; + +connect (con2,localhost,root,,); +connection con2; +USE test; +--send call test_data; + +connection default; + +--echo # Waiting for until background bash has executed some inserts +let $wait_condition= + SELECT COUNT(*) >= 1 FROM test.t; +--source include/wait_condition.inc + +--let $gtid_dump = $MYSQLTEST_VARDIR/tmp/gtid_with_trx_running_in_background.sql +--exec $MYSQL_DUMP --socket=$MASTER_MYSOCK --set-gtid-purged=ON --single-transaction --databases test -uroot > $gtid_dump + +--echo # Waiting for until background bash has executed all inserts +connection con2; +--reap + +--echo # RESET +connection default; +RESET MASTER; +--echo # DUMP RESTORE WITH THE DUMP FILE HAVING DATA WRITTEN IN BACKGROUND. +--exec $MYSQL -h localhost -P $MASTER_MYPORT < $gtid_dump + +--let $gtid_seqno= `SELECT COUNT(*) FROM test.t` +--echo # Checking rows vs gtid seqno +--let $assert_text= Committed rows vs gtid seqno +--let $assert_cond= "[SELECT @@GLOBAL.GTID_EXECUTED]" = "$master_uuid:1-$gtid_seqno" +--source include/assert.inc + --echo #CLEANUP +disconnect con2; DROP TABLE t; +DROP PROCEDURE test_data; RESET MASTER; --source include/restart_mysqld.inc