diff options
author | Nirbhay Choubey <nirbhay.choubey@oracle.com> | 2011-12-23 23:05:00 +0530 |
---|---|---|
committer | Nirbhay Choubey <nirbhay.choubey@oracle.com> | 2011-12-23 23:05:00 +0530 |
commit | a4343d56eda71ab95e8d092cebedfd5abf7c710b (patch) | |
tree | d9aca95cf2b8365f593db3f7ddc7ec48f0cb969c /client/mysqldump.c | |
parent | 74a8331c084a038cab39a47cbb67c027aa8a9170 (diff) | |
download | mariadb-git-a4343d56eda71ab95e8d092cebedfd5abf7c710b.tar.gz |
Bug#12809202 61854: MYSQLDUMP --SINGLE-TRANSACTION
--FLUSH-LOG BREAKS CONSISTENCY
The transaction started by mysqldump gets committed
implicitly when flush-log is specified along with
single-transaction option, and hence can break
consistency.
This is because, COM_REFRESH is executed in order
to flush logs and starting from 5.5 this command
performs an implicit commit.
Fixed by making sure that COM_REFRESH is executed
before the transaction has started and not after it.
Note : This patch triggers following behavioral
changes in mysqldump :
1) After this patch we no longer flush logs before
dumping each database if --single-transaction
option is given like it was done before (in the
absence of --lock-all-tables and --master-data
options).
2) Also, after this patch, we start acquiring
FTWRL before flushing logs in cases when only
--single-transaction and --flush-logs are given.
It becomes safe to use mysqldump with these two
options and without --master-data parameter for
backups.
Diffstat (limited to 'client/mysqldump.c')
-rw-r--r-- | client/mysqldump.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c index 8ccf1f90c97..11b76932692 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -4079,6 +4079,8 @@ static int dump_all_tables_in_db(char *database) if (mysql_refresh(mysql, REFRESH_LOG)) DB_error(mysql, "when doing refresh"); /* We shall continue here, if --force was given */ + else + verbose_msg("-- dump_all_tables_in_db : logs flushed successfully!\n"); } while ((table= getTableName(0))) { @@ -4179,6 +4181,8 @@ static my_bool dump_all_views_in_db(char *database) if (mysql_refresh(mysql, REFRESH_LOG)) DB_error(mysql, "when doing refresh"); /* We shall continue here, if --force was given */ + else + verbose_msg("-- dump_all_views_in_db : logs flushed successfully!\n"); } while ((table= getTableName(0))) { @@ -4317,6 +4321,8 @@ static int dump_selected_tables(char *db, char **table_names, int tables) DB_error(mysql, "when doing refresh"); } /* We shall countinue here, if --force was given */ + else + verbose_msg("-- dump_selected_tables : logs flushed successfully!\n"); } if (opt_xml) print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS); @@ -4600,6 +4606,7 @@ static int purge_bin_logs_to(MYSQL *mysql_con, char* log_name) static int start_transaction(MYSQL *mysql_con) { + verbose_msg("-- Starting transaction...\n"); /* We use BEGIN for old servers. --single-transaction --master-data will fail on old servers, but that's ok as it was already silently broken (it didn't @@ -5199,24 +5206,39 @@ int main(int argc, char **argv) if (opt_slave_data && do_stop_slave_sql(mysql)) goto err; - if ((opt_lock_all_tables || opt_master_data) && + if ((opt_lock_all_tables || opt_master_data || + (opt_single_transaction && flush_logs)) && do_flush_tables_read_lock(mysql)) goto err; - if (opt_single_transaction && start_transaction(mysql)) - goto err; - if (opt_delete_master_logs) + + /* + Flush logs before starting transaction since + this causes implicit commit starting mysql-5.5. + */ + if (opt_lock_all_tables || opt_master_data || + (opt_single_transaction && flush_logs) || + opt_delete_master_logs) { - if (mysql_refresh(mysql, REFRESH_LOG) || - get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name))) - goto err; + if (flush_logs || opt_delete_master_logs) + { + if (mysql_refresh(mysql, REFRESH_LOG)) + goto err; + verbose_msg("-- main : logs flushed successfully!\n"); + } + + /* Not anymore! That would not be sensible. */ flush_logs= 0; } - if (opt_lock_all_tables || opt_master_data) + + if (opt_delete_master_logs) { - if (flush_logs && mysql_refresh(mysql, REFRESH_LOG)) + if (get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name))) goto err; - flush_logs= 0; /* not anymore; that would not be sensible */ } + + if (opt_single_transaction && start_transaction(mysql)) + goto err; + /* Add 'STOP SLAVE to beginning of dump */ if (opt_slave_apply && add_stop_slave()) goto err; |