78
76
#define IGNORE_DATA 0x01 /* don't dump data for this table */
79
77
#define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */
82
static bool use_drizzle_protocol= false;
83
static bool quick= true;
84
static bool ignore_errors= false;
85
static bool flush_logs= false;
86
static bool opt_keywords= false;
87
static bool opt_compress= false;
88
static bool opt_delayed= false;
89
static bool create_options= true;
90
static bool opt_quoted= false;
91
bool opt_databases= false;
92
bool opt_alldbs= false;
93
static bool opt_lock_all_tables= false;
94
static bool opt_set_charset= false;
95
static bool opt_dump_date= true;
96
static bool opt_autocommit= false;
97
static bool opt_single_transaction= false;
98
static bool opt_comments;
99
static bool opt_compact;
100
static bool opt_order_by_primary=false;
101
bool opt_ignore= false;
102
static bool opt_complete_insert= false;
103
static bool opt_drop_database;
104
static bool opt_alltspcs= false;
105
bool opt_no_create_info;
106
bool opt_no_data= false;
107
bool opt_create_db= false;
108
bool opt_disable_keys= true;
109
bool extended_insert= true;
110
bool opt_replace_into= false;
112
uint32_t show_progress_size= 0;
113
//static uint64_t total_rows= 0;
114
static string insert_pat;
115
//static char *order_by= NULL;
116
static uint32_t opt_drizzle_port= 0;
117
static int first_error= 0;
118
static string extended_row;
79
static void add_load_option(DYNAMIC_STRING *str, const char *option,
80
const char *option_value);
81
static ulong find_set(TYPELIB *lib, const char *x, uint length,
82
char **err_pos, uint *err_len);
84
static void field_escape(DYNAMIC_STRING* in, const char *from);
85
static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
86
quick= 1, extended_insert= 1,
87
lock_tables=1,ignore_errors=0,flush_logs=0,flush_privileges=0,
88
opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0,
89
opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0,
90
opt_alldbs=0,opt_create_db=0,opt_lock_all_tables=0,
91
opt_set_charset=0, opt_dump_date=1,
92
opt_autocommit=0,opt_disable_keys=1,opt_xml=0,
93
opt_delete_master_logs=0, tty_password=0,
94
opt_single_transaction=0, opt_comments= 0, opt_compact= 0,
95
opt_hex_blob=0, opt_order_by_primary=0, opt_ignore=0,
96
opt_complete_insert= 0, opt_drop_database= 0,
98
opt_routines=0, opt_tz_utc=1,
100
opt_include_master_host_port= 0,
102
opt_alltspcs=0, opt_notspcs= 0;
103
static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
104
static ulong opt_max_allowed_packet, opt_net_buffer_length;
105
static MYSQL mysql_connection,*mysql=0;
106
static DYNAMIC_STRING insert_pat;
107
static char *opt_password=0,*current_user=0,
108
*current_host=0,*path=0,*fields_terminated=0,
109
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
110
*where=0, *order_by=0,
111
*opt_compatible_mode_str= 0,
113
*log_error_file= NULL;
114
static char **defaults_argv= 0;
115
static char compatible_mode_normal_str[255];
116
/* Server supports character_set_results session variable? */
117
static my_bool server_supports_switching_charsets= TRUE;
118
static ulong opt_compatible_mode= 0;
119
#define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
120
#define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
121
#define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
122
#define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2
123
static uint opt_mysql_port= 0, opt_master_data;
124
static uint opt_slave_data;
125
static uint my_end_arg;
126
static int first_error=0;
127
static DYNAMIC_STRING extended_row;
119
128
FILE *md_result_file= 0;
120
FILE *stderror_file= 0;
121
std::vector<DrizzleDumpDatabase*> database_store;
122
DrizzleDumpConnection* db_connection;
123
DrizzleDumpConnection* destination_connection;
131
int opt_destination= DESTINATION_STDOUT;
132
std::string opt_destination_host;
133
uint16_t opt_destination_port;
134
std::string opt_destination_user;
135
std::string opt_destination_password;
136
std::string opt_destination_database;
138
const string progname= "drizzledump";
153
//static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
155
boost::unordered_set<string> ignore_table;
157
void maybe_exit(int error);
129
FILE *stderror_file=0;
132
static char *shared_memory_base_name=0;
134
static uint opt_protocol= MYSQL_PROTOCOL_TCP;
137
Dynamic_string wrapper functions. In this file use these
138
wrappers, they will terminate the process if there is
139
an allocation failure.
141
static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str,
142
uint init_alloc, uint alloc_increment);
143
static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src);
144
static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str);
145
static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append,
147
static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size);
149
Constant for detection of default value of default_charset.
150
If default_charset is equal to mysql_universal_client_charset, then
151
it is the default value which assigned at the very beginning of main().
153
static const char *mysql_universal_client_charset=
154
MYSQL_UNIVERSAL_CLIENT_CHARSET;
155
static char *default_charset;
156
static CHARSET_INFO *charset_info= &my_charset_latin1;
157
const char *default_dbug_option="d:t:o,/tmp/mysqldump.trace";
158
/* have we seen any VIEWs during table scanning? */
159
my_bool seen_views= 0;
160
const char *compatible_mode_names[]=
162
"MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2",
163
"MAXDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS",
167
#define MASK_ANSI_QUOTES \
169
(1<<2) | /* POSTGRESQL */\
170
(1<<3) | /* ORACLE */\
171
(1<<4) | /* MSSQL */\
173
(1<<6) | /* MAXDB */\
176
TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
177
"", compatible_mode_names, NULL};
181
static struct my_option my_long_options[] =
183
{"all", 'a', "Deprecated. Use --create-options instead.",
184
(uchar**) &create_options, (uchar**) &create_options, 0, GET_BOOL, NO_ARG, 1,
186
{"all-databases", 'A',
187
"Dump all the databases. This will be same as --databases with all databases selected.",
188
(uchar**) &opt_alldbs, (uchar**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
190
{"all-tablespaces", 'Y',
191
"Dump all the tablespaces.",
192
(uchar**) &opt_alltspcs, (uchar**) &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
194
{"no-tablespaces", 'y',
195
"Do not dump any tablespace information.",
196
(uchar**) &opt_notspcs, (uchar**) &opt_notspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
198
{"add-drop-database", OPT_DROP_DATABASE, "Add a 'DROP DATABASE' before each create.",
199
(uchar**) &opt_drop_database, (uchar**) &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
201
{"add-drop-table", OPT_DROP, "Add a 'drop table' before each create.",
202
(uchar**) &opt_drop, (uchar**) &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
204
{"add-locks", OPT_LOCKS, "Add locks around insert statements.",
205
(uchar**) &opt_lock, (uchar**) &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
207
{"allow-keywords", OPT_KEYWORDS,
208
"Allow creation of column names that are keywords.", (uchar**) &opt_keywords,
209
(uchar**) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
210
{"apply-slave-statements", OPT_MYSQLDUMP_SLAVE_APPLY,
211
"Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
212
(uchar**) &opt_slave_apply, (uchar**) &opt_slave_apply, 0, GET_BOOL, NO_ARG,
214
{"character-sets-dir", OPT_CHARSETS_DIR,
215
"Directory where character sets are.", (uchar**) &charsets_dir,
216
(uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
217
{"comments", 'i', "Write additional information.",
218
(uchar**) &opt_comments, (uchar**) &opt_comments, 0, GET_BOOL, NO_ARG,
220
{"compatible", OPT_COMPATIBLE,
221
"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.",
222
(uchar**) &opt_compatible_mode_str, (uchar**) &opt_compatible_mode_str, 0,
223
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
224
{"compact", OPT_COMPACT,
225
"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",
226
(uchar**) &opt_compact, (uchar**) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
228
{"complete-insert", 'c', "Use complete insert statements.",
229
(uchar**) &opt_complete_insert, (uchar**) &opt_complete_insert, 0, GET_BOOL,
230
NO_ARG, 0, 0, 0, 0, 0, 0},
231
{"compress", 'C', "Use compression in server/client protocol.",
232
(uchar**) &opt_compress, (uchar**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
234
{"create-options", OPT_CREATE_OPTIONS,
235
"Include all MySQL specific create options.",
236
(uchar**) &create_options, (uchar**) &create_options, 0, GET_BOOL, NO_ARG, 1,
239
"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.",
240
(uchar**) &opt_databases, (uchar**) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
243
{"debug", '#', "This is a non-debug version. Catch this and exit",
244
0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
246
{"debug", '#', "Output debug log", (uchar**) &default_dbug_option,
247
(uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
249
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
250
(uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0,
251
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
252
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
253
(uchar**) &debug_info_flag, (uchar**) &debug_info_flag,
254
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
255
{"default-character-set", OPT_DEFAULT_CHARSET,
256
"Set the default character set.", (uchar**) &default_charset,
257
(uchar**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
258
{"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED; ",
259
(uchar**) &opt_delayed, (uchar**) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
261
{"delete-master-logs", OPT_DELETE_MASTER_LOGS,
262
"Delete logs on master after backup. This automatically enables --master-data.",
263
(uchar**) &opt_delete_master_logs, (uchar**) &opt_delete_master_logs, 0,
264
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
265
{"disable-keys", 'K',
266
"'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (uchar**) &opt_disable_keys,
267
(uchar**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
268
{"dump-slave", OPT_MYSQLDUMP_SLAVE_DATA,
269
"This causes the binary log position and filename of the master to be "
270
"appended to the dumped data output. Setting the value to 1, will print"
271
"it as a CHANGE MASTER command in the dumped data output; if equal"
272
" to 2, that command will be prefixed with a comment symbol. "
273
"This option will turn --lock-all-tables on, unless "
274
"--single-transaction is specified too (in which case a "
275
"global read lock is only taken a short time at the beginning of the dump "
276
"- don't forget to read about --single-transaction below). In all cases "
277
"any action on logs will happen at the exact moment of the dump."
278
"Option automatically turns --lock-tables off.",
279
(uchar**) &opt_slave_data, (uchar**) &opt_slave_data, 0,
280
GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
281
{"events", 'E', "Dump events.",
282
(uchar**) &opt_events, (uchar**) &opt_events, 0, GET_BOOL,
283
NO_ARG, 0, 0, 0, 0, 0, 0},
284
{"extended-insert", 'e',
285
"Allows utilization of the new, much faster INSERT syntax.",
286
(uchar**) &extended_insert, (uchar**) &extended_insert, 0, GET_BOOL, NO_ARG,
288
{"fields-terminated-by", OPT_FTB,
289
"Fields in the textfile are terminated by ...", (uchar**) &fields_terminated,
290
(uchar**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
291
{"fields-enclosed-by", OPT_ENC,
292
"Fields in the importfile are enclosed by ...", (uchar**) &enclosed,
293
(uchar**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
294
{"fields-optionally-enclosed-by", OPT_O_ENC,
295
"Fields in the i.file are opt. enclosed by ...", (uchar**) &opt_enclosed,
296
(uchar**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
297
{"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
298
(uchar**) &escaped, (uchar**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
299
{"first-slave", 'x', "Deprecated, renamed to --lock-all-tables.",
300
(uchar**) &opt_lock_all_tables, (uchar**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
302
{"flush-logs", 'F', "Flush logs file in server before starting dump. "
303
"Note that if you dump many databases at once (using the option "
304
"--databases= or --all-databases), the logs will be flushed for "
305
"each database dumped. The exception is when using --lock-all-tables "
307
"in this case the logs will be flushed only once, corresponding "
308
"to the moment all tables are locked. So if you want your dump and "
309
"the log flush to happen at the same exact moment you should use "
310
"--lock-all-tables or --master-data with --flush-logs",
311
(uchar**) &flush_logs, (uchar**) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
313
{"flush-privileges", OPT_ESC, "Emit a FLUSH PRIVILEGES statement "
314
"after dumping the mysql database. This option should be used any "
315
"time the dump contains the mysql database and any other database "
316
"that depends on the data in the mysql database for proper restore. ",
317
(uchar**) &flush_privileges, (uchar**) &flush_privileges, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
319
{"force", 'f', "Continue even if we get an sql-error.",
320
(uchar**) &ignore_errors, (uchar**) &ignore_errors, 0, GET_BOOL, NO_ARG,
322
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
323
NO_ARG, 0, 0, 0, 0, 0, 0},
324
{"hex-blob", OPT_HEXBLOB, "Dump binary strings (BINARY, "
325
"VARBINARY, BLOB) in hexadecimal format.",
326
(uchar**) &opt_hex_blob, (uchar**) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
327
{"host", 'h', "Connect to host.", (uchar**) ¤t_host,
328
(uchar**) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
329
{"ignore-table", OPT_IGNORE_TABLE,
330
"Do not dump the specified table. To specify more than one table to ignore, "
331
"use the directive multiple times, once for each table. Each table must "
332
"be specified with both database and table names, e.g. --ignore-table=database.table",
333
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
334
{"include-master-host-port", OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT,
335
"Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' in dump produced with --dump-slave.",
336
(uchar**) &opt_include_master_host_port,
337
(uchar**) &opt_include_master_host_port,
340
{"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
341
(uchar**) &opt_ignore, (uchar**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
343
{"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
344
(uchar**) &lines_terminated, (uchar**) &lines_terminated, 0, GET_STR,
345
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
346
{"lock-all-tables", 'x', "Locks all tables across all databases. This "
347
"is achieved by taking a global read lock for the duration of the whole "
348
"dump. Automatically turns --single-transaction and --lock-tables off.",
349
(uchar**) &opt_lock_all_tables, (uchar**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
351
{"lock-tables", 'l', "Lock all tables for read.", (uchar**) &lock_tables,
352
(uchar**) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
353
{"log-error", OPT_ERROR_LOG_FILE, "Append warnings and errors to given file.",
354
(uchar**) &log_error_file, (uchar**) &log_error_file, 0, GET_STR,
355
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
356
{"master-data", OPT_MASTER_DATA,
357
"This causes the binary log position and filename to be appended to the "
358
"output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
359
" to 2, that command will be prefixed with a comment symbol. "
360
"This option will turn --lock-all-tables on, unless "
361
"--single-transaction is specified too (in which case a "
362
"global read lock is only taken a short time at the beginning of the dump "
363
"- don't forget to read about --single-transaction below). In all cases "
364
"any action on logs will happen at the exact moment of the dump."
365
"Option automatically turns --lock-tables off.",
366
(uchar**) &opt_master_data, (uchar**) &opt_master_data, 0,
367
GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_MASTER_DATA_COMMENTED_SQL, 0, 0, 0},
368
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "",
369
(uchar**) &opt_max_allowed_packet, (uchar**) &opt_max_allowed_packet, 0,
370
GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096,
371
(longlong) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
372
{"net_buffer_length", OPT_NET_BUFFER_LENGTH, "",
373
(uchar**) &opt_net_buffer_length, (uchar**) &opt_net_buffer_length, 0,
374
GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L,
375
MALLOC_OVERHEAD-1024, 1024, 0},
376
{"no-autocommit", OPT_AUTOCOMMIT,
377
"Wrap tables with autocommit/commit statements.",
378
(uchar**) &opt_autocommit, (uchar**) &opt_autocommit, 0, GET_BOOL, NO_ARG,
380
{"no-create-db", 'n',
381
"'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.}.",
382
(uchar**) &opt_create_db, (uchar**) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
384
{"no-create-info", 't', "Don't write table creation info.",
385
(uchar**) &opt_no_create_info, (uchar**) &opt_no_create_info, 0, GET_BOOL,
386
NO_ARG, 0, 0, 0, 0, 0, 0},
387
{"no-data", 'd', "No row information.", (uchar**) &opt_no_data,
388
(uchar**) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
389
{"no-set-names", 'N',
390
"Deprecated. Use --skip-set-charset instead.",
391
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
392
{"opt", OPT_OPTIMIZE,
393
"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.",
394
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
395
{"order-by-primary", OPT_ORDER_BY_PRIMARY,
396
"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.",
397
(uchar**) &opt_order_by_primary, (uchar**) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
399
"Password to use when connecting to server. If password is not given it's solicited on the tty.",
400
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
401
{"port", 'P', "Port number to use for connection.", (uchar**) &opt_mysql_port,
402
(uchar**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
404
{"quick", 'q', "Don't buffer query, dump directly to stdout.",
405
(uchar**) &quick, (uchar**) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
406
{"quote-names",'Q', "Quote table and column names with backticks (`).",
407
(uchar**) &opt_quoted, (uchar**) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
409
{"replace", OPT_MYSQL_REPLACE_INTO, "Use REPLACE INTO instead of INSERT INTO.",
410
(uchar**) &opt_replace_into, (uchar**) &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
413
"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).",
414
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
415
{"routines", 'R', "Dump stored routines (functions and procedures).",
416
(uchar**) &opt_routines, (uchar**) &opt_routines, 0, GET_BOOL,
417
NO_ARG, 0, 0, 0, 0, 0, 0},
418
{"set-charset", OPT_SET_CHARSET,
419
"Add 'SET NAMES default_character_set' to the output.",
420
(uchar**) &opt_set_charset, (uchar**) &opt_set_charset, 0, GET_BOOL, NO_ARG, 1,
422
{"set-variable", 'O',
423
"Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
424
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
426
{"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
427
"Base name of shared memory.", (uchar**) &shared_memory_base_name, (uchar**) &shared_memory_base_name,
428
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
431
Note that the combination --single-transaction --master-data
432
will give bullet-proof binlog position only if server >=4.1.3. That's the
433
old "FLUSH TABLES WITH READ LOCK does not block commit" fixed bug.
435
{"single-transaction", OPT_TRANSACTION,
436
"Creates a consistent snapshot by dumping all tables in a single "
437
"transaction. Works ONLY for tables stored in storage engines which "
438
"support multiversioning (currently only InnoDB does); the dump is NOT "
439
"guaranteed to be consistent for other storage engines. "
440
"While a --single-transaction dump is in process, to ensure a valid "
441
"dump file (correct table contents and binary log position), no other "
442
"connection should use the following statements: ALTER TABLE, DROP "
443
"TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not "
444
"isolated from them. Option automatically turns off --lock-tables.",
445
(uchar**) &opt_single_transaction, (uchar**) &opt_single_transaction, 0,
446
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
447
{"dump-date", OPT_DUMP_DATE, "Put a dump date to the end of the output.",
448
(uchar**) &opt_dump_date, (uchar**) &opt_dump_date, 0,
449
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
450
{"skip-opt", OPT_SKIP_OPTIMIZATION,
451
"Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.",
452
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
454
"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.",
455
(uchar**) &path, (uchar**) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
456
{"tables", OPT_TABLES, "Overrides option --databases (-B).",
457
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
458
{"tz-utc", OPT_TZ_UTC,
459
"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.",
460
(uchar**) &opt_tz_utc, (uchar**) &opt_tz_utc, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
461
#ifndef DONT_ALLOW_USER_CHANGE
462
{"user", 'u', "User for login if not current user.",
463
(uchar**) ¤t_user, (uchar**) ¤t_user, 0, GET_STR, REQUIRED_ARG,
466
{"verbose", 'v', "Print info about the various stages.",
467
(uchar**) &verbose, (uchar**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
468
{"version",'V', "Output version information and exit.", 0, 0, 0,
469
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
470
{"where", 'w', "Dump only selected records; QUOTES mandatory!",
471
(uchar**) &where, (uchar**) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
472
{"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
473
NO_ARG, 0, 0, 0, 0, 0, 0},
474
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
477
static const char *load_default_groups[]= { "mysqldump","client",0 };
479
static void maybe_exit(int error);
158
480
static void die(int error, const char* reason, ...);
159
static void write_header(char *db_name);
160
static int dump_selected_tables(const string &db, const vector<string> &table_names);
161
static int dump_databases(const vector<string> &db_names);
162
static int dump_all_databases(void);
163
int get_server_type();
164
void dump_all_tables(void);
165
void generate_dump(void);
166
void generate_dump_db(void);
168
void dump_all_tables(void)
170
std::vector<DrizzleDumpDatabase*>::iterator i;
171
for (i= database_store.begin(); i != database_store.end(); ++i)
173
if (not (*i)->populateTables())
174
maybe_exit(EX_DRIZZLEERR);
178
void generate_dump(void)
180
std::vector<DrizzleDumpDatabase*>::iterator i;
182
cout << endl << "SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION;" << endl;
186
cout << endl << "SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;"
187
<< endl << "SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;" << endl;
189
for (i= database_store.begin(); i != database_store.end(); ++i)
191
DrizzleDumpDatabase *database= *i;
197
cout << "SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;"
198
<< endl << "SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;" << endl;
201
cout << "SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION;" << endl;
204
void generate_dump_db(void)
206
std::vector<DrizzleDumpDatabase*>::iterator i;
207
DrizzleStringBuf sbuf(1024);
208
destination_connection= new DrizzleDumpConnection(opt_destination_host,
209
opt_destination_port, opt_destination_user, opt_destination_password,
211
sbuf.setConnection(destination_connection);
212
std::ostream sout(&sbuf);
214
sout << "SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION;" << endl;
218
sout << "SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;" << endl;
219
sout << "SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;" << endl;
222
for (i= database_store.begin(); i != database_store.end(); ++i)
224
DrizzleDumpDatabase *database= *i;
230
sout << "SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;" << endl;
231
sout << "SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;" << endl;
234
sout << "SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION;" << endl;
481
static void maybe_die(int error, const char* reason, ...);
482
static void write_header(FILE *sql_file, char *db_name);
483
static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
484
const char *prefix,const char *name,
486
static int dump_selected_tables(char *db, char **table_names, int tables);
487
static int dump_all_tables_in_db(char *db);
488
static int init_dumping_tables(char *);
489
static int init_dumping(char *, int init_func(char*));
490
static int dump_databases(char **);
491
static int dump_all_databases();
492
static char *quote_name(const char *name, char *buff, my_bool force);
493
char check_if_ignore_table(const char *table_name, char *table_type);
494
static char *primary_key_fields(const char *table_name);
496
#include <help_start.h>
499
Print the supplied message if in verbose mode
504
... variable number of parameters
507
static void verbose_msg(const char *fmt, ...)
510
DBUG_ENTER("verbose_msg");
516
vfprintf(stderr, fmt, args);
238
523
exit with message if ferror(file)
245
static void check_io(FILE *file)
530
void check_io(FILE *file)
247
532
if (ferror(file))
248
die(EX_EOF, _("Got errno %d on write"), errno);
251
static void write_header(char *db_name)
253
if ((not opt_compact) and (opt_comments))
255
cout << "-- drizzledump " << VERSION << " libdrizzle "
256
<< drizzle_version() << ", for " << HOST_VENDOR << "-" << HOST_OS
257
<< " (" << HOST_CPU << ")" << endl << "--" << endl;
258
cout << "-- Host: " << current_host << " Database: " << db_name << endl;
259
cout << "-- ------------------------------------------------------" << endl;
260
cout << "-- Server version\t" << db_connection->getServerVersion();
261
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
262
cout << " (MySQL server)";
263
else if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_DRIZZLE_FOUND)
264
cout << " (Drizzle server)";
265
cout << endl << endl;
533
die(EX_EOF, "Got errno %d on write", errno);
536
static void print_version(void)
538
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,DUMP_VERSION,
539
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
540
} /* print_version */
543
static void short_usage_sub(void)
545
printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
546
printf("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n",
548
printf("OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname);
552
static void usage(void)
555
puts("By Igor Romanenko, Monty, Jani & Sinisa");
556
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");
557
puts("Dumping definition and data mysql database or table");
559
print_defaults("my",load_default_groups);
560
my_print_help(my_long_options);
561
my_print_variables(my_long_options);
565
static void short_usage(void)
568
printf("For more options, use %s --help\n", my_progname);
571
#include <help_end.h>
574
static void write_header(FILE *sql_file, char *db_name)
578
fputs("<?xml version=\"1.0\"?>\n", sql_file);
580
Schema reference. Allows use of xsi:nil for NULL values and
581
xsi:type to define an element's data type.
583
fputs("<mysqldump ", sql_file);
584
fputs("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"",
586
fputs(">\n", sql_file);
589
else if (!opt_compact)
594
"-- MySQL dump %s Distrib %s, for %s (%s)\n--\n",
595
DUMP_VERSION, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
596
fprintf(sql_file, "-- Host: %s Database: %s\n",
597
current_host ? current_host : "localhost", db_name ? db_name :
599
fputs("-- ------------------------------------------------------\n",
601
fprintf(sql_file, "-- Server version\t%s\n",
602
mysql_get_server_info(&mysql_connection));
606
"\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;"
607
"\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;"
608
"\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;"
609
"\n/*!40101 SET NAMES %s */;\n",default_charset);
613
fprintf(sql_file, "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;\n");
614
fprintf(sql_file, "/*!40103 SET TIME_ZONE='+00:00' */;\n");
619
fprintf(md_result_file,"\
620
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n\
621
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;\n\
267
626
} /* write_header */
270
629
static void write_footer(FILE *sql_file)
633
fputs("</mysqldump>\n", sql_file);
636
else if (!opt_compact)
639
fprintf(sql_file,"/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;\n");
643
fprintf(md_result_file,"\
644
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n\
645
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;\n");
649
"/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n"
650
"/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n"
651
"/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
653
"/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\n");
654
fputs("\n", sql_file);
274
655
if (opt_comments)
276
657
if (opt_dump_date)
278
boost::posix_time::ptime time(boost::posix_time::second_clock::local_time());
660
get_date(time_str, GETDATE_DATE_TIME, 0);
279
661
fprintf(sql_file, "-- Dump completed on %s\n",
280
boost::posix_time::to_simple_string(time).c_str());
283
665
fprintf(sql_file, "-- Dump completed\n");
287
669
} /* write_footer */
289
static int get_options(void)
292
if (path.empty() && (! enclosed.empty() || ! opt_enclosed.empty() || ! escaped.empty() || ! lines_terminated.empty() ||
293
! fields_terminated.empty()))
672
static void free_table_ent(char *key)
674
my_free(key, MYF(0));
678
uchar* get_table_key(const char *entry, size_t *length,
679
my_bool not_used __attribute__((unused)))
681
*length= strlen(entry);
682
return (uchar*) entry;
687
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
694
char *start=argument;
695
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
696
opt_password=my_strdup(argument,MYF(MY_FAE));
697
while (*argument) *argument++= 'x'; /* Destroy argument */
699
start[1]=0; /* Cut length of argument */
706
if (!(md_result_file= my_fopen(argument, O_WRONLY | FILE_BINARY,
716
if (strlen(argument) >= FN_REFLEN)
719
This check is made because the some the file functions below
720
have FN_REFLEN sized stack allocated buffers and will cause
721
a crash even if the input destination buffer is large enough
724
die(EX_USAGE, "Input filename too long: %s", argument);
729
DBUG_PUSH(argument ? argument : default_dbug_option);
732
case 'V': print_version(); exit(0);
735
extended_insert= opt_drop= opt_lock=
736
opt_disable_keys= opt_autocommit= opt_create_db= 0;
742
case (int) OPT_MASTER_DATA:
743
if (!argument) /* work like in old versions */
744
opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL;
746
case (int) OPT_MYSQLDUMP_SLAVE_DATA:
747
if (!argument) /* work like in old versions */
748
opt_slave_data= MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL;
750
case (int) OPT_OPTIMIZE:
751
extended_insert= opt_drop= opt_lock= quick= create_options=
752
opt_disable_keys= lock_tables= opt_set_charset= 1;
754
case (int) OPT_SKIP_OPTIMIZATION:
755
extended_insert= opt_drop= opt_lock= quick= create_options=
756
opt_disable_keys= lock_tables= opt_set_charset= 0;
758
case (int) OPT_COMPACT:
761
opt_comments= opt_drop= opt_disable_keys= opt_lock= 0;
764
case (int) OPT_TABLES:
767
case (int) OPT_IGNORE_TABLE:
769
if (!strchr(argument, '.'))
771
fprintf(stderr, "Illegal use of option --ignore-table=<database>.<table>\n");
774
if (my_hash_insert(&ignore_table, (uchar*)my_strdup(argument, MYF(0))))
778
case (int) OPT_COMPATIBLE:
781
char *end= compatible_mode_normal_str;
788
opt_compatible_mode_str= argument;
789
opt_compatible_mode= find_set(&compatible_mode_typelib,
790
argument, strlen(argument),
794
strmake(buff, err_ptr, min(sizeof(buff), err_len));
795
fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
798
#if !defined(DBUG_OFF)
800
uint size_for_sql_mode= 0;
802
for (ptr= compatible_mode_names; *ptr; ptr++)
803
size_for_sql_mode+= strlen(*ptr);
804
size_for_sql_mode+= sizeof(compatible_mode_names)-1;
805
DBUG_ASSERT(sizeof(compatible_mode_normal_str)>=size_for_sql_mode);
808
mode= opt_compatible_mode;
809
for (i= 0, mode= opt_compatible_mode; mode; mode>>= 1, i++)
813
end= strmov(end, compatible_mode_names[i]);
814
end= strmov(end, ",");
817
if (end!=compatible_mode_normal_str)
820
Set charset to the default compiled value if it hasn't
821
been reset yet by --default-character-set=xxx.
823
if (default_charset == mysql_universal_client_charset)
824
default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
831
static int get_options(int *argc, char ***argv)
834
MYSQL_PARAMETERS *mysql_params= mysql_get_parameters();
836
opt_max_allowed_packet= *mysql_params->p_max_allowed_packet;
837
opt_net_buffer_length= *mysql_params->p_net_buffer_length;
839
md_result_file= stdout;
840
load_defaults("my",load_default_groups,argc,argv);
841
defaults_argv= *argv;
843
if (hash_init(&ignore_table, charset_info, 16, 0, 0,
844
(hash_get_key) get_table_key,
845
(hash_free_key) free_table_ent, 0))
847
/* Don't copy internal log tables */
848
if (my_hash_insert(&ignore_table,
849
(uchar*) my_strdup("mysql.apply_status", MYF(MY_WME))) ||
850
my_hash_insert(&ignore_table,
851
(uchar*) my_strdup("mysql.schema", MYF(MY_WME))) ||
852
my_hash_insert(&ignore_table,
853
(uchar*) my_strdup("mysql.general_log", MYF(MY_WME))) ||
854
my_hash_insert(&ignore_table,
855
(uchar*) my_strdup("mysql.slow_log", MYF(MY_WME))) ||
856
my_hash_insert(&ignore_table,
857
(uchar*) my_strdup("mysql.online_backup", MYF(MY_WME))) ||
858
my_hash_insert(&ignore_table,
859
(uchar*) my_strdup("mysql.online_backup_progress", MYF(MY_WME))))
862
if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
865
*mysql_params->p_max_allowed_packet= opt_max_allowed_packet;
866
*mysql_params->p_net_buffer_length= opt_net_buffer_length;
868
my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
869
if (debug_check_flag)
870
my_end_arg= MY_CHECK_ERROR;
873
opt_lock=0; /* Can't have lock with delayed */
874
if (!path && (enclosed || opt_enclosed || escaped || lines_terminated ||
296
_("%s: You must use option --tab with --fields-...\n"), progname.c_str());
878
"%s: You must use option --tab with --fields-...\n", my_progname);
297
879
return(EX_USAGE);
882
/* We don't delete master logs if slave data option */
885
opt_lock_all_tables= !opt_single_transaction;
887
opt_delete_master_logs= 0;
890
/* Ensure consistency of the set of binlog & locking options */
891
if (opt_delete_master_logs && !opt_master_data)
892
opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL;
300
893
if (opt_single_transaction && opt_lock_all_tables)
302
fprintf(stderr, _("%s: You can't use --single-transaction and "
303
"--lock-all-tables at the same time.\n"), progname.c_str());
306
if (! enclosed.empty() && ! opt_enclosed.empty())
308
fprintf(stderr, _("%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n"), progname.c_str());
311
if ((opt_databases || opt_alldbs) && ! path.empty())
895
fprintf(stderr, "%s: You can't use --single-transaction and "
896
"--lock-all-tables at the same time.\n", my_progname);
901
opt_lock_all_tables= !opt_single_transaction;
904
if (opt_single_transaction || opt_lock_all_tables)
906
if (enclosed && opt_enclosed)
908
fprintf(stderr, "%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n", my_progname);
911
if ((opt_databases || opt_alldbs) && path)
314
_("%s: --databases or --all-databases can't be used with --tab.\n"),
914
"%s: --databases or --all-databases can't be used with --tab.\n",
316
916
return(EX_USAGE);
918
if (strcmp(default_charset, charset_info->csname) &&
919
!(charset_info= get_charset_by_csname(default_charset,
920
MY_CS_PRIMARY, MYF(MY_WME))))
922
if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs))
319
927
if (tty_password)
320
opt_password=client_get_tty_password(NULL);
928
opt_password=get_tty_password(NullS);
322
930
} /* get_options */
934
** DB_error -- prints mysql error message and exits the program.
936
static void DB_error(MYSQL *mysql_arg, const char *when)
938
DBUG_ENTER("DB_error");
939
maybe_die(EX_MYSQLERR, "Got error: %d: %s %s",
940
mysql_errno(mysql_arg), mysql_error(mysql_arg), when);
326
947
Prints out an error message and kills the process.
330
error_num - process return value
331
fmt_reason - a format string for use by vsnprintf.
332
... - variable arguments for above fmt_reason string
951
error_num - process return value
952
fmt_reason - a format string for use by my_vsnprintf.
953
... - variable arguments for above fmt_reason string
335
This call prints out the formatted error message to stderr and then
336
terminates the process.
956
This call prints out the formatted error message to stderr and then
957
terminates the process.
338
959
static void die(int error_num, const char* fmt_reason, ...)
340
961
char buffer[1000];
342
963
va_start(args,fmt_reason);
343
vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
964
my_vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
346
fprintf(stderr, "%s: %s\n", progname.c_str(), buffer);
967
fprintf(stderr, "%s: %s\n", my_progname, buffer);
349
970
ignore_errors= 0; /* force the exit */
350
971
maybe_exit(error_num);
353
static void free_resources(void)
976
Prints out an error message and maybe kills the process.
980
error_num - process return value
981
fmt_reason - a format string for use by my_vsnprintf.
982
... - variable arguments for above fmt_reason string
985
This call prints out the formatted error message to stderr and then
986
terminates the process, unless the --force command line option is used.
988
This call should be used for non-fatal errors (such as database
989
errors) that the code may still be able to continue to the next unit
993
static void maybe_die(int error_num, const char* fmt_reason, ...)
997
va_start(args,fmt_reason);
998
my_vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
1001
fprintf(stderr, "%s: %s\n", my_progname, buffer);
1004
maybe_exit(error_num);
1010
Sends a query to server, optionally reads result, prints error message if
1014
mysql_query_with_error_report()
1015
mysql_con connection to use
1016
res if non zero, result will be put there with
1017
mysql_store_result()
1018
query query to send to server
1021
0 query sending and (if res!=0) result reading went ok
1025
static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res,
1028
if (mysql_query(mysql_con, query) ||
1029
(res && !((*res)= mysql_store_result(mysql_con))))
1031
maybe_die(EX_MYSQLERR, "Couldn't execute '%s': %s (%d)",
1032
query, mysql_error(mysql_con), mysql_errno(mysql_con));
1040
Switch charset for results to some specified charset. If the server does not
1041
support character_set_results variable, nothing can be done here. As for
1042
whether something should be done here, future new callers of this function
1043
should be aware that the server lacking the facility of switching charsets is
1046
@note If the server lacks support, then nothing is changed and no error
1047
condition is returned.
1049
@returns whether there was an error or not
1051
static int switch_character_set_results(MYSQL *mysql, const char *cs_name)
1053
char query_buffer[QUERY_LENGTH];
1054
size_t query_length;
1056
/* Server lacks facility. This is not an error, by arbitrary decision . */
1057
if (!server_supports_switching_charsets)
1060
query_length= my_snprintf(query_buffer,
1061
sizeof (query_buffer),
1062
"SET SESSION character_set_results = '%s'",
1063
(const char *) cs_name);
1065
return mysql_real_query(mysql, query_buffer, query_length);
1069
Open a new .sql file to dump the table or view into
1072
open_sql_file_for_table
1073
name name of the table or view
1076
0 Failed to open file
1077
> 0 Handle of the open file
1079
static FILE* open_sql_file_for_table(const char* table)
1082
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
1083
convert_dirname(tmp_path,path,NullS);
1084
res= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
1085
O_WRONLY, MYF(MY_WME));
1090
static void free_resources()
355
1092
if (md_result_file && md_result_file != stdout)
356
fclose(md_result_file);
357
opt_password.erase();
1093
my_fclose(md_result_file, MYF(0));
1094
my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
1095
if (hash_inited(&ignore_table))
1096
hash_free(&ignore_table);
1097
if (extended_insert)
1098
dynstr_free(&extended_row);
1099
if (insert_pat_inited)
1100
dynstr_free(&insert_pat);
1102
free_defaults(defaults_argv);
361
void maybe_exit(int error)
1107
static void maybe_exit(int error)
363
1109
if (!first_error)
364
1110
first_error= error;
365
1111
if (ignore_errors)
367
delete db_connection;
368
if (destination_connection)
369
delete destination_connection;
370
1115
free_resources();
1121
db_connect -- connects to the host and selects DB.
1124
static int connect_to_db(char *host, char *user,char *passwd)
1126
char buff[20+FN_REFLEN];
1127
DBUG_ENTER("connect_to_db");
1129
verbose_msg("-- Connecting to %s...\n", host ? host : "localhost");
1130
mysql_init(&mysql_connection);
1132
mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS);
1134
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
1136
if (shared_memory_base_name)
1137
mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
1139
mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
1140
if (!(mysql= mysql_real_connect(&mysql_connection,host,user,passwd,
1141
NULL,opt_mysql_port, NULL,
1144
DB_error(&mysql_connection, "when trying to connect");
1147
if (mysql_get_server_version(&mysql_connection) < 40100)
1149
/* Don't dump SET NAMES with a pre-4.1 server (bug#7997). */
1152
/* Don't switch charsets for 4.1 and earlier. (bug#34192). */
1153
server_supports_switching_charsets= FALSE;
1156
set time_zone to UTC to allow dumping date types between servers with
1157
different time zone settings
1161
my_snprintf(buff, sizeof(buff), "/*!40103 SET TIME_ZONE='+00:00' */");
1162
if (mysql_query_with_error_report(mysql, 0, buff))
1166
} /* connect_to_db */
1170
** dbDisconnect -- disconnects from the host.
1172
static void dbDisconnect(char *host)
1174
verbose_msg("-- Disconnecting from %s...\n", host ? host : "localhost");
1176
} /* dbDisconnect */
1179
static void unescape(FILE *file,char *pos,uint length)
1182
DBUG_ENTER("unescape");
1183
if (!(tmp=(char*) my_malloc(length*2+1, MYF(MY_WME))))
1184
die(EX_MYSQLERR, "Couldn't allocate memory");
1186
mysql_real_escape_string(&mysql_connection, tmp, pos, length);
1191
my_free(tmp, MYF(MY_WME));
1196
static my_bool test_if_special_chars(const char *str)
1198
#if MYSQL_VERSION_ID >= 32300
1199
for ( ; *str ; str++)
1200
if (!my_isvar(charset_info,*str) && *str != '$')
1204
} /* test_if_special_chars */
1209
quote_name(name, buff, force)
1211
Quotes char string, taking into account compatible mode
1215
name Unquoted string containing that which will be quoted
1216
buff The buffer that contains the quoted value, also returned
1217
force Flag to make it ignore 'test_if_special_chars'
1224
static char *quote_name(const char *name, char *buff, my_bool force)
1227
char qtype= (opt_compatible_mode & MASK_ANSI_QUOTES) ? '\"' : '`';
1229
if (!force && !opt_quoted && !test_if_special_chars(name))
1230
return (char*) name;
1245
Quote a table name so it can be used in "SHOW TABLES LIKE <tabname>"
1249
name name of the table
1250
buff quoted name of the table
1253
Quote \, _, ' and % characters
1255
Note: Because MySQL uses the C escape syntax in strings
1256
(for example, '\n' to represent newline), you must double
1257
any '\' that you use in your LIKE strings. For example, to
1258
search for '\n', specify it as '\\n'. To search for '\', specify
1259
it as '\\\\' (the backslashes are stripped once by the parser
1260
and another time when the pattern match is done, leaving a
1261
single backslash to be matched).
1263
Example: "t\1" => "t\\\\1"
1266
static char *quote_for_like(const char *name, char *buff)
1278
else if (*name == '\'' || *name == '_' || *name == '%')
1289
Quote and print a string.
1293
xml_file - output file
1294
str - string to print
1298
Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
1301
static void print_quoted_xml(FILE *xml_file, const char *str, ulong len)
1305
for (end= str + len; str != end; str++)
1309
fputs("<", xml_file);
1312
fputs(">", xml_file);
1315
fputs("&", xml_file);
1318
fputs(""", xml_file);
1321
fputc(*str, xml_file);
1330
Print xml tag. Optionally add attribute(s).
1333
print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
1334
..., attribute_name_n, attribute_value_n, NullS)
1335
xml_file - output file
1336
sbeg - line beginning
1337
line_end - line ending
1338
tag_name - XML tag name.
1339
first_attribute_name - tag and first attribute
1340
first_attribute_value - (Implied) value of first attribute
1341
attribute_name_n - attribute n
1342
attribute_value_n - value of attribute n
1345
Print XML tag with any number of attribute="value" pairs to the xml_file.
1348
sbeg<tag_name first_attribute_name="first_attribute_value" ...
1349
attribute_name_n="attribute_value_n">send
1351
Additional arguments must be present in attribute/value pairs.
1352
The last argument should be the null character pointer.
1353
All attribute_value arguments MUST be NULL terminated strings.
1354
All attribute_value arguments will be quoted before output.
1357
static void print_xml_tag(FILE * xml_file, const char* sbeg,
1358
const char* line_end,
1359
const char* tag_name,
1360
const char* first_attribute_name, ...)
1363
const char *attribute_name, *attribute_value;
1365
fputs(sbeg, xml_file);
1366
fputc('<', xml_file);
1367
fputs(tag_name, xml_file);
1369
va_start(arg_list, first_attribute_name);
1370
attribute_name= first_attribute_name;
1371
while (attribute_name != NullS)
1373
attribute_value= va_arg(arg_list, char *);
1374
DBUG_ASSERT(attribute_value != NullS);
1376
fputc(' ', xml_file);
1377
fputs(attribute_name, xml_file);
1378
fputc('\"', xml_file);
1380
print_quoted_xml(xml_file, attribute_value, strlen(attribute_value));
1381
fputc('\"', xml_file);
1383
attribute_name= va_arg(arg_list, char *);
1387
fputc('>', xml_file);
1388
fputs(line_end, xml_file);
1394
Print xml tag with for a field that is null
1397
print_xml_null_tag()
1398
xml_file - output file
1399
sbeg - line beginning
1400
stag_atr - tag and attribute
1401
sval - value of attribute
1402
line_end - line ending
1405
Print tag with one attribute to the xml_file. Format is:
1406
<stag_atr="sval" xsi:nil="true"/>
1408
sval MUST be a NULL terminated string.
1409
sval string will be qouted before output.
1412
static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
1413
const char* stag_atr, const char* sval,
1414
const char* line_end)
1416
fputs(sbeg, xml_file);
1417
fputs("<", xml_file);
1418
fputs(stag_atr, xml_file);
1419
fputs("\"", xml_file);
1420
print_quoted_xml(xml_file, sval, strlen(sval));
1421
fputs("\" xsi:nil=\"true\" />", xml_file);
1422
fputs(line_end, xml_file);
1428
Print xml tag with many attributes.
1432
xml_file - output file
1433
row_name - xml tag name
1434
tableRes - query result
1438
Print tag with many attribute to the xml_file. Format is:
1439
\t\t<row_name Atr1="Val1" Atr2="Val2"... />
1441
All atributes and values will be quoted before output.
1444
static void print_xml_row(FILE *xml_file, const char *row_name,
1445
MYSQL_RES *tableRes, MYSQL_ROW *row)
1449
ulong *lengths= mysql_fetch_lengths(tableRes);
1451
fprintf(xml_file, "\t\t<%s", row_name);
1453
mysql_field_seek(tableRes, 0);
1454
for (i= 0; (field= mysql_fetch_field(tableRes)); i++)
1458
fputc(' ', xml_file);
1459
print_quoted_xml(xml_file, field->name, field->name_length);
1460
fputs("=\"", xml_file);
1461
print_quoted_xml(xml_file, (*row)[i], lengths[i]);
1462
fputc('"', xml_file);
1466
fputs(" />\n", xml_file);
1472
Print hex value for blob data.
1476
output_file - output file
1477
str - string to print
1481
Print hex value for blob data.
1484
static void print_blob_as_hex(FILE *output_file, const char *str, ulong len)
1486
/* sakaik got the idea to to provide blob's in hex notation. */
1487
const char *ptr= str, *end= ptr + len;
1488
for (; ptr < end ; ptr++)
1489
fprintf(output_file, "%02X", *((uchar *)ptr));
1490
check_io(output_file);
1494
get_table_structure -- retrievs database structure, prints out corresponding
1495
CREATE statement and fills out insert_pat if the table is the type we will
1501
table_type - table type, e.g. "MyISAM" or "InnoDB", but also "VIEW"
1502
ignore_flag - what we must particularly ignore - see IGNORE_ defines above
1505
number of fields in table, 0 if error
1508
static uint get_table_structure(char *table, char *db, char *table_type,
1511
my_bool init=0, delayed, write_data, complete_insert;
1512
my_ulonglong num_fields;
1513
char *result_table, *opt_quoted_table;
1514
const char *insert_option;
1515
char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
1516
char table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
1517
FILE *sql_file= md_result_file;
1521
DBUG_ENTER("get_table_structure");
1522
DBUG_PRINT("enter", ("db: %s table: %s", db, table));
1524
*ignore_flag= check_if_ignore_table(table, table_type);
1526
delayed= opt_delayed;
1527
if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
1530
verbose_msg("-- Warning: Unable to use delayed inserts for table '%s' "
1531
"because it's of type %s\n", table, table_type);
1535
if ((write_data= !(*ignore_flag & IGNORE_DATA)))
1537
complete_insert= opt_complete_insert;
1538
if (!insert_pat_inited)
1540
insert_pat_inited= 1;
1541
init_dynamic_string_checked(&insert_pat, "", 1024, 1024);
1544
dynstr_set_checked(&insert_pat, "");
1547
insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
1548
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : "");
1550
verbose_msg("-- Retrieving table structure for table %s...\n", table);
1552
len= my_snprintf(query_buff, sizeof(query_buff),
1553
"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
1554
(opt_quoted || opt_keywords));
1556
result_table= quote_name(table, table_buff, 1);
1557
opt_quoted_table= quote_name(table, table_buff2, 0);
1559
if (opt_order_by_primary)
1561
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
1562
order_by= primary_key_fields(result_table);
1565
if (!opt_xml && !mysql_query_with_error_report(mysql, 0, query_buff))
1567
/* using SHOW CREATE statement */
1568
if (!opt_no_create_info)
1570
/* Make an sql-file, if path was given iow. option -T was given */
1571
char buff[20+FN_REFLEN];
1574
my_snprintf(buff, sizeof(buff), "show create table %s", result_table);
1576
if (switch_character_set_results(mysql, "binary") ||
1577
mysql_query_with_error_report(mysql, &result, buff) ||
1578
switch_character_set_results(mysql, default_charset))
1583
if (!(sql_file= open_sql_file_for_table(table)))
1586
write_header(sql_file, db);
1588
if (!opt_xml && opt_comments)
1590
if (strcmp (table_type, "VIEW") == 0) /* view */
1591
fprintf(sql_file, "\n--\n-- Temporary table structure for view %s\n--\n\n",
1594
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1601
Even if the "table" is a view, we do a DROP TABLE here. The
1602
view-specific code below fills in the DROP VIEW.
1604
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",
1609
field= mysql_fetch_field_direct(result, 0);
1610
if (strcmp(field->name, "View") == 0)
1612
char *scv_buff= NULL;
1614
verbose_msg("-- It's a view, create dummy table for view\n");
1616
/* save "show create" statement for later */
1617
if ((row= mysql_fetch_row(result)) && (scv_buff=row[1]))
1618
scv_buff= my_strdup(scv_buff, MYF(0));
1620
mysql_free_result(result);
1623
Create a table with the same name as the view and with columns of
1624
the same name in order to satisfy views that depend on this view.
1625
The table will be removed when the actual view is created.
1627
The properties of each column, aside from the data type, are not
1628
preserved in this temporary table, because they are not necessary.
1630
This will not be necessary once we can determine dependencies
1631
between views and can simply dump them in the appropriate order.
1633
my_snprintf(query_buff, sizeof(query_buff),
1634
"SHOW FIELDS FROM %s", result_table);
1635
if (switch_character_set_results(mysql, "binary") ||
1636
mysql_query_with_error_report(mysql, &result, query_buff) ||
1637
switch_character_set_results(mysql, default_charset))
1640
View references invalid or privileged table/col/fun (err 1356),
1641
so we cannot create a stand-in table. Be defensive and dump
1642
a comment with the view's 'show create' statement. (Bug #17371)
1645
if (mysql_errno(mysql) == ER_VIEW_INVALID)
1646
fprintf(sql_file, "\n-- failed on view %s: %s\n\n", result_table, scv_buff ? scv_buff : "");
1648
my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR));
1653
my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR));
1655
if (mysql_num_rows(result))
1660
We have already dropped any table of the same name above, so
1661
here we just drop the view.
1664
fprintf(sql_file, "/*!50001 DROP VIEW IF EXISTS %s*/;\n",
1670
"SET @saved_cs_client = @@character_set_client;\n"
1671
"SET character_set_client = utf8;\n"
1672
"/*!50001 CREATE TABLE %s (\n",
1676
Get first row, following loop will prepend comma - keeps from
1677
having to know if the row being printed is last to determine if
1678
there should be a _trailing_ comma.
1681
row= mysql_fetch_row(result);
1683
fprintf(sql_file, " %s %s", quote_name(row[0], name_buff, 0),
1686
while((row= mysql_fetch_row(result)))
1688
/* col name, col type */
1689
fprintf(sql_file, ",\n %s %s",
1690
quote_name(row[0], name_buff, 0), row[1]);
1694
"SET character_set_client = @saved_cs_client;\n");
1699
mysql_free_result(result);
1702
my_fclose(sql_file, MYF(MY_WME));
1708
row= mysql_fetch_row(result);
1711
"SET @saved_cs_client = @@character_set_client;\n"
1712
"SET character_set_client = utf8;\n"
1714
"SET character_set_client = @saved_cs_client;\n",
1718
mysql_free_result(result);
1720
my_snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1722
if (mysql_query_with_error_report(mysql, &result, query_buff))
1725
my_fclose(sql_file, MYF(MY_WME));
1730
If write_data is true, then we build up insert statements for
1731
the table's data. Note: in subsequent lines of code, this test
1732
will have to be performed each time we are appending to
1737
if (opt_replace_into)
1738
dynstr_append_checked(&insert_pat, "REPLACE ");
1740
dynstr_append_checked(&insert_pat, "INSERT ");
1741
dynstr_append_checked(&insert_pat, insert_option);
1742
dynstr_append_checked(&insert_pat, "INTO ");
1743
dynstr_append_checked(&insert_pat, opt_quoted_table);
1744
if (complete_insert)
1746
dynstr_append_checked(&insert_pat, " (");
1750
dynstr_append_checked(&insert_pat, " VALUES ");
1751
if (!extended_insert)
1752
dynstr_append_checked(&insert_pat, "(");
1756
while ((row= mysql_fetch_row(result)))
1758
if (complete_insert)
1762
dynstr_append_checked(&insert_pat, ", ");
1765
dynstr_append_checked(&insert_pat,
1766
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1769
num_fields= mysql_num_rows(result);
1770
mysql_free_result(result);
1774
verbose_msg("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n",
1775
my_progname, mysql_error(mysql));
1777
my_snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1779
if (mysql_query_with_error_report(mysql, &result, query_buff))
1782
/* Make an sql-file, if path was given iow. option -T was given */
1783
if (!opt_no_create_info)
1787
if (!(sql_file= open_sql_file_for_table(table)))
1789
write_header(sql_file, db);
1791
if (!opt_xml && opt_comments)
1792
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1795
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
1797
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
1799
print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
1806
if (opt_replace_into)
1807
dynstr_append_checked(&insert_pat, "REPLACE ");
1809
dynstr_append_checked(&insert_pat, "INSERT ");
1810
dynstr_append_checked(&insert_pat, insert_option);
1811
dynstr_append_checked(&insert_pat, "INTO ");
1812
dynstr_append_checked(&insert_pat, result_table);
1813
if (complete_insert)
1814
dynstr_append_checked(&insert_pat, " (");
1817
dynstr_append_checked(&insert_pat, " VALUES ");
1818
if (!extended_insert)
1819
dynstr_append_checked(&insert_pat, "(");
1823
while ((row= mysql_fetch_row(result)))
1825
ulong *lengths= mysql_fetch_lengths(result);
1828
if (!opt_xml && !opt_no_create_info)
1830
fputs(",\n",sql_file);
1833
if (complete_insert)
1834
dynstr_append_checked(&insert_pat, ", ");
1837
if (complete_insert)
1838
dynstr_append_checked(&insert_pat,
1839
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1840
if (!opt_no_create_info)
1844
print_xml_row(sql_file, "field", result, &row);
1849
fprintf(sql_file, " %s.%s %s", result_table,
1850
quote_name(row[SHOW_FIELDNAME],name_buff, 0),
1853
fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME],
1856
if (row[SHOW_DEFAULT])
1858
fputs(" DEFAULT ", sql_file);
1859
unescape(sql_file, row[SHOW_DEFAULT], lengths[SHOW_DEFAULT]);
1861
if (!row[SHOW_NULL][0])
1862
fputs(" NOT NULL", sql_file);
1863
if (row[SHOW_EXTRA][0])
1864
fprintf(sql_file, " %s",row[SHOW_EXTRA]);
1868
num_fields= mysql_num_rows(result);
1869
mysql_free_result(result);
1870
if (!opt_no_create_info)
1872
/* Make an sql-file, if path was given iow. option -T was given */
1873
char buff[20+FN_REFLEN];
1874
uint keynr,primary_key;
1875
my_snprintf(buff, sizeof(buff), "show keys from %s", result_table);
1876
if (mysql_query_with_error_report(mysql, &result, buff))
1878
if (mysql_errno(mysql) == ER_WRONG_OBJECT)
1881
fputs("\t\t<options Comment=\"view\" />\n", sql_file);
1884
fprintf(stderr, "%s: Can't get keys for table %s (%s)\n",
1885
my_progname, result_table, mysql_error(mysql));
1887
my_fclose(sql_file, MYF(MY_WME));
1891
/* Find first which key is primary key */
1893
primary_key=INT_MAX;
1894
while ((row= mysql_fetch_row(result)))
1896
if (atoi(row[3]) == 1)
1899
#ifdef FORCE_PRIMARY_KEY
1900
if (atoi(row[1]) == 0 && primary_key == INT_MAX)
1903
if (!strcmp(row[2],"PRIMARY"))
1910
mysql_data_seek(result,0);
1912
while ((row= mysql_fetch_row(result)))
1916
print_xml_row(sql_file, "key", result, &row);
1920
if (atoi(row[3]) == 1)
1923
putc(')', sql_file);
1924
if (atoi(row[1])) /* Test if duplicate key */
1925
/* Duplicate allowed */
1926
fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff,0));
1927
else if (keynr == primary_key)
1928
fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
1930
fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,
1934
putc(',', sql_file);
1935
fputs(quote_name(row[4], name_buff, 0), sql_file);
1937
fprintf(sql_file, " (%s)",row[7]); /* Sub key */
1940
mysql_free_result(result);
1944
putc(')', sql_file);
1945
fputs("\n)",sql_file);
1949
/* Get MySQL specific create options */
1952
char show_name_buff[NAME_LEN*2+2+24];
1954
/* Check memory for quote_for_like() */
1955
my_snprintf(buff, sizeof(buff), "show table status like %s",
1956
quote_for_like(table, show_name_buff));
1958
if (mysql_query_with_error_report(mysql, &result, buff))
1960
if (mysql_errno(mysql) != ER_PARSE_ERROR)
1961
{ /* If old MySQL version */
1962
verbose_msg("-- Warning: Couldn't get status information for " \
1963
"table %s (%s)\n", result_table,mysql_error(mysql));
1966
else if (!(row= mysql_fetch_row(result)))
1969
"Error: Couldn't read status information for table %s (%s)\n",
1970
result_table,mysql_error(mysql));
1975
print_xml_row(sql_file, "options", result, &row);
1978
fputs("/*!",sql_file);
1979
print_value(sql_file,result,row,"engine=","Engine",0);
1980
print_value(sql_file,result,row,"","Create_options",0);
1981
print_value(sql_file,result,row,"comment=","Comment",1);
1982
fputs(" */",sql_file);
1986
mysql_free_result(result); /* Is always safe to free */
1990
fputs(";\n", sql_file);
1992
fputs("\t</table_structure>\n", sql_file);
1996
if (complete_insert)
1998
dynstr_append_checked(&insert_pat, ") VALUES ");
1999
if (!extended_insert)
2000
dynstr_append_checked(&insert_pat, "(");
2002
if (sql_file != md_result_file)
2004
fputs("\n", sql_file);
2005
write_footer(sql_file);
2006
my_fclose(sql_file, MYF(MY_WME));
2008
DBUG_RETURN((uint) num_fields);
2009
} /* get_table_structure */
2011
static void add_load_option(DYNAMIC_STRING *str, const char *option,
2012
const char *option_value)
2016
/* Null value means we don't add this option. */
2020
dynstr_append_checked(str, option);
2022
if (strncmp(option_value, "0x", sizeof("0x")-1) == 0)
2024
/* It's a hex constant, don't escape */
2025
dynstr_append_checked(str, option_value);
2029
/* char constant; escape */
2030
field_escape(str, option_value);
2036
Allow the user to specify field terminator strings like:
2037
"'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
2038
This is done by doubling ' and add a end -\ if needed to avoid
2039
syntax errors from the SQL parser.
2042
static void field_escape(DYNAMIC_STRING* in, const char *from)
2044
uint end_backslashes= 0;
2046
dynstr_append_checked(in, "'");
2050
dynstr_append_mem_checked(in, from, 1);
2053
end_backslashes^=1; /* find odd number of backslashes */
2056
if (*from == '\'' && !end_backslashes)
2058
/* We want a duplicate of "'" for MySQL */
2059
dynstr_append_checked(in, "\'");
2065
/* Add missing backslashes if user has specified odd number of backs.*/
2066
if (end_backslashes)
2067
dynstr_append_checked(in, "\\");
2069
dynstr_append_checked(in, "'");
2079
dump_table saves database contents as a series of INSERT statements.
2090
static void dump_table(char *table, char *db)
2093
char buf[200], table_buff[NAME_LEN+3];
2094
DYNAMIC_STRING query_string;
2095
char table_type[NAME_LEN];
2096
char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
2098
ulong rownr, row_break, total_length, init_length;
2103
DBUG_ENTER("dump_table");
2106
Make sure you get the create table info before the following check for
2107
--no-data flag below. Otherwise, the create table info won't be printed.
2109
num_fields= get_table_structure(table, db, table_type, &ignore_flag);
2112
The "table" could be a view. If so, we don't do anything here.
2114
if (strcmp(table_type, "VIEW") == 0)
2117
/* Check --no-data flag */
2120
verbose_msg("-- Skipping dump data for table '%s', --no-data was used\n",
2126
("ignore_flag: %x num_fields: %d", (int) ignore_flag,
2129
If the table type is a merge table or any type that has to be
2130
_completely_ ignored and no data dumped
2132
if (ignore_flag & IGNORE_DATA)
2134
verbose_msg("-- Warning: Skipping data for table '%s' because " \
2135
"it's of type %s\n", table, table_type);
2138
/* Check that there are any fields in the table */
2139
if (num_fields == 0)
2141
verbose_msg("-- Skipping dump data for table '%s', it has no fields\n",
2147
Check --skip-events flag: it is not enough to skip creation of events
2148
discarding SHOW CREATE EVENT statements generation. The myslq.event
2149
table data should be skipped too.
2151
if (!opt_events && !my_strcasecmp(&my_charset_latin1, db, "mysql") &&
2152
!my_strcasecmp(&my_charset_latin1, table, "event"))
2154
verbose_msg("-- Skipping data table mysql.event, --skip-events was used\n");
2158
result_table= quote_name(table,table_buff, 1);
2159
opt_quoted_table= quote_name(table, table_buff2, 0);
2161
verbose_msg("-- Sending SELECT query...\n");
2163
init_dynamic_string_checked(&query_string, "", 1024, 1024);
2167
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
2170
Convert the path to native os format
2171
and resolve to the full filepath.
2173
convert_dirname(tmp_path,path,NullS);
2174
my_load_path(tmp_path, tmp_path, NULL);
2175
fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
2177
/* Must delete the file that 'INTO OUTFILE' will write to */
2178
my_delete(filename, MYF(0));
2180
/* convert to a unix path name to stick into the query */
2181
to_unix_path(filename);
2183
/* now build the query string */
2185
dynstr_append_checked(&query_string, "SELECT * INTO OUTFILE '");
2186
dynstr_append_checked(&query_string, filename);
2187
dynstr_append_checked(&query_string, "'");
2189
if (fields_terminated || enclosed || opt_enclosed || escaped)
2190
dynstr_append_checked(&query_string, " FIELDS");
2192
add_load_option(&query_string, " TERMINATED BY ", fields_terminated);
2193
add_load_option(&query_string, " ENCLOSED BY ", enclosed);
2194
add_load_option(&query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed);
2195
add_load_option(&query_string, " ESCAPED BY ", escaped);
2196
add_load_option(&query_string, " LINES TERMINATED BY ", lines_terminated);
2198
dynstr_append_checked(&query_string, " FROM ");
2199
dynstr_append_checked(&query_string, result_table);
2203
dynstr_append_checked(&query_string, " WHERE ");
2204
dynstr_append_checked(&query_string, where);
2209
dynstr_append_checked(&query_string, " ORDER BY ");
2210
dynstr_append_checked(&query_string, order_by);
2213
if (mysql_real_query(mysql, query_string.str, query_string.length))
2215
DB_error(mysql, "when executing 'SELECT INTO OUTFILE'");
2216
dynstr_free(&query_string);
2222
if (!opt_xml && opt_comments)
2224
fprintf(md_result_file,"\n--\n-- Dumping data for table %s\n--\n",
2226
check_io(md_result_file);
2229
dynstr_append_checked(&query_string, "SELECT * FROM ");
2230
dynstr_append_checked(&query_string, result_table);
2234
if (!opt_xml && opt_comments)
2236
fprintf(md_result_file, "-- WHERE: %s\n", where);
2237
check_io(md_result_file);
2240
dynstr_append_checked(&query_string, " WHERE ");
2241
dynstr_append_checked(&query_string, where);
2245
if (!opt_xml && opt_comments)
2247
fprintf(md_result_file, "-- ORDER BY: %s\n", order_by);
2248
check_io(md_result_file);
2250
dynstr_append_checked(&query_string, " ORDER BY ");
2251
dynstr_append_checked(&query_string, order_by);
2254
if (!opt_xml && !opt_compact)
2256
fputs("\n", md_result_file);
2257
check_io(md_result_file);
2259
if (mysql_query_with_error_report(mysql, 0, query_string.str))
2261
DB_error(mysql, "when retrieving data from server");
2265
res=mysql_use_result(mysql);
2267
res=mysql_store_result(mysql);
2270
DB_error(mysql, "when retrieving data from server");
2274
verbose_msg("-- Retrieving rows...\n");
2275
if (mysql_num_fields(res) != num_fields)
2277
fprintf(stderr,"%s: Error in field count for table: %s ! Aborting.\n",
2278
my_progname, result_table);
2279
error= EX_CONSCHECK;
2285
fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table);
2286
check_io(md_result_file);
2288
/* Moved disable keys to after lock per bug 15977 */
2289
if (opt_disable_keys)
2291
fprintf(md_result_file, "/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",
2293
check_io(md_result_file);
2296
total_length= opt_net_buffer_length; /* Force row break */
2299
init_length=(uint) insert_pat.length+4;
2301
print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table,
2305
fprintf(md_result_file, "set autocommit=0;\n");
2306
check_io(md_result_file);
2309
while ((row= mysql_fetch_row(res)))
2312
ulong *lengths= mysql_fetch_lengths(res);
2314
if (!extended_insert && !opt_xml)
2316
fputs(insert_pat.str,md_result_file);
2317
check_io(md_result_file);
2319
mysql_field_seek(res,0);
2323
fputs("\t<row>\n", md_result_file);
2324
check_io(md_result_file);
2327
for (i= 0; i < mysql_num_fields(res); i++)
2330
ulong length= lengths[i];
2332
if (!(field= mysql_fetch_field(res)))
2334
"Not enough fields from table %s! Aborting.\n",
2338
63 is my_charset_bin. If charsetnr is not 63,
2339
we have not a BLOB but a TEXT column.
2340
we'll dump in hex only BLOB columns.
2342
is_blob= (opt_hex_blob && field->charsetnr == 63 &&
2343
(field->type == MYSQL_TYPE_BIT ||
2344
field->type == MYSQL_TYPE_STRING ||
2345
field->type == MYSQL_TYPE_VAR_STRING ||
2346
field->type == MYSQL_TYPE_VARCHAR ||
2347
field->type == MYSQL_TYPE_BLOB ||
2348
field->type == MYSQL_TYPE_LONG_BLOB ||
2349
field->type == MYSQL_TYPE_MEDIUM_BLOB ||
2350
field->type == MYSQL_TYPE_TINY_BLOB)) ? 1 : 0;
2351
if (extended_insert && !opt_xml)
2354
dynstr_set_checked(&extended_row,"(");
2356
dynstr_append_checked(&extended_row,",");
2362
if (!IS_NUM_FIELD(field))
2365
"length * 2 + 2" is OK for both HEX and non-HEX modes:
2366
- In HEX mode we need exactly 2 bytes per character
2367
plus 2 bytes for '0x' prefix.
2368
- In non-HEX mode we need up to 2 bytes per character,
2369
plus 2 bytes for leading and trailing '\'' characters.
2370
Also we need to reserve 1 byte for terminating '\0'.
2372
dynstr_realloc_checked(&extended_row,length * 2 + 2 + 1);
2373
if (opt_hex_blob && is_blob)
2375
dynstr_append_checked(&extended_row, "0x");
2376
extended_row.length+= mysql_hex_string(extended_row.str +
2377
extended_row.length,
2379
DBUG_ASSERT(extended_row.length+1 <= extended_row.max_length);
2380
/* mysql_hex_string() already terminated string by '\0' */
2381
DBUG_ASSERT(extended_row.str[extended_row.length] == '\0');
2385
dynstr_append_checked(&extended_row,"'");
2386
extended_row.length +=
2387
mysql_real_escape_string(&mysql_connection,
2388
&extended_row.str[extended_row.length],
2390
extended_row.str[extended_row.length]='\0';
2391
dynstr_append_checked(&extended_row,"'");
2396
/* change any strings ("inf", "-inf", "nan") into NULL */
2398
if (my_isalpha(charset_info, *ptr) || (*ptr == '-' &&
2399
my_isalpha(charset_info, ptr[1])))
2400
dynstr_append_checked(&extended_row, "NULL");
2403
if (field->type == MYSQL_TYPE_DECIMAL)
2405
/* add " signs around */
2406
dynstr_append_checked(&extended_row, "'");
2407
dynstr_append_checked(&extended_row, ptr);
2408
dynstr_append_checked(&extended_row, "'");
2411
dynstr_append_checked(&extended_row, ptr);
2416
dynstr_append_checked(&extended_row,"''");
2419
dynstr_append_checked(&extended_row,"NULL");
2425
fputc(',', md_result_file);
2426
check_io(md_result_file);
2430
if (!IS_NUM_FIELD(field))
2434
if (opt_hex_blob && is_blob && length)
2436
/* Define xsi:type="xs:hexBinary" for hex encoded data */
2437
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2438
field->name, "xsi:type=", "xs:hexBinary", NullS);
2439
print_blob_as_hex(md_result_file, row[i], length);
2443
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2444
field->name, NullS);
2445
print_quoted_xml(md_result_file, row[i], length);
2447
fputs("</field>\n", md_result_file);
2449
else if (opt_hex_blob && is_blob && length)
2451
fputs("0x", md_result_file);
2452
print_blob_as_hex(md_result_file, row[i], length);
2455
unescape(md_result_file, row[i], length);
2459
/* change any strings ("inf", "-inf", "nan") into NULL */
2463
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2464
field->name, NullS);
2465
fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
2467
fputs("</field>\n", md_result_file);
2469
else if (my_isalpha(charset_info, *ptr) ||
2470
(*ptr == '-' && my_isalpha(charset_info, ptr[1])))
2471
fputs("NULL", md_result_file);
2472
else if (field->type == MYSQL_TYPE_DECIMAL)
2474
/* add " signs around */
2475
fputc('\'', md_result_file);
2476
fputs(ptr, md_result_file);
2477
fputc('\'', md_result_file);
2480
fputs(ptr, md_result_file);
2485
/* The field value is NULL */
2487
fputs("NULL", md_result_file);
2489
print_xml_null_tag(md_result_file, "\t\t", "field name=",
2492
check_io(md_result_file);
2498
fputs("\t</row>\n", md_result_file);
2499
check_io(md_result_file);
2502
if (extended_insert)
2505
dynstr_append_checked(&extended_row,")");
2506
row_length= 2 + extended_row.length;
2507
if (total_length + row_length < opt_net_buffer_length)
2509
total_length+= row_length;
2510
fputc(',',md_result_file); /* Always row break */
2511
fputs(extended_row.str,md_result_file);
2516
fputs(";\n", md_result_file);
2517
row_break=1; /* This is first row */
2519
fputs(insert_pat.str,md_result_file);
2520
fputs(extended_row.str,md_result_file);
2521
total_length= row_length+init_length;
2523
check_io(md_result_file);
2527
fputs(");\n", md_result_file);
2528
check_io(md_result_file);
2532
/* XML - close table tag and supress regular output */
2534
fputs("\t</table_data>\n", md_result_file);
2535
else if (extended_insert && row_break)
2536
fputs(";\n", md_result_file); /* If not empty table */
2537
fflush(md_result_file);
2538
check_io(md_result_file);
2539
if (mysql_errno(mysql))
2541
my_snprintf(buf, sizeof(buf),
2542
"%s: Error %d: %s when dumping table %s at row: %ld\n",
2549
error= EX_CONSCHECK;
2553
/* Moved enable keys to before unlock per bug 15977 */
2554
if (opt_disable_keys)
2556
fprintf(md_result_file,"/*!40000 ALTER TABLE %s ENABLE KEYS */;\n",
2558
check_io(md_result_file);
2562
fputs("UNLOCK TABLES;\n", md_result_file);
2563
check_io(md_result_file);
2567
fprintf(md_result_file, "commit;\n");
2568
check_io(md_result_file);
2570
mysql_free_result(res);
2572
dynstr_free(&query_string);
2576
dynstr_free(&query_string);
2582
static char *getTableName(int reset)
2584
static MYSQL_RES *res= NULL;
2589
if (!(res= mysql_list_tables(mysql,NullS)))
2592
if ((row= mysql_fetch_row(res)))
2593
return((char*) row[0]);
2596
mysql_data_seek(res,0); /* We want to read again */
2599
mysql_free_result(res);
2603
} /* getTableName */
374
2606
static int dump_all_databases()
377
drizzle_result_st *tableres;
2609
MYSQL_RES *tableres;
380
DrizzleDumpDatabase *database;
383
std::cerr << _("-- Retrieving database structures...") << std::endl;
385
/* Blocking the MySQL privilege tables too because we can't import them due to bug#646187 */
386
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
387
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'performance_schema', 'mysql')";
389
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM DATA_DICTIONARY.SCHEMAS WHERE SCHEMA_NAME NOT IN ('information_schema','data_dictionary')";
391
tableres= db_connection->query(query);
392
while ((row= drizzle_row_next(tableres)))
2612
if (mysql_query_with_error_report(mysql, &tableres, "SHOW DATABASES"))
2614
while ((row= mysql_fetch_row(tableres)))
394
std::string database_name(row[0]);
395
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
396
database= new DrizzleDumpDatabaseMySQL(database_name, db_connection);
398
database= new DrizzleDumpDatabaseDrizzle(database_name, db_connection);
400
database->setCollate(row[1]);
401
database_store.push_back(database);
2616
if (dump_all_tables_in_db(row[0]))
403
db_connection->freeResult(tableres);
406
2621
/* dump_all_databases */
409
static int dump_databases(const vector<string> &db_names)
2624
static int dump_databases(char **db_names)
413
DrizzleDumpDatabase *database;
2628
DBUG_ENTER("dump_databases");
415
for (vector<string>::const_iterator it= db_names.begin(); it != db_names.end(); ++it)
2630
for (db= db_names ; *db ; db++)
418
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
419
database= new DrizzleDumpDatabaseMySQL(temp, db_connection);
421
database= new DrizzleDumpDatabaseDrizzle(temp, db_connection);
422
database_store.push_back(database);
2632
if (dump_all_tables_in_db(*db))
2635
DBUG_RETURN(result);
425
2636
} /* dump_databases */
427
static int dump_selected_tables(const string &db, const vector<string> &table_names)
429
DrizzleDumpDatabase *database;
431
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
432
database= new DrizzleDumpDatabaseMySQL(db, db_connection);
434
database= new DrizzleDumpDatabaseDrizzle(db, db_connection);
436
if (not database->populateTables(table_names))
439
maybe_exit(EX_DRIZZLEERR);
442
database_store.push_back(database);
2640
Table Specific database initalization.
2644
qdatabase quoted name of the database
2651
int init_dumping_tables(char *qdatabase)
2653
DBUG_ENTER("init_dumping_tables");
2661
my_snprintf(qbuf, sizeof(qbuf),
2662
"SHOW CREATE DATABASE IF NOT EXISTS %s",
2665
if (mysql_query(mysql, qbuf) || !(dbinfo = mysql_store_result(mysql)))
2667
/* Old server version, dump generic CREATE DATABASE */
2668
if (opt_drop_database)
2669
fprintf(md_result_file,
2670
"\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n",
2672
fprintf(md_result_file,
2673
"\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n",
2678
if (opt_drop_database)
2679
fprintf(md_result_file,
2680
"\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n",
2682
row = mysql_fetch_row(dbinfo);
2685
fprintf(md_result_file,"\n%s;\n",row[1]);
2687
mysql_free_result(dbinfo);
2691
} /* init_dumping_tables */
2694
static int init_dumping(char *database, int init_func(char*))
2696
if (mysql_get_server_version(mysql) >= 50003 &&
2697
!my_strcasecmp(&my_charset_latin1, database, "information_schema"))
2700
if (mysql_select_db(mysql, database))
2702
DB_error(mysql, "when selecting the database");
2703
return 1; /* If --force */
2705
if (!path && !opt_xml)
2707
if (opt_databases || opt_alldbs)
2710
length of table name * 2 (if name contains quotes), 2 quotes and 0
2712
char quoted_database_buf[NAME_LEN*2+3];
2713
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
2716
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
2717
check_io(md_result_file);
2720
/* Call the view or table specific function */
2721
init_func(qdatabase);
2723
fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
2724
check_io(md_result_file);
2727
if (extended_insert)
2728
init_dynamic_string_checked(&extended_row, "", 1024, 1024);
2730
} /* init_dumping */
2733
/* Return 1 if we should copy the table */
2735
my_bool include_table(const uchar *hash_key, size_t len)
2737
return !hash_search(&ignore_table, hash_key, len);
2741
static int dump_all_tables_in_db(char *database)
2745
char table_buff[NAME_LEN*2+3];
2746
char hash_key[2*NAME_LEN+2]; /* "db.tablename" */
2748
int using_mysql_db= my_strcasecmp(&my_charset_latin1, database, "mysql");
2749
DBUG_ENTER("dump_all_tables_in_db");
2751
afterdot= strmov(hash_key, database);
2754
if (init_dumping(database, init_dumping_tables))
2757
print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
2760
DYNAMIC_STRING query;
2761
init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);
2762
for (numrows= 0 ; (table= getTableName(1)) ; )
2764
char *end= strmov(afterdot, table);
2765
if (include_table((uchar*) hash_key,end - hash_key))
2768
dynstr_append_checked(&query, quote_name(table, table_buff, 1));
2769
dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
2772
if (numrows && mysql_real_query(mysql, query.str, query.length-1))
2773
DB_error(mysql, "when using LOCK TABLES");
2774
/* We shall continue here, if --force was given */
2775
dynstr_free(&query);
2779
if (mysql_refresh(mysql, REFRESH_LOG))
2780
DB_error(mysql, "when doing refresh");
2781
/* We shall continue here, if --force was given */
2783
while ((table= getTableName(0)))
2785
char *end= strmov(afterdot, table);
2786
if (include_table((uchar*) hash_key, end - hash_key))
2788
dump_table(table,database);
2789
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
2795
fputs("</database>\n", md_result_file);
2796
check_io(md_result_file);
2799
VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
2800
if (flush_privileges && using_mysql_db == 0)
2802
fprintf(md_result_file,"\n--\n-- Flush Grant Tables \n--\n");
2803
fprintf(md_result_file,"\n/*! FLUSH PRIVILEGES */;\n");
2806
} /* dump_all_tables_in_db */
2810
get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
2811
table name from the server for the table name given on the command line.
2812
we do this because the table name given on the command line may be a
2813
different case (e.g. T1 vs t1)
2816
pointer to the table name
2820
static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root)
2823
MYSQL_RES *table_res;
2825
char query[50 + 2*NAME_LEN];
2826
char show_name_buff[FN_REFLEN];
2827
DBUG_ENTER("get_actual_table_name");
2829
/* Check memory for quote_for_like() */
2830
DBUG_ASSERT(2*sizeof(old_table_name) < sizeof(show_name_buff));
2831
my_snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
2832
quote_for_like(old_table_name, show_name_buff));
2834
if (mysql_query_with_error_report(mysql, 0, query))
2837
if ((table_res= mysql_store_result(mysql)))
2839
my_ulonglong num_rows= mysql_num_rows(table_res);
2845
TODO: Return all matching rows
2847
row= mysql_fetch_row(table_res);
2848
lengths= mysql_fetch_lengths(table_res);
2849
name= strmake_root(root, row[0], lengths[0]);
2851
mysql_free_result(table_res);
2853
DBUG_PRINT("exit", ("new_table_name: %s", name));
2858
static int dump_selected_tables(char *db, char **table_names, int tables)
2860
char table_buff[NAME_LEN*2+3];
2861
DYNAMIC_STRING lock_tables_query;
2863
char **dump_tables, **pos, **end;
2864
DBUG_ENTER("dump_selected_tables");
2866
if (init_dumping(db, init_dumping_tables))
2869
init_alloc_root(&root, 8192, 0);
2870
if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
2871
die(EX_EOM, "alloc_root failure.");
2873
init_dynamic_string_checked(&lock_tables_query, "LOCK TABLES ", 256, 1024);
2874
for (; tables > 0 ; tables-- , table_names++)
2876
/* the table name passed on commandline may be wrong case */
2877
if ((*pos= get_actual_table_name(*table_names, &root)))
2879
/* Add found table name to lock_tables_query */
2882
dynstr_append_checked(&lock_tables_query, quote_name(*pos, table_buff, 1));
2883
dynstr_append_checked(&lock_tables_query, " READ /*!32311 LOCAL */,");
2891
dynstr_free(&lock_tables_query);
2892
free_root(&root, MYF(0));
2894
maybe_die(EX_ILLEGAL_TABLE, "Couldn't find table: \"%s\"", *table_names);
2895
/* We shall countinue here, if --force was given */
2902
if (mysql_real_query(mysql, lock_tables_query.str,
2903
lock_tables_query.length-1))
2907
dynstr_free(&lock_tables_query);
2908
free_root(&root, MYF(0));
2910
DB_error(mysql, "when doing LOCK TABLES");
2911
/* We shall countinue here, if --force was given */
2914
dynstr_free(&lock_tables_query);
2917
if (mysql_refresh(mysql, REFRESH_LOG))
2920
free_root(&root, MYF(0));
2921
DB_error(mysql, "when doing refresh");
2923
/* We shall countinue here, if --force was given */
2926
print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS);
2928
/* Dump each selected table */
2929
for (pos= dump_tables; pos < end; pos++)
2931
DBUG_PRINT("info",("Dumping table %s", *pos));
2932
dump_table(*pos, db);
2935
free_root(&root, MYF(0));
2936
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
2940
fputs("</database>\n", md_result_file);
2941
check_io(md_result_file);
2944
VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
445
2946
} /* dump_selected_tables */
447
static int do_flush_tables_read_lock()
2949
static int do_show_master_status(MYSQL *mysql_con)
2953
const char *comment_prefix=
2954
(opt_master_data == MYSQL_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : "";
2955
if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS"))
2961
row= mysql_fetch_row(master);
2962
if (row && row[0] && row[1])
2964
/* SHOW MASTER STATUS reports file and position */
2966
fprintf(md_result_file,
2967
"\n--\n-- Position to start replication or point-in-time "
2968
"recovery from\n--\n\n");
2969
fprintf(md_result_file,
2970
"%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
2971
comment_prefix, row[0], row[1]);
2972
check_io(md_result_file);
2974
else if (!ignore_errors)
2976
/* SHOW MASTER STATUS reports nothing and --force is not enabled */
2977
my_printf_error(0, "Error: Binlogging on server not active",
2979
mysql_free_result(master);
2980
maybe_exit(EX_MYSQLERR);
2983
mysql_free_result(master);
2988
static int do_stop_slave_sql(MYSQL *mysql_con)
2991
/* We need to check if the slave sql is running in the first place */
2992
if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
2996
MYSQL_ROW row= mysql_fetch_row(slave);
2999
/* if SLAVE SQL is not running, we don't stop it */
3000
if (!strcmp(row[11],"No"))
3002
mysql_free_result(slave);
3003
/* Silently assume that they don't have the slave running */
3008
mysql_free_result(slave);
3010
/* now, stop slave if running */
3011
if (mysql_query_with_error_report(mysql_con, 0, "STOP SLAVE SQL_THREAD"))
3017
static int add_stop_slave(void)
3020
fprintf(md_result_file,
3021
"\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
3022
fprintf(md_result_file, "STOP SLAVE;\n");
3026
static int add_slave_statements(void)
3029
fprintf(md_result_file,
3030
"\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
3031
fprintf(md_result_file, "START SLAVE;\n");
3035
static int do_show_slave_status(MYSQL *mysql_con)
3038
const char *comment_prefix=
3039
(opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
3040
if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
3044
/* SHOW SLAVE STATUS reports nothing and --force is not enabled */
3045
my_printf_error(0, "Error: Slave not set up", MYF(0));
3051
MYSQL_ROW row= mysql_fetch_row(slave);
3052
if (row && row[9] && row[21])
3054
/* SHOW MASTER STATUS reports file and position */
3056
fprintf(md_result_file,
3057
"\n--\n-- Position to start replication or point-in-time "
3058
"recovery from (the master of this slave)\n--\n\n");
3060
fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
3062
if (opt_include_master_host_port)
3065
fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
3067
fprintf(md_result_file, "MASTER_PORT='%s', ", row[3]);
3069
fprintf(md_result_file,
3070
"MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
3072
check_io(md_result_file);
3074
mysql_free_result(slave);
3079
static int do_start_slave_sql(MYSQL *mysql_con)
3082
/* We need to check if the slave sql is stopped in the first place */
3083
if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
3087
MYSQL_ROW row= mysql_fetch_row(slave);
3090
/* if SLAVE SQL is not running, we don't start it */
3091
if (!strcmp(row[11],"Yes"))
3093
mysql_free_result(slave);
3094
/* Silently assume that they don't have the slave running */
3099
mysql_free_result(slave);
3101
/* now, start slave if stopped */
3102
if (mysql_query_with_error_report(mysql_con, 0, "START SLAVE"))
3104
my_printf_error(0, "Error: Unable to start slave", MYF(0));
3112
static int do_flush_tables_read_lock(MYSQL *mysql_con)
450
3115
We do first a FLUSH TABLES. If a long update is running, the FLUSH TABLES
451
3116
will wait but will not stall the whole mysqld, and when the long update is
452
3117
done the FLUSH TABLES WITH READ LOCK will start and succeed quickly. So,
453
FLUSH TABLES is to lower the probability of a stage where both drizzled
3118
FLUSH TABLES is to lower the probability of a stage where both mysqldump
454
3119
and most client connections are stalled. Of course, if a second long
455
3120
update starts between the two FLUSHes, we have that bad stall.
458
db_connection->queryNoResult("FLUSH TABLES");
459
db_connection->queryNoResult("FLUSH TABLES WITH READ LOCK");
464
static int do_unlock_tables()
466
db_connection->queryNoResult("UNLOCK TABLES");
470
static int start_transaction()
472
db_connection->queryNoResult("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ");
473
db_connection->queryNoResult("START TRANSACTION WITH CONSISTENT SNAPSHOT");
3123
( mysql_query_with_error_report(mysql_con, 0, "FLUSH TABLES") ||
3124
mysql_query_with_error_report(mysql_con, 0,
3125
"FLUSH TABLES WITH READ LOCK") );
3129
static int do_unlock_tables(MYSQL *mysql_con)
3131
return mysql_query_with_error_report(mysql_con, 0, "UNLOCK TABLES");
3134
static int get_bin_log_name(MYSQL *mysql_con,
3135
char* buff_log_name, uint buff_len)
3140
if (mysql_query(mysql_con, "SHOW MASTER STATUS") ||
3141
!(res= mysql_store_result(mysql)))
3144
if (!(row= mysql_fetch_row(res)))
3146
mysql_free_result(res);
3150
Only one row is returned, and the first column is the name of the
3153
strmake(buff_log_name, row[0], buff_len - 1);
3155
mysql_free_result(res);
3159
static int purge_bin_logs_to(MYSQL *mysql_con, char* log_name)
3163
init_dynamic_string_checked(&str, "PURGE BINARY LOGS TO '", 1024, 1024);
3164
dynstr_append_checked(&str, log_name);
3165
dynstr_append_checked(&str, "'");
3166
err = mysql_query_with_error_report(mysql_con, 0, str.str);
3172
static int start_transaction(MYSQL *mysql_con)
3175
We use BEGIN for old servers. --single-transaction --master-data will fail
3176
on old servers, but that's ok as it was already silently broken (it didn't
3177
do a consistent read, so better tell people frankly, with the error).
3179
We want the first consistent read to be used for all tables to dump so we
3180
need the REPEATABLE READ level (not anything lower, for example READ
3181
COMMITTED would give one new consistent read per dumped table).
3183
if ((mysql_get_server_version(mysql_con) < 40100) && opt_master_data)
3185
fprintf(stderr, "-- %s: the combination of --single-transaction and "
3186
"--master-data requires a MySQL server version of at least 4.1 "
3187
"(current server's version is %s). %s\n",
3188
ignore_errors ? "Warning" : "Error",
3189
mysql_con->server_version ? mysql_con->server_version : "unknown",
3190
ignore_errors ? "Continuing due to --force, backup may not be consistent across all tables!" : "Aborting.");
3195
return (mysql_query_with_error_report(mysql_con, 0,
3196
"SET SESSION TRANSACTION ISOLATION "
3197
"LEVEL REPEATABLE READ") ||
3198
mysql_query_with_error_report(mysql_con, 0,
3199
"START TRANSACTION "
3200
"/*!40100 WITH CONSISTENT SNAPSHOT */"));
3204
static ulong find_set(TYPELIB *lib, const char *x, uint length,
3205
char **err_pos, uint *err_len)
3207
const char *end= x + length;
3212
*err_pos= 0; /* No error yet */
3213
while (end > x && my_isspace(charset_info, end[-1]))
3219
const char *start= x;
3222
const char *pos= start;
3225
for (; pos != end && *pos != ','; pos++) ;
3226
var_len= (uint) (pos - start);
3227
strmake(buff, start, min(sizeof(buff), var_len));
3228
find= find_type(buff, lib, var_len);
3231
*err_pos= (char*) start;
3235
found|= ((longlong) 1 << (find - 1));
3245
/* Print a value with a prefix on file */
3246
static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
3247
const char *prefix, const char *name,
3251
mysql_field_seek(result, 0);
3253
for ( ; (field= mysql_fetch_field(result)) ; row++)
3255
if (!strcmp(field->name,name))
3257
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
3260
fputs(prefix, file);
3262
unescape(file,row[0],(uint) strlen(row[0]));
3264
fputs(row[0], file);
3270
return; /* This shouldn't happen */
3277
Check if we the table is one of the table types that should be ignored:
3278
MRG_ISAM, MRG_MYISAM, if opt_delayed, if that table supports delayed inserts.
3279
If the table should be altogether ignored, it returns a TRUE, FALSE if it
3280
should not be ignored. If the user has selected to use INSERT DELAYED, it
3281
sets the value of the bool pointer supports_delayed_inserts to 0 if not
3282
supported, 1 if it is supported.
3286
check_if_ignore_table()
3287
table_name Table name to check
3288
table_type Type of table
3291
mysql MySQL connection
3292
verbose Write warning messages
3295
char (bit value) See IGNORE_ values at top
3298
char check_if_ignore_table(const char *table_name, char *table_type)
3300
char result= IGNORE_NONE;
3301
char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
3302
MYSQL_RES *res= NULL;
3304
DBUG_ENTER("check_if_ignore_table");
3306
/* Check memory for quote_for_like() */
3307
DBUG_ASSERT(2*sizeof(table_name) < sizeof(show_name_buff));
3308
my_snprintf(buff, sizeof(buff), "show table status like %s",
3309
quote_for_like(table_name, show_name_buff));
3310
if (mysql_query_with_error_report(mysql, &res, buff))
3312
if (mysql_errno(mysql) != ER_PARSE_ERROR)
3313
{ /* If old MySQL version */
3314
verbose_msg("-- Warning: Couldn't get status information for "
3315
"table %s (%s)\n", table_name, mysql_error(mysql));
3316
DBUG_RETURN(result); /* assume table is ok */
3319
if (!(row= mysql_fetch_row(res)))
3322
"Error: Couldn't read status information for table %s (%s)\n",
3323
table_name, mysql_error(mysql));
3324
mysql_free_result(res);
3325
DBUG_RETURN(result); /* assume table is ok */
3328
strmake(table_type, "VIEW", NAME_LEN-1);
3332
If the table type matches any of these, we do support delayed inserts.
3333
Note: we do not want to skip dumping this table if if is not one of
3334
these types, but we do want to use delayed inserts in the dump if
3335
the table type is _NOT_ one of these types
3337
strmake(table_type, row[1], NAME_LEN-1);
3340
if (strcmp(table_type,"MyISAM") &&
3341
strcmp(table_type,"ISAM") &&
3342
strcmp(table_type,"ARCHIVE") &&
3343
strcmp(table_type,"HEAP") &&
3344
strcmp(table_type,"MEMORY"))
3345
result= IGNORE_INSERT_DELAYED;
3349
If these two types, we do want to skip dumping the table
3352
(!my_strcasecmp(&my_charset_latin1, table_type, "MRG_MyISAM") ||
3353
!strcmp(table_type,"MRG_ISAM")))
3354
result= IGNORE_DATA;
3356
mysql_free_result(res);
3357
DBUG_RETURN(result);
3362
Get string of comma-separated primary key field names
3365
char *primary_key_fields(const char *table_name)
3366
RETURNS pointer to allocated buffer (must be freed by caller)
3367
table_name quoted table name
3370
Use SHOW KEYS FROM table_name, allocate a buffer to hold the
3371
field names, and then build that string and return the pointer
3374
Returns NULL if there is no PRIMARY or UNIQUE key on the table,
3375
or if there is some failure. It is better to continue to dump
3376
the table unsorted, rather than exit without dumping the data.
3379
static char *primary_key_fields(const char *table_name)
3381
MYSQL_RES *res= NULL;
3383
/* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */
3384
char show_keys_buff[15 + NAME_LEN * 2 + 3];
3385
uint result_length= 0;
3387
char buff[NAME_LEN * 2 + 3];
3390
my_snprintf(show_keys_buff, sizeof(show_keys_buff),
3391
"SHOW KEYS FROM %s", table_name);
3392
if (mysql_query(mysql, show_keys_buff) ||
3393
!(res= mysql_store_result(mysql)))
3395
fprintf(stderr, "Warning: Couldn't read keys from table %s;"
3396
" records are NOT sorted (%s)\n",
3397
table_name, mysql_error(mysql));
3398
/* Don't exit, because it's better to print out unsorted records */
3403
* Figure out the length of the ORDER BY clause result.
3404
* Note that SHOW KEYS is ordered: a PRIMARY key is always the first
3405
* row, and UNIQUE keys come before others. So we only need to check
3406
* the first key, not all keys.
3408
if ((row= mysql_fetch_row(res)) && atoi(row[1]) == 0)
3413
quoted_field= quote_name(row[4], buff, 0);
3414
result_length+= strlen(quoted_field) + 1; /* + 1 for ',' or \0 */
3415
} while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1);
3418
/* Build the ORDER BY clause result */
3422
/* result (terminating \0 is already in result_length) */
3423
result= my_malloc(result_length + 10, MYF(MY_WME));
3426
fprintf(stderr, "Error: Not enough memory to store ORDER BY clause\n");
3429
mysql_data_seek(res, 0);
3430
row= mysql_fetch_row(res);
3431
quoted_field= quote_name(row[4], buff, 0);
3432
end= strmov(result, quoted_field);
3433
while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1)
3435
quoted_field= quote_name(row[4], buff, 0);
3436
end= strxmov(end, ",", quoted_field, NullS);
3442
mysql_free_result(res);
3448
The following functions are wrappers for the dynamic string functions
3449
and if they fail, the wrappers will terminate the current process.
3452
#define DYNAMIC_STR_ERROR_MSG "Couldn't perform DYNAMIC_STRING operation"
3454
static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str,
3455
uint init_alloc, uint alloc_increment)
3457
if (init_dynamic_string(str, init_str, init_alloc, alloc_increment))
3458
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
3461
static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src)
3463
if (dynstr_append(dest, src))
3464
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
3467
static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str)
3469
if (dynstr_set(str, init_str))
3470
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
3473
static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append,
3476
if (dynstr_append_mem(str, append, length))
3477
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
3480
static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size)
3482
if (dynstr_realloc(str, additional_size))
3483
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
477
3487
int main(int argc, char **argv)
3489
char bin_log_name[FN_REFLEN];
483
po::options_description commandline_options(N_("Options used only in command line"));
484
commandline_options.add_options()
485
("all-databases,A", po::value<bool>(&opt_alldbs)->default_value(false)->zero_tokens(),
486
N_("Dump all the databases. This will be same as --databases with all databases selected."))
487
("all-tablespaces,Y", po::value<bool>(&opt_alltspcs)->default_value(false)->zero_tokens(),
488
N_("Dump all the tablespaces."))
489
("complete-insert,c", po::value<bool>(&opt_complete_insert)->default_value(false)->zero_tokens(),
490
N_("Use complete insert statements."))
491
("compress,C", po::value<bool>(&opt_compress)->default_value(false)->zero_tokens(),
492
N_("Use compression in server/client protocol."))
493
("flush-logs,F", po::value<bool>(&flush_logs)->default_value(false)->zero_tokens(),
494
N_("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"))
495
("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
496
N_("Continue even if we get an sql-error."))
497
("help,?", N_("Display this help message and exit."))
498
("lock-all-tables,x", po::value<bool>(&opt_lock_all_tables)->default_value(false)->zero_tokens(),
499
N_("Locks all tables across all databases. This is achieved by taking a global read lock for the duration of the whole dump. Automatically turns --single-transaction and --lock-tables off."))
500
("order-by-primary", po::value<bool>(&opt_order_by_primary)->default_value(false)->zero_tokens(),
501
N_("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."))
502
("single-transaction", po::value<bool>(&opt_single_transaction)->default_value(false)->zero_tokens(),
503
N_("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. Option automatically turns off --lock-tables."))
504
("opt", N_("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."))
506
N_("Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys."))
507
("tables", N_("Overrides option --databases (-B)."))
508
("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(10000),
509
N_("Number of rows before each output progress report (requires --verbose)."))
510
("verbose,v", po::value<bool>(&verbose)->default_value(false)->zero_tokens(),
511
N_("Print info about the various stages."))
512
("version,V", N_("Output version information and exit."))
513
("skip-comments", N_("Turn off Comments"))
514
("skip-create", N_("Turn off create-options"))
515
("skip-extended-insert", N_("Turn off extended-insert"))
516
("skip-dump-date",N_( "Turn off dump date at the end of the output"))
517
("no-defaults", N_("Do not read from the configuration files"))
520
po::options_description dump_options(N_("Options specific to the drizzle client"));
521
dump_options.add_options()
522
("add-drop-database", po::value<bool>(&opt_drop_database)->default_value(false)->zero_tokens(),
523
N_("Add a 'DROP DATABASE' before each create."))
524
("skip-drop-table", N_("Do not add a 'drop table' before each create."))
525
("allow-keywords", po::value<bool>(&opt_keywords)->default_value(false)->zero_tokens(),
526
N_("Allow creation of column names that are keywords."))
527
("compact", po::value<bool>(&opt_compact)->default_value(false)->zero_tokens(),
528
N_("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"))
529
("databases,B", po::value<bool>(&opt_databases)->default_value(false)->zero_tokens(),
530
N_("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."))
531
("delayed-insert", po::value<bool>(&opt_delayed)->default_value(false)->zero_tokens(),
532
N_("Insert rows with INSERT DELAYED;"))
533
("skip-disable-keys,K",
534
N_("'ALTER TABLE tb_name DISABLE KEYS; and 'ALTER TABLE tb_name ENABLE KEYS; will not be put in the output."))
535
("ignore-table", po::value<string>(),
536
N_("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"))
537
("insert-ignore", po::value<bool>(&opt_ignore)->default_value(false)->zero_tokens(),
538
N_("Insert rows with INSERT IGNORE."))
539
("lines-terminated-by", po::value<string>(&lines_terminated)->default_value(""),
540
N_("Lines in the i.file are terminated by ..."))
541
("no-autocommit", po::value<bool>(&opt_autocommit)->default_value(false)->zero_tokens(),
542
N_("Wrap tables with autocommit/commit statements."))
543
("no-create-db,n", po::value<bool>(&opt_create_db)->default_value(false)->zero_tokens(),
544
N_("'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."))
545
("no-create-info,t", po::value<bool>(&opt_no_create_info)->default_value(false)->zero_tokens(),
546
N_("Don't write table creation info."))
547
("no-data,d", po::value<bool>(&opt_no_data)->default_value(false)->zero_tokens(),
548
N_("No row information."))
549
("no-set-names,N", N_("Deprecated. Use --skip-set-charset instead."))
550
("set-charset", po::value<bool>(&opt_set_charset)->default_value(false)->zero_tokens(),
551
N_("Enable set-name"))
552
("slow", N_("Buffer query instead of dumping directly to stdout."))
553
("replace", po::value<bool>(&opt_replace_into)->default_value(false)->zero_tokens(),
554
N_("Use REPLACE INTO instead of INSERT INTO."))
555
("result-file,r", po::value<string>(),
556
N_("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)."))
557
("destination-type", po::value<string>()->default_value("stdout"),
558
N_("Where to send output to (stdout|database"))
559
("destination-host", po::value<string>(&opt_destination_host)->default_value("localhost"),
560
N_("Hostname for destination db server (requires --destination=database)"))
561
("destination-port", po::value<uint16_t>(&opt_destination_port)->default_value(3306),
562
N_("Port number for destination db server (requires --destination=database)"))
563
("destination-user", po::value<string>(&opt_destination_user),
564
N_("User name for destination db server (resquires --destination=database)"))
565
("destination-password", po::value<string>(&opt_destination_password),
566
N_("Password for destination db server (requires --destination=database)"))
567
("destination-database", po::value<string>(&opt_destination_database),
568
N_("The database in the destination db server (requires --destination=database, not for use with --all-databases)"))
571
po::options_description client_options(N_("Options specific to the client"));
572
client_options.add_options()
573
("host,h", po::value<string>(¤t_host)->default_value("localhost"),
574
N_("Connect to host."))
575
("password,P", po::value<string>(&password)->default_value(PASSWORD_SENTINEL),
576
N_("Password to use when connecting to server. If password is not given it's solicited on the tty."))
577
("port,p", po::value<uint32_t>(&opt_drizzle_port)->default_value(0),
578
N_("Port number to use for connection."))
579
("user,u", po::value<string>(¤t_user)->default_value(""),
580
N_("User for login if not current user."))
581
("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
582
N_("The protocol of connection (mysql or drizzle)."))
585
po::options_description hidden_options(N_("Hidden Options"));
586
hidden_options.add_options()
587
("database-used", po::value<vector<string> >(), N_("Used to select the database"))
588
("Table-used", po::value<vector<string> >(), N_("Used to select the tables"))
591
po::options_description all_options(N_("Allowed Options + Hidden Options"));
592
all_options.add(commandline_options).add(dump_options).add(client_options).add(hidden_options);
594
po::options_description long_options(N_("Allowed Options"));
595
long_options.add(commandline_options).add(dump_options).add(client_options);
597
std::string system_config_dir_dump(SYSCONFDIR);
598
system_config_dir_dump.append("/drizzle/drizzledump.cnf");
600
std::string system_config_dir_client(SYSCONFDIR);
601
system_config_dir_client.append("/drizzle/client.cnf");
603
std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
605
po::positional_options_description p;
606
p.add("database-used", 1);
607
p.add("Table-used",-1);
609
md_result_file= stdout;
611
po::variables_map vm;
613
// Disable allow_guessing
614
int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
616
po::store(po::command_line_parser(argc, argv).style(style).
617
options(all_options).positional(p).
618
extra_parser(parse_password_arg).run(), vm);
620
if (! vm.count("no-defaults"))
622
std::string user_config_dir_dump(user_config_dir);
623
user_config_dir_dump.append("/drizzle/drizzledump.cnf");
625
std::string user_config_dir_client(user_config_dir);
626
user_config_dir_client.append("/drizzle/client.cnf");
628
ifstream user_dump_ifs(user_config_dir_dump.c_str());
629
po::store(parse_config_file(user_dump_ifs, dump_options), vm);
631
ifstream user_client_ifs(user_config_dir_client.c_str());
632
po::store(parse_config_file(user_client_ifs, client_options), vm);
634
ifstream system_dump_ifs(system_config_dir_dump.c_str());
635
po::store(parse_config_file(system_dump_ifs, dump_options), vm);
637
ifstream system_client_ifs(system_config_dir_client.c_str());
638
po::store(parse_config_file(system_client_ifs, client_options), vm);
643
if ((not vm.count("database-used") && not vm.count("Table-used")
644
&& not opt_alldbs && path.empty())
645
|| (vm.count("help")) || vm.count("version"))
647
printf(_("Drizzledump %s build %s, for %s-%s (%s)\n"),
648
drizzle_version(), VERSION, HOST_VENDOR, HOST_OS, HOST_CPU);
649
if (vm.count("version"))
652
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"));
653
puts(_("Dumps definitions and data from a Drizzle database server"));
654
printf(_("Usage: %s [OPTIONS] database [tables]\n"), progname.c_str());
655
printf(_("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n"),
657
printf(_("OR %s [OPTIONS] --all-databases [OPTIONS]\n"), progname.c_str());
658
cout << long_options;
659
if (vm.count("help"))
665
/* Inverted Booleans */
667
opt_drop= (vm.count("skip-drop-table")) ? false : true;
668
opt_comments= (vm.count("skip-comments")) ? false : true;
669
extended_insert= (vm.count("skip-extended-insert")) ? false : true;
670
opt_dump_date= (vm.count("skip-dump-date")) ? false : true;
671
opt_disable_keys= (vm.count("skip-disable-keys")) ? false : true;
672
quick= (vm.count("slow")) ? false : true;
673
opt_quoted= (vm.count("skip-quote-names")) ? false : true;
675
if (vm.count("protocol"))
677
std::transform(opt_protocol.begin(), opt_protocol.end(),
678
opt_protocol.begin(), ::tolower);
680
if (not opt_protocol.compare("mysql"))
681
use_drizzle_protocol=false;
682
else if (not opt_protocol.compare("drizzle"))
683
use_drizzle_protocol=true;
686
cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
691
if (vm.count("port"))
693
/* If the port number is > 65535 it is not a valid port
694
* This also helps with potential data loss casting unsigned long to a
697
if (opt_drizzle_port > 65535)
699
fprintf(stderr, _("Value supplied for port is not valid.\n"));
704
if(vm.count("password"))
706
if (!opt_password.empty())
707
opt_password.erase();
708
if (password == PASSWORD_SENTINEL)
714
opt_password= password;
723
if (vm.count("result-file"))
725
if (!(md_result_file= fopen(vm["result-file"].as<string>().c_str(), "w")))
729
if (vm.count("no-set-names"))
739
if (vm.count("skip-opt"))
741
extended_insert= opt_drop= quick= create_options= 0;
742
opt_disable_keys= opt_set_charset= 0;
747
opt_comments= opt_drop= opt_disable_keys= 0;
753
extended_insert= opt_drop= quick= create_options= 1;
754
opt_disable_keys= opt_set_charset= 1;
757
if (vm.count("tables"))
759
opt_databases= false;
762
if (vm.count("ignore-table"))
764
if (!strchr(vm["ignore-table"].as<string>().c_str(), '.'))
766
fprintf(stderr, _("Illegal use of option --ignore-table=<database>.<table>\n"));
767
exit(EXIT_ARGUMENT_INVALID);
769
string tmpptr(vm["ignore-table"].as<string>());
770
ignore_table.insert(tmpptr);
773
if (vm.count("skip-create"))
775
opt_create_db= opt_no_create_info= create_options= false;
778
exit_code= get_options();
3491
MY_INIT("mysqldump");
3493
compatible_mode_normal_str[0]= 0;
3494
default_charset= (char *)mysql_universal_client_charset;
3495
bzero((char*) &ignore_table, sizeof(ignore_table));
3497
exit_code= get_options(&argc, &argv);
782
3501
exit(exit_code);
785
db_connection = new DrizzleDumpConnection(current_host, opt_drizzle_port,
786
current_user, opt_password, use_drizzle_protocol);
788
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
789
db_connection->queryNoResult("SET NAMES 'utf8'");
791
if (vm.count("destination-type"))
793
string tmp_destination(vm["destination-type"].as<string>());
794
if (tmp_destination.compare("database") == 0)
795
opt_destination= DESTINATION_DB;
796
else if (tmp_destination.compare("stdout") == 0)
797
opt_destination= DESTINATION_STDOUT;
799
exit(EXIT_ARGUMENT_INVALID);
803
if (path.empty() && vm.count("database-used"))
805
string database_used= *vm["database-used"].as< vector<string> >().begin();
806
write_header((char *)database_used.c_str());
809
if ((opt_lock_all_tables) && do_flush_tables_read_lock())
811
if (opt_single_transaction && start_transaction())
813
if (opt_lock_all_tables)
814
db_connection->queryNoResult("FLUSH LOGS");
815
if (opt_single_transaction && do_unlock_tables()) /* unlock but no commit! */
3506
if(!(stderror_file= freopen(log_error_file, "a+", stderr)))
3513
if (connect_to_db(current_host, current_user, opt_password))
3519
write_header(md_result_file, *argv);
3521
if (opt_slave_data && do_stop_slave_sql(mysql))
3524
if ((opt_lock_all_tables || opt_master_data) &&
3525
do_flush_tables_read_lock(mysql))
3527
if (opt_single_transaction && start_transaction(mysql))
3529
if (opt_delete_master_logs)
3531
if (mysql_refresh(mysql, REFRESH_LOG) ||
3532
get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name)))
3536
if (opt_lock_all_tables || opt_master_data)
3538
if (flush_logs && mysql_refresh(mysql, REFRESH_LOG))
3540
flush_logs= 0; /* not anymore; that would not be sensible */
3542
/* Add 'STOP SLAVE to beginning of dump */
3543
if (opt_slave_apply && add_stop_slave())
3545
if (opt_master_data && do_show_master_status(mysql))
3547
if (opt_slave_data && do_show_slave_status(mysql))
3549
if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */
820
3554
dump_all_databases();
823
if (vm.count("database-used") && vm.count("Table-used") && ! opt_databases)
3556
else if (argc > 1 && !opt_databases)
825
string database_used= *vm["database-used"].as< vector<string> >().begin();
826
3558
/* Only one database and selected table(s) */
827
dump_selected_tables(database_used, vm["Table-used"].as< vector<string> >());
830
if (vm.count("Table-used") && opt_databases)
834
vector<string> database_used= vm["database-used"].as< vector<string> >();
835
vector<string> table_used= vm["Table-used"].as< vector<string> >();
837
for (vector<string>::iterator it= table_used.begin();
838
it != table_used.end();
841
database_used.insert(database_used.end(), *it);
843
dump_databases(database_used);
848
if (vm.count("database-used") && ! vm.count("Table-used"))
850
dump_databases(vm["database-used"].as< vector<string> >());
853
if (opt_destination == DESTINATION_STDOUT)
3559
dump_selected_tables(*argv, (argv + 1), (argc - 1));
3563
dump_databases(argv);
3566
/* if --dump-slave , start the slave sql thread */
3567
if (opt_slave_data && do_start_slave_sql(mysql))
3570
/* add 'START SLAVE' to end of dump */
3571
if (opt_slave_apply && add_slave_statements())
858
3574
/* ensure dumped data flushed */
859
3575
if (md_result_file && fflush(md_result_file))
861
3577
if (!first_error)
862
first_error= EX_DRIZZLEERR;
3578
first_error= EX_MYSQLERR;
3581
/* everything successful, purge the old logs files */
3582
if (opt_delete_master_logs && purge_bin_logs_to(mysql, bin_log_name))
3586
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
867
3589
No reason to explicitely COMMIT the transaction, neither to explicitely
868
3590
UNLOCK TABLES: these will be automatically be done by the server when we