1
/* Copyright 2000-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
2
* Copyright (C) 2010 Vijay Samuel
3
* Copyright (C) 2010 Andrew Hutchings
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
18
/* drizzledump.cc - Dump a tables contents and format to an ASCII file
20
* Derived from mysqldump, which originally came from:
22
** The author's original notes follow :-
24
** AUTHOR: Igor Romanenko (igor@frog.kiev.ua)
25
** DATE: December 3, 1994
26
** WARRANTY: None, expressed, impressed, implied
28
** STATUS: Public domain
30
* and more work by Monty, Jani & Sinisa
31
* and all the MySQL developers over the years.
1
/* Copyright (C) 2000 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
/* mysqldump.c - Dump a tables contents and format to an ASCII file
18
** The author's original notes follow :-
20
** AUTHOR: Igor Romanenko (igor@frog.kiev.ua)
21
** DATE: December 3, 1994
22
** WARRANTY: None, expressed, impressed, implied
24
** STATUS: Public domain
25
** Adapted and optimized for MySQL by
26
** Michael Widenius, Sinisa Milivojevic, Jani Tolonen
27
** -w --where added 9/10/98 by Jim Faucette
28
** slave code by David Saez Padros <david@ols.es>
29
** master/autocommit code by Brian Aker <brian@tangent.org>
31
** Andrei Errapart <andreie@no.spam.ee>
32
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
33
** XML by Gary Huntress <ghuntress@mediaone.net> 10/10/01, cleaned up
34
** and adapted to mysqldump 05/11/01 by Jani Tolonen
35
** Added --single-transaction option 06/06/2002 by Peter Zaitsev
36
** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov
39
#define DUMP_VERSION "10.13"
41
#include <my_global.h>
34
48
#include "client_priv.h"
38
#include <boost/unordered_set.hpp>
41
#include <drizzled/gettext.h>
42
#include <drizzled/configmake.h>
43
#include <drizzled/error.h>
44
#include <boost/program_options.hpp>
45
#include <boost/regex.hpp>
46
#include <boost/date_time/posix_time/posix_time.hpp>
47
#include "drizzledump_data.h"
48
#include "drizzledump_mysql.h"
49
#include "drizzledump_drizzle.h"
52
using namespace drizzled;
53
namespace po= boost::program_options;
49
#include "drizzle_version.h"
50
#include "mysqld_error.h"
58
#define EX_DRIZZLEERR 2
56
#define EX_CONSCHECK 3
59
58
#define EX_EOF 5 /* ferror for output file was got */
62
static bool use_drizzle_protocol= false;
63
bool ignore_errors= false;
64
static bool flush_logs= false;
65
static bool create_options= true;
66
static bool opt_quoted= false;
67
bool opt_databases= false;
68
bool opt_alldbs= false;
69
static bool opt_lock_all_tables= false;
70
static bool opt_dump_date= true;
71
bool opt_autocommit= false;
72
static bool opt_single_transaction= false;
73
static bool opt_comments;
74
static bool opt_compact;
75
bool opt_ignore= false;
76
bool opt_drop_database;
77
bool opt_no_create_info;
78
bool opt_no_data= false;
79
bool opt_create_db= false;
80
bool opt_disable_keys= true;
81
bool extended_insert= true;
82
bool opt_replace_into= false;
84
bool opt_data_is_mangled= false;
85
uint32_t show_progress_size= 0;
86
static string insert_pat;
87
static uint32_t opt_drizzle_port= 0;
88
static int first_error= 0;
89
static string extended_row;
59
#define EX_ILLEGAL_TABLE 6
61
/* index into 'show fields from table' */
63
#define SHOW_FIELDNAME 0
66
#define SHOW_DEFAULT 4
69
/* Size of buffer for dump's select query */
70
#define QUERY_LENGTH 1536
72
/* ignore table flags */
73
#define IGNORE_NONE 0x00 /* no ignore */
74
#define IGNORE_DATA 0x01 /* don't dump data for this table */
75
#define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */
77
static void add_load_option(DYNAMIC_STRING *str, const char *option,
78
const char *option_value);
79
static ulong find_set(TYPELIB *lib, const char *x, uint length,
80
char **err_pos, uint *err_len);
82
static void field_escape(DYNAMIC_STRING* in, const char *from);
83
static bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
84
quick= 1, extended_insert= 1,
85
lock_tables=1,ignore_errors=0,flush_logs=0,flush_privileges=0,
86
opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0,
87
opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0,
88
opt_alldbs=0,opt_create_db=0,opt_lock_all_tables=0,
89
opt_set_charset=0, opt_dump_date=1,
90
opt_autocommit=0,opt_disable_keys=1,opt_xml=0,
91
opt_delete_master_logs=0, tty_password=0,
92
opt_single_transaction=0, opt_comments= 0, opt_compact= 0,
93
opt_hex_blob=0, opt_order_by_primary=0, opt_ignore=0,
94
opt_complete_insert= 0, opt_drop_database= 0,
96
opt_routines=0, opt_tz_utc=1,
98
opt_include_master_host_port= 0,
100
opt_alltspcs=0, opt_notspcs= 0;
101
static bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
102
static ulong opt_max_allowed_packet, opt_net_buffer_length;
103
static MYSQL mysql_connection,*mysql=0;
104
static DYNAMIC_STRING insert_pat;
105
static char *opt_password=0,*current_user=0,
106
*current_host=0,*path=0,*fields_terminated=0,
107
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
108
*where=0, *order_by=0,
109
*opt_compatible_mode_str= 0,
111
*log_error_file= NULL;
112
static char **defaults_argv= 0;
113
static char compatible_mode_normal_str[255];
114
/* Server supports character_set_results session variable? */
115
static bool server_supports_switching_charsets= true;
116
static ulong opt_compatible_mode= 0;
117
#define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
118
#define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
119
#define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
120
#define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2
121
static uint opt_mysql_port= 0, opt_master_data;
122
static uint opt_slave_data;
123
static uint my_end_arg;
124
static int first_error=0;
125
static DYNAMIC_STRING extended_row;
90
126
FILE *md_result_file= 0;
91
FILE *stderror_file= 0;
92
std::vector<DrizzleDumpDatabase*> database_store;
93
DrizzleDumpConnection* db_connection;
94
DrizzleDumpConnection* destination_connection;
102
int opt_destination= DESTINATION_STDOUT;
103
std::string opt_destination_host;
104
uint16_t opt_destination_port;
105
std::string opt_destination_user;
106
std::string opt_destination_password;
107
std::string opt_destination_database;
109
const string progname= "drizzledump";
121
boost::unordered_set<string> ignore_table;
123
void maybe_exit(int error);
127
FILE *stderror_file=0;
129
static uint opt_protocol= MYSQL_PROTOCOL_TCP;
132
Dynamic_string wrapper functions. In this file use these
133
wrappers, they will terminate the process if there is
134
an allocation failure.
136
static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str,
137
uint init_alloc, uint alloc_increment);
138
static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src);
139
static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str);
140
static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append,
142
static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size);
144
Constant for detection of default value of default_charset.
145
If default_charset is equal to mysql_universal_client_charset, then
146
it is the default value which assigned at the very beginning of main().
148
static const char *mysql_universal_client_charset=
149
MYSQL_UNIVERSAL_CLIENT_CHARSET;
150
static char *default_charset;
151
static CHARSET_INFO *charset_info= &my_charset_latin1;
152
const char *default_dbug_option="d:t:o,/tmp/mysqldump.trace";
153
/* have we seen any VIEWs during table scanning? */
155
const char *compatible_mode_names[]=
157
"MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2",
158
"MAXDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS",
162
#define MASK_ANSI_QUOTES \
164
(1<<2) | /* POSTGRESQL */\
165
(1<<3) | /* ORACLE */\
166
(1<<4) | /* MSSQL */\
168
(1<<6) | /* MAXDB */\
171
TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
172
"", compatible_mode_names, NULL};
176
static struct my_option my_long_options[] =
178
{"all", 'a', "Deprecated. Use --create-options instead.",
179
(char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
181
{"all-databases", 'A',
182
"Dump all the databases. This will be same as --databases with all databases selected.",
183
(char**) &opt_alldbs, (char**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
185
{"all-tablespaces", 'Y',
186
"Dump all the tablespaces.",
187
(char**) &opt_alltspcs, (char**) &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
189
{"no-tablespaces", 'y',
190
"Do not dump any tablespace information.",
191
(char**) &opt_notspcs, (char**) &opt_notspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
193
{"add-drop-database", OPT_DROP_DATABASE, "Add a 'DROP DATABASE' before each create.",
194
(char**) &opt_drop_database, (char**) &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
196
{"add-drop-table", OPT_DROP, "Add a 'drop table' before each create.",
197
(char**) &opt_drop, (char**) &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
199
{"add-locks", OPT_LOCKS, "Add locks around insert statements.",
200
(char**) &opt_lock, (char**) &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
202
{"allow-keywords", OPT_KEYWORDS,
203
"Allow creation of column names that are keywords.", (char**) &opt_keywords,
204
(char**) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
205
{"apply-slave-statements", OPT_MYSQLDUMP_SLAVE_APPLY,
206
"Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
207
(char**) &opt_slave_apply, (char**) &opt_slave_apply, 0, GET_BOOL, NO_ARG,
209
{"character-sets-dir", OPT_CHARSETS_DIR,
210
"Directory where character sets are.", (char**) &charsets_dir,
211
(char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
212
{"comments", 'i', "Write additional information.",
213
(char**) &opt_comments, (char**) &opt_comments, 0, GET_BOOL, NO_ARG,
215
{"compatible", OPT_COMPATIBLE,
216
"Change the dump to be compatible with a given mode. By default tables are dumped in a format optimized for MySQL. Legal modes are: ansi, mysql323, mysql40, postgresql, oracle, mssql, db2, maxdb, no_key_options, no_table_options, no_field_options. One can use several modes separated by commas. Note: Requires MySQL server version 4.1.0 or higher. This option is ignored with earlier server versions.",
217
(char**) &opt_compatible_mode_str, (char**) &opt_compatible_mode_str, 0,
218
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
219
{"compact", OPT_COMPACT,
220
"Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables options --skip-add-drop-table --no-set-names --skip-disable-keys --skip-add-locks",
221
(char**) &opt_compact, (char**) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
223
{"complete-insert", 'c', "Use complete insert statements.",
224
(char**) &opt_complete_insert, (char**) &opt_complete_insert, 0, GET_BOOL,
225
NO_ARG, 0, 0, 0, 0, 0, 0},
226
{"compress", 'C', "Use compression in server/client protocol.",
227
(char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
229
{"create-options", OPT_CREATE_OPTIONS,
230
"Include all MySQL specific create options.",
231
(char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
234
"To dump several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames. 'USE db_name;' will be included in the output.",
235
(char**) &opt_databases, (char**) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
237
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
238
(char**) &debug_check_flag, (char**) &debug_check_flag, 0,
239
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
240
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
241
(char**) &debug_info_flag, (char**) &debug_info_flag,
242
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
243
{"default-character-set", OPT_DEFAULT_CHARSET,
244
"Set the default character set.", (char**) &default_charset,
245
(char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
246
{"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED; ",
247
(char**) &opt_delayed, (char**) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
249
{"delete-master-logs", OPT_DELETE_MASTER_LOGS,
250
"Delete logs on master after backup. This automatically enables --master-data.",
251
(char**) &opt_delete_master_logs, (char**) &opt_delete_master_logs, 0,
252
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
253
{"disable-keys", 'K',
254
"'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (char**) &opt_disable_keys,
255
(char**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
256
{"dump-slave", OPT_MYSQLDUMP_SLAVE_DATA,
257
"This causes the binary log position and filename of the master to be "
258
"appended to the dumped data output. Setting the value to 1, will print"
259
"it as a CHANGE MASTER command in the dumped data output; if equal"
260
" to 2, that command will be prefixed with a comment symbol. "
261
"This option will turn --lock-all-tables on, unless "
262
"--single-transaction is specified too (in which case a "
263
"global read lock is only taken a short time at the beginning of the dump "
264
"- don't forget to read about --single-transaction below). In all cases "
265
"any action on logs will happen at the exact moment of the dump."
266
"Option automatically turns --lock-tables off.",
267
(char**) &opt_slave_data, (char**) &opt_slave_data, 0,
268
GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
269
{"events", 'E', "Dump events.",
270
(char**) &opt_events, (char**) &opt_events, 0, GET_BOOL,
271
NO_ARG, 0, 0, 0, 0, 0, 0},
272
{"extended-insert", 'e',
273
"Allows utilization of the new, much faster INSERT syntax.",
274
(char**) &extended_insert, (char**) &extended_insert, 0, GET_BOOL, NO_ARG,
276
{"fields-terminated-by", OPT_FTB,
277
"Fields in the textfile are terminated by ...", (char**) &fields_terminated,
278
(char**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
279
{"fields-enclosed-by", OPT_ENC,
280
"Fields in the importfile are enclosed by ...", (char**) &enclosed,
281
(char**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
282
{"fields-optionally-enclosed-by", OPT_O_ENC,
283
"Fields in the i.file are opt. enclosed by ...", (char**) &opt_enclosed,
284
(char**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
285
{"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
286
(char**) &escaped, (char**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
287
{"first-slave", 'x', "Deprecated, renamed to --lock-all-tables.",
288
(char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
290
{"flush-logs", 'F', "Flush logs file in server before starting dump. "
291
"Note that if you dump many databases at once (using the option "
292
"--databases= or --all-databases), the logs will be flushed for "
293
"each database dumped. The exception is when using --lock-all-tables "
295
"in this case the logs will be flushed only once, corresponding "
296
"to the moment all tables are locked. So if you want your dump and "
297
"the log flush to happen at the same exact moment you should use "
298
"--lock-all-tables or --master-data with --flush-logs",
299
(char**) &flush_logs, (char**) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
301
{"flush-privileges", OPT_ESC, "Emit a FLUSH PRIVILEGES statement "
302
"after dumping the mysql database. This option should be used any "
303
"time the dump contains the mysql database and any other database "
304
"that depends on the data in the mysql database for proper restore. ",
305
(char**) &flush_privileges, (char**) &flush_privileges, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
307
{"force", 'f', "Continue even if we get an sql-error.",
308
(char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG,
310
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
311
NO_ARG, 0, 0, 0, 0, 0, 0},
312
{"hex-blob", OPT_HEXBLOB, "Dump binary strings (BINARY, "
313
"VARBINARY, BLOB) in hexadecimal format.",
314
(char**) &opt_hex_blob, (char**) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
315
{"host", 'h', "Connect to host.", (char**) ¤t_host,
316
(char**) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
317
{"ignore-table", OPT_IGNORE_TABLE,
318
"Do not dump the specified table. To specify more than one table to ignore, "
319
"use the directive multiple times, once for each table. Each table must "
320
"be specified with both database and table names, e.g. --ignore-table=database.table",
321
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
322
{"include-master-host-port", OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT,
323
"Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' in dump produced with --dump-slave.",
324
(char**) &opt_include_master_host_port,
325
(char**) &opt_include_master_host_port,
328
{"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
329
(char**) &opt_ignore, (char**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
331
{"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
332
(char**) &lines_terminated, (char**) &lines_terminated, 0, GET_STR,
333
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
334
{"lock-all-tables", 'x', "Locks all tables across all databases. This "
335
"is achieved by taking a global read lock for the duration of the whole "
336
"dump. Automatically turns --single-transaction and --lock-tables off.",
337
(char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
339
{"lock-tables", 'l', "Lock all tables for read.", (char**) &lock_tables,
340
(char**) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
341
{"log-error", OPT_ERROR_LOG_FILE, "Append warnings and errors to given file.",
342
(char**) &log_error_file, (char**) &log_error_file, 0, GET_STR,
343
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
344
{"master-data", OPT_MASTER_DATA,
345
"This causes the binary log position and filename to be appended to the "
346
"output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
347
" to 2, that command will be prefixed with a comment symbol. "
348
"This option will turn --lock-all-tables on, unless "
349
"--single-transaction is specified too (in which case a "
350
"global read lock is only taken a short time at the beginning of the dump "
351
"- don't forget to read about --single-transaction below). In all cases "
352
"any action on logs will happen at the exact moment of the dump."
353
"Option automatically turns --lock-tables off.",
354
(char**) &opt_master_data, (char**) &opt_master_data, 0,
355
GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_MASTER_DATA_COMMENTED_SQL, 0, 0, 0},
356
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "",
357
(char**) &opt_max_allowed_packet, (char**) &opt_max_allowed_packet, 0,
358
GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096,
359
(int64_t) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
360
{"net_buffer_length", OPT_NET_BUFFER_LENGTH, "",
361
(char**) &opt_net_buffer_length, (char**) &opt_net_buffer_length, 0,
362
GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L,
363
MALLOC_OVERHEAD-1024, 1024, 0},
364
{"no-autocommit", OPT_AUTOCOMMIT,
365
"Wrap tables with autocommit/commit statements.",
366
(char**) &opt_autocommit, (char**) &opt_autocommit, 0, GET_BOOL, NO_ARG,
368
{"no-create-db", 'n',
369
"'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.}.",
370
(char**) &opt_create_db, (char**) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
372
{"no-create-info", 't', "Don't write table creation info.",
373
(char**) &opt_no_create_info, (char**) &opt_no_create_info, 0, GET_BOOL,
374
NO_ARG, 0, 0, 0, 0, 0, 0},
375
{"no-data", 'd', "No row information.", (char**) &opt_no_data,
376
(char**) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
377
{"no-set-names", 'N',
378
"Deprecated. Use --skip-set-charset instead.",
379
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
380
{"opt", OPT_OPTIMIZE,
381
"Same as --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys. Enabled by default, disable with --skip-opt.",
382
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
383
{"order-by-primary", OPT_ORDER_BY_PRIMARY,
384
"Sorts each table's rows by primary key, or first unique key, if such a key exists. Useful when dumping a MyISAM table to be loaded into an InnoDB table, but will make the dump itself take considerably longer.",
385
(char**) &opt_order_by_primary, (char**) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
387
"Password to use when connecting to server. If password is not given it's solicited on the tty.",
388
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
389
{"port", 'P', "Port number to use for connection.", (char**) &opt_mysql_port,
390
(char**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
392
{"quick", 'q', "Don't buffer query, dump directly to stdout.",
393
(char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
394
{"quote-names",'Q', "Quote table and column names with backticks (`).",
395
(char**) &opt_quoted, (char**) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
397
{"replace", OPT_MYSQL_REPLACE_INTO, "Use REPLACE INTO instead of INSERT INTO.",
398
(char**) &opt_replace_into, (char**) &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
401
"Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).",
402
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
403
{"routines", 'R', "Dump stored routines (functions and procedures).",
404
(char**) &opt_routines, (char**) &opt_routines, 0, GET_BOOL,
405
NO_ARG, 0, 0, 0, 0, 0, 0},
406
{"set-charset", OPT_SET_CHARSET,
407
"Add 'SET NAMES default_character_set' to the output.",
408
(char**) &opt_set_charset, (char**) &opt_set_charset, 0, GET_BOOL, NO_ARG, 1,
410
{"set-variable", 'O',
411
"Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
412
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
414
Note that the combination --single-transaction --master-data
415
will give bullet-proof binlog position only if server >=4.1.3. That's the
416
old "FLUSH TABLES WITH READ LOCK does not block commit" fixed bug.
418
{"single-transaction", OPT_TRANSACTION,
419
"Creates a consistent snapshot by dumping all tables in a single "
420
"transaction. Works ONLY for tables stored in storage engines which "
421
"support multiversioning (currently only InnoDB does); the dump is NOT "
422
"guaranteed to be consistent for other storage engines. "
423
"While a --single-transaction dump is in process, to ensure a valid "
424
"dump file (correct table contents and binary log position), no other "
425
"connection should use the following statements: ALTER TABLE, DROP "
426
"TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not "
427
"isolated from them. Option automatically turns off --lock-tables.",
428
(char**) &opt_single_transaction, (char**) &opt_single_transaction, 0,
429
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
430
{"dump-date", OPT_DUMP_DATE, "Put a dump date to the end of the output.",
431
(char**) &opt_dump_date, (char**) &opt_dump_date, 0,
432
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
433
{"skip-opt", OPT_SKIP_OPTIMIZATION,
434
"Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.",
435
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
437
"Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if mysqldump is run on the same machine as the mysqld daemon.",
438
(char**) &path, (char**) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
439
{"tables", OPT_TABLES, "Overrides option --databases (-B).",
440
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
441
{"tz-utc", OPT_TZ_UTC,
442
"SET TIME_ZONE='+00:00' at top of dump to allow dumping of TIMESTAMP data when a server has data in different time zones or data is being moved between servers with different time zones.",
443
(char**) &opt_tz_utc, (char**) &opt_tz_utc, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
444
#ifndef DONT_ALLOW_USER_CHANGE
445
{"user", 'u', "User for login if not current user.",
446
(char**) ¤t_user, (char**) ¤t_user, 0, GET_STR, REQUIRED_ARG,
449
{"verbose", 'v', "Print info about the various stages.",
450
(char**) &verbose, (char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
451
{"version",'V', "Output version information and exit.", 0, 0, 0,
452
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
453
{"where", 'w', "Dump only selected records; QUOTES mandatory!",
454
(char**) &where, (char**) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
455
{"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
456
NO_ARG, 0, 0, 0, 0, 0, 0},
457
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
460
static const char *load_default_groups[]= { "mysqldump","client",0 };
462
static void maybe_exit(int error);
124
463
static void die(int error, const char* reason, ...);
125
static void write_header(char *db_name);
126
static int dump_selected_tables(const string &db, const vector<string> &table_names);
127
static int dump_databases(const vector<string> &db_names);
464
static void maybe_die(int error, const char* reason, ...);
465
static void write_header(FILE *sql_file, char *db_name);
466
static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
467
const char *prefix,const char *name,
469
static int dump_selected_tables(char *db, char **table_names, int tables);
470
static int dump_all_tables_in_db(char *db);
471
static int init_dumping_tables(char *);
472
static int init_dumping(char *, int init_func(char*));
473
static int dump_databases(char **);
128
474
static int dump_all_databases(void);
129
int get_server_type();
130
void dump_all_tables(void);
131
void generate_dump(void);
132
void generate_dump_db(void);
134
void dump_all_tables(void)
136
std::vector<DrizzleDumpDatabase*>::iterator i;
137
for (i= database_store.begin(); i != database_store.end(); ++i)
139
if ((not (*i)->populateTables()) && (not ignore_errors))
140
maybe_exit(EX_DRIZZLEERR);
144
void generate_dump(void)
146
std::vector<DrizzleDumpDatabase*>::iterator i;
150
cout << endl << "SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;"
151
<< endl << "SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;" << endl;
155
cout << "SET AUTOCOMMIT=0;" << endl;
157
for (i= database_store.begin(); i != database_store.end(); ++i)
159
DrizzleDumpDatabase *database= *i;
165
cout << "SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;"
166
<< endl << "SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;" << endl;
170
void generate_dump_db(void)
172
std::vector<DrizzleDumpDatabase*>::iterator i;
173
DrizzleStringBuf sbuf(1024);
176
destination_connection= new DrizzleDumpConnection(opt_destination_host,
177
opt_destination_port, opt_destination_user, opt_destination_password,
180
catch (std::exception&)
182
cerr << "Could not connect to destination database server" << endl;
183
maybe_exit(EX_DRIZZLEERR);
185
sbuf.setConnection(destination_connection);
186
std::ostream sout(&sbuf);
187
sout.exceptions(ios_base::badbit);
191
sout << "SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;" << endl;
192
sout << "SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;" << endl;
196
cout << "SET AUTOCOMMIT=0;" << endl;
198
for (i= database_store.begin(); i != database_store.end(); ++i)
202
DrizzleDumpDatabase *database= *i;
205
catch (std::exception&)
207
std::cout << _("Error inserting into destination database") << std::endl;
208
if (not ignore_errors)
209
maybe_exit(EX_DRIZZLEERR);
215
sout << "SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;" << endl;
216
sout << "SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;" << endl;
475
static char *quote_name(const char *name, char *buff, bool force);
476
char check_if_ignore_table(const char *table_name, char *table_type);
477
static char *primary_key_fields(const char *table_name);
479
#include <help_start.h>
482
Print the supplied message if in verbose mode
487
... variable number of parameters
490
static void verbose_msg(const char *fmt, ...)
499
vfprintf(stderr, fmt, args);
221
506
exit with message if ferror(file)
228
513
static void check_io(FILE *file)
230
515
if (ferror(file))
231
die(EX_EOF, _("Got errno %d on write"), errno);
234
static void write_header(char *db_name)
236
if ((not opt_compact) and (opt_comments))
238
cout << "-- drizzledump " << VERSION << " libdrizzle "
239
<< drizzle_version() << ", for " << HOST_VENDOR << "-" << HOST_OS
240
<< " (" << HOST_CPU << ")" << endl << "--" << endl;
241
cout << "-- Host: " << current_host << " Database: " << db_name << endl;
242
cout << "-- ------------------------------------------------------" << endl;
243
cout << "-- Server version\t" << db_connection->getServerVersion();
244
if (db_connection->getServerType() == ServerDetect::SERVER_MYSQL_FOUND)
245
cout << " (MySQL server)";
246
else if (db_connection->getServerType() == ServerDetect::SERVER_DRIZZLE_FOUND)
247
cout << " (Drizzle server)";
248
cout << endl << endl;
516
die(EX_EOF, "Got errno %d on write", errno);
519
static void print_version(void)
521
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,DUMP_VERSION,
522
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
523
} /* print_version */
526
static void short_usage_sub(void)
528
printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
529
printf("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n",
531
printf("OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname);
535
static void usage(void)
538
puts("By Igor Romanenko, Monty, Jani & Sinisa");
539
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
540
puts("Dumping definition and data mysql database or table");
542
print_defaults("my",load_default_groups);
543
my_print_help(my_long_options);
544
my_print_variables(my_long_options);
548
static void short_usage(void)
551
printf("For more options, use %s --help\n", my_progname);
554
#include <help_end.h>
557
static void write_header(FILE *sql_file, char *db_name)
561
fputs("<?xml version=\"1.0\"?>\n", sql_file);
563
Schema reference. Allows use of xsi:nil for NULL values and
564
xsi:type to define an element's data type.
566
fputs("<mysqldump ", sql_file);
567
fputs("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"",
569
fputs(">\n", sql_file);
572
else if (!opt_compact)
577
"-- MySQL dump %s Distrib %s, for %s (%s)\n--\n",
578
DUMP_VERSION, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
579
fprintf(sql_file, "-- Host: %s Database: %s\n",
580
current_host ? current_host : "localhost", db_name ? db_name :
582
fputs("-- ------------------------------------------------------\n",
584
fprintf(sql_file, "-- Server version\t%s\n",
585
mysql_get_server_info(&mysql_connection));
589
"\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;"
590
"\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;"
591
"\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;"
592
"\n/*!40101 SET NAMES %s */;\n",default_charset);
596
fprintf(sql_file, "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;\n");
597
fprintf(sql_file, "/*!40103 SET TIME_ZONE='+00:00' */;\n");
602
fprintf(md_result_file,"\
603
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n\
604
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;\n\
250
609
} /* write_header */
253
612
static void write_footer(FILE *sql_file)
616
fputs("</mysqldump>\n", sql_file);
619
else if (!opt_compact)
622
fprintf(sql_file,"/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;\n");
626
fprintf(md_result_file,"\
627
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n\
628
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;\n");
632
"/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n"
633
"/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n"
634
"/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
636
"/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\n");
637
fputs("\n", sql_file);
257
638
if (opt_comments)
259
640
if (opt_dump_date)
261
boost::posix_time::ptime time(boost::posix_time::second_clock::local_time());
643
get_date(time_str, GETDATE_DATE_TIME, 0);
262
644
fprintf(sql_file, "-- Dump completed on %s\n",
263
boost::posix_time::to_simple_string(time).c_str());
266
648
fprintf(sql_file, "-- Dump completed\n");
312
933
vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
315
fprintf(stderr, "%s: %s\n", progname.c_str(), buffer);
936
fprintf(stderr, "%s: %s\n", my_progname, buffer);
318
939
ignore_errors= 0; /* force the exit */
319
940
maybe_exit(error_num);
945
Prints out an error message and maybe kills the process.
949
error_num - process return value
950
fmt_reason - a format string for use by vsnprintf.
951
... - variable arguments for above fmt_reason string
954
This call prints out the formatted error message to stderr and then
955
terminates the process, unless the --force command line option is used.
957
This call should be used for non-fatal errors (such as database
958
errors) that the code may still be able to continue to the next unit
962
static void maybe_die(int error_num, const char* fmt_reason, ...)
966
va_start(args,fmt_reason);
967
vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
970
fprintf(stderr, "%s: %s\n", my_progname, buffer);
973
maybe_exit(error_num);
979
Sends a query to server, optionally reads result, prints error message if
983
mysql_query_with_error_report()
984
mysql_con connection to use
985
res if non zero, result will be put there with
987
query query to send to server
990
0 query sending and (if res!=0) result reading went ok
994
static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res,
997
if (mysql_query(mysql_con, query) ||
998
(res && !((*res)= mysql_store_result(mysql_con))))
1000
maybe_die(EX_MYSQLERR, "Couldn't execute '%s': %s (%d)",
1001
query, mysql_error(mysql_con), mysql_errno(mysql_con));
1009
Switch charset for results to some specified charset. If the server does not
1010
support character_set_results variable, nothing can be done here. As for
1011
whether something should be done here, future new callers of this function
1012
should be aware that the server lacking the facility of switching charsets is
1015
@note If the server lacks support, then nothing is changed and no error
1016
condition is returned.
1018
@returns whether there was an error or not
1020
static int switch_character_set_results(MYSQL *mysql, const char *cs_name)
1022
char query_buffer[QUERY_LENGTH];
1023
size_t query_length;
1025
/* Server lacks facility. This is not an error, by arbitrary decision . */
1026
if (!server_supports_switching_charsets)
1029
query_length= snprintf(query_buffer,
1030
sizeof (query_buffer),
1031
"SET SESSION character_set_results = '%s'",
1032
(const char *) cs_name);
1034
return mysql_real_query(mysql, query_buffer, query_length);
1038
Open a new .sql file to dump the table or view into
1041
open_sql_file_for_table
1042
name name of the table or view
1045
0 Failed to open file
1046
> 0 Handle of the open file
1048
static FILE* open_sql_file_for_table(const char* table)
1051
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
1052
convert_dirname(tmp_path,path,NullS);
1053
res= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
1054
O_WRONLY, MYF(MY_WME));
322
1059
static void free_resources(void)
324
1061
if (md_result_file && md_result_file != stdout)
325
fclose(md_result_file);
326
opt_password.erase();
1062
my_fclose(md_result_file, MYF(0));
1063
my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
1064
if (hash_inited(&ignore_table))
1065
hash_free(&ignore_table);
1066
if (extended_insert)
1067
dynstr_free(&extended_row);
1068
if (insert_pat_inited)
1069
dynstr_free(&insert_pat);
1071
free_defaults(defaults_argv);
330
void maybe_exit(int error)
1076
static void maybe_exit(int error)
332
1078
if (!first_error)
333
1079
first_error= error;
334
1080
if (ignore_errors)
336
delete db_connection;
337
delete destination_connection;
338
1084
free_resources();
1090
db_connect -- connects to the host and selects DB.
1093
static int connect_to_db(char *host, char *user,char *passwd)
1095
char buff[20+FN_REFLEN];
1098
verbose_msg("-- Connecting to %s...\n", host ? host : "localhost");
1099
mysql_init(&mysql_connection);
1101
mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS);
1103
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
1104
mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
1105
if (!(mysql= mysql_real_connect(&mysql_connection,host,user,passwd,
1106
NULL,opt_mysql_port, NULL,
1109
DB_error(&mysql_connection, "when trying to connect");
1112
if (mysql_get_server_version(&mysql_connection) < 40100)
1114
/* Don't dump SET NAMES with a pre-4.1 server (bug#7997). */
1117
/* Don't switch charsets for 4.1 and earlier. (bug#34192). */
1118
server_supports_switching_charsets= false;
1121
set time_zone to UTC to allow dumping date types between servers with
1122
different time zone settings
1126
snprintf(buff, sizeof(buff), "/*!40103 SET TIME_ZONE='+00:00' */");
1127
if (mysql_query_with_error_report(mysql, 0, buff))
1131
} /* connect_to_db */
1135
** dbDisconnect -- disconnects from the host.
1137
static void dbDisconnect(char *host)
1139
verbose_msg("-- Disconnecting from %s...\n", host ? host : "localhost");
1141
} /* dbDisconnect */
1144
static void unescape(FILE *file,char *pos,uint length)
1148
if (!(tmp=(char*) my_malloc(length*2+1, MYF(MY_WME))))
1149
die(EX_MYSQLERR, "Couldn't allocate memory");
1151
mysql_real_escape_string(&mysql_connection, tmp, pos, length);
1156
my_free(tmp, MYF(MY_WME));
1161
static bool test_if_special_chars(const char *str)
1163
#if MYSQL_VERSION_ID >= 32300
1164
for ( ; *str ; str++)
1165
if (!my_isvar(charset_info,*str) && *str != '$')
1169
} /* test_if_special_chars */
1174
quote_name(name, buff, force)
1176
Quotes char string, taking into account compatible mode
1180
name Unquoted string containing that which will be quoted
1181
buff The buffer that contains the quoted value, also returned
1182
force Flag to make it ignore 'test_if_special_chars'
1189
static char *quote_name(const char *name, char *buff, bool force)
1192
char qtype= (opt_compatible_mode & MASK_ANSI_QUOTES) ? '\"' : '`';
1194
if (!force && !opt_quoted && !test_if_special_chars(name))
1195
return (char*) name;
1210
Quote a table name so it can be used in "SHOW TABLES LIKE <tabname>"
1214
name name of the table
1215
buff quoted name of the table
1218
Quote \, _, ' and % characters
1220
Note: Because MySQL uses the C escape syntax in strings
1221
(for example, '\n' to represent newline), you must double
1222
any '\' that you use in your LIKE strings. For example, to
1223
search for '\n', specify it as '\\n'. To search for '\', specify
1224
it as '\\\\' (the backslashes are stripped once by the parser
1225
and another time when the pattern match is done, leaving a
1226
single backslash to be matched).
1228
Example: "t\1" => "t\\\\1"
1231
static char *quote_for_like(const char *name, char *buff)
1243
else if (*name == '\'' || *name == '_' || *name == '%')
1254
Quote and print a string.
1258
xml_file - output file
1259
str - string to print
1263
Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
1266
static void print_quoted_xml(FILE *xml_file, const char *str, ulong len)
1270
for (end= str + len; str != end; str++)
1274
fputs("<", xml_file);
1277
fputs(">", xml_file);
1280
fputs("&", xml_file);
1283
fputs(""", xml_file);
1286
fputc(*str, xml_file);
1295
Print xml tag. Optionally add attribute(s).
1298
print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
1299
..., attribute_name_n, attribute_value_n, NullS)
1300
xml_file - output file
1301
sbeg - line beginning
1302
line_end - line ending
1303
tag_name - XML tag name.
1304
first_attribute_name - tag and first attribute
1305
first_attribute_value - (Implied) value of first attribute
1306
attribute_name_n - attribute n
1307
attribute_value_n - value of attribute n
1310
Print XML tag with any number of attribute="value" pairs to the xml_file.
1313
sbeg<tag_name first_attribute_name="first_attribute_value" ...
1314
attribute_name_n="attribute_value_n">send
1316
Additional arguments must be present in attribute/value pairs.
1317
The last argument should be the null character pointer.
1318
All attribute_value arguments MUST be NULL terminated strings.
1319
All attribute_value arguments will be quoted before output.
1322
static void print_xml_tag(FILE * xml_file, const char* sbeg,
1323
const char* line_end,
1324
const char* tag_name,
1325
const char* first_attribute_name, ...)
1328
const char *attribute_name, *attribute_value;
1330
fputs(sbeg, xml_file);
1331
fputc('<', xml_file);
1332
fputs(tag_name, xml_file);
1334
va_start(arg_list, first_attribute_name);
1335
attribute_name= first_attribute_name;
1336
while (attribute_name != NullS)
1338
attribute_value= va_arg(arg_list, char *);
1339
assert(attribute_value != NullS);
1341
fputc(' ', xml_file);
1342
fputs(attribute_name, xml_file);
1343
fputc('\"', xml_file);
1345
print_quoted_xml(xml_file, attribute_value, strlen(attribute_value));
1346
fputc('\"', xml_file);
1348
attribute_name= va_arg(arg_list, char *);
1352
fputc('>', xml_file);
1353
fputs(line_end, xml_file);
1359
Print xml tag with for a field that is null
1362
print_xml_null_tag()
1363
xml_file - output file
1364
sbeg - line beginning
1365
stag_atr - tag and attribute
1366
sval - value of attribute
1367
line_end - line ending
1370
Print tag with one attribute to the xml_file. Format is:
1371
<stag_atr="sval" xsi:nil="true"/>
1373
sval MUST be a NULL terminated string.
1374
sval string will be qouted before output.
1377
static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
1378
const char* stag_atr, const char* sval,
1379
const char* line_end)
1381
fputs(sbeg, xml_file);
1382
fputs("<", xml_file);
1383
fputs(stag_atr, xml_file);
1384
fputs("\"", xml_file);
1385
print_quoted_xml(xml_file, sval, strlen(sval));
1386
fputs("\" xsi:nil=\"true\" />", xml_file);
1387
fputs(line_end, xml_file);
1393
Print xml tag with many attributes.
1397
xml_file - output file
1398
row_name - xml tag name
1399
tableRes - query result
1403
Print tag with many attribute to the xml_file. Format is:
1404
\t\t<row_name Atr1="Val1" Atr2="Val2"... />
1406
All atributes and values will be quoted before output.
1409
static void print_xml_row(FILE *xml_file, const char *row_name,
1410
MYSQL_RES *tableRes, MYSQL_ROW *row)
1414
uint32_t *lengths= mysql_fetch_lengths(tableRes);
1416
fprintf(xml_file, "\t\t<%s", row_name);
1418
mysql_field_seek(tableRes, 0);
1419
for (i= 0; (field= mysql_fetch_field(tableRes)); i++)
1423
fputc(' ', xml_file);
1424
print_quoted_xml(xml_file, field->name, field->name_length);
1425
fputs("=\"", xml_file);
1426
print_quoted_xml(xml_file, (*row)[i], lengths[i]);
1427
fputc('"', xml_file);
1431
fputs(" />\n", xml_file);
1437
Print hex value for blob data.
1441
output_file - output file
1442
str - string to print
1446
Print hex value for blob data.
1449
static void print_blob_as_hex(FILE *output_file, const char *str, ulong len)
1451
/* sakaik got the idea to to provide blob's in hex notation. */
1452
const char *ptr= str, *end= ptr + len;
1453
for (; ptr < end ; ptr++)
1454
fprintf(output_file, "%02X", *((uchar *)ptr));
1455
check_io(output_file);
1459
get_table_structure -- retrievs database structure, prints out corresponding
1460
CREATE statement and fills out insert_pat if the table is the type we will
1466
table_type - table type, e.g. "MyISAM" or "InnoDB", but also "VIEW"
1467
ignore_flag - what we must particularly ignore - see IGNORE_ defines above
1470
number of fields in table, 0 if error
1473
static uint get_table_structure(char *table, char *db, char *table_type,
1476
bool init=0, delayed, write_data, complete_insert;
1477
uint64_t num_fields;
1478
char *result_table, *opt_quoted_table;
1479
const char *insert_option;
1480
char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
1481
char table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
1482
FILE *sql_file= md_result_file;
1487
*ignore_flag= check_if_ignore_table(table, table_type);
1489
delayed= opt_delayed;
1490
if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
1493
verbose_msg("-- Warning: Unable to use delayed inserts for table '%s' "
1494
"because it's of type %s\n", table, table_type);
1498
if ((write_data= !(*ignore_flag & IGNORE_DATA)))
1500
complete_insert= opt_complete_insert;
1501
if (!insert_pat_inited)
1503
insert_pat_inited= 1;
1504
init_dynamic_string_checked(&insert_pat, "", 1024, 1024);
1507
dynstr_set_checked(&insert_pat, "");
1510
insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
1511
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : "");
1513
verbose_msg("-- Retrieving table structure for table %s...\n", table);
1515
len= snprintf(query_buff, sizeof(query_buff),
1516
"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
1517
(opt_quoted || opt_keywords));
1519
result_table= quote_name(table, table_buff, 1);
1520
opt_quoted_table= quote_name(table, table_buff2, 0);
1522
if (opt_order_by_primary)
1524
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
1525
order_by= primary_key_fields(result_table);
1528
if (!opt_xml && !mysql_query_with_error_report(mysql, 0, query_buff))
1530
/* using SHOW CREATE statement */
1531
if (!opt_no_create_info)
1533
/* Make an sql-file, if path was given iow. option -T was given */
1534
char buff[20+FN_REFLEN];
1537
snprintf(buff, sizeof(buff), "show create table %s", result_table);
1539
if (switch_character_set_results(mysql, "binary") ||
1540
mysql_query_with_error_report(mysql, &result, buff) ||
1541
switch_character_set_results(mysql, default_charset))
1546
if (!(sql_file= open_sql_file_for_table(table)))
1549
write_header(sql_file, db);
1551
if (!opt_xml && opt_comments)
1553
if (strcmp (table_type, "VIEW") == 0) /* view */
1554
fprintf(sql_file, "\n--\n-- Temporary table structure for view %s\n--\n\n",
1557
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1564
Even if the "table" is a view, we do a DROP TABLE here. The
1565
view-specific code below fills in the DROP VIEW.
1567
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",
1572
field= mysql_fetch_field_direct(result, 0);
1573
if (strcmp(field->name, "View") == 0)
1575
char *scv_buff= NULL;
1577
verbose_msg("-- It's a view, create dummy table for view\n");
1579
/* save "show create" statement for later */
1580
if ((row= mysql_fetch_row(result)) && (scv_buff=row[1]))
1581
scv_buff= my_strdup(scv_buff, MYF(0));
1583
mysql_free_result(result);
1586
Create a table with the same name as the view and with columns of
1587
the same name in order to satisfy views that depend on this view.
1588
The table will be removed when the actual view is created.
1590
The properties of each column, aside from the data type, are not
1591
preserved in this temporary table, because they are not necessary.
1593
This will not be necessary once we can determine dependencies
1594
between views and can simply dump them in the appropriate order.
1596
snprintf(query_buff, sizeof(query_buff),
1597
"SHOW FIELDS FROM %s", result_table);
1598
if (switch_character_set_results(mysql, "binary") ||
1599
mysql_query_with_error_report(mysql, &result, query_buff) ||
1600
switch_character_set_results(mysql, default_charset))
1603
View references invalid or privileged table/col/fun (err 1356),
1604
so we cannot create a stand-in table. Be defensive and dump
1605
a comment with the view's 'show create' statement. (Bug #17371)
1608
if (mysql_errno(mysql) == ER_VIEW_INVALID)
1609
fprintf(sql_file, "\n-- failed on view %s: %s\n\n", result_table, scv_buff ? scv_buff : "");
1611
my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR));
1616
my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR));
1618
if (mysql_num_rows(result))
1623
We have already dropped any table of the same name above, so
1624
here we just drop the view.
1627
fprintf(sql_file, "/*!50001 DROP VIEW IF EXISTS %s*/;\n",
1633
"SET @saved_cs_client = @@character_set_client;\n"
1634
"SET character_set_client = utf8;\n"
1635
"/*!50001 CREATE TABLE %s (\n",
1639
Get first row, following loop will prepend comma - keeps from
1640
having to know if the row being printed is last to determine if
1641
there should be a _trailing_ comma.
1644
row= mysql_fetch_row(result);
1646
fprintf(sql_file, " %s %s", quote_name(row[0], name_buff, 0),
1649
while((row= mysql_fetch_row(result)))
1651
/* col name, col type */
1652
fprintf(sql_file, ",\n %s %s",
1653
quote_name(row[0], name_buff, 0), row[1]);
1657
"SET character_set_client = @saved_cs_client;\n");
1662
mysql_free_result(result);
1665
my_fclose(sql_file, MYF(MY_WME));
1671
row= mysql_fetch_row(result);
1674
"SET @saved_cs_client = @@character_set_client;\n"
1675
"SET character_set_client = utf8;\n"
1677
"SET character_set_client = @saved_cs_client;\n",
1681
mysql_free_result(result);
1683
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1685
if (mysql_query_with_error_report(mysql, &result, query_buff))
1688
my_fclose(sql_file, MYF(MY_WME));
1693
If write_data is true, then we build up insert statements for
1694
the table's data. Note: in subsequent lines of code, this test
1695
will have to be performed each time we are appending to
1700
if (opt_replace_into)
1701
dynstr_append_checked(&insert_pat, "REPLACE ");
1703
dynstr_append_checked(&insert_pat, "INSERT ");
1704
dynstr_append_checked(&insert_pat, insert_option);
1705
dynstr_append_checked(&insert_pat, "INTO ");
1706
dynstr_append_checked(&insert_pat, opt_quoted_table);
1707
if (complete_insert)
1709
dynstr_append_checked(&insert_pat, " (");
1713
dynstr_append_checked(&insert_pat, " VALUES ");
1714
if (!extended_insert)
1715
dynstr_append_checked(&insert_pat, "(");
1719
while ((row= mysql_fetch_row(result)))
1721
if (complete_insert)
1725
dynstr_append_checked(&insert_pat, ", ");
1728
dynstr_append_checked(&insert_pat,
1729
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1732
num_fields= mysql_num_rows(result);
1733
mysql_free_result(result);
1737
verbose_msg("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n",
1738
my_progname, mysql_error(mysql));
1740
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1742
if (mysql_query_with_error_report(mysql, &result, query_buff))
1745
/* Make an sql-file, if path was given iow. option -T was given */
1746
if (!opt_no_create_info)
1750
if (!(sql_file= open_sql_file_for_table(table)))
1752
write_header(sql_file, db);
1754
if (!opt_xml && opt_comments)
1755
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1758
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
1760
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
1762
print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
1769
if (opt_replace_into)
1770
dynstr_append_checked(&insert_pat, "REPLACE ");
1772
dynstr_append_checked(&insert_pat, "INSERT ");
1773
dynstr_append_checked(&insert_pat, insert_option);
1774
dynstr_append_checked(&insert_pat, "INTO ");
1775
dynstr_append_checked(&insert_pat, result_table);
1776
if (complete_insert)
1777
dynstr_append_checked(&insert_pat, " (");
1780
dynstr_append_checked(&insert_pat, " VALUES ");
1781
if (!extended_insert)
1782
dynstr_append_checked(&insert_pat, "(");
1786
while ((row= mysql_fetch_row(result)))
1788
uint32_t *lengths= mysql_fetch_lengths(result);
1791
if (!opt_xml && !opt_no_create_info)
1793
fputs(",\n",sql_file);
1796
if (complete_insert)
1797
dynstr_append_checked(&insert_pat, ", ");
1800
if (complete_insert)
1801
dynstr_append_checked(&insert_pat,
1802
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1803
if (!opt_no_create_info)
1807
print_xml_row(sql_file, "field", result, &row);
1812
fprintf(sql_file, " %s.%s %s", result_table,
1813
quote_name(row[SHOW_FIELDNAME],name_buff, 0),
1816
fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME],
1819
if (row[SHOW_DEFAULT])
1821
fputs(" DEFAULT ", sql_file);
1822
unescape(sql_file, row[SHOW_DEFAULT], lengths[SHOW_DEFAULT]);
1824
if (!row[SHOW_NULL][0])
1825
fputs(" NOT NULL", sql_file);
1826
if (row[SHOW_EXTRA][0])
1827
fprintf(sql_file, " %s",row[SHOW_EXTRA]);
1831
num_fields= mysql_num_rows(result);
1832
mysql_free_result(result);
1833
if (!opt_no_create_info)
1835
/* Make an sql-file, if path was given iow. option -T was given */
1836
char buff[20+FN_REFLEN];
1837
uint keynr,primary_key;
1838
snprintf(buff, sizeof(buff), "show keys from %s", result_table);
1839
if (mysql_query_with_error_report(mysql, &result, buff))
1841
if (mysql_errno(mysql) == ER_WRONG_OBJECT)
1844
fputs("\t\t<options Comment=\"view\" />\n", sql_file);
1847
fprintf(stderr, "%s: Can't get keys for table %s (%s)\n",
1848
my_progname, result_table, mysql_error(mysql));
1850
my_fclose(sql_file, MYF(MY_WME));
1854
/* Find first which key is primary key */
1856
primary_key=INT_MAX;
1857
while ((row= mysql_fetch_row(result)))
1859
if (atoi(row[3]) == 1)
1862
#ifdef FORCE_PRIMARY_KEY
1863
if (atoi(row[1]) == 0 && primary_key == INT_MAX)
1866
if (!strcmp(row[2],"PRIMARY"))
1873
mysql_data_seek(result,0);
1875
while ((row= mysql_fetch_row(result)))
1879
print_xml_row(sql_file, "key", result, &row);
1883
if (atoi(row[3]) == 1)
1886
putc(')', sql_file);
1887
if (atoi(row[1])) /* Test if duplicate key */
1888
/* Duplicate allowed */
1889
fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff,0));
1890
else if (keynr == primary_key)
1891
fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
1893
fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,
1897
putc(',', sql_file);
1898
fputs(quote_name(row[4], name_buff, 0), sql_file);
1900
fprintf(sql_file, " (%s)",row[7]); /* Sub key */
1903
mysql_free_result(result);
1907
putc(')', sql_file);
1908
fputs("\n)",sql_file);
1912
/* Get MySQL specific create options */
1915
char show_name_buff[NAME_LEN*2+2+24];
1917
/* Check memory for quote_for_like() */
1918
snprintf(buff, sizeof(buff), "show table status like %s",
1919
quote_for_like(table, show_name_buff));
1921
if (mysql_query_with_error_report(mysql, &result, buff))
1923
if (mysql_errno(mysql) != ER_PARSE_ERROR)
1924
{ /* If old MySQL version */
1925
verbose_msg("-- Warning: Couldn't get status information for " \
1926
"table %s (%s)\n", result_table,mysql_error(mysql));
1929
else if (!(row= mysql_fetch_row(result)))
1932
"Error: Couldn't read status information for table %s (%s)\n",
1933
result_table,mysql_error(mysql));
1938
print_xml_row(sql_file, "options", result, &row);
1941
fputs("/*!",sql_file);
1942
print_value(sql_file,result,row,"engine=","Engine",0);
1943
print_value(sql_file,result,row,"","Create_options",0);
1944
print_value(sql_file,result,row,"comment=","Comment",1);
1945
fputs(" */",sql_file);
1949
mysql_free_result(result); /* Is always safe to free */
1953
fputs(";\n", sql_file);
1955
fputs("\t</table_structure>\n", sql_file);
1959
if (complete_insert)
1961
dynstr_append_checked(&insert_pat, ") VALUES ");
1962
if (!extended_insert)
1963
dynstr_append_checked(&insert_pat, "(");
1965
if (sql_file != md_result_file)
1967
fputs("\n", sql_file);
1968
write_footer(sql_file);
1969
my_fclose(sql_file, MYF(MY_WME));
1971
return((uint) num_fields);
1972
} /* get_table_structure */
1974
static void add_load_option(DYNAMIC_STRING *str, const char *option,
1975
const char *option_value)
1979
/* Null value means we don't add this option. */
1983
dynstr_append_checked(str, option);
1985
if (strncmp(option_value, "0x", sizeof("0x")-1) == 0)
1987
/* It's a hex constant, don't escape */
1988
dynstr_append_checked(str, option_value);
1992
/* char constant; escape */
1993
field_escape(str, option_value);
1999
Allow the user to specify field terminator strings like:
2000
"'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
2001
This is done by doubling ' and add a end -\ if needed to avoid
2002
syntax errors from the SQL parser.
2005
static void field_escape(DYNAMIC_STRING* in, const char *from)
2007
uint end_backslashes= 0;
2009
dynstr_append_checked(in, "'");
2013
dynstr_append_mem_checked(in, from, 1);
2016
end_backslashes^=1; /* find odd number of backslashes */
2019
if (*from == '\'' && !end_backslashes)
2021
/* We want a duplicate of "'" for MySQL */
2022
dynstr_append_checked(in, "\'");
2028
/* Add missing backslashes if user has specified odd number of backs.*/
2029
if (end_backslashes)
2030
dynstr_append_checked(in, "\\");
2032
dynstr_append_checked(in, "'");
2042
dump_table saves database contents as a series of INSERT statements.
2053
static void dump_table(char *table, char *db)
2056
char buf[200], table_buff[NAME_LEN+3];
2057
DYNAMIC_STRING query_string;
2058
char table_type[NAME_LEN];
2059
char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
2061
ulong rownr, row_break, total_length, init_length;
2069
Make sure you get the create table info before the following check for
2070
--no-data flag below. Otherwise, the create table info won't be printed.
2072
num_fields= get_table_structure(table, db, table_type, &ignore_flag);
2075
The "table" could be a view. If so, we don't do anything here.
2077
if (strcmp(table_type, "VIEW") == 0)
2080
/* Check --no-data flag */
2083
verbose_msg("-- Skipping dump data for table '%s', --no-data was used\n",
2089
If the table type is a merge table or any type that has to be
2090
_completely_ ignored and no data dumped
2092
if (ignore_flag & IGNORE_DATA)
2094
verbose_msg("-- Warning: Skipping data for table '%s' because " \
2095
"it's of type %s\n", table, table_type);
2098
/* Check that there are any fields in the table */
2099
if (num_fields == 0)
2101
verbose_msg("-- Skipping dump data for table '%s', it has no fields\n",
2107
Check --skip-events flag: it is not enough to skip creation of events
2108
discarding SHOW CREATE EVENT statements generation. The myslq.event
2109
table data should be skipped too.
2111
if (!opt_events && !my_strcasecmp(&my_charset_latin1, db, "mysql") &&
2112
!my_strcasecmp(&my_charset_latin1, table, "event"))
2114
verbose_msg("-- Skipping data table mysql.event, --skip-events was used\n");
2118
result_table= quote_name(table,table_buff, 1);
2119
opt_quoted_table= quote_name(table, table_buff2, 0);
2121
verbose_msg("-- Sending SELECT query...\n");
2123
init_dynamic_string_checked(&query_string, "", 1024, 1024);
2127
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
2130
Convert the path to native os format
2131
and resolve to the full filepath.
2133
convert_dirname(tmp_path,path,NullS);
2134
my_load_path(tmp_path, tmp_path, NULL);
2135
fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
2137
/* Must delete the file that 'INTO OUTFILE' will write to */
2138
my_delete(filename, MYF(0));
2140
/* convert to a unix path name to stick into the query */
2141
to_unix_path(filename);
2143
/* now build the query string */
2145
dynstr_append_checked(&query_string, "SELECT * INTO OUTFILE '");
2146
dynstr_append_checked(&query_string, filename);
2147
dynstr_append_checked(&query_string, "'");
2149
if (fields_terminated || enclosed || opt_enclosed || escaped)
2150
dynstr_append_checked(&query_string, " FIELDS");
2152
add_load_option(&query_string, " TERMINATED BY ", fields_terminated);
2153
add_load_option(&query_string, " ENCLOSED BY ", enclosed);
2154
add_load_option(&query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed);
2155
add_load_option(&query_string, " ESCAPED BY ", escaped);
2156
add_load_option(&query_string, " LINES TERMINATED BY ", lines_terminated);
2158
dynstr_append_checked(&query_string, " FROM ");
2159
dynstr_append_checked(&query_string, result_table);
2163
dynstr_append_checked(&query_string, " WHERE ");
2164
dynstr_append_checked(&query_string, where);
2169
dynstr_append_checked(&query_string, " ORDER BY ");
2170
dynstr_append_checked(&query_string, order_by);
2173
if (mysql_real_query(mysql, query_string.str, query_string.length))
2175
DB_error(mysql, "when executing 'SELECT INTO OUTFILE'");
2176
dynstr_free(&query_string);
2182
if (!opt_xml && opt_comments)
2184
fprintf(md_result_file,"\n--\n-- Dumping data for table %s\n--\n",
2186
check_io(md_result_file);
2189
dynstr_append_checked(&query_string, "SELECT * FROM ");
2190
dynstr_append_checked(&query_string, result_table);
2194
if (!opt_xml && opt_comments)
2196
fprintf(md_result_file, "-- WHERE: %s\n", where);
2197
check_io(md_result_file);
2200
dynstr_append_checked(&query_string, " WHERE ");
2201
dynstr_append_checked(&query_string, where);
2205
if (!opt_xml && opt_comments)
2207
fprintf(md_result_file, "-- ORDER BY: %s\n", order_by);
2208
check_io(md_result_file);
2210
dynstr_append_checked(&query_string, " ORDER BY ");
2211
dynstr_append_checked(&query_string, order_by);
2214
if (!opt_xml && !opt_compact)
2216
fputs("\n", md_result_file);
2217
check_io(md_result_file);
2219
if (mysql_query_with_error_report(mysql, 0, query_string.str))
2221
DB_error(mysql, "when retrieving data from server");
2225
res=mysql_use_result(mysql);
2227
res=mysql_store_result(mysql);
2230
DB_error(mysql, "when retrieving data from server");
2234
verbose_msg("-- Retrieving rows...\n");
2235
if (mysql_num_fields(res) != num_fields)
2237
fprintf(stderr,"%s: Error in field count for table: %s ! Aborting.\n",
2238
my_progname, result_table);
2239
error= EX_CONSCHECK;
2245
fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table);
2246
check_io(md_result_file);
2248
/* Moved disable keys to after lock per bug 15977 */
2249
if (opt_disable_keys)
2251
fprintf(md_result_file, "/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",
2253
check_io(md_result_file);
2256
total_length= opt_net_buffer_length; /* Force row break */
2259
init_length=(uint) insert_pat.length+4;
2261
print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table,
2265
fprintf(md_result_file, "set autocommit=0;\n");
2266
check_io(md_result_file);
2269
while ((row= mysql_fetch_row(res)))
2272
uint32_t *lengths= mysql_fetch_lengths(res);
2274
if (!extended_insert && !opt_xml)
2276
fputs(insert_pat.str,md_result_file);
2277
check_io(md_result_file);
2279
mysql_field_seek(res,0);
2283
fputs("\t<row>\n", md_result_file);
2284
check_io(md_result_file);
2287
for (i= 0; i < mysql_num_fields(res); i++)
2290
ulong length= lengths[i];
2292
if (!(field= mysql_fetch_field(res)))
2294
"Not enough fields from table %s! Aborting.\n",
2298
63 is my_charset_bin. If charsetnr is not 63,
2299
we have not a BLOB but a TEXT column.
2300
we'll dump in hex only BLOB columns.
2302
is_blob= (opt_hex_blob && field->charsetnr == 63 &&
2303
(field->type == MYSQL_TYPE_STRING ||
2304
field->type == MYSQL_TYPE_VARCHAR ||
2305
field->type == MYSQL_TYPE_BLOB)) ? 1 : 0;
2306
if (extended_insert && !opt_xml)
2309
dynstr_set_checked(&extended_row,"(");
2311
dynstr_append_checked(&extended_row,",");
2317
if (!IS_NUM_FIELD(field))
2320
"length * 2 + 2" is OK for both HEX and non-HEX modes:
2321
- In HEX mode we need exactly 2 bytes per character
2322
plus 2 bytes for '0x' prefix.
2323
- In non-HEX mode we need up to 2 bytes per character,
2324
plus 2 bytes for leading and trailing '\'' characters.
2325
Also we need to reserve 1 byte for terminating '\0'.
2327
dynstr_realloc_checked(&extended_row,length * 2 + 2 + 1);
2328
if (opt_hex_blob && is_blob)
2330
dynstr_append_checked(&extended_row, "0x");
2331
extended_row.length+= mysql_hex_string(extended_row.str +
2332
extended_row.length,
2334
assert(extended_row.length+1 <= extended_row.max_length);
2335
/* mysql_hex_string() already terminated string by '\0' */
2336
assert(extended_row.str[extended_row.length] == '\0');
2340
dynstr_append_checked(&extended_row,"'");
2341
extended_row.length +=
2342
mysql_real_escape_string(&mysql_connection,
2343
&extended_row.str[extended_row.length],
2345
extended_row.str[extended_row.length]='\0';
2346
dynstr_append_checked(&extended_row,"'");
2351
/* change any strings ("inf", "-inf", "nan") into NULL */
2353
if (my_isalpha(charset_info, *ptr) || (*ptr == '-' &&
2354
my_isalpha(charset_info, ptr[1])))
2355
dynstr_append_checked(&extended_row, "NULL");
2358
dynstr_append_checked(&extended_row, ptr);
2363
dynstr_append_checked(&extended_row,"''");
2366
dynstr_append_checked(&extended_row,"NULL");
2372
fputc(',', md_result_file);
2373
check_io(md_result_file);
2377
if (!IS_NUM_FIELD(field))
2381
if (opt_hex_blob && is_blob && length)
2383
/* Define xsi:type="xs:hexBinary" for hex encoded data */
2384
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2385
field->name, "xsi:type=", "xs:hexBinary", NullS);
2386
print_blob_as_hex(md_result_file, row[i], length);
2390
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2391
field->name, NullS);
2392
print_quoted_xml(md_result_file, row[i], length);
2394
fputs("</field>\n", md_result_file);
2396
else if (opt_hex_blob && is_blob && length)
2398
fputs("0x", md_result_file);
2399
print_blob_as_hex(md_result_file, row[i], length);
2402
unescape(md_result_file, row[i], length);
2406
/* change any strings ("inf", "-inf", "nan") into NULL */
2410
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2411
field->name, NullS);
2412
fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
2414
fputs("</field>\n", md_result_file);
2416
else if (my_isalpha(charset_info, *ptr) ||
2417
(*ptr == '-' && my_isalpha(charset_info, ptr[1])))
2418
fputs("NULL", md_result_file);
2420
fputs(ptr, md_result_file);
2425
/* The field value is NULL */
2427
fputs("NULL", md_result_file);
2429
print_xml_null_tag(md_result_file, "\t\t", "field name=",
2432
check_io(md_result_file);
2438
fputs("\t</row>\n", md_result_file);
2439
check_io(md_result_file);
2442
if (extended_insert)
2445
dynstr_append_checked(&extended_row,")");
2446
row_length= 2 + extended_row.length;
2447
if (total_length + row_length < opt_net_buffer_length)
2449
total_length+= row_length;
2450
fputc(',',md_result_file); /* Always row break */
2451
fputs(extended_row.str,md_result_file);
2456
fputs(";\n", md_result_file);
2457
row_break=1; /* This is first row */
2459
fputs(insert_pat.str,md_result_file);
2460
fputs(extended_row.str,md_result_file);
2461
total_length= row_length+init_length;
2463
check_io(md_result_file);
2467
fputs(");\n", md_result_file);
2468
check_io(md_result_file);
2472
/* XML - close table tag and supress regular output */
2474
fputs("\t</table_data>\n", md_result_file);
2475
else if (extended_insert && row_break)
2476
fputs(";\n", md_result_file); /* If not empty table */
2477
fflush(md_result_file);
2478
check_io(md_result_file);
2479
if (mysql_errno(mysql))
2481
snprintf(buf, sizeof(buf),
2482
"%s: Error %d: %s when dumping table %s at row: %ld\n",
2489
error= EX_CONSCHECK;
2493
/* Moved enable keys to before unlock per bug 15977 */
2494
if (opt_disable_keys)
2496
fprintf(md_result_file,"/*!40000 ALTER TABLE %s ENABLE KEYS */;\n",
2498
check_io(md_result_file);
2502
fputs("UNLOCK TABLES;\n", md_result_file);
2503
check_io(md_result_file);
2507
fprintf(md_result_file, "commit;\n");
2508
check_io(md_result_file);
2510
mysql_free_result(res);
2512
dynstr_free(&query_string);
2516
dynstr_free(&query_string);
2522
static char *getTableName(int reset)
2524
static MYSQL_RES *res= NULL;
2529
if (!(res= mysql_list_tables(mysql,NullS)))
2532
if ((row= mysql_fetch_row(res)))
2533
return((char*) row[0]);
2536
mysql_data_seek(res,0); /* We want to read again */
2539
mysql_free_result(res);
2543
} /* getTableName */
342
2546
static int dump_all_databases()
345
drizzle_result_st *tableres;
2549
MYSQL_RES *tableres;
348
DrizzleDumpDatabase *database;
351
std::cerr << _("-- Retrieving database structures...") << std::endl;
353
/* Blocking the MySQL privilege tables too because we can't import them due to bug#646187 */
354
if (db_connection->getServerType() == ServerDetect::SERVER_MYSQL_FOUND)
355
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'performance_schema', 'mysql')";
357
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM DATA_DICTIONARY.SCHEMAS WHERE SCHEMA_NAME NOT IN ('information_schema','data_dictionary')";
359
tableres= db_connection->query(query);
360
while ((row= drizzle_row_next(tableres)))
2552
if (mysql_query_with_error_report(mysql, &tableres, "SHOW DATABASES"))
2554
while ((row= mysql_fetch_row(tableres)))
362
std::string database_name(row[0]);
363
if (db_connection->getServerType() == ServerDetect::SERVER_MYSQL_FOUND)
364
database= new DrizzleDumpDatabaseMySQL(database_name, db_connection);
366
database= new DrizzleDumpDatabaseDrizzle(database_name, db_connection);
368
database->setCollate(row[1]);
369
database_store.push_back(database);
2556
if (dump_all_tables_in_db(row[0]))
371
db_connection->freeResult(tableres);
374
2561
/* dump_all_databases */
377
static int dump_databases(const vector<string> &db_names)
2564
static int dump_databases(char **db_names)
381
DrizzleDumpDatabase *database;
383
for (vector<string>::const_iterator it= db_names.begin(); it != db_names.end(); ++it)
2570
for (db= db_names ; *db ; db++)
386
if (db_connection->getServerType() == ServerDetect::SERVER_MYSQL_FOUND)
387
database= new DrizzleDumpDatabaseMySQL(temp, db_connection);
389
database= new DrizzleDumpDatabaseDrizzle(temp, db_connection);
390
database_store.push_back(database);
2572
if (dump_all_tables_in_db(*db))
393
2576
} /* dump_databases */
395
static int dump_selected_tables(const string &db, const vector<string> &table_names)
397
DrizzleDumpDatabase *database;
399
if (db_connection->getServerType() == ServerDetect::SERVER_MYSQL_FOUND)
400
database= new DrizzleDumpDatabaseMySQL(db, db_connection);
402
database= new DrizzleDumpDatabaseDrizzle(db, db_connection);
404
if (not database->populateTables(table_names))
407
if (not ignore_errors)
408
maybe_exit(EX_DRIZZLEERR);
411
database_store.push_back(database);
2580
Table Specific database initalization.
2584
qdatabase quoted name of the database
2591
int init_dumping_tables(char *qdatabase)
2601
snprintf(qbuf, sizeof(qbuf),
2602
"SHOW CREATE DATABASE IF NOT EXISTS %s",
2605
if (mysql_query(mysql, qbuf) || !(dbinfo = mysql_store_result(mysql)))
2607
/* Old server version, dump generic CREATE DATABASE */
2608
if (opt_drop_database)
2609
fprintf(md_result_file,
2610
"\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n",
2612
fprintf(md_result_file,
2613
"\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n",
2618
if (opt_drop_database)
2619
fprintf(md_result_file,
2620
"\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n",
2622
row = mysql_fetch_row(dbinfo);
2625
fprintf(md_result_file,"\n%s;\n",row[1]);
2627
mysql_free_result(dbinfo);
2631
} /* init_dumping_tables */
2634
static int init_dumping(char *database, int init_func(char*))
2636
if (mysql_get_server_version(mysql) >= 50003 &&
2637
!my_strcasecmp(&my_charset_latin1, database, "information_schema"))
2640
if (mysql_select_db(mysql, database))
2642
DB_error(mysql, "when selecting the database");
2643
return 1; /* If --force */
2645
if (!path && !opt_xml)
2647
if (opt_databases || opt_alldbs)
2650
length of table name * 2 (if name contains quotes), 2 quotes and 0
2652
char quoted_database_buf[NAME_LEN*2+3];
2653
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
2656
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
2657
check_io(md_result_file);
2660
/* Call the view or table specific function */
2661
init_func(qdatabase);
2663
fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
2664
check_io(md_result_file);
2667
if (extended_insert)
2668
init_dynamic_string_checked(&extended_row, "", 1024, 1024);
2670
} /* init_dumping */
2673
/* Return 1 if we should copy the table */
2675
static bool include_table(const uchar *hash_key, size_t len)
2677
return !hash_search(&ignore_table, hash_key, len);
2681
static int dump_all_tables_in_db(char *database)
2685
char table_buff[NAME_LEN*2+3];
2686
char hash_key[2*NAME_LEN+2]; /* "db.tablename" */
2688
int using_mysql_db= my_strcasecmp(&my_charset_latin1, database, "mysql");
2691
afterdot= strmov(hash_key, database);
2694
if (init_dumping(database, init_dumping_tables))
2697
print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
2700
DYNAMIC_STRING query;
2701
init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);
2702
for (numrows= 0 ; (table= getTableName(1)) ; )
2704
char *end= strmov(afterdot, table);
2705
if (include_table((uchar*) hash_key,end - hash_key))
2708
dynstr_append_checked(&query, quote_name(table, table_buff, 1));
2709
dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
2712
if (numrows && mysql_real_query(mysql, query.str, query.length-1))
2713
DB_error(mysql, "when using LOCK TABLES");
2714
/* We shall continue here, if --force was given */
2715
dynstr_free(&query);
2719
if (mysql_refresh(mysql, REFRESH_LOG))
2720
DB_error(mysql, "when doing refresh");
2721
/* We shall continue here, if --force was given */
2723
while ((table= getTableName(0)))
2725
char *end= strmov(afterdot, table);
2726
if (include_table((uchar*) hash_key, end - hash_key))
2728
dump_table(table,database);
2729
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
2735
fputs("</database>\n", md_result_file);
2736
check_io(md_result_file);
2739
VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
2740
if (flush_privileges && using_mysql_db == 0)
2742
fprintf(md_result_file,"\n--\n-- Flush Grant Tables \n--\n");
2743
fprintf(md_result_file,"\n/*! FLUSH PRIVILEGES */;\n");
2746
} /* dump_all_tables_in_db */
2750
get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
2751
table name from the server for the table name given on the command line.
2752
we do this because the table name given on the command line may be a
2753
different case (e.g. T1 vs t1)
2756
pointer to the table name
2760
static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root)
2763
MYSQL_RES *table_res;
2765
char query[50 + 2*NAME_LEN];
2766
char show_name_buff[FN_REFLEN];
2769
/* Check memory for quote_for_like() */
2770
assert(2*sizeof(old_table_name) < sizeof(show_name_buff));
2771
snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
2772
quote_for_like(old_table_name, show_name_buff));
2774
if (mysql_query_with_error_report(mysql, 0, query))
2777
if ((table_res= mysql_store_result(mysql)))
2779
uint64_t num_rows= mysql_num_rows(table_res);
2785
TODO: Return all matching rows
2787
row= mysql_fetch_row(table_res);
2788
lengths= mysql_fetch_lengths(table_res);
2789
name= strmake_root(root, row[0], lengths[0]);
2791
mysql_free_result(table_res);
2797
static int dump_selected_tables(char *db, char **table_names, int tables)
2799
char table_buff[NAME_LEN*2+3];
2800
DYNAMIC_STRING lock_tables_query;
2802
char **dump_tables, **pos, **end;
2805
if (init_dumping(db, init_dumping_tables))
2808
init_alloc_root(&root, 8192, 0);
2809
if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
2810
die(EX_EOM, "alloc_root failure.");
2812
init_dynamic_string_checked(&lock_tables_query, "LOCK TABLES ", 256, 1024);
2813
for (; tables > 0 ; tables-- , table_names++)
2815
/* the table name passed on commandline may be wrong case */
2816
if ((*pos= get_actual_table_name(*table_names, &root)))
2818
/* Add found table name to lock_tables_query */
2821
dynstr_append_checked(&lock_tables_query, quote_name(*pos, table_buff, 1));
2822
dynstr_append_checked(&lock_tables_query, " READ /*!32311 LOCAL */,");
2830
dynstr_free(&lock_tables_query);
2831
free_root(&root, MYF(0));
2833
maybe_die(EX_ILLEGAL_TABLE, "Couldn't find table: \"%s\"", *table_names);
2834
/* We shall countinue here, if --force was given */
2841
if (mysql_real_query(mysql, lock_tables_query.str,
2842
lock_tables_query.length-1))
2846
dynstr_free(&lock_tables_query);
2847
free_root(&root, MYF(0));
2849
DB_error(mysql, "when doing LOCK TABLES");
2850
/* We shall countinue here, if --force was given */
2853
dynstr_free(&lock_tables_query);
2856
if (mysql_refresh(mysql, REFRESH_LOG))
2859
free_root(&root, MYF(0));
2860
DB_error(mysql, "when doing refresh");
2862
/* We shall countinue here, if --force was given */
2865
print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS);
2867
/* Dump each selected table */
2868
for (pos= dump_tables; pos < end; pos++)
2869
dump_table(*pos, db);
2871
free_root(&root, MYF(0));
2872
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
2876
fputs("</database>\n", md_result_file);
2877
check_io(md_result_file);
2880
VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
414
2882
} /* dump_selected_tables */
416
static int do_flush_tables_read_lock()
2885
static int do_show_master_status(MYSQL *mysql_con)
2889
const char *comment_prefix=
2890
(opt_master_data == MYSQL_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : "";
2891
if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS"))
2897
row= mysql_fetch_row(master);
2898
if (row && row[0] && row[1])
2900
/* SHOW MASTER STATUS reports file and position */
2902
fprintf(md_result_file,
2903
"\n--\n-- Position to start replication or point-in-time "
2904
"recovery from\n--\n\n");
2905
fprintf(md_result_file,
2906
"%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
2907
comment_prefix, row[0], row[1]);
2908
check_io(md_result_file);
2910
else if (!ignore_errors)
2912
/* SHOW MASTER STATUS reports nothing and --force is not enabled */
2913
my_printf_error(0, "Error: Binlogging on server not active",
2915
mysql_free_result(master);
2916
maybe_exit(EX_MYSQLERR);
2919
mysql_free_result(master);
2924
static int do_stop_slave_sql(MYSQL *mysql_con)
2927
/* We need to check if the slave sql is running in the first place */
2928
if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
2932
MYSQL_ROW row= mysql_fetch_row(slave);
2935
/* if SLAVE SQL is not running, we don't stop it */
2936
if (!strcmp(row[11],"No"))
2938
mysql_free_result(slave);
2939
/* Silently assume that they don't have the slave running */
2944
mysql_free_result(slave);
2946
/* now, stop slave if running */
2947
if (mysql_query_with_error_report(mysql_con, 0, "STOP SLAVE SQL_THREAD"))
2953
static int add_stop_slave(void)
2956
fprintf(md_result_file,
2957
"\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
2958
fprintf(md_result_file, "STOP SLAVE;\n");
2962
static int add_slave_statements(void)
2965
fprintf(md_result_file,
2966
"\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
2967
fprintf(md_result_file, "START SLAVE;\n");
2971
static int do_show_slave_status(MYSQL *mysql_con)
2974
const char *comment_prefix=
2975
(opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
2976
if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
2980
/* SHOW SLAVE STATUS reports nothing and --force is not enabled */
2981
my_printf_error(0, "Error: Slave not set up", MYF(0));
2987
MYSQL_ROW row= mysql_fetch_row(slave);
2988
if (row && row[9] && row[21])
2990
/* SHOW MASTER STATUS reports file and position */
2992
fprintf(md_result_file,
2993
"\n--\n-- Position to start replication or point-in-time "
2994
"recovery from (the master of this slave)\n--\n\n");
2996
fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
2998
if (opt_include_master_host_port)
3001
fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
3003
fprintf(md_result_file, "MASTER_PORT='%s', ", row[3]);
3005
fprintf(md_result_file,
3006
"MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
3008
check_io(md_result_file);
3010
mysql_free_result(slave);
3015
static int do_start_slave_sql(MYSQL *mysql_con)
3018
/* We need to check if the slave sql is stopped in the first place */
3019
if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
3023
MYSQL_ROW row= mysql_fetch_row(slave);
3026
/* if SLAVE SQL is not running, we don't start it */
3027
if (!strcmp(row[11],"Yes"))
3029
mysql_free_result(slave);
3030
/* Silently assume that they don't have the slave running */
3035
mysql_free_result(slave);
3037
/* now, start slave if stopped */
3038
if (mysql_query_with_error_report(mysql_con, 0, "START SLAVE"))
3040
my_printf_error(0, "Error: Unable to start slave", MYF(0));
3048
static int do_flush_tables_read_lock(MYSQL *mysql_con)
419
3051
We do first a FLUSH TABLES. If a long update is running, the FLUSH TABLES
420
3052
will wait but will not stall the whole mysqld, and when the long update is
421
3053
done the FLUSH TABLES WITH READ LOCK will start and succeed quickly. So,
422
FLUSH TABLES is to lower the probability of a stage where both drizzled
3054
FLUSH TABLES is to lower the probability of a stage where both mysqldump
423
3055
and most client connections are stalled. Of course, if a second long
424
3056
update starts between the two FLUSHes, we have that bad stall.
427
db_connection->queryNoResult("FLUSH TABLES");
428
db_connection->queryNoResult("FLUSH TABLES WITH READ LOCK");
433
static int do_unlock_tables()
435
db_connection->queryNoResult("UNLOCK TABLES");
439
static int start_transaction()
441
db_connection->queryNoResult("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ");
442
db_connection->queryNoResult("START TRANSACTION WITH CONSISTENT SNAPSHOT");
3059
( mysql_query_with_error_report(mysql_con, 0, "FLUSH TABLES") ||
3060
mysql_query_with_error_report(mysql_con, 0,
3061
"FLUSH TABLES WITH READ LOCK") );
3065
static int do_unlock_tables(MYSQL *mysql_con)
3067
return mysql_query_with_error_report(mysql_con, 0, "UNLOCK TABLES");
3070
static int get_bin_log_name(MYSQL *mysql_con,
3071
char* buff_log_name, uint buff_len)
3076
if (mysql_query(mysql_con, "SHOW MASTER STATUS") ||
3077
!(res= mysql_store_result(mysql)))
3080
if (!(row= mysql_fetch_row(res)))
3082
mysql_free_result(res);
3086
Only one row is returned, and the first column is the name of the
3089
strmake(buff_log_name, row[0], buff_len - 1);
3091
mysql_free_result(res);
3095
static int purge_bin_logs_to(MYSQL *mysql_con, char* log_name)
3099
init_dynamic_string_checked(&str, "PURGE BINARY LOGS TO '", 1024, 1024);
3100
dynstr_append_checked(&str, log_name);
3101
dynstr_append_checked(&str, "'");
3102
err = mysql_query_with_error_report(mysql_con, 0, str.str);
3108
static int start_transaction(MYSQL *mysql_con)
3111
We use BEGIN for old servers. --single-transaction --master-data will fail
3112
on old servers, but that's ok as it was already silently broken (it didn't
3113
do a consistent read, so better tell people frankly, with the error).
3115
We want the first consistent read to be used for all tables to dump so we
3116
need the REPEATABLE READ level (not anything lower, for example READ
3117
COMMITTED would give one new consistent read per dumped table).
3119
if ((mysql_get_server_version(mysql_con) < 40100) && opt_master_data)
3121
fprintf(stderr, "-- %s: the combination of --single-transaction and "
3122
"--master-data requires a MySQL server version of at least 4.1 "
3123
"(current server's version is %s). %s\n",
3124
ignore_errors ? "Warning" : "Error",
3125
mysql_con->server_version ? mysql_con->server_version : "unknown",
3126
ignore_errors ? "Continuing due to --force, backup may not be consistent across all tables!" : "Aborting.");
3131
return (mysql_query_with_error_report(mysql_con, 0,
3132
"SET SESSION TRANSACTION ISOLATION "
3133
"LEVEL REPEATABLE READ") ||
3134
mysql_query_with_error_report(mysql_con, 0,
3135
"START TRANSACTION "
3136
"/*!40100 WITH CONSISTENT SNAPSHOT */"));
3140
static ulong find_set(TYPELIB *lib, const char *x, uint length,
3141
char **err_pos, uint *err_len)
3143
const char *end= x + length;
3148
*err_pos= 0; /* No error yet */
3149
while (end > x && my_isspace(charset_info, end[-1]))
3155
const char *start= x;
3158
const char *pos= start;
3161
for (; pos != end && *pos != ','; pos++) ;
3162
var_len= (uint) (pos - start);
3163
strmake(buff, start, min(sizeof(buff), var_len));
3164
find= find_type(buff, lib, var_len);
3167
*err_pos= (char*) start;
3171
found|= ((int64_t) 1 << (find - 1));
3181
/* Print a value with a prefix on file */
3182
static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
3183
const char *prefix, const char *name,
3187
mysql_field_seek(result, 0);
3189
for ( ; (field= mysql_fetch_field(result)) ; row++)
3191
if (!strcmp(field->name,name))
3193
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
3196
fputs(prefix, file);
3198
unescape(file,row[0],(uint) strlen(row[0]));
3200
fputs(row[0], file);
3206
return; /* This shouldn't happen */
3213
Check if we the table is one of the table types that should be ignored:
3214
MRG_ISAM, MRG_MYISAM, if opt_delayed, if that table supports delayed inserts.
3215
If the table should be altogether ignored, it returns a true, false if it
3216
should not be ignored. If the user has selected to use INSERT DELAYED, it
3217
sets the value of the bool pointer supports_delayed_inserts to 0 if not
3218
supported, 1 if it is supported.
3222
check_if_ignore_table()
3223
table_name Table name to check
3224
table_type Type of table
3227
mysql MySQL connection
3228
verbose Write warning messages
3231
char (bit value) See IGNORE_ values at top
3234
char check_if_ignore_table(const char *table_name, char *table_type)
3236
char result= IGNORE_NONE;
3237
char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
3238
MYSQL_RES *res= NULL;
3242
/* Check memory for quote_for_like() */
3243
assert(2*sizeof(table_name) < sizeof(show_name_buff));
3244
snprintf(buff, sizeof(buff), "show table status like %s",
3245
quote_for_like(table_name, show_name_buff));
3246
if (mysql_query_with_error_report(mysql, &res, buff))
3248
if (mysql_errno(mysql) != ER_PARSE_ERROR)
3249
{ /* If old MySQL version */
3250
verbose_msg("-- Warning: Couldn't get status information for "
3251
"table %s (%s)\n", table_name, mysql_error(mysql));
3252
return(result); /* assume table is ok */
3255
if (!(row= mysql_fetch_row(res)))
3258
"Error: Couldn't read status information for table %s (%s)\n",
3259
table_name, mysql_error(mysql));
3260
mysql_free_result(res);
3261
return(result); /* assume table is ok */
3264
strmake(table_type, "VIEW", NAME_LEN-1);
3268
If the table type matches any of these, we do support delayed inserts.
3269
Note: we do not want to skip dumping this table if if is not one of
3270
these types, but we do want to use delayed inserts in the dump if
3271
the table type is _NOT_ one of these types
3273
strmake(table_type, row[1], NAME_LEN-1);
3276
if (strcmp(table_type,"MyISAM") &&
3277
strcmp(table_type,"ISAM") &&
3278
strcmp(table_type,"ARCHIVE") &&
3279
strcmp(table_type,"HEAP") &&
3280
strcmp(table_type,"MEMORY"))
3281
result= IGNORE_INSERT_DELAYED;
3285
If these two types, we do want to skip dumping the table
3288
(!my_strcasecmp(&my_charset_latin1, table_type, "MRG_MyISAM") ||
3289
!strcmp(table_type,"MRG_ISAM")))
3290
result= IGNORE_DATA;
3292
mysql_free_result(res);
3298
Get string of comma-separated primary key field names
3301
char *primary_key_fields(const char *table_name)
3302
RETURNS pointer to allocated buffer (must be freed by caller)
3303
table_name quoted table name
3306
Use SHOW KEYS FROM table_name, allocate a buffer to hold the
3307
field names, and then build that string and return the pointer
3310
Returns NULL if there is no PRIMARY or UNIQUE key on the table,
3311
or if there is some failure. It is better to continue to dump
3312
the table unsorted, rather than exit without dumping the data.
3315
static char *primary_key_fields(const char *table_name)
3317
MYSQL_RES *res= NULL;
3319
/* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */
3320
char show_keys_buff[15 + NAME_LEN * 2 + 3];
3321
uint result_length= 0;
3323
char buff[NAME_LEN * 2 + 3];
3326
snprintf(show_keys_buff, sizeof(show_keys_buff),
3327
"SHOW KEYS FROM %s", table_name);
3328
if (mysql_query(mysql, show_keys_buff) ||
3329
!(res= mysql_store_result(mysql)))
3331
fprintf(stderr, "Warning: Couldn't read keys from table %s;"
3332
" records are NOT sorted (%s)\n",
3333
table_name, mysql_error(mysql));
3334
/* Don't exit, because it's better to print out unsorted records */
3339
* Figure out the length of the ORDER BY clause result.
3340
* Note that SHOW KEYS is ordered: a PRIMARY key is always the first
3341
* row, and UNIQUE keys come before others. So we only need to check
3342
* the first key, not all keys.
3344
if ((row= mysql_fetch_row(res)) && atoi(row[1]) == 0)
3349
quoted_field= quote_name(row[4], buff, 0);
3350
result_length+= strlen(quoted_field) + 1; /* + 1 for ',' or \0 */
3351
} while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1);
3354
/* Build the ORDER BY clause result */
3358
/* result (terminating \0 is already in result_length) */
3359
result= my_malloc(result_length + 10, MYF(MY_WME));
3362
fprintf(stderr, "Error: Not enough memory to store ORDER BY clause\n");
3365
mysql_data_seek(res, 0);
3366
row= mysql_fetch_row(res);
3367
quoted_field= quote_name(row[4], buff, 0);
3368
end= strmov(result, quoted_field);
3369
while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1)
3371
quoted_field= quote_name(row[4], buff, 0);
3372
end= strxmov(end, ",", quoted_field, NullS);
3378
mysql_free_result(res);
3384
The following functions are wrappers for the dynamic string functions
3385
and if they fail, the wrappers will terminate the current process.
3388
#define DYNAMIC_STR_ERROR_MSG "Couldn't perform DYNAMIC_STRING operation"
3390
static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str,
3391
uint init_alloc, uint alloc_increment)
3393
if (init_dynamic_string(str, init_str, init_alloc, alloc_increment))
3394
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
3397
static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src)
3399
if (dynstr_append(dest, src))
3400
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
3403
static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str)
3405
if (dynstr_set(str, init_str))
3406
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
3409
static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append,
3412
if (dynstr_append_mem(str, append, length))
3413
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
3416
static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size)
3418
if (dynstr_realloc(str, additional_size))
3419
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
446
3423
int main(int argc, char **argv)
3425
char bin_log_name[FN_REFLEN];
452
#if defined(ENABLE_NLS)
453
# if defined(HAVE_LOCALE_H)
454
setlocale(LC_ALL, "");
456
bindtextdomain("drizzle7", LOCALEDIR);
457
textdomain("drizzle7");
460
po::options_description commandline_options(_("Options used only in command line"));
461
commandline_options.add_options()
462
("all-databases,A", po::value<bool>(&opt_alldbs)->default_value(false)->zero_tokens(),
463
_("Dump all the databases. This will be same as --databases with all databases selected."))
464
("flush-logs,F", po::value<bool>(&flush_logs)->default_value(false)->zero_tokens(),
465
_("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. The exception is when using --lock-all-tables 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 --flush-logs"))
466
("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
467
_("Continue even if we get an sql-error."))
468
("help,?", _("Display this help message and exit."))
469
("lock-all-tables,x", po::value<bool>(&opt_lock_all_tables)->default_value(false)->zero_tokens(),
470
_("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 off."))
471
("single-transaction", po::value<bool>(&opt_single_transaction)->default_value(false)->zero_tokens(),
472
_("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. While a --single-transaction dump is in process, to ensure a valid dump file (correct table contents), no other connection should use the following statements: ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not isolated from them."))
474
_("Disable --opt. Disables --add-drop-table, --add-locks, --create-options, ---extended-insert and --disable-keys."))
475
("tables", _("Overrides option --databases (-B)."))
476
("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(10000),
477
_("Number of rows before each output progress report (requires --verbose)."))
478
("verbose,v", po::value<bool>(&verbose)->default_value(false)->zero_tokens(),
479
_("Print info about the various stages."))
480
("version,V", _("Output version information and exit."))
481
("skip-comments", _("Turn off Comments"))
482
("skip-create", _("Turn off create-options"))
483
("skip-extended-insert", _("Turn off extended-insert"))
484
("skip-dump-date", _( "Turn off dump date at the end of the output"))
485
("no-defaults", _("Do not read from the configuration files"))
488
po::options_description dump_options(_("Options specific to the drizzle client"));
489
dump_options.add_options()
490
("add-drop-database", po::value<bool>(&opt_drop_database)->default_value(false)->zero_tokens(),
491
_("Add a 'DROP DATABASE' before each create."))
492
("skip-drop-table", _("Do not add a 'drop table' before each create."))
493
("compact", po::value<bool>(&opt_compact)->default_value(false)->zero_tokens(),
494
_("Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables options --skip-add-drop-table --no-set-names --skip-disable-keys"))
495
("databases,B", po::value<bool>(&opt_databases)->default_value(false)->zero_tokens(),
496
_("To dump several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames. 'USE db_name;' will be included in the output."))
497
("skip-disable-keys,K",
498
_("'ALTER TABLE tb_name DISABLE KEYS;' and 'ALTER TABLE tb_name ENABLE KEYS;' will not be put in the output."))
499
("ignore-table", po::value<string>(),
500
_("Do not dump the specified table. To specify more than one table to ignore, use the directive multiple times, once for each table. Each table must be specified with both database and table names, e.g. --ignore-table=database.table"))
501
("insert-ignore", po::value<bool>(&opt_ignore)->default_value(false)->zero_tokens(),
502
_("Insert rows with INSERT IGNORE."))
503
("no-autocommit", po::value<bool>(&opt_autocommit)->default_value(false)->zero_tokens(),
504
_("Wrap a table's data in START TRANSACTION/COMMIT statements."))
505
("no-create-db,n", po::value<bool>(&opt_create_db)->default_value(false)->zero_tokens(),
506
_("'CREATE DATABASE IF NOT EXISTS db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given."))
507
("no-data,d", po::value<bool>(&opt_no_data)->default_value(false)->zero_tokens(),
508
_("No row information."))
509
("replace", po::value<bool>(&opt_replace_into)->default_value(false)->zero_tokens(),
510
_("Use REPLACE INTO instead of INSERT INTO."))
511
("destination-type", po::value<string>()->default_value("stdout"),
512
_("Where to send output to (stdout|database"))
513
("destination-host", po::value<string>(&opt_destination_host)->default_value("localhost"),
514
_("Hostname for destination db server (requires --destination-type=database)"))
515
("destination-port", po::value<uint16_t>(&opt_destination_port)->default_value(4427),
516
_("Port number for destination db server (requires --destination-type=database)"))
517
("destination-user", po::value<string>(&opt_destination_user),
518
_("User name for destination db server (resquires --destination-type=database)"))
519
("destination-password", po::value<string>(&opt_destination_password),
520
_("Password for destination db server (requires --destination-type=database)"))
521
("destination-database", po::value<string>(&opt_destination_database),
522
_("The database in the destination db server (requires --destination-type=database, not for use with --all-databases)"))
523
("my-data-is-mangled", po::value<bool>(&opt_data_is_mangled)->default_value(false)->zero_tokens(),
524
_("Do not make a UTF8 connection to MySQL, use if you have UTF8 data in a non-UTF8 table"))
527
po::options_description client_options(_("Options specific to the client"));
528
client_options.add_options()
529
("host,h", po::value<string>(¤t_host)->default_value("localhost"),
530
_("Connect to host."))
531
("password,P", po::value<string>(&password)->default_value(PASSWORD_SENTINEL),
532
_("Password to use when connecting to server. If password is not given it's solicited on the tty."))
533
("port,p", po::value<uint32_t>(&opt_drizzle_port)->default_value(0),
534
_("Port number to use for connection."))
535
("user,u", po::value<string>(¤t_user)->default_value(""),
536
_("User for login if not current user."))
537
("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
538
_("The protocol of connection (mysql or drizzle)."))
541
po::options_description hidden_options(_("Hidden Options"));
542
hidden_options.add_options()
543
("database-used", po::value<vector<string> >(), _("Used to select the database"))
544
("Table-used", po::value<vector<string> >(), _("Used to select the tables"))
547
po::options_description all_options(_("Allowed Options + Hidden Options"));
548
all_options.add(commandline_options).add(dump_options).add(client_options).add(hidden_options);
550
po::options_description long_options(_("Allowed Options"));
551
long_options.add(commandline_options).add(dump_options).add(client_options);
553
std::string system_config_dir_dump(SYSCONFDIR);
554
system_config_dir_dump.append("/drizzle/drizzledump.cnf");
556
std::string system_config_dir_client(SYSCONFDIR);
557
system_config_dir_client.append("/drizzle/client.cnf");
559
std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
561
if (user_config_dir.compare(0, 2, "~/") == 0)
564
homedir= getenv("HOME");
566
user_config_dir.replace(0, 1, homedir);
569
po::positional_options_description p;
570
p.add("database-used", 1);
571
p.add("Table-used",-1);
573
md_result_file= stdout;
575
po::variables_map vm;
577
// Disable allow_guessing
578
int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
580
po::store(po::command_line_parser(argc, argv).style(style).
581
options(all_options).positional(p).
582
extra_parser(parse_password_arg).run(), vm);
584
if (! vm.count("no-defaults"))
586
std::string user_config_dir_dump(user_config_dir);
587
user_config_dir_dump.append("/drizzle/drizzledump.cnf");
589
std::string user_config_dir_client(user_config_dir);
590
user_config_dir_client.append("/drizzle/client.cnf");
592
ifstream user_dump_ifs(user_config_dir_dump.c_str());
593
po::store(parse_config_file(user_dump_ifs, dump_options), vm);
595
ifstream user_client_ifs(user_config_dir_client.c_str());
596
po::store(parse_config_file(user_client_ifs, client_options), vm);
598
ifstream system_dump_ifs(system_config_dir_dump.c_str());
599
po::store(parse_config_file(system_dump_ifs, dump_options), vm);
601
ifstream system_client_ifs(system_config_dir_client.c_str());
602
po::store(parse_config_file(system_client_ifs, client_options), vm);
607
if ((not vm.count("database-used") && not vm.count("Table-used")
608
&& not opt_alldbs && path.empty())
609
|| (vm.count("help")) || vm.count("version"))
611
printf(_("Drizzledump %s build %s, for %s-%s (%s)\n"),
612
drizzle_version(), VERSION, HOST_VENDOR, HOST_OS, HOST_CPU);
613
if (vm.count("version"))
616
puts(_("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"));
617
puts(_("Dumps definitions and data from a Drizzle database server"));
618
printf(_("Usage: %s [OPTIONS] database [tables]\n"), progname.c_str());
619
printf(_("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n"),
621
printf(_("OR %s [OPTIONS] --all-databases [OPTIONS]\n"), progname.c_str());
622
cout << long_options;
623
if (vm.count("help"))
629
/* Inverted Booleans */
631
opt_drop= (vm.count("skip-drop-table")) ? false : true;
632
opt_comments= (vm.count("skip-comments")) ? false : true;
633
extended_insert= (vm.count("skip-extended-insert")) ? false : true;
634
opt_dump_date= (vm.count("skip-dump-date")) ? false : true;
635
opt_disable_keys= (vm.count("skip-disable-keys")) ? false : true;
636
opt_quoted= (vm.count("skip-quote-names")) ? false : true;
638
if (vm.count("protocol"))
640
std::transform(opt_protocol.begin(), opt_protocol.end(),
641
opt_protocol.begin(), ::tolower);
643
if (not opt_protocol.compare("mysql"))
644
use_drizzle_protocol=false;
645
else if (not opt_protocol.compare("drizzle"))
646
use_drizzle_protocol=true;
649
cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
654
if (vm.count("port"))
656
/* If the port number is > 65535 it is not a valid port
657
* This also helps with potential data loss casting unsigned long to a
660
if (opt_drizzle_port > 65535)
662
fprintf(stderr, _("Value supplied for port is not valid.\n"));
667
if(vm.count("password"))
669
if (!opt_password.empty())
670
opt_password.erase();
671
if (password == PASSWORD_SENTINEL)
677
opt_password= password;
691
if (vm.count("skip-opt"))
693
extended_insert= opt_drop= create_options= 0;
699
opt_comments= opt_drop= opt_disable_keys= 0;
704
extended_insert= opt_drop= create_options= 1;
708
if (vm.count("tables"))
710
opt_databases= false;
713
if (vm.count("ignore-table"))
715
if (!strchr(vm["ignore-table"].as<string>().c_str(), '.'))
717
fprintf(stderr, _("Illegal use of option --ignore-table=<database>.<table>\n"));
718
exit(EXIT_ARGUMENT_INVALID);
720
string tmpptr(vm["ignore-table"].as<string>());
721
ignore_table.insert(tmpptr);
724
if (vm.count("skip-create"))
726
opt_create_db= opt_no_create_info= create_options= false;
729
exit_code= get_options();
3427
MY_INIT("mysqldump");
3429
compatible_mode_normal_str[0]= 0;
3430
default_charset= (char *)mysql_universal_client_charset;
3431
bzero((char*) &ignore_table, sizeof(ignore_table));
3433
exit_code= get_options(&argc, &argv);
732
3436
free_resources();
733
3437
exit(exit_code);
737
db_connection = new DrizzleDumpConnection(current_host, opt_drizzle_port,
738
current_user, opt_password, use_drizzle_protocol);
740
catch (std::exception&)
742
maybe_exit(EX_DRIZZLEERR);
745
if ((db_connection->getServerType() == ServerDetect::SERVER_MYSQL_FOUND) and (not opt_data_is_mangled))
746
db_connection->queryNoResult("SET NAMES 'utf8'");
748
if (vm.count("destination-type"))
750
string tmp_destination(vm["destination-type"].as<string>());
751
if (tmp_destination.compare("database") == 0)
752
opt_destination= DESTINATION_DB;
753
else if (tmp_destination.compare("stdout") == 0)
754
opt_destination= DESTINATION_STDOUT;
756
exit(EXIT_ARGUMENT_INVALID);
760
if (path.empty() && vm.count("database-used"))
762
string database_used= *vm["database-used"].as< vector<string> >().begin();
763
write_header((char *)database_used.c_str());
766
if ((opt_lock_all_tables) && do_flush_tables_read_lock())
768
if (opt_single_transaction && start_transaction())
770
if (opt_lock_all_tables)
771
db_connection->queryNoResult("FLUSH LOGS");
772
if (opt_single_transaction && do_unlock_tables()) /* unlock but no commit! */
3442
if(!(stderror_file= freopen(log_error_file, "a+", stderr)))
3449
if (connect_to_db(current_host, current_user, opt_password))
3455
write_header(md_result_file, *argv);
3457
if (opt_slave_data && do_stop_slave_sql(mysql))
3460
if ((opt_lock_all_tables || opt_master_data) &&
3461
do_flush_tables_read_lock(mysql))
3463
if (opt_single_transaction && start_transaction(mysql))
3465
if (opt_delete_master_logs)
3467
if (mysql_refresh(mysql, REFRESH_LOG) ||
3468
get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name)))
3472
if (opt_lock_all_tables || opt_master_data)
3474
if (flush_logs && mysql_refresh(mysql, REFRESH_LOG))
3476
flush_logs= 0; /* not anymore; that would not be sensible */
3478
/* Add 'STOP SLAVE to beginning of dump */
3479
if (opt_slave_apply && add_stop_slave())
3481
if (opt_master_data && do_show_master_status(mysql))
3483
if (opt_slave_data && do_show_slave_status(mysql))
3485
if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */
777
3490
dump_all_databases();
780
if (vm.count("database-used") && vm.count("Table-used") && ! opt_databases)
3492
else if (argc > 1 && !opt_databases)
782
string database_used= *vm["database-used"].as< vector<string> >().begin();
783
3494
/* Only one database and selected table(s) */
784
dump_selected_tables(database_used, vm["Table-used"].as< vector<string> >());
787
if (vm.count("Table-used") and opt_databases)
789
vector<string> database_used= vm["database-used"].as< vector<string> >();
790
vector<string> table_used= vm["Table-used"].as< vector<string> >();
792
for (vector<string>::iterator it= table_used.begin();
793
it != table_used.end();
796
database_used.insert(database_used.end(), *it);
799
dump_databases(database_used);
803
if (vm.count("database-used") && ! vm.count("Table-used"))
805
dump_databases(vm["database-used"].as< vector<string> >());
809
if (opt_destination == DESTINATION_STDOUT)
3495
dump_selected_tables(*argv, (argv + 1), (argc - 1));
3499
dump_databases(argv);
3502
/* if --dump-slave , start the slave sql thread */
3503
if (opt_slave_data && do_start_slave_sql(mysql))
3506
/* add 'START SLAVE' to end of dump */
3507
if (opt_slave_apply && add_slave_statements())
814
3510
/* ensure dumped data flushed */
815
3511
if (md_result_file && fflush(md_result_file))
817
3513
if (!first_error)
818
first_error= EX_DRIZZLEERR;
3514
first_error= EX_MYSQLERR;
3517
/* everything successful, purge the old logs files */
3518
if (opt_delete_master_logs && purge_bin_logs_to(mysql, bin_log_name))
823
3522
No reason to explicitely COMMIT the transaction, neither to explicitely