diff options
author | unknown <guilhem@mysql.com> | 2004-11-10 17:56:45 +0100 |
---|---|---|
committer | unknown <guilhem@mysql.com> | 2004-11-10 17:56:45 +0100 |
commit | 313ce62f7036d1626f248bc8cbb197ffc4a9001c (patch) | |
tree | 2902d9154cc1add516be37d0682553b94d6610a7 /client/mysqldump.c | |
parent | c4d04e9ec112e5df429844934507488c2c3990b9 (diff) | |
download | mariadb-git-313ce62f7036d1626f248bc8cbb197ffc4a9001c.tar.gz |
WL#1596 "make mysqldump --master-data --single-transaction able to do online dump of InnoDB AND report reliable
binlog coordinates corresponding to the dump".
The good news is that now mysqldump can be used to get an online backup of InnoDB *which works for
point-in-time recovery and replication slave creation*. Formerly, mysqldump --master-data --single-transaction
used to call in fact mysqldump --master-data, so the dump was not an online dump (took big lock all time of dump).
The only lock which is now taken in this patch is at the beginning of the dump: mysqldump does:
FLUSH TABLES WITH READ LOCK; START TRANSACTION WITH CONSISTENT SNAPSHOT; SHOW MASTER STATUS; UNLOCK TABLES;
so the lock time is in fact the time FLUSH TABLES WITH READ LOCK takes to return (can be 0 or very long, if
a table is undergoing a huge update).
I have done some more minor changes listed in the paragraph of mysqldump.c.
WL#2237 "WITH CONSISTENT SNAPSHOT clause for START TRANSACTION":
it's a START TRANSACTION which additionally starts a consistent read on all
capable storage engine (i.e. InnoDB). So, can serve as a replacement for
BEGIN; SELECT * FROM some_innodb_table LIMIT 1; which starts a consistent read too.
client/mysqldump.c:
Main change: mysqldump --single-transaction --master-data is now able to, at the same time,
take an online dump of InnoDB (using consistent read) AND get the binlog position corresponding to this dump
(before, using the two options used to silently cancel --single-transaction).
This uses the new START TRANSACTION WITH CONSISTENT SNAPSHOT syntax.
Additional changes:
a) cleanup:
- DBerror calls exit() so some code was unneeded
- no need to call COMMIT at end, leave disconnection do the job
- mysql_query_with_error_report()
b) requirements I had heard from colleagues:
- --master-data now requires an argument, to comment out ("--") the CHANGE MASTER or not
(commenting had been asked for point-in-time recovery when replication is not necessary).
- --first-slave is renamed to --lock-all-tables
c) more sensible behaviours (has been discussed internally):
- if used with --master-data, --flush-logs is probably intended to get a flush synchronous
with the dump, not one random flush per dumped db.
- disabled automatic reconnection as, at least, SQL_MODE would be lost (and also, depending
on options, LOCK TABLES, BEGIN, FLUSH TABLES WITH READ LOCK).
include/mysqld_error.h:
an error if START TRANSACTION WITH CONSISTENT SNAPSHOT is called and there is no consistent-read capable storage engine
(idea ((C) PeterG) is that it's a bit like CREATE TABLE ENGINE=InnoDB when there is no support for InnoDB).
sql/handler.cc:
new ha_start_consistent_snapshot(), which, inside an existing transaction, starts a consistent read
(offers an alternative to SELECTing any InnoDB table). Does something only for InnoDB.
Warning if no suitable engine supported.
sql/handler.h:
declarations
sql/lex.h:
symbols for lex
sql/share/czech/errmsg.txt:
new message
sql/share/danish/errmsg.txt:
new message
sql/share/dutch/errmsg.txt:
new message
sql/share/english/errmsg.txt:
new message
sql/share/estonian/errmsg.txt:
new message
sql/share/french/errmsg.txt:
new message
sql/share/german/errmsg.txt:
new message
sql/share/greek/errmsg.txt:
new message
sql/share/hungarian/errmsg.txt:
new message
sql/share/italian/errmsg.txt:
new message
sql/share/japanese/errmsg.txt:
new message
sql/share/korean/errmsg.txt:
new message
sql/share/norwegian-ny/errmsg.txt:
new message
sql/share/norwegian/errmsg.txt:
new message
sql/share/polish/errmsg.txt:
new message
sql/share/portuguese/errmsg.txt:
new message
sql/share/romanian/errmsg.txt:
new message
sql/share/russian/errmsg.txt:
new message
sql/share/serbian/errmsg.txt:
new message
sql/share/slovak/errmsg.txt:
new message
sql/share/spanish/errmsg.txt:
new message
sql/share/swedish/errmsg.txt:
new message
sql/share/ukrainian/errmsg.txt:
new message
sql/sql_lex.h:
new option in lex (transaction options)
sql/sql_parse.cc:
warning comment (never make UNLOCK TABLES commit a transaction, please);
support for starting consistent snapshot.
sql/sql_yacc.yy:
new clause WITH CONSISTENT SNAPSHOT (syntax ok'd by PeterG) for START TRANSACTION.
Diffstat (limited to 'client/mysqldump.c')
-rw-r--r-- | client/mysqldump.c | 331 |
1 files changed, 196 insertions, 135 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c index 1686278096b..8ee30d39f01 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -37,7 +37,7 @@ ** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov */ -#define DUMP_VERSION "10.8" +#define DUMP_VERSION "10.9" #include <my_global.h> #include <my_sys.h> @@ -78,8 +78,8 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick= 1, extended_insert= 1, lock_tables=1,ignore_errors=0,flush_logs=0,replace=0, ignore=0,opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0, opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0, - opt_alldbs=0,opt_create_db=0,opt_first_slave=0,opt_set_charset, - opt_autocommit=0,opt_master_data,opt_disable_keys=1,opt_xml=0, + opt_alldbs=0,opt_create_db=0,opt_lock_all_tables=0,opt_set_charset, + opt_autocommit=0,opt_disable_keys=1,opt_xml=0, opt_delete_master_logs=0, tty_password=0, opt_single_transaction=0, opt_comments= 0, opt_compact= 0, opt_hex_blob=0; @@ -93,7 +93,9 @@ static char insert_pat[12 * 1024],*opt_password=0,*current_user=0, *err_ptr= 0; static char compatible_mode_normal_str[255]; static ulong opt_compatible_mode= 0; -static uint opt_mysql_port= 0, err_len= 0; +#define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1 +#define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2 +static uint opt_mysql_port= 0, err_len= 0, opt_master_data; static my_string opt_mysql_unix_port=0; static int first_error=0; static DYNAMIC_STRING extended_row; @@ -183,8 +185,9 @@ static struct my_option my_long_options[] = (gptr*) &opt_delayed, (gptr*) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"delete-master-logs", OPT_DELETE_MASTER_LOGS, - "Delete logs on master after backup. This automatically enables --first-slave.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + "Delete logs on master after backup. This automatically enables --master-data.", + (gptr*) &opt_delete_master_logs, (gptr*) &opt_delete_master_logs, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"disable-keys", 'K', "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (gptr*) &opt_disable_keys, (gptr*) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -203,13 +206,18 @@ static struct my_option my_long_options[] = (gptr*) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0}, {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...", (gptr*) &escaped, (gptr*) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"first-slave", 'x', "Locks all tables across all databases.", - (gptr*) &opt_first_slave, (gptr*) &opt_first_slave, 0, GET_BOOL, NO_ARG, + {"first-slave", 'x', "Deprecated, renamed to --lock-all-tables.", + (gptr*) &opt_lock_all_tables, (gptr*) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"flush-logs", 'F', "Flush logs file in server before starting dump. " - "Note that if you dump many databases at once (using the option " - "--databases= or --all-databases), the logs will be flushed for " - "each database dumped.", + "Note that if you dump many databases at once (using the option " + "--databases= or --all-databases), the logs will be flushed for " + "each database dumped. The exception is when using --lock-all-tables " + "or --master-data: " + "in this case the logs will be flushed only once, corresponding " + "to the moment all tables are locked. So if you want your dump and " + "the log flush to happen at the same exact moment you should use " + "--lock-all-tables or --master-data with --flush-logs", (gptr*) &flush_logs, (gptr*) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"force", 'f', "Continue even if we get an sql-error.", @@ -222,17 +230,40 @@ static struct my_option my_long_options[] = {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...", (gptr*) &lines_terminated, (gptr*) &lines_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"lock-all-tables", 'x', "Locks all tables across all databases. This " + "is achieved by taking a global read lock for the duration of the whole " + "dump. Automatically turns --single-transaction and --lock-tables off.", + (gptr*) &opt_lock_all_tables, (gptr*) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, {"lock-tables", 'l', "Lock all tables for read.", (gptr*) &lock_tables, (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"master-data", OPT_MASTER_DATA, - "This causes the master position and filename to be appended to your output. This automatically enables --first-slave.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + "This causes the binary log position and filename to be appended to the " + "output. If equal to 1, will print it as a CHANGE MASTER command; if equal" + " to 2, that command will be prefixed with a comment symbol. " + "This option will turn --lock-all-tables on, unless " + "--single-transaction is specified too (in which case a " + "global read lock is only taken a short time at the beginning of the dump " + "- don't forget to read about --single-transaction below). In all cases " + "any action on logs will happen at the exact moment of the dump." + "Option automatically turns --lock-tables off.", + (gptr*) &opt_master_data, (gptr*) &opt_master_data, 0, + GET_UINT, REQUIRED_ARG, 0, 0, MYSQL_OPT_MASTER_DATA_COMMENTED_SQL, 0, 0, 0}, {"no-autocommit", OPT_AUTOCOMMIT, "Wrap tables with autocommit/commit statements.", (gptr*) &opt_autocommit, (gptr*) &opt_autocommit, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + /* + Note that the combination --single-transaction --master-data + will give bullet-proof binlog position only if server >=4.1.3. That's the + old "FLUSH TABLES WITH READ LOCK does not block commit" fixed bug. + */ {"single-transaction", OPT_TRANSACTION, - "Dump all tables in single transaction to get consistent snapshot. Mutually exclusive with --lock-tables.", + "Creates a consistent snapshot by dumping all tables in a single " + "transaction. Works ONLY for tables stored in storage engines which " + "support multiversioning (currently only InnoDB does); the dump is NOT " + "guaranteed to be consistent for other storage engines. Option " + "automatically turns off --lock-tables.", (gptr*) &opt_single_transaction, (gptr*) &opt_single_transaction, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"no-create-db", 'n', @@ -472,14 +503,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char *argument) { switch (optid) { - case OPT_MASTER_DATA: - opt_master_data=1; - opt_first_slave=1; - break; - case OPT_DELETE_MASTER_LOGS: - opt_delete_master_logs=1; - opt_first_slave=1; - break; case 'p': if (argument) { @@ -527,7 +550,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case (int) OPT_OPTIMIZE: extended_insert= opt_drop= opt_lock= quick= create_options= opt_disable_keys= lock_tables= opt_set_charset= 1; - if (opt_single_transaction) lock_tables=0; break; case (int) OPT_SKIP_OPTIMIZATION: extended_insert= opt_drop= opt_lock= quick= create_options= @@ -623,7 +645,19 @@ static int get_options(int *argc, char ***argv) "%s: You must use option --tab with --fields-...\n", my_progname); return(1); } - if (opt_single_transaction) + + /* Ensure consistency of the set of binlog & locking options */ + if (opt_delete_master_logs && !opt_master_data) + opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL; + if (opt_single_transaction && opt_lock_all_tables) + { + fprintf(stderr, "%s: You can't use --single-transaction and " + "--lock-all-tables at the same time.\n", my_progname); + return(1); + } + if (opt_master_data) + opt_lock_all_tables= !opt_single_transaction; + if (opt_single_transaction || opt_lock_all_tables) lock_tables= 0; if (enclosed && opt_enclosed) { @@ -670,6 +704,36 @@ static void DBerror(MYSQL *mysql, const char *when) } /* DBerror */ +/* + Sends a query to server, optionally reads result, prints error message if + some. + + SYNOPSIS + mysql_query_with_error_report() + mysql_con connection to use + res if non zero, result will be put there with mysql_store_result + query query to send to server + + RETURN VALUES + 0 query sending and (if res!=0) result reading went ok + 1 error +*/ + +static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res, + const char *query) +{ + if (mysql_query(mysql_con, query) || + (res && !((*res)= mysql_store_result(mysql_con)))) + { + my_printf_error(0, "%s: Couldn't execute '%s': %s (%d)", + MYF(0), my_progname, query, + mysql_error(mysql_con), mysql_errno(mysql_con)); + return 1; + } + return 0; +} + + static void safe_exit(int error) { if (!first_error) @@ -717,12 +781,15 @@ static int dbConnect(char *host, char *user,char *passwd) DBerror(&mysql_connection, "when trying to connect"); return 1; } + /* + As we're going to set SQL_MODE, it would be lost on reconnect, so we + cannot reconnect. + */ + sock->reconnect= 0; sprintf(buff, "/*!40100 SET @@SQL_MODE=\"%s\" */", compatible_mode_normal_str); - if (mysql_query(sock, buff)) + if (mysql_query_with_error_report(sock, 0, buff)) { - fprintf(stderr, "%s: Can't set the compatible mode %s (error %s)\n", - my_progname, compatible_mode_normal_str, mysql_error(sock)); mysql_close(sock); safe_exit(EX_MYSQLERR); return 1; @@ -961,7 +1028,7 @@ static uint getTableStructure(char *table, char* db) result_table= quote_name(table, table_buff, 1); opt_quoted_table= quote_name(table, table_buff2, 0); - if (!opt_xml && !mysql_query(sock,insert_pat)) + if (!opt_xml && !mysql_query_with_error_report(sock, 0, insert_pat)) { /* using SHOW CREATE statement */ if (!tFlag) @@ -970,10 +1037,8 @@ static uint getTableStructure(char *table, char* db) char buff[20+FN_REFLEN]; sprintf(buff,"show create table %s", result_table); - if (mysql_query(sock, buff)) + if (mysql_query_with_error_report(sock, 0, buff)) { - fprintf(stderr, "%s: Can't get CREATE TABLE for table %s (%s)\n", - my_progname, result_table, mysql_error(sock)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -1010,10 +1075,8 @@ static uint getTableStructure(char *table, char* db) mysql_free_result(tableRes); } sprintf(insert_pat,"show fields from %s", result_table); - if (mysql_query(sock,insert_pat) || !(tableRes=mysql_store_result(sock))) + if (mysql_query_with_error_report(sock, &tableRes, insert_pat)) { - fprintf(stderr, "%s: Can't get info about table: %s\nerror: %s\n", - my_progname, result_table, mysql_error(sock)); if (path) my_fclose(sql_file, MYF(MY_WME)); safe_exit(EX_MYSQLERR); @@ -1053,10 +1116,8 @@ static uint getTableStructure(char *table, char* db) my_progname, mysql_error(sock)); sprintf(insert_pat,"show fields from %s", result_table); - if (mysql_query(sock,insert_pat) || !(tableRes=mysql_store_result(sock))) + if (mysql_query_with_error_report(sock, &tableRes, insert_pat)) { - fprintf(stderr, "%s: Can't get info about table: %s\nerror: %s\n", - my_progname, result_table, mysql_error(sock)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -1150,17 +1211,14 @@ static uint getTableStructure(char *table, char* db) char buff[20+FN_REFLEN]; uint keynr,primary_key; sprintf(buff,"show keys from %s", result_table); - if (mysql_query(sock, buff)) + if (mysql_query_with_error_report(sock, &tableRes, buff)) { - fprintf(stderr, "%s: Can't get keys for table %s (%s)\n", - my_progname, result_table, mysql_error(sock)); if (path) my_fclose(sql_file, MYF(MY_WME)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } - tableRes=mysql_store_result(sock); /* Find first which key is primary key */ keynr=0; primary_key=INT_MAX; @@ -1224,7 +1282,7 @@ static uint getTableStructure(char *table, char* db) char show_name_buff[FN_REFLEN]; sprintf(buff,"show table status like %s", quote_for_like(table, show_name_buff)); - if (mysql_query(sock, buff)) + if (mysql_query_with_error_report(sock, &tableRes, buff)) { if (mysql_errno(sock) != ER_PARSE_ERROR) { /* If old MySQL version */ @@ -1234,8 +1292,7 @@ static uint getTableStructure(char *table, char* db) result_table,mysql_error(sock)); } } - else if (!(tableRes=mysql_store_result(sock)) || - !(row=mysql_fetch_row(tableRes))) + else if (!(row=mysql_fetch_row(tableRes))) { fprintf(stderr, "Error: Couldn't read status information for table %s (%s)\n", @@ -1439,22 +1496,14 @@ static void dumpTable(uint numFields, char *table) fputs("\n", md_result_file); check_io(md_result_file); } - if (mysql_query(sock, query)) - { + if (mysql_query_with_error_report(sock, 0, query)) DBerror(sock, "when retrieving data from server"); - error= EX_CONSCHECK; - goto err; - } if (quick) res=mysql_use_result(sock); else res=mysql_store_result(sock); if (!res) - { DBerror(sock, "when retrieving data from server"); - error= EX_CONSCHECK; - goto err; - } if (verbose) fprintf(stderr, "-- Retrieving rows...\n"); if (mysql_num_fields(res) != numFields) @@ -1784,13 +1833,8 @@ static int dump_all_databases() MYSQL_RES *tableres; int result=0; - if (mysql_query(sock, "SHOW DATABASES") || - !(tableres = mysql_store_result(sock))) - { - my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s", - MYF(0), mysql_error(sock)); + if (mysql_query_with_error_report(sock, &tableres, "SHOW DATABASES")) return 1; - } while ((row = mysql_fetch_row(tableres))) { if (dump_all_tables_in_db(row[0])) @@ -1843,7 +1887,7 @@ static int init_dumping(char *database) sprintf(qbuf,"SHOW CREATE DATABASE WITH IF NOT EXISTS %s", qdatabase); - if (mysql_query(sock, qbuf) || !(dbinfo = mysql_store_result(sock))) + if (mysql_query_with_error_report(sock, &dbinfo, qbuf)) { /* Old server version, dump generic CREATE DATABASE */ fprintf(md_result_file, @@ -1912,7 +1956,7 @@ static int dump_all_tables_in_db(char *database) check_io(md_result_file); } if (lock_tables) - mysql_query(sock,"UNLOCK TABLES"); + mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"); return 0; } /* dump_all_tables_in_db */ @@ -1961,11 +2005,76 @@ static int dump_selected_tables(char *db, char **table_names, int tables) check_io(md_result_file); } if (lock_tables) - mysql_query(sock,"UNLOCK TABLES"); + mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"); return 0; } /* dump_selected_tables */ +static int do_show_master_status(MYSQL *mysql_con) +{ + MYSQL_ROW row; + MYSQL_RES *master; + const char *comment_prefix= + (opt_master_data == MYSQL_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : ""; + if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS")) + { + my_printf_error(0, "Error: Couldn't execute 'SHOW MASTER STATUS': %s", + MYF(0), mysql_error(mysql_con)); + return 1; + } + else + { + row = mysql_fetch_row(master); + if (row && row[0] && row[1]) + { + if (opt_comments) + fprintf(md_result_file, + "\n--\n-- Position to start replication or point-in-time " + "recovery from\n--\n\n"); + fprintf(md_result_file, + "%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", + comment_prefix, row[0], row[1]); + check_io(md_result_file); + } + mysql_free_result(master); + } + return 0; +} + + +static int do_flush_tables_read_lock(MYSQL *mysql_con) +{ + return + mysql_query_with_error_report(mysql_con, 0, "FLUSH TABLES WITH READ LOCK"); +} + + +static int do_unlock_tables(MYSQL *mysql_con) +{ + return mysql_query_with_error_report(mysql_con, 0, "UNLOCK TABLES"); +} + + +static int do_reset_master(MYSQL *mysql_con) +{ + return mysql_query_with_error_report(mysql_con, 0, "RESET MASTER"); +} + + +static int start_transaction(MYSQL *mysql_con, my_bool consistent_read_now) +{ + /* + 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 + do a consistent read, so better tell people frankly, with the error). + */ + return (mysql_query_with_error_report(mysql_con, 0, + consistent_read_now ? + "START TRANSACTION " + "WITH CONSISTENT SNAPSHOT" : + "BEGIN")); +} + static ulong find_set(TYPELIB *lib, const char *x, uint length, char **err_pos, uint *err_len) @@ -2063,7 +2172,7 @@ static const char *check_if_ignore_table(const char *table_name) sprintf(buff,"show table status like %s", quote_for_like(table_name, show_name_buff)); - if (mysql_query(sock, buff)) + if (mysql_query_with_error_report(sock, &res, buff)) { if (mysql_errno(sock) != ER_PARSE_ERROR) { /* If old MySQL version */ @@ -2074,8 +2183,7 @@ static const char *check_if_ignore_table(const char *table_name) return 0; /* assume table is ok */ } } - if (!(res= mysql_store_result(sock)) || - !(row= mysql_fetch_row(res))) + if (!(row= mysql_fetch_row(res))) { fprintf(stderr, "Error: Couldn't read status information for table %s (%s)\n", @@ -2094,8 +2202,6 @@ static const char *check_if_ignore_table(const char *table_name) int main(int argc, char **argv) { - MYSQL_ROW row; - MYSQL_RES *master; compatible_mode_normal_str[0]= 0; MY_INIT(argv[0]); @@ -2109,28 +2215,24 @@ int main(int argc, char **argv) if (!path) write_header(md_result_file, *argv); - if (opt_first_slave) - { - lock_tables=0; /* No other locks needed */ - if (mysql_query(sock, "FLUSH TABLES WITH READ LOCK")) - { - my_printf_error(0, "Error: Couldn't execute 'FLUSH TABLES WITH READ LOCK': %s", - MYF(0), mysql_error(sock)); - my_end(0); - return(first_error); - } - } - else if (opt_single_transaction) + if ((opt_lock_all_tables || opt_master_data) && + do_flush_tables_read_lock(sock)) + goto err; + if (opt_single_transaction && start_transaction(sock, test(opt_master_data))) + goto err; + if (opt_delete_master_logs && do_reset_master(sock)) + goto err; + if (opt_lock_all_tables || opt_master_data) { - /* There is no sense to start transaction if all tables are locked */ - if (mysql_query(sock, "BEGIN")) - { - my_printf_error(0, "Error: Couldn't execute 'BEGIN': %s", - MYF(0), mysql_error(sock)); - my_end(0); - return(first_error); - } + if (flush_logs && mysql_refresh(sock, REFRESH_LOG)) + goto err; + flush_logs= 0; /* not anymore; that would not be sensible */ } + if (opt_master_data && do_show_master_status(sock)) + goto err; + if (opt_single_transaction && do_unlock_tables(sock)) // unlock but no commit! + goto err; + if (opt_alldbs) dump_all_databases(); else if (argc > 1 && !opt_databases) @@ -2143,57 +2245,16 @@ int main(int argc, char **argv) /* One or more databases, all tables */ dump_databases(argv); } - - if (opt_first_slave) - { - if (opt_delete_master_logs && mysql_query(sock, "FLUSH MASTER")) - { - my_printf_error(0, "Error: Couldn't execute 'FLUSH MASTER': %s", - MYF(0), mysql_error(sock)); - } - if (opt_master_data) - { - if (mysql_query(sock, "SHOW MASTER STATUS") || - !(master = mysql_store_result(sock))) - my_printf_error(0, "Error: Couldn't execute 'SHOW MASTER STATUS': %s", - MYF(0), mysql_error(sock)); - else - { - row = mysql_fetch_row(master); - if (row && row[0] && row[1]) - { - if (opt_comments) - fprintf(md_result_file, - "\n--\n-- Position to start replication from\n--\n\n"); - fprintf(md_result_file, - "CHANGE MASTER TO MASTER_LOG_FILE='%s', \ -MASTER_LOG_POS=%s ;\n",row[0],row[1]); - check_io(md_result_file); - } - mysql_free_result(master); - } - } - if (mysql_query(sock, "UNLOCK TABLES")) - my_printf_error(0, "Error: Couldn't execute 'UNLOCK TABLES': %s", - MYF(0), mysql_error(sock)); - } - else if (opt_single_transaction) /* Just to make it beautiful enough */ #ifdef HAVE_SMEM my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif - { - /* - In case we were locking all tables, we did not start transaction - so there is no need to commit it. - */ - - /* This should just free locks as we did not change anything */ - if (mysql_query(sock, "COMMIT")) - { - my_printf_error(0, "Error: Couldn't execute 'COMMIT': %s", - MYF(0), mysql_error(sock)); - } - } + /* + No reason to explicitely COMMIT the transaction, neither to explicitely + UNLOCK TABLES: these will be automatically be done by the server when we + disconnect now. Saves some code here, some network trips, adds nothing to + server. + */ +err: dbDisconnect(current_host); if (!path) write_footer(md_result_file); |