41 #define DUMP_VERSION "10.13"
43 #include <my_global.h>
51 #include "client_priv.h"
52 #include "my_default.h"
54 #include "mysql_version.h"
55 #include "mysqld_error.h"
57 #include <welcome_copyright_notice.h>
63 #define EX_CONSCHECK 3
66 #define EX_ILLEGAL_TABLE 6
70 #define SHOW_FIELDNAME 0
73 #define SHOW_DEFAULT 4
77 #define QUERY_LENGTH 1536
80 #define COMMENT_LENGTH 2048
83 #define IGNORE_NONE 0x00
84 #define IGNORE_DATA 0x01
85 #define IGNORE_INSERT_DELAYED 0x02
90 static ulong find_set(
TYPELIB *lib,
const char *x, uint length,
91 char **err_pos, uint *err_len);
92 static char *alloc_query_str(ulong
size);
95 static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
96 quick= 1, extended_insert= 1,
97 lock_tables=1,ignore_errors=0,flush_logs=0,flush_privileges=0,
98 opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0,
99 opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0,
100 opt_alldbs=0,opt_create_db=0,opt_lock_all_tables=0,
101 opt_set_charset=0, opt_dump_date=1,
102 opt_autocommit=0,opt_disable_keys=1,opt_xml=0,
103 opt_delete_master_logs=0, tty_password=0,
104 opt_single_transaction=0, opt_comments= 0, opt_compact= 0,
105 opt_hex_blob=0, opt_order_by_primary=0, opt_ignore=0,
106 opt_complete_insert= 0, opt_drop_database= 0,
108 opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
110 opt_include_master_host_port= 0,
111 opt_events= 0, opt_comments_used= 0,
112 opt_alltspcs=0, opt_notspcs= 0, opt_drop_trigger= 0;
113 static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
114 static ulong opt_max_allowed_packet, opt_net_buffer_length;
115 static MYSQL mysql_connection,*mysql=0;
117 static char *opt_password=0,*current_user=0,
118 *current_host=0,*path=0,*fields_terminated=0,
119 *lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
120 *where=0, *order_by=0,
121 *opt_compatible_mode_str= 0,
123 *log_error_file= NULL;
124 static char **defaults_argv= 0;
125 static char compatible_mode_normal_str[255];
127 static my_bool server_supports_switching_charsets= TRUE;
128 static ulong opt_compatible_mode= 0;
129 #define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
130 #define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
131 #define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
132 #define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2
133 static uint opt_mysql_port= 0, opt_master_data;
134 static uint opt_slave_data;
135 static uint my_end_arg;
136 static char * opt_mysql_unix_port=0;
137 static char *opt_bind_addr = NULL;
138 static int first_error=0;
140 #include <sslopt-vars.h>
141 FILE *md_result_file= 0;
142 FILE *stderror_file=0;
144 const char *set_gtid_purged_mode_names[]=
145 {
"OFF",
"AUTO",
"ON", NullS};
146 static TYPELIB set_gtid_purged_mode_typelib=
147 {array_elements(set_gtid_purged_mode_names) -1,
"",
148 set_gtid_purged_mode_names, NULL};
149 static enum enum_set_gtid_purged_mode {
150 SET_GTID_PURGED_OFF= 0,
151 SET_GTID_PURGED_AUTO =1,
153 } opt_set_gtid_purged_mode= SET_GTID_PURGED_AUTO;
156 static char *shared_memory_base_name=0;
158 static uint opt_protocol= 0;
159 static char *opt_plugin_dir= 0, *opt_default_auth= 0;
166 static void init_dynamic_string_checked(
DYNAMIC_STRING *str,
const char *init_str,
167 uint init_alloc, uint alloc_increment);
168 static void dynstr_append_checked(
DYNAMIC_STRING* dest,
const char* src);
169 static void dynstr_set_checked(
DYNAMIC_STRING *str,
const char *init_str);
170 static void dynstr_append_mem_checked(
DYNAMIC_STRING *str,
const char *append,
172 static void dynstr_realloc_checked(
DYNAMIC_STRING *str, ulong additional_size);
178 static const char *mysql_universal_client_charset=
179 MYSQL_UNIVERSAL_CLIENT_CHARSET;
180 static char *default_charset;
182 const char *default_dbug_option=
"d:t:o,/tmp/mysqldump.trace";
184 my_bool seen_views= 0;
185 const char *compatible_mode_names[]=
187 "MYSQL323",
"MYSQL40",
"POSTGRESQL",
"ORACLE",
"MSSQL",
"DB2",
188 "MAXDB",
"NO_KEY_OPTIONS",
"NO_TABLE_OPTIONS",
"NO_FIELD_OPTIONS",
192 #define MASK_ANSI_QUOTES \
201 TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
202 "", compatible_mode_names, NULL};
206 static struct my_option my_long_options[] =
208 {
"all-databases",
'A',
209 "Dump all the databases. This will be same as --databases with all databases selected.",
210 &opt_alldbs, &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
212 {
"all-tablespaces",
'Y',
213 "Dump all the tablespaces.",
214 &opt_alltspcs, &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
216 {
"no-tablespaces",
'y',
217 "Do not dump any tablespace information.",
218 &opt_notspcs, &opt_notspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
220 {
"add-drop-database", OPT_DROP_DATABASE,
"Add a DROP DATABASE before each create.",
221 &opt_drop_database, &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
223 {
"add-drop-table", OPT_DROP,
"Add a DROP TABLE before each create.",
224 &opt_drop, &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
226 {
"add-drop-trigger", 0,
"Add a DROP TRIGGER before each create.",
227 &opt_drop_trigger, &opt_drop_trigger, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
229 {
"add-locks", OPT_LOCKS,
"Add locks around INSERT statements.",
230 &opt_lock, &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
232 {
"allow-keywords", OPT_KEYWORDS,
233 "Allow creation of column names that are keywords.", &opt_keywords,
234 &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
235 {
"apply-slave-statements", OPT_MYSQLDUMP_SLAVE_APPLY,
236 "Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
237 &opt_slave_apply, &opt_slave_apply, 0, GET_BOOL, NO_ARG,
239 {
"bind-address", 0,
"IP address to bind to.",
240 (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
241 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
242 {
"character-sets-dir", OPT_CHARSETS_DIR,
243 "Directory for character set files.", &charsets_dir,
244 &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
245 {
"comments",
'i',
"Write additional information.",
246 &opt_comments, &opt_comments, 0, GET_BOOL, NO_ARG,
248 {
"compatible", OPT_COMPATIBLE,
249 "Change the dump to be compatible with a given mode. By default tables "
250 "are dumped in a format optimized for MySQL. Legal modes are: ansi, "
251 "mysql323, mysql40, postgresql, oracle, mssql, db2, maxdb, no_key_options, "
252 "no_table_options, no_field_options. One can use several modes separated "
253 "by commas. Note: Requires MySQL server version 4.1.0 or higher. "
254 "This option is ignored with earlier server versions.",
255 &opt_compatible_mode_str, &opt_compatible_mode_str, 0,
256 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
257 {
"compact", OPT_COMPACT,
258 "Give less verbose output (useful for debugging). Disables structure "
259 "comments and header/footer constructs. Enables options --skip-add-"
260 "drop-table --skip-add-locks --skip-comments --skip-disable-keys "
261 "--skip-set-charset.",
262 &opt_compact, &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
263 {
"complete-insert",
'c',
"Use complete insert statements.",
264 &opt_complete_insert, &opt_complete_insert, 0, GET_BOOL,
265 NO_ARG, 0, 0, 0, 0, 0, 0},
266 {
"compress",
'C',
"Use compression in server/client protocol.",
267 &opt_compress, &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
269 {
"create-options",
'a',
270 "Include all MySQL specific create options.",
271 &create_options, &create_options, 0, GET_BOOL, NO_ARG, 1,
274 "Dump several databases. Note the difference in usage; in this case no tables are given. All name arguments are regarded as database names. 'USE db_name;' will be included in the output.",
275 &opt_databases, &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
278 {
"debug",
'#',
"This is a non-debug version. Catch this and exit.",
279 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
281 {
"debug",
'#',
"Output debug log.", &default_dbug_option,
282 &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
284 {
"debug-check", OPT_DEBUG_CHECK,
"Check memory and open file usage at exit.",
285 &debug_check_flag, &debug_check_flag, 0,
286 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
287 {
"debug-info", OPT_DEBUG_INFO,
"Print some debug info at exit.",
288 &debug_info_flag, &debug_info_flag,
289 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
290 {
"default-character-set", OPT_DEFAULT_CHARSET,
291 "Set the default character set.", &default_charset,
292 &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
293 {
"delayed-insert", OPT_DELAYED,
"Insert rows with INSERT DELAYED.",
294 &opt_delayed, &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
296 {
"delete-master-logs", OPT_DELETE_MASTER_LOGS,
297 "Delete logs on master after backup. This automatically enables --master-data.",
298 &opt_delete_master_logs, &opt_delete_master_logs, 0,
299 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
300 {
"disable-keys",
'K',
301 "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER "
302 "TABLE tb_name ENABLE KEYS */; will be put in the output.", &opt_disable_keys,
303 &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
304 {
"dump-slave", OPT_MYSQLDUMP_SLAVE_DATA,
305 "This causes the binary log position and filename of the master to be "
306 "appended to the dumped data output. Setting the value to 1, will print"
307 "it as a CHANGE MASTER command in the dumped data output; if equal"
308 " to 2, that command will be prefixed with a comment symbol. "
309 "This option will turn --lock-all-tables on, unless "
310 "--single-transaction is specified too (in which case a "
311 "global read lock is only taken a short time at the beginning of the dump "
312 "- don't forget to read about --single-transaction below). In all cases "
313 "any action on logs will happen at the exact moment of the dump."
314 "Option automatically turns --lock-tables off.",
315 &opt_slave_data, &opt_slave_data, 0,
316 GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
317 {
"events",
'E',
"Dump events.",
318 &opt_events, &opt_events, 0, GET_BOOL,
319 NO_ARG, 0, 0, 0, 0, 0, 0},
320 {
"extended-insert",
'e',
321 "Use multiple-row INSERT syntax that include several VALUES lists.",
322 &extended_insert, &extended_insert, 0, GET_BOOL, NO_ARG,
324 {
"fields-terminated-by", OPT_FTB,
325 "Fields in the output file are terminated by the given string.",
326 &fields_terminated, &fields_terminated, 0,
327 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
328 {
"fields-enclosed-by", OPT_ENC,
329 "Fields in the output file are enclosed by the given character.",
330 &enclosed, &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
331 {
"fields-optionally-enclosed-by", OPT_O_ENC,
332 "Fields in the output file are optionally enclosed by the given character.",
333 &opt_enclosed, &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
334 {
"fields-escaped-by", OPT_ESC,
335 "Fields in the output file are escaped by the given character.",
336 &escaped, &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
337 {
"flush-logs",
'F',
"Flush logs file in server before starting dump. "
338 "Note that if you dump many databases at once (using the option "
339 "--databases= or --all-databases), the logs will be flushed for "
340 "each database dumped. The exception is when using --lock-all-tables "
342 "in this case the logs will be flushed only once, corresponding "
343 "to the moment all tables are locked. So if you want your dump and "
344 "the log flush to happen at the same exact moment you should use "
345 "--lock-all-tables or --master-data with --flush-logs.",
346 &flush_logs, &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
348 {
"flush-privileges", OPT_ESC,
"Emit a FLUSH PRIVILEGES statement "
349 "after dumping the mysql database. This option should be used any "
350 "time the dump contains the mysql database and any other database "
351 "that depends on the data in the mysql database for proper restore. ",
352 &flush_privileges, &flush_privileges, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
354 {
"force",
'f',
"Continue even if we get an SQL error.",
355 &ignore_errors, &ignore_errors, 0, GET_BOOL, NO_ARG,
357 {
"help",
'?',
"Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
358 NO_ARG, 0, 0, 0, 0, 0, 0},
359 {
"hex-blob", OPT_HEXBLOB,
"Dump binary strings (BINARY, "
360 "VARBINARY, BLOB) in hexadecimal format.",
361 &opt_hex_blob, &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
362 {
"host",
'h',
"Connect to host.", ¤t_host,
363 ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
364 {
"ignore-table", OPT_IGNORE_TABLE,
365 "Do not dump the specified table. To specify more than one table to ignore, "
366 "use the directive multiple times, once for each table. Each table must "
367 "be specified with both database and table names, e.g., "
368 "--ignore-table=database.table.",
369 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
370 {
"include-master-host-port", OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT,
371 "Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' "
372 "in dump produced with --dump-slave.", &opt_include_master_host_port,
373 &opt_include_master_host_port, 0, GET_BOOL, NO_ARG,
375 {
"insert-ignore", OPT_INSERT_IGNORE,
"Insert rows with INSERT IGNORE.",
376 &opt_ignore, &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
378 {
"lines-terminated-by", OPT_LTB,
379 "Lines in the output file are terminated by the given string.",
380 &lines_terminated, &lines_terminated, 0, GET_STR,
381 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
382 {
"lock-all-tables",
'x',
"Locks all tables across all databases. This "
383 "is achieved by taking a global read lock for the duration of the whole "
384 "dump. Automatically turns --single-transaction and --lock-tables off.",
385 &opt_lock_all_tables, &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
387 {
"lock-tables",
'l',
"Lock all tables for read.", &
lock_tables,
388 &
lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
389 {
"log-error", OPT_ERROR_LOG_FILE,
"Append warnings and errors to given file.",
390 &log_error_file, &log_error_file, 0, GET_STR,
391 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
392 {
"master-data", OPT_MASTER_DATA,
393 "This causes the binary log position and filename to be appended to the "
394 "output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
395 " to 2, that command will be prefixed with a comment symbol. "
396 "This option will turn --lock-all-tables on, unless "
397 "--single-transaction is specified too (in which case a "
398 "global read lock is only taken a short time at the beginning of the dump; "
399 "don't forget to read about --single-transaction below). In all cases, "
400 "any action on logs will happen at the exact moment of the dump. "
401 "Option automatically turns --lock-tables off.",
402 &opt_master_data, &opt_master_data, 0,
403 GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_MASTER_DATA_COMMENTED_SQL, 0, 0, 0},
404 {
"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
405 "The maximum packet length to send to or receive from server.",
406 &opt_max_allowed_packet, &opt_max_allowed_packet, 0,
407 GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096,
408 (longlong) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
409 {
"net_buffer_length", OPT_NET_BUFFER_LENGTH,
410 "The buffer size for TCP/IP and socket communication.",
411 &opt_net_buffer_length, &opt_net_buffer_length, 0,
412 GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L,
413 MALLOC_OVERHEAD-1024, 1024, 0},
414 {
"no-autocommit", OPT_AUTOCOMMIT,
415 "Wrap tables with autocommit/commit statements.",
416 &opt_autocommit, &opt_autocommit, 0, GET_BOOL, NO_ARG,
418 {
"no-create-db",
'n',
419 "Suppress the CREATE DATABASE ... IF EXISTS statement that normally is "
420 "output for each dumped database if --all-databases or --databases is "
422 &opt_create_db, &opt_create_db, 0,
423 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
424 {
"no-create-info",
't',
"Don't write table creation info.",
425 &opt_no_create_info, &opt_no_create_info, 0, GET_BOOL,
426 NO_ARG, 0, 0, 0, 0, 0, 0},
427 {
"no-data",
'd',
"No row information.", &opt_no_data,
428 &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
429 {
"no-set-names",
'N',
"Same as --skip-set-charset.",
430 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
431 {
"opt", OPT_OPTIMIZE,
432 "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.",
433 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
434 {
"order-by-primary", OPT_ORDER_BY_PRIMARY,
435 "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.",
436 &opt_order_by_primary, &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
438 "Password to use when connecting to server. If password is not given it's solicited on the tty.",
439 0, 0, 0, GET_PASSWORD, OPT_ARG, 0, 0, 0, 0, 0, 0},
441 {
"pipe",
'W',
"Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
442 NO_ARG, 0, 0, 0, 0, 0, 0},
444 {
"port",
'P',
"Port number to use for connection.", &opt_mysql_port,
445 &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
447 {
"protocol", OPT_MYSQL_PROTOCOL,
448 "The protocol to use for connection (tcp, socket, pipe, memory).",
449 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
450 {
"quick",
'q',
"Don't buffer query, dump directly to stdout.",
451 &quick, &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
452 {
"quote-names",
'Q',
"Quote table and column names with backticks (`).",
453 &opt_quoted, &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
455 {
"replace", OPT_MYSQL_REPLACE_INTO,
"Use REPLACE INTO instead of INSERT INTO.",
456 &opt_replace_into, &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
459 "Direct output to a given file. This option should be used in systems "
460 "(e.g., DOS, Windows) that use carriage-return linefeed pairs (\\r\\n) "
461 "to separate text lines. This option ensures that only a single newline "
462 "is used.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
463 {
"routines",
'R',
"Dump stored routines (functions and procedures).",
464 &opt_routines, &opt_routines, 0, GET_BOOL,
465 NO_ARG, 0, 0, 0, 0, 0, 0},
466 {
"set-charset", OPT_SET_CHARSET,
467 "Add 'SET NAMES default_character_set' to the output.",
468 &opt_set_charset, &opt_set_charset, 0, GET_BOOL, NO_ARG, 1,
470 {
"set-gtid-purged", OPT_SET_GTID_PURGED,
471 "Add 'SET @@GLOBAL.GTID_PURGED' to the output. Possible values for "
472 "this option are ON, OFF and AUTO. If ON is used and GTIDs "
473 "are not enabled on the server, an error is generated. If OFF is "
474 "used, this option does nothing. If AUTO is used and GTIDs are enabled "
475 "on the server, 'SET @@GLOBAL.GTID_PURGED' is added to the output. "
476 "If GTIDs are disabled, AUTO does nothing. Default is AUTO.",
477 0, 0, 0, GET_STR, OPT_ARG,
480 {
"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
481 "Base name of shared memory.", &shared_memory_base_name, &shared_memory_base_name,
482 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
489 {
"single-transaction", OPT_TRANSACTION,
490 "Creates a consistent snapshot by dumping all tables in a single "
491 "transaction. Works ONLY for tables stored in storage engines which "
492 "support multiversioning (currently only InnoDB does); the dump is NOT "
493 "guaranteed to be consistent for other storage engines. "
494 "While a --single-transaction dump is in process, to ensure a valid "
495 "dump file (correct table contents and binary log position), no other "
496 "connection should use the following statements: ALTER TABLE, DROP "
497 "TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not "
498 "isolated from them. Option automatically turns off --lock-tables.",
499 &opt_single_transaction, &opt_single_transaction, 0,
500 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
501 {
"dump-date", OPT_DUMP_DATE,
"Put a dump date to the end of the output.",
502 &opt_dump_date, &opt_dump_date, 0,
503 GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
504 {
"skip-opt", OPT_SKIP_OPTIMIZATION,
505 "Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.",
506 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
507 {
"socket",
'S',
"The socket file to use for connection.",
508 &opt_mysql_unix_port, &opt_mysql_unix_port, 0,
509 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
510 #include <sslopt-longopts.h>
512 "Create tab-separated textfile for each table to given path. (Create .sql "
513 "and .txt files.) NOTE: This only works if mysqldump is run on the same "
514 "machine as the mysqld server.",
515 &path, &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
516 {
"tables", OPT_TABLES,
"Overrides option --databases (-B).",
517 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
518 {
"triggers", OPT_TRIGGERS,
"Dump triggers for each dumped table.",
519 &opt_dump_triggers, &opt_dump_triggers, 0, GET_BOOL,
520 NO_ARG, 1, 0, 0, 0, 0, 0},
521 {
"tz-utc", OPT_TZ_UTC,
522 "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.",
523 &opt_tz_utc, &opt_tz_utc, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
524 #ifndef DONT_ALLOW_USER_CHANGE
525 {
"user",
'u',
"User for login if not current user.",
526 ¤t_user, ¤t_user, 0, GET_STR, REQUIRED_ARG,
529 {
"verbose",
'v',
"Print info about the various stages.",
530 &verbose, &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
531 {
"version",
'V',
"Output version information and exit.", 0, 0, 0,
532 GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
533 {
"where",
'w',
"Dump only selected records. Quotes are mandatory.",
534 &where, &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
535 {
"xml",
'X',
"Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
536 NO_ARG, 0, 0, 0, 0, 0, 0},
537 {
"plugin_dir", OPT_PLUGIN_DIR,
"Directory for client-side plugins.",
538 &opt_plugin_dir, &opt_plugin_dir, 0,
539 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
540 {
"default_auth", OPT_DEFAULT_AUTH,
541 "Default authentication client-side plugin to use.",
542 &opt_default_auth, &opt_default_auth, 0,
543 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
544 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
547 static const char *load_default_groups[]= {
"mysqldump",
"client",0 };
549 static void maybe_exit(
int error);
550 static void die(
int error,
const char* reason, ...);
551 static void maybe_die(
int error,
const char* reason, ...);
552 static void write_header(FILE *sql_file,
char *db_name);
553 static void print_value(FILE *
file,
MYSQL_RES *result, MYSQL_ROW row,
554 const char *prefix,
const char *
name,
556 static int dump_selected_tables(
char *db,
char **table_names,
int tables);
557 static int dump_all_tables_in_db(
char *db);
558 static int init_dumping_views(
char *);
559 static int init_dumping_tables(
char *);
560 static int init_dumping(
char *,
int init_func(
char*));
561 static int dump_databases(
char **);
562 static int dump_all_databases();
563 static char *quote_name(
const char *
name,
char *buff, my_bool force);
564 char check_if_ignore_table(
const char *
table_name,
char *table_type);
565 static char *primary_key_fields(
const char *
table_name);
566 static my_bool get_view_structure(
char *
table,
char* db);
567 static my_bool dump_all_views_in_db(
char *database);
568 static int dump_all_tablespaces();
569 static int dump_tablespaces_for_tables(
char *db,
char **table_names,
int tables);
570 static int dump_tablespaces_for_databases(
char** databases);
571 static int dump_tablespaces(
char* ts_where);
572 static void print_comment(FILE *sql_file, my_bool is_error,
const char *format,
585 static void verbose_msg(
const char *
fmt, ...)
588 DBUG_ENTER(
"verbose_msg");
594 vfprintf(stderr, fmt, args);
610 void check_io(FILE *
file)
613 die(EX_EOF,
"Got errno %d on write", errno);
616 static void print_version(
void)
618 printf(
"%s Ver %s Distrib %s, for %s (%s)\n",my_progname,DUMP_VERSION,
619 MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
623 static void short_usage_sub(
void)
625 printf(
"Usage: %s [OPTIONS] database [tables]\n", my_progname);
626 printf(
"OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n",
628 printf(
"OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname);
632 static void usage(
void)
635 puts(ORACLE_WELCOME_COPYRIGHT_NOTICE(
"2000"));
636 puts(
"Dumping structure and contents of MySQL databases and tables.");
638 print_defaults(
"my",load_default_groups);
639 my_print_help(my_long_options);
640 my_print_variables(my_long_options);
644 static void short_usage(
void)
647 printf(
"For more options, use %s --help\n", my_progname);
651 static void write_header(FILE *sql_file,
char *db_name)
655 fputs(
"<?xml version=\"1.0\"?>\n", sql_file);
660 fputs(
"<mysqldump ", sql_file);
661 fputs(
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"",
663 fputs(
">\n", sql_file);
666 else if (!opt_compact)
668 print_comment(sql_file, 0,
669 "-- MySQL dump %s Distrib %s, for %s (%s)\n--\n",
670 DUMP_VERSION, MYSQL_SERVER_VERSION, SYSTEM_TYPE,
672 print_comment(sql_file, 0,
"-- Host: %s Database: %s\n",
673 current_host ? current_host :
"localhost",
674 db_name ? db_name :
"");
675 print_comment(sql_file, 0,
676 "-- ------------------------------------------------------\n"
678 print_comment(sql_file, 0,
"-- Server version\t%s\n",
679 mysql_get_server_info(&mysql_connection));
683 "\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;"
684 "\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;"
685 "\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;"
686 "\n/*!40101 SET NAMES %s */;\n",default_charset);
690 fprintf(sql_file,
"/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;\n");
691 fprintf(sql_file,
"/*!40103 SET TIME_ZONE='+00:00' */;\n");
696 fprintf(md_result_file,
"\;\n\;\n\
702 "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='%s%s%s' */;\n"
703 "/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;\n",
704 path?
"":
"NO_AUTO_VALUE_ON_ZERO",compatible_mode_normal_str[0]==0?
"":
",",
705 compatible_mode_normal_str);
711 static void write_footer(FILE *sql_file)
715 fputs(
"</mysqldump>\n", sql_file);
718 else if (!opt_compact)
721 fprintf(sql_file,
"/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;\n");
723 fprintf(sql_file,
"\n/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;\n");
726 fprintf(md_result_file,
"\;\n\;\n");
732 "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n"
733 "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n"
734 "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
736 "/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\n");
737 fputs(
"\n", sql_file);
742 get_date(time_str, GETDATE_DATE_TIME, 0);
743 print_comment(sql_file, 0,
"-- Dump completed on %s\n", time_str);
746 print_comment(sql_file, 0,
"-- Dump completed\n");
753 uchar* get_table_key(
const char *
entry,
size_t *length,
754 my_bool not_used __attribute__((unused)))
756 *length= strlen(entry);
757 return (uchar*)
entry;
762 get_one_option(
int optid,
const struct my_option *opt __attribute__((unused)),
767 if (argument == disabled_my_option)
768 argument= (
char*)
"";
771 char *start=argument;
772 my_free(opt_password);
773 opt_password=my_strdup(argument,MYF(MY_FAE));
774 while (*argument) *argument++=
'x';
783 if (!(md_result_file= my_fopen(argument, O_WRONLY | FILE_BINARY,
789 opt_protocol= MYSQL_PROTOCOL_PIPE;
798 if (strlen(argument) >= FN_REFLEN)
806 die(EX_USAGE,
"Input filename too long: %s", argument);
811 DBUG_PUSH(argument ? argument : default_dbug_option);
814 #include <sslopt-case.h>
815 case 'V': print_version(); exit(0);
818 extended_insert= opt_drop= opt_lock=
819 opt_disable_keys= opt_autocommit= opt_create_db= 0;
822 opt_comments_used= 1;
828 case (
int) OPT_MASTER_DATA:
830 opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL;
832 case (
int) OPT_MYSQLDUMP_SLAVE_DATA:
834 opt_slave_data= MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL;
836 case (
int) OPT_OPTIMIZE:
837 extended_insert= opt_drop= opt_lock= quick= create_options=
840 case (
int) OPT_SKIP_OPTIMIZATION:
841 extended_insert= opt_drop= opt_lock= quick= create_options=
844 case (
int) OPT_COMPACT:
847 opt_comments= opt_drop= opt_disable_keys= opt_lock= 0;
851 case (
int) OPT_TABLES:
854 case (
int) OPT_IGNORE_TABLE:
856 if (!strchr(argument,
'.'))
858 fprintf(stderr,
"Illegal use of option --ignore-table=<database>.<table>\n");
861 if (my_hash_insert(&ignore_table, (uchar*)my_strdup(argument, MYF(0))))
865 case (
int) OPT_COMPATIBLE:
868 char *end= compatible_mode_normal_str;
875 opt_compatible_mode_str= argument;
876 opt_compatible_mode= find_set(&compatible_mode_typelib,
877 argument, (uint) strlen(argument),
881 strmake(buff, err_ptr, MY_MIN(
sizeof(buff) - 1, err_len));
882 fprintf(stderr,
"Invalid mode to --compatible: %s\n", buff);
885 #if !defined(DBUG_OFF)
887 uint size_for_sql_mode= 0;
889 for (ptr= compatible_mode_names; *ptr; ptr++)
890 size_for_sql_mode+= strlen(*ptr);
891 size_for_sql_mode+=
sizeof(compatible_mode_names)-1;
892 DBUG_ASSERT(
sizeof(compatible_mode_normal_str)>=size_for_sql_mode);
895 mode= opt_compatible_mode;
896 for (i= 0, mode= opt_compatible_mode;
mode; mode>>= 1, i++)
900 end= strmov(end, compatible_mode_names[i]);
901 end= strmov(end,
",");
904 if (end!=compatible_mode_normal_str)
910 if (default_charset == mysql_universal_client_charset)
911 default_charset= (
char*) MYSQL_DEFAULT_CHARSET_NAME;
914 case (
int) OPT_MYSQL_PROTOCOL:
915 opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
918 case (
int) OPT_SET_GTID_PURGED:
920 opt_set_gtid_purged_mode= find_type_or_exit(argument,
921 &set_gtid_purged_mode_typelib,
929 static int get_options(
int *argc,
char ***argv)
934 opt_max_allowed_packet= *mysql_params->p_max_allowed_packet;
935 opt_net_buffer_length= *mysql_params->p_net_buffer_length;
937 md_result_file= stdout;
938 my_getopt_use_args_separator= TRUE;
939 if (load_defaults(
"my",load_default_groups,argc,argv))
941 my_getopt_use_args_separator= FALSE;
943 defaults_argv= *argv;
945 if (my_hash_init(&ignore_table, charset_info, 16, 0, 0,
946 (my_hash_get_key) get_table_key, my_free, 0))
949 if (my_hash_insert(&ignore_table,
950 (uchar*) my_strdup(
"mysql.apply_status", MYF(MY_WME))) ||
951 my_hash_insert(&ignore_table,
952 (uchar*) my_strdup(
"mysql.schema", MYF(MY_WME))) ||
953 my_hash_insert(&ignore_table,
954 (uchar*) my_strdup(
"mysql.general_log", MYF(MY_WME))) ||
955 my_hash_insert(&ignore_table,
956 (uchar*) my_strdup(
"mysql.slow_log", MYF(MY_WME))))
959 if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
962 *mysql_params->p_max_allowed_packet= opt_max_allowed_packet;
963 *mysql_params->p_net_buffer_length= opt_net_buffer_length;
965 my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
966 if (debug_check_flag)
967 my_end_arg= MY_CHECK_ERROR;
971 if (!path && (enclosed || opt_enclosed || escaped || lines_terminated ||
975 "%s: You must use option --tab with --fields-...\n", my_progname);
982 opt_lock_all_tables= !opt_single_transaction;
984 opt_delete_master_logs= 0;
988 if (opt_delete_master_logs && !opt_master_data)
989 opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL;
990 if (opt_single_transaction && opt_lock_all_tables)
992 fprintf(stderr,
"%s: You can't use --single-transaction and "
993 "--lock-all-tables at the same time.\n", my_progname);
998 opt_lock_all_tables= !opt_single_transaction;
1001 if (opt_single_transaction || opt_lock_all_tables)
1003 if (enclosed && opt_enclosed)
1005 fprintf(stderr,
"%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n", my_progname);
1008 if ((opt_databases || opt_alldbs) && path)
1011 "%s: --databases or --all-databases can't be used with --tab.\n",
1015 if (strcmp(default_charset, charset_info->csname) &&
1016 !(charset_info= get_charset_by_csname(default_charset,
1017 MY_CS_PRIMARY, MYF(MY_WME))))
1019 if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs))
1025 opt_password=get_tty_password(NullS);
1033 static void DB_error(
MYSQL *mysql_arg,
const char *when)
1035 DBUG_ENTER(
"DB_error");
1036 maybe_die(EX_MYSQLERR,
"Got error: %d: %s %s",
1037 mysql_errno(mysql_arg), mysql_error(mysql_arg), when);
1056 static void die(
int error_num,
const char* fmt_reason, ...)
1060 va_start(args,fmt_reason);
1061 my_vsnprintf(buffer,
sizeof(buffer), fmt_reason, args);
1064 fprintf(stderr,
"%s: %s\n", my_progname, buffer);
1068 maybe_exit(error_num);
1090 static void maybe_die(
int error_num,
const char* fmt_reason, ...)
1094 va_start(args,fmt_reason);
1095 my_vsnprintf(buffer,
sizeof(buffer), fmt_reason, args);
1098 fprintf(stderr,
"%s: %s\n", my_progname, buffer);
1101 maybe_exit(error_num);
1122 static int mysql_query_with_error_report(
MYSQL *mysql_con,
MYSQL_RES **res,
1125 if (mysql_query(mysql_con, query) ||
1126 (res && !((*res)= mysql_store_result(mysql_con))))
1128 maybe_die(EX_MYSQLERR,
"Couldn't execute '%s': %s (%d)",
1129 query, mysql_error(mysql_con), mysql_errno(mysql_con));
1136 static int fetch_db_collation(
const char *db_name,
1140 my_bool err_status= FALSE;
1141 char query[QUERY_LENGTH];
1143 MYSQL_ROW db_cl_row;
1144 char quoted_database_buf[NAME_LEN*2+3];
1145 char *qdatabase= quote_name(db_name, quoted_database_buf, 1);
1147 my_snprintf(query,
sizeof (query),
"use %s", qdatabase);
1149 if (mysql_query_with_error_report(mysql, NULL, query))
1152 if (mysql_query_with_error_report(mysql, &db_cl_res,
1153 "select @@collation_database"))
1158 if (mysql_num_rows(db_cl_res) != 1)
1164 if (!(db_cl_row= mysql_fetch_row(db_cl_res)))
1170 strncpy(db_cl_name, db_cl_row[0], db_cl_size);
1171 db_cl_name[db_cl_size - 1]= 0;
1175 mysql_free_result(db_cl_res);
1177 return err_status ? 1 : 0;
1181 static char *my_case_str(
const char *str,
1188 uint status= my_charset_latin1.coll->instr(&my_charset_latin1,
1193 return status ? (
char *) str + match.end : NULL;
1197 static int switch_db_collation(FILE *sql_file,
1198 const char *db_name,
1199 const char *delimiter,
1200 const char *current_db_cl_name,
1201 const char *required_db_cl_name,
1204 if (strcmp(current_db_cl_name, required_db_cl_name) != 0)
1206 char quoted_db_buf[NAME_LEN * 2 + 3];
1207 char *quoted_db_name= quote_name(db_name, quoted_db_buf, FALSE);
1209 CHARSET_INFO *db_cl= get_charset_by_name(required_db_cl_name, MYF(0));
1215 "ALTER DATABASE %s CHARACTER SET %s COLLATE %s %s\n",
1216 (
const char *) quoted_db_name,
1217 (
const char *) db_cl->csname,
1218 (
const char *) db_cl->name,
1219 (
const char *) delimiter);
1232 static int restore_db_collation(FILE *sql_file,
1233 const char *db_name,
1234 const char *delimiter,
1235 const char *db_cl_name)
1237 char quoted_db_buf[NAME_LEN * 2 + 3];
1238 char *quoted_db_name= quote_name(db_name, quoted_db_buf, FALSE);
1240 CHARSET_INFO *db_cl= get_charset_by_name(db_cl_name, MYF(0));
1246 "ALTER DATABASE %s CHARACTER SET %s COLLATE %s %s\n",
1247 (
const char *) quoted_db_name,
1248 (
const char *) db_cl->csname,
1249 (
const char *) db_cl->name,
1250 (
const char *) delimiter);
1256 static void switch_cs_variables(FILE *sql_file,
1257 const char *delimiter,
1258 const char *character_set_client,
1259 const char *character_set_results,
1260 const char *collation_connection)
1263 "/*!50003 SET @saved_cs_client = @@character_set_client */ %s\n"
1264 "/*!50003 SET @saved_cs_results = @@character_set_results */ %s\n"
1265 "/*!50003 SET @saved_col_connection = @@collation_connection */ %s\n"
1266 "/*!50003 SET character_set_client = %s */ %s\n"
1267 "/*!50003 SET character_set_results = %s */ %s\n"
1268 "/*!50003 SET collation_connection = %s */ %s\n",
1269 (
const char *) delimiter,
1270 (
const char *) delimiter,
1271 (
const char *) delimiter,
1273 (
const char *) character_set_client,
1274 (
const char *) delimiter,
1276 (
const char *) character_set_results,
1277 (
const char *) delimiter,
1279 (
const char *) collation_connection,
1280 (
const char *) delimiter);
1284 static void restore_cs_variables(FILE *sql_file,
1285 const char *delimiter)
1288 "/*!50003 SET character_set_client = @saved_cs_client */ %s\n"
1289 "/*!50003 SET character_set_results = @saved_cs_results */ %s\n"
1290 "/*!50003 SET collation_connection = @saved_col_connection */ %s\n",
1291 (
const char *) delimiter,
1292 (
const char *) delimiter,
1293 (
const char *) delimiter);
1297 static void switch_sql_mode(FILE *sql_file,
1298 const char *delimiter,
1299 const char *sql_mode)
1302 "/*!50003 SET @saved_sql_mode = @@sql_mode */ %s\n"
1303 "/*!50003 SET sql_mode = '%s' */ %s\n",
1304 (
const char *) delimiter,
1306 (
const char *) sql_mode,
1307 (
const char *) delimiter);
1311 static void restore_sql_mode(FILE *sql_file,
1312 const char *delimiter)
1315 "/*!50003 SET sql_mode = @saved_sql_mode */ %s\n",
1316 (
const char *) delimiter);
1320 static void switch_time_zone(FILE *sql_file,
1321 const char *delimiter,
1322 const char *time_zone)
1325 "/*!50003 SET @saved_time_zone = @@time_zone */ %s\n"
1326 "/*!50003 SET time_zone = '%s' */ %s\n",
1327 (
const char *) delimiter,
1329 (
const char *) time_zone,
1330 (
const char *) delimiter);
1334 static void restore_time_zone(FILE *sql_file,
1335 const char *delimiter)
1338 "/*!50003 SET time_zone = @saved_time_zone */ %s\n",
1339 (
const char *) delimiter);
1355 static int switch_character_set_results(
MYSQL *mysql,
const char *cs_name)
1357 char query_buffer[QUERY_LENGTH];
1358 size_t query_length;
1361 if (!server_supports_switching_charsets)
1364 query_length= my_snprintf(query_buffer,
1365 sizeof (query_buffer),
1366 "SET SESSION character_set_results = '%s'",
1367 (
const char *) cs_name);
1369 return mysql_real_query(mysql, query_buffer, query_length);
1397 static char *cover_definer_clause(
const char *stmt_str,
1399 const char *definer_version_str,
1400 uint definer_version_length,
1401 const char *stmt_version_str,
1402 uint stmt_version_length,
1403 const char *keyword_str,
1404 uint keyword_length)
1406 char *definer_begin= my_case_str(stmt_str, stmt_length,
1407 C_STRING_WITH_LEN(
" DEFINER"));
1408 char *definer_end= NULL;
1410 char *query_str= NULL;
1416 definer_end= my_case_str(definer_begin, strlen(definer_begin),
1417 keyword_str, keyword_length);
1426 query_str= alloc_query_str(stmt_length + 23);
1428 query_ptr= strnmov(query_str, stmt_str, definer_begin - stmt_str);
1429 query_ptr= strnmov(query_ptr, C_STRING_WITH_LEN(
"*/ /*!"));
1430 query_ptr= strnmov(query_ptr, definer_version_str, definer_version_length);
1431 query_ptr= strnmov(query_ptr, definer_begin, definer_end - definer_begin);
1432 query_ptr= strnmov(query_ptr, C_STRING_WITH_LEN(
"*/ /*!"));
1433 query_ptr= strnmov(query_ptr, stmt_version_str, stmt_version_length);
1434 query_ptr= strxmov(query_ptr, definer_end, NullS);
1451 static FILE* open_sql_file_for_table(
const char*
table,
int flags)
1454 char filename[FN_REFLEN], tmp_path[FN_REFLEN];
1455 convert_dirname(tmp_path,path,NullS);
1456 res= my_fopen(fn_format(filename, table, tmp_path,
".sql", 4),
1457 flags, MYF(MY_WME));
1462 static void free_resources()
1464 if (md_result_file && md_result_file != stdout)
1465 my_fclose(md_result_file, MYF(0));
1466 my_free(opt_password);
1467 if (my_hash_inited(&ignore_table))
1468 my_hash_free(&ignore_table);
1469 if (extended_insert)
1470 dynstr_free(&extended_row);
1471 if (insert_pat_inited)
1472 dynstr_free(&insert_pat);
1474 free_defaults(defaults_argv);
1479 static void maybe_exit(
int error)
1496 static int connect_to_db(
char *host,
char *user,
char *passwd)
1498 char buff[20+FN_REFLEN];
1499 DBUG_ENTER(
"connect_to_db");
1501 verbose_msg(
"-- Connecting to %s...\n", host ? host :
"localhost");
1502 mysql_init(&mysql_connection);
1504 mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS);
1508 mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
1509 opt_ssl_capath, opt_ssl_cipher);
1510 mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
1511 mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
1513 mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
1514 (
char*)&opt_ssl_verify_server_cert);
1517 mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(
char*)&opt_protocol);
1519 mysql_options(&mysql_connection,MYSQL_OPT_BIND,opt_bind_addr);
1521 if (shared_memory_base_name)
1522 mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
1524 mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
1526 if (opt_plugin_dir && *opt_plugin_dir)
1527 mysql_options(&mysql_connection, MYSQL_PLUGIN_DIR, opt_plugin_dir);
1529 if (opt_default_auth && *opt_default_auth)
1530 mysql_options(&mysql_connection, MYSQL_DEFAULT_AUTH, opt_default_auth);
1532 mysql_options(&mysql_connection, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
1533 mysql_options4(&mysql_connection, MYSQL_OPT_CONNECT_ATTR_ADD,
1534 "program_name",
"mysqldump");
1535 if (!(mysql= mysql_real_connect(&mysql_connection,host,user,passwd,
1536 NULL,opt_mysql_port,opt_mysql_unix_port,
1539 DB_error(&mysql_connection,
"when trying to connect");
1542 if ((mysql_get_server_version(&mysql_connection) < 40100) ||
1543 (opt_compatible_mode & 3))
1549 server_supports_switching_charsets= FALSE;
1555 mysql->reconnect= 0;
1556 my_snprintf(buff,
sizeof(buff),
"/*!40100 SET @@SQL_MODE='%s' */",
1557 compatible_mode_normal_str);
1558 if (mysql_query_with_error_report(mysql, 0, buff))
1566 my_snprintf(buff,
sizeof(buff),
"/*!40103 SET TIME_ZONE='+00:00' */");
1567 if (mysql_query_with_error_report(mysql, 0, buff))
1577 static void dbDisconnect(
char *host)
1579 verbose_msg(
"-- Disconnecting from %s...\n", host ? host :
"localhost");
1584 static void unescape(FILE *file,
char *pos,uint length)
1587 DBUG_ENTER(
"unescape");
1588 if (!(tmp=(
char*) my_malloc(length*2+1, MYF(MY_WME))))
1589 die(EX_MYSQLERR,
"Couldn't allocate memory");
1591 mysql_real_escape_string(&mysql_connection, tmp, pos, length);
1601 static my_bool test_if_special_chars(
const char *str)
1603 #if MYSQL_VERSION_ID >= 32300
1604 for ( ; *str ; str++)
1605 if (!my_isvar(charset_info,*str) && *str !=
'$')
1629 static char *quote_name(
const char *
name,
char *buff, my_bool force)
1632 char qtype= (opt_compatible_mode & MASK_ANSI_QUOTES) ?
'\"' :
'`';
1634 if (!force && !opt_quoted && !test_if_special_chars(name))
1635 return (
char*)
name;
1671 static char *quote_for_like(
const char *name,
char *buff)
1683 else if (*name ==
'\'' || *name ==
'_' || *name ==
'%')
1705 static void print_quoted_xml(FILE *xml_file,
const char *str, ulong len,
1706 my_bool is_attribute_name)
1710 for (end= str + len; str != end; str++)
1714 fputs(
"<", xml_file);
1717 fputs(
">", xml_file);
1720 fputs(
"&", xml_file);
1723 fputs(
""", xml_file);
1727 if (is_attribute_name)
1729 fputs(
"_", xml_file);
1734 fputc(*str, xml_file);
1770 static void print_xml_tag(FILE * xml_file,
const char* sbeg,
1771 const char* line_end,
1772 const char* tag_name,
1773 const char* first_attribute_name, ...)
1776 const char *attribute_name, *attribute_value;
1778 fputs(sbeg, xml_file);
1779 fputc(
'<', xml_file);
1780 fputs(tag_name, xml_file);
1782 va_start(arg_list, first_attribute_name);
1783 attribute_name= first_attribute_name;
1784 while (attribute_name != NullS)
1786 attribute_value= va_arg(arg_list,
char *);
1787 DBUG_ASSERT(attribute_value != NullS);
1789 fputc(
' ', xml_file);
1790 fputs(attribute_name, xml_file);
1791 fputc(
'\"', xml_file);
1793 print_quoted_xml(xml_file, attribute_value, strlen(attribute_value), 0);
1794 fputc(
'\"', xml_file);
1796 attribute_name= va_arg(arg_list,
char *);
1800 fputc(
'>', xml_file);
1801 fputs(line_end, xml_file);
1825 static void print_xml_null_tag(FILE * xml_file,
const char* sbeg,
1826 const char* stag_atr,
const char* sval,
1827 const char* line_end)
1829 fputs(sbeg, xml_file);
1830 fputs(
"<", xml_file);
1831 fputs(stag_atr, xml_file);
1832 fputs(
"\"", xml_file);
1833 print_quoted_xml(xml_file, sval, strlen(sval), 0);
1834 fputs(
"\" xsi:nil=\"true\" />", xml_file);
1835 fputs(line_end, xml_file);
1853 static void print_xml_cdata(FILE *xml_file,
const char *str, ulong len)
1857 fputs(
"<![CDATA[\n", xml_file);
1858 for (end= str + len; str != end; str++)
1862 if ((*(str + 1) ==
']') && (*(str + 2) ==
'>'))
1864 fputs(
"]]]]><![CDATA[>", xml_file);
1870 fputc(*str, xml_file);
1874 fputs(
"\n]]>\n", xml_file);
1897 static void print_xml_row(FILE *xml_file,
const char *row_name,
1899 const char *str_create)
1902 my_bool body_found= 0;
1903 char *create_stmt_ptr= NULL;
1904 ulong create_stmt_len= 0;
1906 ulong *lengths= mysql_fetch_lengths(tableRes);
1908 fprintf(xml_file,
"\t\t<%s", row_name);
1910 mysql_field_seek(tableRes, 0);
1911 for (i= 0; (field= mysql_fetch_field(tableRes)); i++)
1916 if ((str_create) && (strcmp(str_create, field->name) == 0))
1918 create_stmt_ptr= (*row)[
i];
1919 create_stmt_len= lengths[
i];
1924 fputc(
' ', xml_file);
1925 print_quoted_xml(xml_file, field->name, field->name_length, 1);
1926 fputs(
"=\"", xml_file);
1927 print_quoted_xml(xml_file, (*row)[i], lengths[i], 0);
1928 fputc(
'"', xml_file);
1934 if (create_stmt_len)
1936 DBUG_ASSERT(body_found);
1937 fputs(
">\n", xml_file);
1938 print_xml_cdata(xml_file, create_stmt_ptr, create_stmt_len);
1939 fprintf(xml_file,
"\t\t</%s>\n", row_name);
1942 fputs(
" />\n", xml_file);
1964 static void print_xml_comment(FILE *xml_file, ulong len,
1965 const char *comment_string)
1969 fputs(
"<!-- ", xml_file);
1971 for (end= comment_string + len; comment_string != end; comment_string++)
1976 switch (*comment_string) {
1978 if (*(comment_string + 1) ==
'-')
1981 fputc(*comment_string, xml_file);
1985 fputs(
" -->\n", xml_file);
1993 static void print_comment(FILE *sql_file, my_bool is_error,
const char *format,
1996 static char comment_buff[COMMENT_LENGTH];
2000 if (!is_error && !opt_comments)
2003 va_start(args, format);
2004 my_vsnprintf(comment_buff, COMMENT_LENGTH, format, args);
2009 fputs(comment_buff, sql_file);
2014 print_xml_comment(sql_file, strlen(comment_buff), comment_buff);
2032 static char *create_delimiter(
char *query,
char *delimiter_buff,
2033 int delimiter_max_size)
2035 int proposed_length;
2038 delimiter_buff[0]=
';';
2040 for (proposed_length= 2; proposed_length < delimiter_max_size;
2041 delimiter_max_size++) {
2043 delimiter_buff[proposed_length-1]=
';';
2044 delimiter_buff[proposed_length]=
'\0';
2046 presence = strstr(query, delimiter_buff);
2047 if (presence == NULL) {
2048 return delimiter_buff;
2065 static uint dump_events_for_db(
char *db)
2067 char query_buff[QUERY_LENGTH];
2068 char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
2070 char delimiter[QUERY_LENGTH];
2071 FILE *sql_file= md_result_file;
2073 MYSQL_ROW row, event_list_row;
2075 char db_cl_name[MY_CS_NAME_SIZE];
2076 int db_cl_altered= FALSE;
2078 DBUG_ENTER(
"dump_events_for_db");
2079 DBUG_PRINT(
"enter", (
"db: '%s'", db));
2081 mysql_real_escape_string(mysql, db_name_buff, db, strlen(db));
2084 print_comment(sql_file, 0,
2085 "\n--\n-- Dumping events for database '%s'\n--\n", db);
2092 mysql_query(mysql,
"LOCK TABLES mysql.event READ");
2094 if (mysql_query_with_error_report(mysql, &event_list_res,
"show events"))
2097 strcpy(delimiter,
";");
2098 if (mysql_num_rows(event_list_res) > 0)
2101 fputs(
"\t<events>\n", sql_file);
2104 fprintf(sql_file,
"/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;\n");
2108 if (fetch_db_collation(db_name_buff, db_cl_name,
sizeof (db_cl_name)))
2112 if (switch_character_set_results(mysql,
"binary"))
2115 while ((event_list_row= mysql_fetch_row(event_list_res)) != NULL)
2117 event_name= quote_name(event_list_row[1], name_buff, 0);
2118 DBUG_PRINT(
"info", (
"retrieving CREATE EVENT for %s", name_buff));
2119 my_snprintf(query_buff,
sizeof(query_buff),
"SHOW CREATE EVENT %s",
2122 if (mysql_query_with_error_report(mysql, &event_res, query_buff))
2125 while ((row= mysql_fetch_row(event_res)) != NULL)
2129 print_xml_row(sql_file,
"event", event_res, &row,
2138 if (strlen(row[3]) != 0)
2143 fprintf(sql_file,
"/*!50106 DROP EVENT IF EXISTS %s */%s\n",
2144 event_name, delimiter);
2146 if (create_delimiter(row[3], delimiter,
sizeof(delimiter)) == NULL)
2148 fprintf(stderr,
"%s: Warning: Can't create delimiter for event '%s'\n",
2149 my_progname, event_name);
2153 fprintf(sql_file,
"DELIMITER %s\n", delimiter);
2155 if (mysql_num_fields(event_res) >= 7)
2157 if (switch_db_collation(sql_file, db_name_buff, delimiter,
2158 db_cl_name, row[6], &db_cl_altered))
2163 switch_cs_variables(sql_file, delimiter,
2181 "-- WARNING: old server version. "
2182 "The following dump may be incomplete.\n"
2186 switch_sql_mode(sql_file, delimiter, row[1]);
2188 switch_time_zone(sql_file, delimiter, row[2]);
2190 query_str= cover_definer_clause(row[3], strlen(row[3]),
2191 C_STRING_WITH_LEN(
"50117"),
2192 C_STRING_WITH_LEN(
"50106"),
2193 C_STRING_WITH_LEN(
" EVENT"));
2196 "/*!50106 %s */ %s\n",
2197 (
const char *) (query_str != NULL ? query_str : row[3]),
2198 (
const char *) delimiter);
2200 restore_time_zone(sql_file, delimiter);
2201 restore_sql_mode(sql_file, delimiter);
2203 if (mysql_num_fields(event_res) >= 7)
2205 restore_cs_variables(sql_file, delimiter);
2209 if (restore_db_collation(sql_file, db_name_buff, delimiter,
2216 mysql_free_result(event_res);
2221 fputs(
"\t</events>\n", sql_file);
2226 fprintf(sql_file,
"DELIMITER ;\n");
2227 fprintf(sql_file,
"/*!50106 SET TIME_ZONE= @save_time_zone */ ;\n");
2230 if (switch_character_set_results(mysql, default_charset))
2233 mysql_free_result(event_list_res);
2236 (void) mysql_query_with_error_report(mysql, 0,
"UNLOCK TABLES");
2254 static void print_blob_as_hex(FILE *output_file,
const char *str, ulong len)
2257 const char *ptr= str, *end= ptr + len;
2258 for (; ptr < end ; ptr++)
2259 fprintf(output_file,
"%02X", *((uchar *)ptr));
2260 check_io(output_file);
2276 static uint dump_routines_for_db(
char *db)
2278 char query_buff[QUERY_LENGTH];
2279 const char *routine_type[]= {
"FUNCTION",
"PROCEDURE"};
2280 char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
2283 FILE *sql_file= md_result_file;
2284 MYSQL_RES *routine_res, *routine_list_res;
2285 MYSQL_ROW row, routine_list_row;
2287 char db_cl_name[MY_CS_NAME_SIZE];
2288 int db_cl_altered= FALSE;
2290 DBUG_ENTER(
"dump_routines_for_db");
2291 DBUG_PRINT(
"enter", (
"db: '%s'", db));
2293 mysql_real_escape_string(mysql, db_name_buff, db, strlen(db));
2296 print_comment(sql_file, 0,
2297 "\n--\n-- Dumping routines for database '%s'\n--\n", db);
2304 mysql_query(mysql,
"LOCK TABLES mysql.proc READ");
2308 if (fetch_db_collation(db_name_buff, db_cl_name,
sizeof (db_cl_name)))
2311 if (switch_character_set_results(mysql,
"binary"))
2315 fputs(
"\t<routines>\n", sql_file);
2318 for (i= 0; i <= 1; i++)
2320 my_snprintf(query_buff,
sizeof(query_buff),
2321 "SHOW %s STATUS WHERE Db = '%s'",
2322 routine_type[i], db_name_buff);
2324 if (mysql_query_with_error_report(mysql, &routine_list_res, query_buff))
2327 if (mysql_num_rows(routine_list_res))
2330 while ((routine_list_row= mysql_fetch_row(routine_list_res)))
2332 routine_name= quote_name(routine_list_row[1], name_buff, 0);
2333 DBUG_PRINT(
"info", (
"retrieving CREATE %s for %s", routine_type[i],
2335 my_snprintf(query_buff,
sizeof(query_buff),
"SHOW CREATE %s %s",
2336 routine_type[i], routine_name);
2338 if (mysql_query_with_error_report(mysql, &routine_res, query_buff))
2341 while ((row= mysql_fetch_row(routine_res)))
2347 DBUG_PRINT(
"info",(
"length of body for %s row[2] '%s' is %d",
2348 routine_name, row[2] ? row[2] :
"(null)",
2349 row[2] ? (
int) strlen(row[2]) : 0));
2352 print_comment(sql_file, 1,
"\n-- insufficient privileges to %s\n",
2354 print_comment(sql_file, 1,
2355 "-- does %s have permissions on mysql.proc?\n\n",
2357 maybe_die(EX_MYSQLERR,
"%s has insufficent privileges to %s!", current_user, query_buff);
2359 else if (strlen(row[2]))
2364 print_xml_row(sql_file,
"routine", routine_res, &row,
2365 "Create Procedure");
2367 print_xml_row(sql_file,
"routine", routine_res, &row,
2372 fprintf(sql_file,
"/*!50003 DROP %s IF EXISTS %s */;\n",
2373 routine_type[i], routine_name);
2375 if (mysql_num_fields(routine_res) >= 6)
2377 if (switch_db_collation(sql_file, db_name_buff,
";",
2378 db_cl_name, row[5], &db_cl_altered))
2383 switch_cs_variables(sql_file,
";",
2402 "-- WARNING: old server version. "
2403 "The following dump may be incomplete.\n"
2408 switch_sql_mode(sql_file,
";", row[1]);
2414 (
const char *) row[2]);
2416 restore_sql_mode(sql_file,
";");
2418 if (mysql_num_fields(routine_res) >= 6)
2420 restore_cs_variables(sql_file,
";");
2424 if (restore_db_collation(sql_file, db_name_buff,
";", db_cl_name))
2431 mysql_free_result(routine_res);
2435 mysql_free_result(routine_list_res);
2440 fputs(
"\t</routines>\n", sql_file);
2444 if (switch_character_set_results(mysql, default_charset))
2448 (void) mysql_query_with_error_report(mysql, 0,
"UNLOCK TABLES");
2453 static inline my_bool general_log_or_slow_log_tables(
const char *db,
2456 return (!my_strcasecmp(charset_info, db,
"mysql")) &&
2457 (!my_strcasecmp(charset_info, table,
"general_log") ||
2458 !my_strcasecmp(charset_info, table,
"slow_log"));
2476 static uint get_table_structure(
char *table,
char *db,
char *table_type,
2479 my_bool init=0, delayed, write_data, complete_insert;
2480 my_ulonglong num_fields;
2481 char *result_table, *opt_quoted_table;
2482 const char *insert_option;
2483 char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
2484 char table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
2485 const char *show_fields_stmt=
"SELECT `COLUMN_NAME` AS `Field`, "
2486 "`COLUMN_TYPE` AS `Type`, "
2487 "`IS_NULLABLE` AS `Null`, "
2488 "`COLUMN_KEY` AS `Key`, "
2489 "`COLUMN_DEFAULT` AS `Default`, "
2490 "`EXTRA` AS `Extra`, "
2491 "`COLUMN_COMMENT` AS `Comment` "
2492 "FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE "
2493 "TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s'";
2494 FILE *sql_file= md_result_file;
2496 my_bool is_log_table;
2499 DBUG_ENTER(
"get_table_structure");
2500 DBUG_PRINT(
"enter", (
"db: %s table: %s", db, table));
2502 *ignore_flag= check_if_ignore_table(table, table_type);
2504 delayed= opt_delayed;
2505 if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
2508 verbose_msg(
"-- Warning: Unable to use delayed inserts for table '%s' "
2509 "because it's of type %s\n", table, table_type);
2513 if ((write_data= !(*ignore_flag & IGNORE_DATA)))
2515 complete_insert= opt_complete_insert;
2516 if (!insert_pat_inited)
2518 insert_pat_inited= 1;
2519 init_dynamic_string_checked(&insert_pat,
"", 1024, 1024);
2522 dynstr_set_checked(&insert_pat,
"");
2525 insert_option= ((delayed && opt_ignore) ?
" DELAYED IGNORE " :
2526 delayed ?
" DELAYED " : opt_ignore ?
" IGNORE " :
"");
2528 verbose_msg(
"-- Retrieving table structure for table %s...\n", table);
2530 len= my_snprintf(query_buff,
sizeof(query_buff),
2531 "SET SQL_QUOTE_SHOW_CREATE=%d",
2532 (opt_quoted || opt_keywords));
2533 if (!create_options)
2534 strmov(query_buff+len,
2535 "/*!40102 ,SQL_MODE=concat(@@sql_mode, _utf8 ',NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS') */");
2537 result_table= quote_name(table, table_buff, 1);
2538 opt_quoted_table= quote_name(table, table_buff2, 0);
2540 if (opt_order_by_primary)
2541 order_by= primary_key_fields(result_table);
2543 if (!opt_xml && !mysql_query_with_error_report(mysql, 0, query_buff))
2546 if (!opt_no_create_info)
2549 char buff[20+FN_REFLEN];
2552 my_snprintf(buff,
sizeof(buff),
"show create table %s", result_table);
2554 if (switch_character_set_results(mysql,
"binary") ||
2555 mysql_query_with_error_report(mysql, &result, buff) ||
2556 switch_character_set_results(mysql, default_charset))
2561 if (!(sql_file= open_sql_file_for_table(table, O_WRONLY)))
2564 write_header(sql_file, db);
2567 if (strcmp (table_type,
"VIEW") == 0)
2568 print_comment(sql_file, 0,
2569 "\n--\n-- Temporary table structure for view %s\n--\n\n",
2572 print_comment(sql_file, 0,
2573 "\n--\n-- Table structure for table %s\n--\n\n",
2584 if (!general_log_or_slow_log_tables(db, table))
2585 fprintf(sql_file,
"DROP TABLE IF EXISTS %s;\n",
2590 field= mysql_fetch_field_direct(result, 0);
2591 if (strcmp(field->name,
"View") == 0)
2593 char *scv_buff= NULL;
2594 my_ulonglong n_cols;
2596 verbose_msg(
"-- It's a view, create dummy table for view\n");
2599 if ((row= mysql_fetch_row(result)) && (scv_buff=row[1]))
2600 scv_buff= my_strdup(scv_buff, MYF(0));
2602 mysql_free_result(result);
2615 my_snprintf(query_buff,
sizeof(query_buff),
2616 "SHOW FIELDS FROM %s", result_table);
2617 if (switch_character_set_results(mysql,
"binary") ||
2618 mysql_query_with_error_report(mysql, &result, query_buff) ||
2619 switch_character_set_results(mysql, default_charset))
2627 if (mysql_errno(mysql) == ER_VIEW_INVALID)
2628 fprintf(sql_file,
"\n-- failed on view %s: %s\n\n", result_table, scv_buff ? scv_buff :
"");
2637 n_cols= mysql_num_rows(result);
2649 "-- Warning: Creating a stand-in table for view %s may"
2650 " fail when replaying the dump file produced because "
2651 "of the number of columns exceeding 1000. Exercise "
2652 "caution when replaying the produced dump file.\n",
2661 fprintf(sql_file,
"/*!50001 DROP VIEW IF EXISTS %s*/;\n",
2667 "SET @saved_cs_client = @@character_set_client;\n"
2668 "SET character_set_client = utf8;\n"
2669 "/*!50001 CREATE TABLE %s (\n",
2678 row= mysql_fetch_row(result);
2685 fprintf(sql_file,
" %s tinyint NOT NULL",
2686 quote_name(row[0], name_buff, 0));
2688 while((row= mysql_fetch_row(result)))
2691 fprintf(sql_file,
",\n %s tinyint NOT NULL",
2692 quote_name(row[0], name_buff, 0));
2702 "\n) ENGINE=MyISAM */;\n"
2703 "SET character_set_client = @saved_cs_client;\n");
2708 mysql_free_result(result);
2711 my_fclose(sql_file, MYF(MY_WME));
2717 row= mysql_fetch_row(result);
2719 is_log_table= general_log_or_slow_log_tables(db, table);
2722 if (opt_compatible_mode & 3)
2725 is_log_table ?
"CREATE TABLE IF NOT EXISTS %s;\n" :
"%s;\n",
2731 "/*!40101 SET @saved_cs_client = @@character_set_client */;\n"
2732 "/*!40101 SET character_set_client = utf8 */;\n"
2734 "/*!40101 SET character_set_client = @saved_cs_client */;\n",
2735 is_log_table ?
"CREATE TABLE IF NOT EXISTS " :
"",
2740 mysql_free_result(result);
2742 my_snprintf(query_buff,
sizeof(query_buff),
"show fields from %s",
2744 if (mysql_query_with_error_report(mysql, &result, query_buff))
2747 my_fclose(sql_file, MYF(MY_WME));
2759 if (opt_replace_into)
2760 dynstr_append_checked(&insert_pat,
"REPLACE ");
2762 dynstr_append_checked(&insert_pat,
"INSERT ");
2763 dynstr_append_checked(&insert_pat, insert_option);
2764 dynstr_append_checked(&insert_pat,
"INTO ");
2765 dynstr_append_checked(&insert_pat, opt_quoted_table);
2766 if (complete_insert)
2768 dynstr_append_checked(&insert_pat,
" (");
2772 dynstr_append_checked(&insert_pat,
" VALUES ");
2773 if (!extended_insert)
2774 dynstr_append_checked(&insert_pat,
"(");
2778 while ((row= mysql_fetch_row(result)))
2780 if (complete_insert)
2784 dynstr_append_checked(&insert_pat,
", ");
2787 dynstr_append_checked(&insert_pat,
2788 quote_name(row[SHOW_FIELDNAME], name_buff, 0));
2791 num_fields= mysql_num_rows(result);
2792 mysql_free_result(result);
2796 verbose_msg(
"%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n",
2797 my_progname, mysql_error(mysql));
2799 my_snprintf(query_buff,
sizeof(query_buff), show_fields_stmt, db, table);
2801 if (mysql_query_with_error_report(mysql, &result, query_buff))
2805 if (!opt_no_create_info)
2809 if (!(sql_file= open_sql_file_for_table(table, O_WRONLY)))
2811 write_header(sql_file, db);
2814 print_comment(sql_file, 0,
2815 "\n--\n-- Table structure for table %s\n--\n\n",
2818 fprintf(sql_file,
"DROP TABLE IF EXISTS %s;\n", result_table);
2820 fprintf(sql_file,
"CREATE TABLE %s (\n", result_table);
2822 print_xml_tag(sql_file,
"\t",
"\n",
"table_structure",
"name=", table,
2829 if (opt_replace_into)
2830 dynstr_append_checked(&insert_pat,
"REPLACE ");
2832 dynstr_append_checked(&insert_pat,
"INSERT ");
2833 dynstr_append_checked(&insert_pat, insert_option);
2834 dynstr_append_checked(&insert_pat,
"INTO ");
2835 dynstr_append_checked(&insert_pat, result_table);
2836 if (complete_insert)
2837 dynstr_append_checked(&insert_pat,
" (");
2840 dynstr_append_checked(&insert_pat,
" VALUES ");
2841 if (!extended_insert)
2842 dynstr_append_checked(&insert_pat,
"(");
2846 while ((row= mysql_fetch_row(result)))
2848 ulong *lengths= mysql_fetch_lengths(result);
2851 if (!opt_xml && !opt_no_create_info)
2853 fputs(
",\n",sql_file);
2856 if (complete_insert)
2857 dynstr_append_checked(&insert_pat,
", ");
2860 if (complete_insert)
2861 dynstr_append_checked(&insert_pat,
2862 quote_name(row[SHOW_FIELDNAME], name_buff, 0));
2863 if (!opt_no_create_info)
2867 print_xml_row(sql_file,
"field", result, &row, NullS);
2872 fprintf(sql_file,
" %s.%s %s", result_table,
2873 quote_name(row[SHOW_FIELDNAME],name_buff, 0),
2876 fprintf(sql_file,
" %s %s", quote_name(row[SHOW_FIELDNAME],
2879 if (row[SHOW_DEFAULT])
2881 fputs(
" DEFAULT ", sql_file);
2882 unescape(sql_file, row[SHOW_DEFAULT], lengths[SHOW_DEFAULT]);
2884 if (!row[SHOW_NULL][0])
2885 fputs(
" NOT NULL", sql_file);
2886 if (row[SHOW_EXTRA][0])
2887 fprintf(sql_file,
" %s",row[SHOW_EXTRA]);
2891 num_fields= mysql_num_rows(result);
2892 mysql_free_result(result);
2893 if (!opt_no_create_info)
2896 char buff[20+FN_REFLEN];
2897 uint keynr,primary_key;
2898 my_snprintf(buff,
sizeof(buff),
"show keys from %s", result_table);
2899 if (mysql_query_with_error_report(mysql, &result, buff))
2901 if (mysql_errno(mysql) == ER_WRONG_OBJECT)
2904 fputs(
"\t\t<options Comment=\"view\" />\n", sql_file);
2907 fprintf(stderr,
"%s: Can't get keys for table %s (%s)\n",
2908 my_progname, result_table, mysql_error(mysql));
2910 my_fclose(sql_file, MYF(MY_WME));
2916 primary_key=INT_MAX;
2917 while ((row= mysql_fetch_row(result)))
2919 if (atoi(row[3]) == 1)
2922 #ifdef FORCE_PRIMARY_KEY
2923 if (atoi(row[1]) == 0 && primary_key == INT_MAX)
2926 if (!strcmp(row[2],
"PRIMARY"))
2933 mysql_data_seek(result,0);
2935 while ((row= mysql_fetch_row(result)))
2939 print_xml_row(sql_file,
"key", result, &row, NullS);
2943 if (atoi(row[3]) == 1)
2946 putc(
')', sql_file);
2949 fprintf(sql_file,
",\n KEY %s (",quote_name(row[2],name_buff,0));
2950 else if (keynr == primary_key)
2951 fputs(
",\n PRIMARY KEY (",sql_file);
2953 fprintf(sql_file,
",\n UNIQUE %s (",quote_name(row[2],name_buff,
2957 putc(
',', sql_file);
2958 fputs(quote_name(row[4], name_buff, 0), sql_file);
2960 fprintf(sql_file,
" (%s)",row[7]);
2963 mysql_free_result(result);
2967 putc(
')', sql_file);
2968 fputs(
"\n)",sql_file);
2975 char show_name_buff[NAME_LEN*2+2+24];
2978 my_snprintf(buff,
sizeof(buff),
"show table status like %s",
2979 quote_for_like(table, show_name_buff));
2981 if (mysql_query_with_error_report(mysql, &result, buff))
2983 if (mysql_errno(mysql) != ER_PARSE_ERROR)
2985 verbose_msg(
"-- Warning: Couldn't get status information for " \
2986 "table %s (%s)\n", result_table,mysql_error(mysql));
2989 else if (!(row= mysql_fetch_row(result)))
2992 "Error: Couldn't read status information for table %s (%s)\n",
2993 result_table,mysql_error(mysql));
2998 print_xml_row(sql_file,
"options", result, &row, NullS);
3001 fputs(
"/*!",sql_file);
3002 print_value(sql_file,result,row,
"engine=",
"Engine",0);
3003 print_value(sql_file,result,row,
"",
"Create_options",0);
3004 print_value(sql_file,result,row,
"comment=",
"Comment",1);
3005 fputs(
" */",sql_file);
3009 mysql_free_result(result);
3013 fputs(
";\n", sql_file);
3015 fputs(
"\t</table_structure>\n", sql_file);
3019 if (complete_insert)
3021 dynstr_append_checked(&insert_pat,
") VALUES ");
3022 if (!extended_insert)
3023 dynstr_append_checked(&insert_pat,
"(");
3025 if (sql_file != md_result_file)
3027 fputs(
"\n", sql_file);
3028 write_footer(sql_file);
3029 my_fclose(sql_file, MYF(MY_WME));
3031 DBUG_RETURN((uint) num_fields);
3034 static void dump_trigger_old(FILE *sql_file,
MYSQL_RES *show_triggers_rs,
3035 MYSQL_ROW *show_trigger_row,
3038 char quoted_table_name_buf[NAME_LEN * 2 + 3];
3039 char *quoted_table_name= quote_name(table_name, quoted_table_name_buf, 1);
3041 char name_buff[NAME_LEN * 4 + 3];
3042 const char *xml_msg=
"\nWarning! mysqldump being run against old server "
3043 "that does not\nsupport 'SHOW CREATE TRIGGERS' "
3044 "statement. Skipping..\n";
3046 DBUG_ENTER(
"dump_trigger_old");
3050 print_xml_comment(sql_file, strlen(xml_msg), xml_msg);
3057 "-- WARNING: old server version. "
3058 "The following dump may be incomplete.\n"
3062 fprintf(sql_file,
"/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n");
3064 if (opt_drop_trigger)
3065 fprintf(sql_file,
"/*!50032 DROP TRIGGER IF EXISTS %s */;\n", (*show_trigger_row)[0]);
3069 "/*!50003 SET SESSION SQL_MODE=\"%s\" */;;\n"
3070 "/*!50003 CREATE */ ",
3071 (*show_trigger_row)[6]);
3073 if (mysql_num_fields(show_triggers_rs) > 7)
3082 size_t user_name_len;
3083 char user_name_str[USERNAME_LENGTH + 1];
3084 char quoted_user_name_str[USERNAME_LENGTH * 2 + 3];
3085 size_t host_name_len;
3086 char host_name_str[HOSTNAME_LENGTH + 1];
3087 char quoted_host_name_str[HOSTNAME_LENGTH * 2 + 3];
3089 parse_user((*show_trigger_row)[7],
3090 strlen((*show_trigger_row)[7]),
3091 user_name_str, &user_name_len,
3092 host_name_str, &host_name_len);
3095 "/*!50017 DEFINER=%s@%s */ ",
3096 quote_name(user_name_str, quoted_user_name_str, FALSE),
3097 quote_name(host_name_str, quoted_host_name_str, FALSE));
3101 "/*!50003 TRIGGER %s %s %s ON %s FOR EACH ROW%s%s */;;\n"
3103 quote_name((*show_trigger_row)[0], name_buff, 0),
3104 (*show_trigger_row)[4],
3105 (*show_trigger_row)[1],
3107 (strchr(
" \t\n\r", *((*show_trigger_row)[3]))) ?
"" :
" ",
3108 (*show_trigger_row)[3] );
3111 fprintf(sql_file,
"/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;\n");
3116 static int dump_trigger(FILE *sql_file,
MYSQL_RES *show_create_trigger_rs,
3117 const char *db_name,
3118 const char *db_cl_name)
3122 int db_cl_altered= FALSE;
3124 DBUG_ENTER(
"dump_trigger");
3126 while ((row= mysql_fetch_row(show_create_trigger_rs)))
3130 print_xml_row(sql_file,
"trigger", show_create_trigger_rs, &row,
3131 "SQL Original Statement");
3136 query_str= cover_definer_clause(row[2], strlen(row[2]),
3137 C_STRING_WITH_LEN(
"50017"),
3138 C_STRING_WITH_LEN(
"50003"),
3139 C_STRING_WITH_LEN(
" TRIGGER"));
3140 if (switch_db_collation(sql_file, db_name,
";",
3141 db_cl_name, row[5], &db_cl_altered))
3144 switch_cs_variables(sql_file,
";",
3149 switch_sql_mode(sql_file,
";", row[1]);
3151 if (opt_drop_trigger)
3152 fprintf(sql_file,
"/*!50032 DROP TRIGGER IF EXISTS %s */;\n", row[0]);
3156 "/*!50003 %s */;;\n"
3158 (
const char *) (query_str != NULL ? query_str : row[2]));
3160 restore_sql_mode(sql_file,
";");
3161 restore_cs_variables(sql_file,
";");
3165 if (restore_db_collation(sql_file, db_name,
";", db_cl_name))
3189 static int dump_triggers_for_table(
char *table_name,
char *db_name)
3191 char name_buff[NAME_LEN*4+3];
3192 char query_buff[QUERY_LENGTH];
3193 uint old_opt_compatible_mode= opt_compatible_mode;
3196 FILE *sql_file= md_result_file;
3198 char db_cl_name[MY_CS_NAME_SIZE];
3201 DBUG_ENTER(
"dump_triggers_for_table");
3202 DBUG_PRINT(
"enter", (
"db: %s, table_name: %s", db_name, table_name));
3204 if (path && !(sql_file= open_sql_file_for_table(table_name,
3205 O_WRONLY | O_APPEND)))
3209 opt_compatible_mode&= ~MASK_ANSI_QUOTES;
3213 if (switch_character_set_results(mysql,
"binary"))
3216 if (fetch_db_collation(db_name, db_cl_name,
sizeof (db_cl_name)))
3221 my_snprintf(query_buff,
sizeof(query_buff),
3222 "SHOW TRIGGERS LIKE %s",
3223 quote_for_like(table_name, name_buff));
3225 if (mysql_query_with_error_report(mysql, &show_triggers_rs, query_buff))
3230 if (! mysql_num_rows(show_triggers_rs))
3234 print_xml_tag(sql_file,
"\t",
"\n",
"triggers",
"name=",
3237 while ((row= mysql_fetch_row(show_triggers_rs)))
3240 my_snprintf(query_buff,
sizeof (query_buff),
3241 "SHOW CREATE TRIGGER %s",
3242 quote_name(row[0], name_buff, TRUE));
3244 if (mysql_query(mysql, query_buff))
3254 dump_trigger_old(sql_file, show_triggers_rs, &row, table_name);
3258 MYSQL_RES *show_create_trigger_rs= mysql_store_result(mysql);
3260 if (!show_create_trigger_rs ||
3261 dump_trigger(sql_file, show_create_trigger_rs, db_name, db_cl_name))
3264 mysql_free_result(show_create_trigger_rs);
3271 fputs(
"\t</triggers>\n", sql_file);
3276 mysql_free_result(show_triggers_rs);
3278 if (switch_character_set_results(mysql, default_charset))
3285 opt_compatible_mode=old_opt_compatible_mode;
3291 my_fclose(sql_file, MYF(0));
3305 dynstr_append_checked(str, option);
3307 if (strncmp(option_value,
"0x",
sizeof(
"0x")-1) == 0)
3310 dynstr_append_checked(str, option_value);
3315 field_escape(str, option_value);
3329 uint end_backslashes= 0;
3331 dynstr_append_checked(in,
"'");
3335 dynstr_append_mem_checked(in, from, 1);
3341 if (*from ==
'\'' && !end_backslashes)
3344 dynstr_append_checked(in,
"\'");
3351 if (end_backslashes)
3352 dynstr_append_checked(in,
"\\");
3354 dynstr_append_checked(in,
"'");
3359 static char *alloc_query_str(ulong
size)
3363 if (!(query= (
char*) my_malloc(size, MYF(MY_WME))))
3364 die(EX_MYSQLERR,
"Couldn't allocate a query string.");
3386 static void dump_table(
char *table,
char *db)
3389 char buf[200], table_buff[NAME_LEN+3];
3391 char table_type[NAME_LEN];
3392 char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
3394 ulong rownr, row_break, total_length, init_length;
3399 DBUG_ENTER(
"dump_table");
3405 num_fields= get_table_structure(table, db, table_type, &ignore_flag);
3410 if (strcmp(table_type,
"VIEW") == 0)
3416 verbose_msg(
"-- Skipping dump data for table '%s', --no-data was used\n",
3422 (
"ignore_flag: %x num_fields: %d", (
int) ignore_flag,
3428 if (ignore_flag & IGNORE_DATA)
3430 verbose_msg(
"-- Warning: Skipping data for table '%s' because " \
3431 "it's of type %s\n", table, table_type);
3435 if (num_fields == 0)
3437 verbose_msg(
"-- Skipping dump data for table '%s', it has no fields\n",
3442 result_table= quote_name(table,table_buff, 1);
3443 opt_quoted_table= quote_name(table, table_buff2, 0);
3445 verbose_msg(
"-- Sending SELECT query...\n");
3447 init_dynamic_string_checked(&query_string,
"", 1024, 1024);
3451 char filename[FN_REFLEN], tmp_path[FN_REFLEN];
3457 convert_dirname(tmp_path,path,NullS);
3458 my_load_path(tmp_path, tmp_path, NULL);
3459 fn_format(filename, table, tmp_path,
".txt", MYF(MY_UNPACK_FILENAME));
3462 my_delete(filename, MYF(0));
3465 to_unix_path(filename);
3469 dynstr_append_checked(&query_string,
"SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '");
3470 dynstr_append_checked(&query_string, filename);
3471 dynstr_append_checked(&query_string,
"'");
3473 dynstr_append_checked(&query_string,
" /*!50138 CHARACTER SET ");
3474 dynstr_append_checked(&query_string, default_charset == mysql_universal_client_charset ?
3475 my_charset_bin.name :
3477 dynstr_append_checked(&query_string,
" */");
3479 if (fields_terminated || enclosed || opt_enclosed || escaped)
3480 dynstr_append_checked(&query_string,
" FIELDS");
3482 add_load_option(&query_string,
" TERMINATED BY ", fields_terminated);
3483 add_load_option(&query_string,
" ENCLOSED BY ", enclosed);
3484 add_load_option(&query_string,
" OPTIONALLY ENCLOSED BY ", opt_enclosed);
3485 add_load_option(&query_string,
" ESCAPED BY ", escaped);
3486 add_load_option(&query_string,
" LINES TERMINATED BY ", lines_terminated);
3488 dynstr_append_checked(&query_string,
" FROM ");
3489 dynstr_append_checked(&query_string, result_table);
3493 dynstr_append_checked(&query_string,
" WHERE ");
3494 dynstr_append_checked(&query_string, where);
3499 dynstr_append_checked(&query_string,
" ORDER BY ");
3500 dynstr_append_checked(&query_string, order_by);
3503 if (mysql_real_query(mysql, query_string.str, query_string.length))
3505 DB_error(mysql,
"when executing 'SELECT INTO OUTFILE'");
3506 dynstr_free(&query_string);
3512 print_comment(md_result_file, 0,
3513 "\n--\n-- Dumping data for table %s\n--\n",
3516 dynstr_append_checked(&query_string,
"SELECT /*!40001 SQL_NO_CACHE */ * FROM ");
3517 dynstr_append_checked(&query_string, result_table);
3521 print_comment(md_result_file, 0,
"-- WHERE: %s\n", where);
3523 dynstr_append_checked(&query_string,
" WHERE ");
3524 dynstr_append_checked(&query_string, where);
3528 print_comment(md_result_file, 0,
"-- ORDER BY: %s\n", order_by);
3530 dynstr_append_checked(&query_string,
" ORDER BY ");
3531 dynstr_append_checked(&query_string, order_by);
3534 if (!opt_xml && !opt_compact)
3536 fputs(
"\n", md_result_file);
3537 check_io(md_result_file);
3539 if (mysql_query_with_error_report(mysql, 0, query_string.str))
3541 DB_error(mysql,
"when retrieving data from server");
3545 res=mysql_use_result(mysql);
3547 res=mysql_store_result(mysql);
3550 DB_error(mysql,
"when retrieving data from server");
3554 verbose_msg(
"-- Retrieving rows...\n");
3555 if (mysql_num_fields(res) != num_fields)
3557 fprintf(stderr,
"%s: Error in field count for table: %s ! Aborting.\n",
3558 my_progname, result_table);
3559 error= EX_CONSCHECK;
3565 fprintf(md_result_file,
"LOCK TABLES %s WRITE;\n", opt_quoted_table);
3566 check_io(md_result_file);
3569 if (opt_disable_keys)
3571 fprintf(md_result_file,
"/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",
3573 check_io(md_result_file);
3576 total_length= opt_net_buffer_length;
3579 init_length=(uint) insert_pat.length+4;
3581 print_xml_tag(md_result_file,
"\t",
"\n",
"table_data",
"name=", table,
3585 fprintf(md_result_file,
"set autocommit=0;\n");
3586 check_io(md_result_file);
3589 while ((row= mysql_fetch_row(res)))
3592 ulong *lengths= mysql_fetch_lengths(res);
3594 if (!extended_insert && !opt_xml)
3596 fputs(insert_pat.str,md_result_file);
3597 check_io(md_result_file);
3599 mysql_field_seek(res,0);
3603 fputs(
"\t<row>\n", md_result_file);
3604 check_io(md_result_file);
3607 for (i= 0; i < mysql_num_fields(res); i++)
3610 ulong length= lengths[
i];
3612 if (!(field= mysql_fetch_field(res)))
3614 "Not enough fields from table %s! Aborting.\n",
3622 is_blob= (opt_hex_blob && field->charsetnr == 63 &&
3623 (field->type == MYSQL_TYPE_BIT ||
3624 field->type == MYSQL_TYPE_STRING ||
3625 field->type == MYSQL_TYPE_VAR_STRING ||
3626 field->type == MYSQL_TYPE_VARCHAR ||
3627 field->type == MYSQL_TYPE_BLOB ||
3628 field->type == MYSQL_TYPE_LONG_BLOB ||
3629 field->type == MYSQL_TYPE_MEDIUM_BLOB ||
3630 field->type == MYSQL_TYPE_TINY_BLOB)) ? 1 : 0;
3631 if (extended_insert && !opt_xml)
3634 dynstr_set_checked(&extended_row,
"(");
3636 dynstr_append_checked(&extended_row,
",");
3642 if (!(field->flags & NUM_FLAG))
3652 dynstr_realloc_checked(&extended_row,length * 2 + 2 + 1);
3653 if (opt_hex_blob && is_blob)
3655 dynstr_append_checked(&extended_row,
"0x");
3656 extended_row.length+= mysql_hex_string(extended_row.str +
3657 extended_row.length,
3659 DBUG_ASSERT(extended_row.length+1 <= extended_row.max_length);
3661 DBUG_ASSERT(extended_row.str[extended_row.length] ==
'\0');
3665 dynstr_append_checked(&extended_row,
"'");
3666 extended_row.length +=
3667 mysql_real_escape_string(&mysql_connection,
3668 &extended_row.str[extended_row.length],
3670 extended_row.str[extended_row.length]=
'\0';
3671 dynstr_append_checked(&extended_row,
"'");
3678 if (my_isalpha(charset_info, *ptr) || (*ptr ==
'-' &&
3679 my_isalpha(charset_info, ptr[1])))
3680 dynstr_append_checked(&extended_row,
"NULL");
3683 if (field->type == MYSQL_TYPE_DECIMAL)
3686 dynstr_append_checked(&extended_row,
"'");
3687 dynstr_append_checked(&extended_row, ptr);
3688 dynstr_append_checked(&extended_row,
"'");
3691 dynstr_append_checked(&extended_row, ptr);
3696 dynstr_append_checked(&extended_row,
"''");
3699 dynstr_append_checked(&extended_row,
"NULL");
3705 fputc(
',', md_result_file);
3706 check_io(md_result_file);
3710 if (!(field->flags & NUM_FLAG))
3714 if (opt_hex_blob && is_blob && length)
3717 print_xml_tag(md_result_file,
"\t\t",
"",
"field",
"name=",
3718 field->name,
"xsi:type=",
"xs:hexBinary", NullS);
3719 print_blob_as_hex(md_result_file, row[i], length);
3723 print_xml_tag(md_result_file,
"\t\t",
"",
"field",
"name=",
3724 field->name, NullS);
3725 print_quoted_xml(md_result_file, row[i], length, 0);
3727 fputs(
"</field>\n", md_result_file);
3729 else if (opt_hex_blob && is_blob && length)
3731 fputs(
"0x", md_result_file);
3732 print_blob_as_hex(md_result_file, row[i], length);
3735 unescape(md_result_file, row[i], length);
3743 print_xml_tag(md_result_file,
"\t\t",
"",
"field",
"name=",
3744 field->name, NullS);
3745 fputs(!my_isalpha(charset_info, *ptr) ? ptr:
"NULL",
3747 fputs(
"</field>\n", md_result_file);
3749 else if (my_isalpha(charset_info, *ptr) ||
3750 (*ptr ==
'-' && my_isalpha(charset_info, ptr[1])))
3751 fputs(
"NULL", md_result_file);
3752 else if (field->type == MYSQL_TYPE_DECIMAL)
3755 fputc(
'\'', md_result_file);
3756 fputs(ptr, md_result_file);
3757 fputc(
'\'', md_result_file);
3760 fputs(ptr, md_result_file);
3767 fputs(
"NULL", md_result_file);
3769 print_xml_null_tag(md_result_file,
"\t\t",
"field name=",
3772 check_io(md_result_file);
3778 fputs(
"\t</row>\n", md_result_file);
3779 check_io(md_result_file);
3782 if (extended_insert)
3785 dynstr_append_checked(&extended_row,
")");
3786 row_length= 2 + extended_row.length;
3787 if (total_length + row_length < opt_net_buffer_length)
3789 total_length+= row_length;
3790 fputc(
',',md_result_file);
3791 fputs(extended_row.str,md_result_file);
3796 fputs(
";\n", md_result_file);
3799 fputs(insert_pat.str,md_result_file);
3800 fputs(extended_row.str,md_result_file);
3801 total_length= row_length+init_length;
3803 check_io(md_result_file);
3807 fputs(
");\n", md_result_file);
3808 check_io(md_result_file);
3814 fputs(
"\t</table_data>\n", md_result_file);
3815 else if (extended_insert && row_break)
3816 fputs(
";\n", md_result_file);
3817 fflush(md_result_file);
3818 check_io(md_result_file);
3819 if (mysql_errno(mysql))
3821 my_snprintf(buf,
sizeof(buf),
3822 "%s: Error %d: %s when dumping table %s at row: %ld\n",
3829 error= EX_CONSCHECK;
3834 if (opt_disable_keys)
3836 fprintf(md_result_file,
"/*!40000 ALTER TABLE %s ENABLE KEYS */;\n",
3838 check_io(md_result_file);
3842 fputs(
"UNLOCK TABLES;\n", md_result_file);
3843 check_io(md_result_file);
3847 fprintf(md_result_file,
"commit;\n");
3848 check_io(md_result_file);
3850 mysql_free_result(res);
3852 dynstr_free(&query_string);
3856 dynstr_free(&query_string);
3862 static char *getTableName(
int reset)
3869 if (!(res= mysql_list_tables(mysql,NullS)))
3872 if ((row= mysql_fetch_row(res)))
3873 return((
char*) row[0]);
3876 mysql_data_seek(res,0);
3879 mysql_free_result(res);
3890 static int dump_all_tablespaces()
3892 return dump_tablespaces(NULL);
3895 static int dump_tablespaces_for_tables(
char *db,
char **table_names,
int tables)
3900 char name_buff[NAME_LEN*2+3];
3902 mysql_real_escape_string(mysql, name_buff, db, strlen(db));
3904 init_dynamic_string_checked(&where,
" AND TABLESPACE_NAME IN ("
3905 "SELECT DISTINCT TABLESPACE_NAME FROM"
3906 " INFORMATION_SCHEMA.PARTITIONS"
3908 " TABLE_SCHEMA='", 256, 1024);
3909 dynstr_append_checked(&where, name_buff);
3910 dynstr_append_checked(&where,
"' AND TABLE_NAME IN (");
3912 for (i=0 ; i<tables ; i++)
3914 mysql_real_escape_string(mysql, name_buff,
3915 table_names[i], strlen(table_names[i]));
3917 dynstr_append_checked(&where,
"'");
3918 dynstr_append_checked(&where, name_buff);
3919 dynstr_append_checked(&where,
"',");
3921 dynstr_trunc(&where, 1);
3922 dynstr_append_checked(&where,
"))");
3924 DBUG_PRINT(
"info",(
"Dump TS for Tables where: %s",where.str));
3925 r= dump_tablespaces(where.str);
3926 dynstr_free(&where);
3930 static int dump_tablespaces_for_databases(
char** databases)
3936 init_dynamic_string_checked(&where,
" AND TABLESPACE_NAME IN ("
3937 "SELECT DISTINCT TABLESPACE_NAME FROM"
3938 " INFORMATION_SCHEMA.PARTITIONS"
3940 " TABLE_SCHEMA IN (", 256, 1024);
3942 for (i=0 ; databases[
i]!=NULL ; i++)
3944 char db_name_buff[NAME_LEN*2+3];
3945 mysql_real_escape_string(mysql, db_name_buff,
3946 databases[i], strlen(databases[i]));
3947 dynstr_append_checked(&where,
"'");
3948 dynstr_append_checked(&where, db_name_buff);
3949 dynstr_append_checked(&where,
"',");
3951 dynstr_trunc(&where, 1);
3952 dynstr_append_checked(&where,
"))");
3954 DBUG_PRINT(
"info",(
"Dump TS for DBs where: %s",where.str));
3955 r= dump_tablespaces(where.str);
3956 dynstr_free(&where);
3960 static int dump_tablespaces(
char* ts_where)
3964 char buf[FN_REFLEN];
3970 char extra_format[]=
"UNDO_BUFFER_SIZE=";
3973 DBUG_ENTER(
"dump_tablespaces");
3975 init_dynamic_string_checked(&sqlbuf,
3976 "SELECT LOGFILE_GROUP_NAME,"
3982 " FROM INFORMATION_SCHEMA.FILES"
3983 " WHERE FILE_TYPE = 'UNDO LOG'"
3984 " AND FILE_NAME IS NOT NULL",
3988 dynstr_append_checked(&sqlbuf,
3989 " AND LOGFILE_GROUP_NAME IN ("
3990 "SELECT DISTINCT LOGFILE_GROUP_NAME"
3991 " FROM INFORMATION_SCHEMA.FILES"
3992 " WHERE FILE_TYPE = 'DATAFILE'"
3994 dynstr_append_checked(&sqlbuf, ts_where);
3995 dynstr_append_checked(&sqlbuf,
")");
3997 dynstr_append_checked(&sqlbuf,
3998 " GROUP BY LOGFILE_GROUP_NAME, FILE_NAME"
4000 " ORDER BY LOGFILE_GROUP_NAME");
4002 if (mysql_query(mysql, sqlbuf.str) ||
4003 !(tableres = mysql_store_result(mysql)))
4005 dynstr_free(&sqlbuf);
4006 if (mysql_errno(mysql) == ER_BAD_TABLE_ERROR ||
4007 mysql_errno(mysql) == ER_BAD_DB_ERROR ||
4008 mysql_errno(mysql) == ER_UNKNOWN_TABLE)
4010 fprintf(md_result_file,
4011 "\n--\n-- Not dumping tablespaces as no INFORMATION_SCHEMA.FILES"
4012 " table on this server\n--\n");
4013 check_io(md_result_file);
4017 my_printf_error(0,
"Error: '%s' when trying to dump tablespaces",
4018 MYF(0), mysql_error(mysql));
4023 while ((row= mysql_fetch_row(tableres)))
4025 if (strcmp(buf, row[0]) != 0)
4029 print_comment(md_result_file, 0,
"\n--\n-- Logfile group: %s\n--\n",
4032 fprintf(md_result_file,
"\nCREATE");
4036 fprintf(md_result_file,
"\nALTER");
4038 fprintf(md_result_file,
4039 " LOGFILE GROUP %s\n"
4040 " ADD UNDOFILE '%s'\n",
4045 ubs= strstr(row[5],extra_format);
4048 ubs+= strlen(extra_format);
4049 endsemi= strstr(ubs,
";");
4052 fprintf(md_result_file,
4053 " UNDO_BUFFER_SIZE %s\n",
4056 fprintf(md_result_file,
4057 " INITIAL_SIZE %s\n"
4061 check_io(md_result_file);
4065 strxmov(buf, row[0], NullS);
4068 dynstr_free(&sqlbuf);
4069 mysql_free_result(tableres);
4070 init_dynamic_string_checked(&sqlbuf,
4071 "SELECT DISTINCT TABLESPACE_NAME,"
4073 " LOGFILE_GROUP_NAME,"
4077 " FROM INFORMATION_SCHEMA.FILES"
4078 " WHERE FILE_TYPE = 'DATAFILE'",
4082 dynstr_append_checked(&sqlbuf, ts_where);
4084 dynstr_append_checked(&sqlbuf,
" ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME");
4086 if (mysql_query_with_error_report(mysql, &tableres, sqlbuf.str))
4088 dynstr_free(&sqlbuf);
4093 while ((row= mysql_fetch_row(tableres)))
4095 if (strcmp(buf, row[0]) != 0)
4099 print_comment(md_result_file, 0,
"\n--\n-- Tablespace: %s\n--\n", row[0]);
4100 fprintf(md_result_file,
"\nCREATE");
4104 fprintf(md_result_file,
"\nALTER");
4106 fprintf(md_result_file,
4108 " ADD DATAFILE '%s'\n",
4113 fprintf(md_result_file,
4114 " USE LOGFILE GROUP %s\n"
4115 " EXTENT_SIZE %s\n",
4119 fprintf(md_result_file,
4120 " INITIAL_SIZE %s\n"
4124 check_io(md_result_file);
4128 strxmov(buf, row[0], NullS);
4132 mysql_free_result(tableres);
4133 dynstr_free(&sqlbuf);
4139 is_ndbinfo(
MYSQL* mysql,
const char* dbname)
4141 static int checked_ndbinfo= 0;
4142 static int have_ndbinfo= 0;
4144 if (!checked_ndbinfo)
4148 char buf[32], query[64];
4150 my_snprintf(query,
sizeof(query),
4151 "SHOW VARIABLES LIKE %s",
4152 quote_for_like(
"ndbinfo_version", buf));
4156 if (mysql_query_with_error_report(mysql, &res, query))
4159 if (!(row= mysql_fetch_row(res)))
4161 mysql_free_result(res);
4166 mysql_free_result(res);
4172 if (my_strcasecmp(&my_charset_latin1, dbname,
"ndbinfo") == 0)
4179 static int dump_all_databases()
4185 if (mysql_query_with_error_report(mysql, &tableres,
"SHOW DATABASES"))
4187 while ((row= mysql_fetch_row(tableres)))
4189 if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION &&
4190 !my_strcasecmp(&my_charset_latin1, row[0], INFORMATION_SCHEMA_DB_NAME))
4193 if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION &&
4194 !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME))
4197 if (is_ndbinfo(mysql, row[0]))
4200 if (dump_all_tables_in_db(row[0]))
4205 if (mysql_query(mysql,
"SHOW DATABASES") ||
4206 !(tableres= mysql_store_result(mysql)))
4208 my_printf_error(0,
"Error: Couldn't execute 'SHOW DATABASES': %s",
4209 MYF(0), mysql_error(mysql));
4212 while ((row= mysql_fetch_row(tableres)))
4214 if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION &&
4215 !my_strcasecmp(&my_charset_latin1, row[0], INFORMATION_SCHEMA_DB_NAME))
4218 if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION &&
4219 !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME))
4222 if (is_ndbinfo(mysql, row[0]))
4225 if (dump_all_views_in_db(row[0]))
4234 static int dump_databases(
char **db_names)
4238 DBUG_ENTER(
"dump_databases");
4240 for (db= db_names ; *db ; db++)
4242 if (dump_all_tables_in_db(*db))
4245 if (!result && seen_views)
4247 for (db= db_names ; *db ; db++)
4249 if (dump_all_views_in_db(*db))
4253 DBUG_RETURN(result);
4268 int init_dumping_views(
char *qdatabase __attribute__((unused)))
4286 int init_dumping_tables(
char *qdatabase)
4288 DBUG_ENTER(
"init_dumping_tables");
4296 my_snprintf(qbuf,
sizeof(qbuf),
4297 "SHOW CREATE DATABASE IF NOT EXISTS %s",
4300 if (mysql_query(mysql, qbuf) || !(dbinfo = mysql_store_result(mysql)))
4303 if (opt_drop_database)
4304 fprintf(md_result_file,
4305 "\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n",
4307 fprintf(md_result_file,
4308 "\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n",
4313 if (opt_drop_database)
4314 fprintf(md_result_file,
4315 "\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n",
4317 row = mysql_fetch_row(dbinfo);
4320 fprintf(md_result_file,
"\n%s;\n",row[1]);
4322 mysql_free_result(dbinfo);
4329 static int init_dumping(
char *database,
int init_func(
char*))
4331 if (is_ndbinfo(mysql, database))
4333 verbose_msg(
"-- Skipping dump of ndbinfo database\n");
4337 if (mysql_select_db(mysql, database))
4339 DB_error(mysql,
"when selecting the database");
4342 if (!path && !opt_xml)
4344 if (opt_databases || opt_alldbs)
4349 char quoted_database_buf[NAME_LEN*2+3];
4350 char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
4352 print_comment(md_result_file, 0,
4353 "\n--\n-- Current Database: %s\n--\n", qdatabase);
4356 init_func(qdatabase);
4358 fprintf(md_result_file,
"\nUSE %s;\n", qdatabase);
4359 check_io(md_result_file);
4362 if (extended_insert)
4363 init_dynamic_string_checked(&extended_row,
"", 1024, 1024);
4370 my_bool include_table(
const uchar *hash_key,
size_t len)
4372 return ! my_hash_search(&ignore_table, hash_key, len);
4376 static int dump_all_tables_in_db(
char *database)
4380 char table_buff[NAME_LEN*2+3];
4381 char hash_key[2*NAME_LEN+2];
4383 my_bool general_log_table_exists= 0, slow_log_table_exists=0;
4384 int using_mysql_db= !my_strcasecmp(charset_info, database,
"mysql");
4385 DBUG_ENTER(
"dump_all_tables_in_db");
4387 afterdot= strmov(hash_key, database);
4390 if (init_dumping(database, init_dumping_tables))
4393 print_xml_tag(md_result_file,
"",
"\n",
"database",
"name=", database, NullS);
4398 init_dynamic_string_checked(&query,
"LOCK TABLES ", 256, 1024);
4399 for (numrows= 0 ; (table= getTableName(1)) ; )
4401 char *end= strmov(afterdot, table);
4402 if (include_table((uchar*) hash_key,end - hash_key))
4405 dynstr_append_checked(&query, quote_name(table, table_buff, 1));
4406 dynstr_append_checked(&query,
" READ /*!32311 LOCAL */,");
4409 if (numrows && mysql_real_query(mysql, query.str, query.length-1))
4410 DB_error(mysql,
"when using LOCK TABLES");
4412 dynstr_free(&query);
4416 if (mysql_refresh(mysql, REFRESH_LOG))
4417 DB_error(mysql,
"when doing refresh");
4420 verbose_msg(
"-- dump_all_tables_in_db : logs flushed successfully!\n");
4422 while ((table= getTableName(0)))
4424 char *end= strmov(afterdot, table);
4425 if (include_table((uchar*) hash_key, end - hash_key))
4427 dump_table(table,database);
4430 if (opt_dump_triggers && mysql_get_server_version(mysql) >= 50009)
4432 if (dump_triggers_for_table(table, database))
4435 my_fclose(md_result_file, MYF(MY_WME));
4436 maybe_exit(EX_MYSQLERR);
4454 if (!my_strcasecmp(charset_info, table,
"general_log"))
4455 general_log_table_exists= 1;
4456 else if (!my_strcasecmp(charset_info, table,
"slow_log"))
4457 slow_log_table_exists= 1;
4461 if (opt_events && mysql_get_server_version(mysql) >= 50106)
4463 DBUG_PRINT(
"info", (
"Dumping events for database %s", database));
4464 dump_events_for_db(database);
4466 if (opt_routines && mysql_get_server_version(mysql) >= 50009)
4468 DBUG_PRINT(
"info", (
"Dumping routines for database %s", database));
4469 dump_routines_for_db(database);
4473 fputs(
"</database>\n", md_result_file);
4474 check_io(md_result_file);
4477 (void) mysql_query_with_error_report(mysql, 0,
"UNLOCK TABLES");
4480 char table_type[NAME_LEN];
4482 if (general_log_table_exists)
4484 if (!get_table_structure((
char *)
"general_log",
4485 database, table_type, &ignore_flag) )
4486 verbose_msg(
"-- Warning: get_table_structure() failed with some internal "
4487 "error for 'general_log' table\n");
4489 if (slow_log_table_exists)
4491 if (!get_table_structure((
char *)
"slow_log",
4492 database, table_type, &ignore_flag) )
4493 verbose_msg(
"-- Warning: get_table_structure() failed with some internal "
4494 "error for 'slow_log' table\n");
4497 if (flush_privileges && using_mysql_db)
4499 fprintf(md_result_file,
"\n--\n-- Flush Grant Tables \n--\n");
4500 fprintf(md_result_file,
"\n/*! FLUSH PRIVILEGES */;\n");
4518 static my_bool dump_all_views_in_db(
char *database)
4522 char table_buff[NAME_LEN*2+3];
4523 char hash_key[2*NAME_LEN+2];
4526 afterdot= strmov(hash_key, database);
4529 if (init_dumping(database, init_dumping_views))
4532 print_xml_tag(md_result_file,
"",
"\n",
"database",
"name=", database, NullS);
4536 init_dynamic_string_checked(&query,
"LOCK TABLES ", 256, 1024);
4537 for (numrows= 0 ; (table= getTableName(1)); )
4539 char *end= strmov(afterdot, table);
4540 if (include_table((uchar*) hash_key,end - hash_key))
4543 dynstr_append_checked(&query, quote_name(table, table_buff, 1));
4544 dynstr_append_checked(&query,
" READ /*!32311 LOCAL */,");
4547 if (numrows && mysql_real_query(mysql, query.str, query.length-1))
4548 DB_error(mysql,
"when using LOCK TABLES");
4550 dynstr_free(&query);
4554 if (mysql_refresh(mysql, REFRESH_LOG))
4555 DB_error(mysql,
"when doing refresh");
4558 verbose_msg(
"-- dump_all_views_in_db : logs flushed successfully!\n");
4560 while ((table= getTableName(0)))
4562 char *end= strmov(afterdot, table);
4563 if (include_table((uchar*) hash_key, end - hash_key))
4564 get_view_structure(table, database);
4568 fputs(
"</database>\n", md_result_file);
4569 check_io(md_result_file);
4572 (void) mysql_query_with_error_report(mysql, 0,
"UNLOCK TABLES");
4588 static char *get_actual_table_name(
const char *old_table_name,
MEM_ROOT *root)
4593 char query[50 + 2*NAME_LEN];
4594 char show_name_buff[FN_REFLEN];
4595 DBUG_ENTER(
"get_actual_table_name");
4598 DBUG_ASSERT(2*
sizeof(old_table_name) <
sizeof(show_name_buff));
4599 my_snprintf(query,
sizeof(query),
"SHOW TABLES LIKE %s",
4600 quote_for_like(old_table_name, show_name_buff));
4602 if (mysql_query_with_error_report(mysql, 0, query))
4605 if ((table_res= mysql_store_result(mysql)))
4607 my_ulonglong num_rows= mysql_num_rows(table_res);
4615 row= mysql_fetch_row(table_res);
4616 lengths= mysql_fetch_lengths(table_res);
4617 name= strmake_root(root, row[0], lengths[0]);
4619 mysql_free_result(table_res);
4621 DBUG_PRINT(
"exit", (
"new_table_name: %s", name));
4626 static int dump_selected_tables(
char *db,
char **table_names,
int tables)
4628 char table_buff[NAME_LEN*2+3];
4631 char **dump_tables, **pos, **end;
4632 DBUG_ENTER(
"dump_selected_tables");
4634 if (init_dumping(db, init_dumping_tables))
4637 init_alloc_root(&root, 8192, 0);
4638 if (!(dump_tables= pos= (
char**) alloc_root(&root, tables *
sizeof(
char *))))
4639 die(EX_EOM,
"alloc_root failure.");
4641 init_dynamic_string_checked(&lock_tables_query,
"LOCK TABLES ", 256, 1024);
4642 for (; tables > 0 ; tables-- , table_names++)
4645 if ((*pos= get_actual_table_name(*table_names, &root)))
4650 dynstr_append_checked(&lock_tables_query, quote_name(*pos, table_buff, 1));
4651 dynstr_append_checked(&lock_tables_query,
" READ /*!32311 LOCAL */,");
4659 dynstr_free(&lock_tables_query);
4660 free_root(&root, MYF(0));
4662 maybe_die(EX_ILLEGAL_TABLE,
"Couldn't find table: \"%s\"", *table_names);
4670 !(mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION &&
4671 !my_strcasecmp(&my_charset_latin1, db, INFORMATION_SCHEMA_DB_NAME)) &&
4672 !(mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION &&
4673 !my_strcasecmp(&my_charset_latin1, db, PERFORMANCE_SCHEMA_DB_NAME)))
4675 if (mysql_real_query(mysql, lock_tables_query.str,
4676 lock_tables_query.length-1))
4680 dynstr_free(&lock_tables_query);
4681 free_root(&root, MYF(0));
4683 DB_error(mysql,
"when doing LOCK TABLES");
4687 dynstr_free(&lock_tables_query);
4690 if (mysql_refresh(mysql, REFRESH_LOG))
4693 free_root(&root, MYF(0));
4694 DB_error(mysql,
"when doing refresh");
4698 verbose_msg(
"-- dump_selected_tables : logs flushed successfully!\n");
4701 print_xml_tag(md_result_file,
"",
"\n",
"database",
"name=", db, NullS);
4704 for (pos= dump_tables; pos < end; pos++)
4706 DBUG_PRINT(
"info",(
"Dumping table %s", *pos));
4707 dump_table(*pos, db);
4708 if (opt_dump_triggers &&
4709 mysql_get_server_version(mysql) >= 50009)
4711 if (dump_triggers_for_table(*pos, db))
4714 my_fclose(md_result_file, MYF(MY_WME));
4715 maybe_exit(EX_MYSQLERR);
4723 for (pos= dump_tables; pos < end; pos++)
4724 get_view_structure(*pos, db);
4726 if (opt_events && mysql_get_server_version(mysql) >= 50106)
4728 DBUG_PRINT(
"info", (
"Dumping events for database %s", db));
4729 dump_events_for_db(db);
4732 if (opt_routines && mysql_get_server_version(mysql) >= 50009)
4734 DBUG_PRINT(
"info", (
"Dumping routines for database %s", db));
4735 dump_routines_for_db(db);
4737 free_root(&root, MYF(0));
4742 fputs(
"</database>\n", md_result_file);
4743 check_io(md_result_file);
4746 (void) mysql_query_with_error_report(mysql, 0,
"UNLOCK TABLES");
4751 static int do_show_master_status(
MYSQL *mysql_con)
4755 const char *comment_prefix=
4756 (opt_master_data == MYSQL_OPT_MASTER_DATA_COMMENTED_SQL) ?
"-- " :
"";
4757 if (mysql_query_with_error_report(mysql_con, &master,
"SHOW MASTER STATUS"))
4763 row= mysql_fetch_row(master);
4764 if (row && row[0] && row[1])
4767 print_comment(md_result_file, 0,
4768 "\n--\n-- Position to start replication or point-in-time "
4769 "recovery from\n--\n\n");
4770 fprintf(md_result_file,
4771 "%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
4772 comment_prefix, row[0], row[1]);
4773 check_io(md_result_file);
4775 else if (!ignore_errors)
4778 my_printf_error(0,
"Error: Binlogging on server not active",
4780 mysql_free_result(master);
4781 maybe_exit(EX_MYSQLERR);
4784 mysql_free_result(master);
4789 static int do_stop_slave_sql(
MYSQL *mysql_con)
4793 if (mysql_query_with_error_report(mysql_con, &slave,
"SHOW SLAVE STATUS"))
4797 MYSQL_ROW row= mysql_fetch_row(slave);
4801 if (!strcmp(row[11],
"No"))
4803 mysql_free_result(slave);
4809 mysql_free_result(slave);
4812 if (mysql_query_with_error_report(mysql_con, 0,
"STOP SLAVE SQL_THREAD"))
4818 static int add_stop_slave(
void)
4821 fprintf(md_result_file,
4822 "\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
4823 fprintf(md_result_file,
"STOP SLAVE;\n");
4827 static int add_slave_statements(
void)
4830 fprintf(md_result_file,
4831 "\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
4832 fprintf(md_result_file,
"START SLAVE;\n");
4836 static int do_show_slave_status(
MYSQL *mysql_con)
4839 const char *comment_prefix=
4840 (opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ?
"-- " :
"";
4841 if (mysql_query_with_error_report(mysql_con, &slave,
"SHOW SLAVE STATUS"))
4846 my_printf_error(0,
"Error: Slave not set up", MYF(0));
4848 mysql_free_result(slave);
4853 MYSQL_ROW row= mysql_fetch_row(slave);
4854 if (row && row[9] && row[21])
4858 fprintf(md_result_file,
4859 "\n--\n-- Position to start replication or point-in-time "
4860 "recovery from (the master of this slave)\n--\n\n");
4862 fprintf(md_result_file,
"%sCHANGE MASTER TO ", comment_prefix);
4864 if (opt_include_master_host_port)
4867 fprintf(md_result_file,
"MASTER_HOST='%s', ", row[1]);
4869 fprintf(md_result_file,
"MASTER_PORT=%s, ", row[3]);
4871 fprintf(md_result_file,
4872 "MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
4874 check_io(md_result_file);
4876 mysql_free_result(slave);
4881 static int do_start_slave_sql(
MYSQL *mysql_con)
4885 if (mysql_query_with_error_report(mysql_con, &slave,
"SHOW SLAVE STATUS"))
4889 MYSQL_ROW row= mysql_fetch_row(slave);
4893 if (!strcmp(row[11],
"Yes"))
4895 mysql_free_result(slave);
4901 mysql_free_result(slave);
4904 if (mysql_query_with_error_report(mysql_con, 0,
"START SLAVE"))
4906 my_printf_error(0,
"Error: Unable to start slave", MYF(0));
4914 static int do_flush_tables_read_lock(
MYSQL *mysql_con)
4925 ( mysql_query_with_error_report(mysql_con, 0,
4926 ((opt_master_data != 0) ?
4927 "FLUSH /*!40101 LOCAL */ TABLES" :
4929 mysql_query_with_error_report(mysql_con, 0,
4930 "FLUSH TABLES WITH READ LOCK") );
4934 static int do_unlock_tables(
MYSQL *mysql_con)
4936 return mysql_query_with_error_report(mysql_con, 0,
"UNLOCK TABLES");
4939 static int get_bin_log_name(
MYSQL *mysql_con,
4940 char* buff_log_name, uint buff_len)
4945 if (mysql_query(mysql_con,
"SHOW MASTER STATUS") ||
4946 !(res= mysql_store_result(mysql)))
4949 if (!(row= mysql_fetch_row(res)))
4951 mysql_free_result(res);
4958 strmake(buff_log_name, row[0], buff_len - 1);
4960 mysql_free_result(res);
4964 static int purge_bin_logs_to(
MYSQL *mysql_con,
char* log_name)
4968 init_dynamic_string_checked(&str,
"PURGE BINARY LOGS TO '", 1024, 1024);
4969 dynstr_append_checked(&str, log_name);
4970 dynstr_append_checked(&str,
"'");
4971 err = mysql_query_with_error_report(mysql_con, 0, str.str);
4977 static int start_transaction(
MYSQL *mysql_con)
4979 verbose_msg(
"-- Starting transaction...\n");
4989 if ((mysql_get_server_version(mysql_con) < 40100) && opt_master_data)
4991 fprintf(stderr,
"-- %s: the combination of --single-transaction and "
4992 "--master-data requires a MySQL server version of at least 4.1 "
4993 "(current server's version is %s). %s\n",
4994 ignore_errors ?
"Warning" :
"Error",
4995 mysql_con->server_version ? mysql_con->server_version :
"unknown",
4996 ignore_errors ?
"Continuing due to --force, backup may not be consistent across all tables!" :
"Aborting.");
5001 return (mysql_query_with_error_report(mysql_con, 0,
5002 "SET SESSION TRANSACTION ISOLATION "
5003 "LEVEL REPEATABLE READ") ||
5004 mysql_query_with_error_report(mysql_con, 0,
5005 "START TRANSACTION "
5006 "/*!40100 WITH CONSISTENT SNAPSHOT */"));
5010 static ulong find_set(
TYPELIB *lib,
const char *x, uint length,
5011 char **err_pos, uint *err_len)
5013 const char *end= x + length;
5019 while (end > x && my_isspace(charset_info, end[-1]))
5025 const char *start= x;
5028 const char *pos= start;
5031 for (; pos != end && *pos !=
','; pos++) ;
5032 var_len= (uint) (pos - start);
5033 strmake(buff, start, MY_MIN(
sizeof(buff) - 1, var_len));
5034 find= find_type(buff, lib, FIND_TYPE_BASIC);
5037 *err_pos= (
char*) start;
5041 found|= ((longlong) 1 << (find - 1));
5052 static void print_value(FILE *file,
MYSQL_RES *result, MYSQL_ROW row,
5053 const char *prefix,
const char *name,
5057 mysql_field_seek(result, 0);
5059 for ( ; (field= mysql_fetch_field(result)) ; row++)
5061 if (!strcmp(field->name,name))
5063 if (row[0] && row[0][0] && strcmp(row[0],
"0"))
5066 fputs(prefix, file);
5068 unescape(file,row[0],(uint) strlen(row[0]));
5070 fputs(row[0], file);
5104 char check_if_ignore_table(
const char *table_name,
char *table_type)
5106 char result= IGNORE_NONE;
5107 char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
5110 DBUG_ENTER(
"check_if_ignore_table");
5113 DBUG_ASSERT(2*
sizeof(table_name) <
sizeof(show_name_buff));
5114 my_snprintf(buff,
sizeof(buff),
"show table status like %s",
5115 quote_for_like(table_name, show_name_buff));
5116 if (mysql_query_with_error_report(mysql, &res, buff))
5118 if (mysql_errno(mysql) != ER_PARSE_ERROR)
5120 verbose_msg(
"-- Warning: Couldn't get status information for "
5121 "table %s (%s)\n", table_name, mysql_error(mysql));
5122 DBUG_RETURN(result);
5125 if (!(row= mysql_fetch_row(res)))
5128 "Error: Couldn't read status information for table %s (%s)\n",
5129 table_name, mysql_error(mysql));
5130 mysql_free_result(res);
5131 DBUG_RETURN(result);
5134 strmake(table_type,
"VIEW", NAME_LEN-1);
5143 strmake(table_type, row[1], NAME_LEN-1);
5146 if (strcmp(table_type,
"MyISAM") &&
5147 strcmp(table_type,
"ISAM") &&
5148 strcmp(table_type,
"ARCHIVE") &&
5149 strcmp(table_type,
"HEAP") &&
5150 strcmp(table_type,
"MEMORY"))
5151 result= IGNORE_INSERT_DELAYED;
5158 (!my_strcasecmp(&my_charset_latin1, table_type,
"MRG_MyISAM") ||
5159 !strcmp(table_type,
"MRG_ISAM") ||
5160 !strcmp(table_type,
"FEDERATED")))
5161 result= IGNORE_DATA;
5163 mysql_free_result(res);
5164 DBUG_RETURN(result);
5186 static char *primary_key_fields(
const char *table_name)
5191 char show_keys_buff[15 + NAME_LEN * 2 + 3];
5192 uint result_length= 0;
5194 char buff[NAME_LEN * 2 + 3];
5197 my_snprintf(show_keys_buff,
sizeof(show_keys_buff),
5198 "SHOW KEYS FROM %s", table_name);
5199 if (mysql_query(mysql, show_keys_buff) ||
5200 !(res= mysql_store_result(mysql)))
5202 fprintf(stderr,
"Warning: Couldn't read keys from table %s;"
5203 " records are NOT sorted (%s)\n",
5204 table_name, mysql_error(mysql));
5215 if ((row= mysql_fetch_row(res)) && atoi(row[1]) == 0)
5220 quoted_field= quote_name(row[4], buff, 0);
5221 result_length+= strlen(quoted_field) + 1;
5222 }
while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1);
5230 result= my_malloc(result_length + 10, MYF(MY_WME));
5233 fprintf(stderr,
"Error: Not enough memory to store ORDER BY clause\n");
5236 mysql_data_seek(res, 0);
5237 row= mysql_fetch_row(res);
5238 quoted_field= quote_name(row[4], buff, 0);
5239 end= strmov(result, quoted_field);
5240 while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1)
5242 quoted_field= quote_name(row[4], buff, 0);
5243 end= strxmov(end,
",", quoted_field, NullS);
5249 mysql_free_result(res);
5272 const char *search_str, ulong search_len,
5273 const char *replace_str, ulong replace_len)
5276 const char *start= strstr(ds_str->str, search_str);
5279 init_dynamic_string_checked(&ds_tmp,
"",
5280 ds_str->length + replace_len, 256);
5281 dynstr_append_mem_checked(&ds_tmp, ds_str->str, start - ds_str->str);
5282 dynstr_append_mem_checked(&ds_tmp, replace_str, replace_len);
5283 dynstr_append_checked(&ds_tmp, start + search_len);
5284 dynstr_set_checked(ds_str, ds_tmp.str);
5285 dynstr_free(&ds_tmp);
5304 static void set_session_binlog(my_bool flag)
5306 static my_bool is_binlog_disabled= FALSE;
5308 if (!flag && !is_binlog_disabled)
5310 fprintf(md_result_file,
5311 "SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;\n");
5312 fprintf(md_result_file,
"SET @@SESSION.SQL_LOG_BIN= 0;\n");
5313 is_binlog_disabled= 1;
5315 else if (flag && is_binlog_disabled)
5317 fprintf(md_result_file,
5318 "SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;\n");
5319 is_binlog_disabled= 0;
5337 static my_bool add_set_gtid_purged(
MYSQL *mysql_con)
5341 ulong num_sets, idx;
5344 if (mysql_query_with_error_report(mysql_con, >id_purged_res,
5345 "SELECT @@GLOBAL.GTID_EXECUTED"))
5349 if ((num_sets= mysql_num_rows(gtid_purged_res)) > 0)
5352 fprintf(md_result_file,
5353 "\n--\n-- GTID state at the beginning of the backup \n--\n\n");
5355 fprintf(md_result_file,
"SET @@GLOBAL.GTID_PURGED='");
5358 for (idx= 0; idx< num_sets-1; idx++)
5360 gtid_set= mysql_fetch_row(gtid_purged_res);
5361 fprintf(md_result_file,
"%s,", (
char*)gtid_set[0]);
5364 gtid_set= mysql_fetch_row(gtid_purged_res);
5366 fprintf(md_result_file,
"%s';\n", (
char*)gtid_set[0]);
5385 static my_bool process_set_gtid_purged(
MYSQL* mysql_con)
5388 MYSQL_ROW gtid_mode_row;
5389 char *gtid_mode_val= 0;
5390 char buf[32], query[64];
5392 if (opt_set_gtid_purged_mode == SET_GTID_PURGED_OFF)
5399 my_snprintf(query,
sizeof(query),
"SHOW VARIABLES LIKE %s",
5400 quote_for_like(
"gtid_mode", buf));
5402 if (mysql_query_with_error_report(mysql_con, >id_mode_res, query))
5405 gtid_mode_row = mysql_fetch_row(gtid_mode_res);
5411 gtid_mode_val = gtid_mode_row ? (
char*)gtid_mode_row[1] : NULL;
5413 if (gtid_mode_val && strcmp(gtid_mode_val,
"OFF"))
5419 if (opt_databases || !opt_alldbs || !opt_dump_triggers
5420 || !opt_routines || !opt_events)
5422 fprintf(stderr,
"Warning: A partial dump from a server that has GTIDs will "
5423 "by default include the GTIDs of all transactions, even "
5424 "those that changed suppressed parts of the database. If "
5425 "you don't want to restore GTIDs, pass "
5426 "--set-gtid-purged=OFF. To make a complete dump, pass "
5427 "--all-databases --triggers --routines --events. \n");
5430 set_session_binlog(FALSE);
5431 if (add_set_gtid_purged(mysql_con))
5436 if (opt_set_gtid_purged_mode == SET_GTID_PURGED_ON)
5438 fprintf(stderr,
"Error: Server has GTIDs disabled.\n");
5460 static my_bool get_view_structure(
char *table,
char* db)
5465 char *result_table, *opt_quoted_table;
5466 char table_buff[NAME_LEN*2+3];
5467 char table_buff2[NAME_LEN*2+3];
5468 char query[QUERY_LENGTH];
5469 FILE *sql_file= md_result_file;
5470 DBUG_ENTER(
"get_view_structure");
5472 if (opt_no_create_info)
5475 verbose_msg(
"-- Retrieving view structure for table %s...\n", table);
5477 #ifdef NOT_REALLY_USED_YET
5478 sprintf(insert_pat,
"SET SQL_QUOTE_SHOW_CREATE=%d",
5479 (opt_quoted || opt_keywords));
5482 result_table= quote_name(table, table_buff, 1);
5483 opt_quoted_table= quote_name(table, table_buff2, 0);
5485 if (switch_character_set_results(mysql,
"binary"))
5488 my_snprintf(query,
sizeof(query),
"SHOW CREATE TABLE %s", result_table);
5490 if (mysql_query_with_error_report(mysql, &table_res, query))
5492 switch_character_set_results(mysql, default_charset);
5497 field= mysql_fetch_field_direct(table_res, 0);
5498 if (strcmp(field->name,
"View") != 0)
5500 switch_character_set_results(mysql, default_charset);
5501 verbose_msg(
"-- It's base table, skipped\n");
5508 if (!(sql_file= open_sql_file_for_table(table, O_WRONLY)))
5511 write_header(sql_file, db);
5514 print_comment(sql_file, 0,
5515 "\n--\n-- Final view structure for view %s\n--\n\n",
5519 fprintf(sql_file,
"/*!50001 DROP TABLE IF EXISTS %s*/;\n", opt_quoted_table);
5522 fprintf(sql_file,
"/*!50001 DROP VIEW IF EXISTS %s*/;\n",
5528 my_snprintf(query,
sizeof(query),
5529 "SELECT CHECK_OPTION, DEFINER, SECURITY_TYPE, "
5530 " CHARACTER_SET_CLIENT, COLLATION_CONNECTION "
5531 "FROM information_schema.views "
5532 "WHERE table_name=\"%s\" AND table_schema=\"%s\"", table, db);
5534 if (mysql_query(mysql, query))
5540 row= mysql_fetch_row(table_res);
5541 fprintf(sql_file,
"/*!50001 %s */;\n", row[1]);
5543 mysql_free_result(table_res);
5549 char search_buf[256], replace_buf[256];
5550 ulong search_len, replace_len;
5554 row= mysql_fetch_row(table_res);
5555 lengths= mysql_fetch_lengths(table_res);
5556 init_dynamic_string_checked(&ds_view, row[1], lengths[1] + 1, 1024);
5557 mysql_free_result(table_res);
5560 if (!(table_res= mysql_store_result(mysql)) ||
5561 !(row= mysql_fetch_row(table_res)))
5564 mysql_free_result(table_res);
5565 dynstr_free(&ds_view);
5566 DB_error(mysql,
"when trying to save the result of SHOW CREATE TABLE in ds_view.");
5570 lengths= mysql_fetch_lengths(table_res);
5576 if (strcmp(row[0],
"NONE"))
5580 search_len= (ulong)(strxmov(ptr,
"WITH ", row[0],
5581 " CHECK OPTION", NullS) - ptr);
5583 replace_len=(ulong)(strxmov(ptr,
"*/\n/*!50002 WITH ", row[0],
5584 " CHECK OPTION", NullS) - ptr);
5585 replace(&ds_view, search_buf, search_len, replace_buf, replace_len);
5593 size_t user_name_len;
5594 char user_name_str[USERNAME_LENGTH + 1];
5595 char quoted_user_name_str[USERNAME_LENGTH * 2 + 3];
5596 size_t host_name_len;
5597 char host_name_str[HOSTNAME_LENGTH + 1];
5598 char quoted_host_name_str[HOSTNAME_LENGTH * 2 + 3];
5600 parse_user(row[1], lengths[1], user_name_str, &user_name_len,
5601 host_name_str, &host_name_len);
5605 (ulong)(strxmov(ptr,
"DEFINER=",
5606 quote_name(user_name_str, quoted_user_name_str, FALSE),
5608 quote_name(host_name_str, quoted_host_name_str, FALSE),
5609 " SQL SECURITY ", row[2], NullS) - ptr);
5612 (ulong)(strxmov(ptr,
"*/\n/*!50013 DEFINER=",
5613 quote_name(user_name_str, quoted_user_name_str, FALSE),
5615 quote_name(host_name_str, quoted_host_name_str, FALSE),
5616 " SQL SECURITY ", row[2],
5617 " */\n/*!50001", NullS) - ptr);
5618 replace(&ds_view, search_buf, search_len, replace_buf, replace_len);
5624 "/*!50001 SET @saved_cs_client = @@character_set_client */;\n"
5625 "/*!50001 SET @saved_cs_results = @@character_set_results */;\n"
5626 "/*!50001 SET @saved_col_connection = @@collation_connection */;\n"
5627 "/*!50001 SET character_set_client = %s */;\n"
5628 "/*!50001 SET character_set_results = %s */;\n"
5629 "/*!50001 SET collation_connection = %s */;\n"
5631 "/*!50001 SET character_set_client = @saved_cs_client */;\n"
5632 "/*!50001 SET character_set_results = @saved_cs_results */;\n"
5633 "/*!50001 SET collation_connection = @saved_col_connection */;\n",
5634 (
const char *) row[3],
5635 (
const char *) row[3],
5636 (
const char *) row[4],
5637 (
const char *) ds_view.str);
5640 mysql_free_result(table_res);
5641 dynstr_free(&ds_view);
5644 if (switch_character_set_results(mysql, default_charset))
5648 if (sql_file != md_result_file)
5650 fputs(
"\n", sql_file);
5651 write_footer(sql_file);
5652 my_fclose(sql_file, MYF(MY_WME));
5662 #define DYNAMIC_STR_ERROR_MSG "Couldn't perform DYNAMIC_STRING operation"
5664 static void init_dynamic_string_checked(
DYNAMIC_STRING *str,
const char *init_str,
5665 uint init_alloc, uint alloc_increment)
5667 if (init_dynamic_string(str, init_str, init_alloc, alloc_increment))
5668 die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
5671 static void dynstr_append_checked(
DYNAMIC_STRING* dest,
const char* src)
5673 if (dynstr_append(dest, src))
5674 die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
5677 static void dynstr_set_checked(
DYNAMIC_STRING *str,
const char *init_str)
5679 if (dynstr_set(str, init_str))
5680 die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
5683 static void dynstr_append_mem_checked(
DYNAMIC_STRING *str,
const char *append,
5686 if (dynstr_append_mem(str, append, length))
5687 die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
5690 static void dynstr_realloc_checked(
DYNAMIC_STRING *str, ulong additional_size)
5692 if (dynstr_realloc(str, additional_size))
5693 die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
5697 int main(
int argc,
char **argv)
5699 char bin_log_name[FN_REFLEN];
5701 MY_INIT(
"mysqldump");
5703 compatible_mode_normal_str[0]= 0;
5704 default_charset= (
char *)mysql_universal_client_charset;
5705 memset(&ignore_table, 0,
sizeof(ignore_table));
5707 exit_code= get_options(&argc, &argv);
5717 if (opt_xml && !opt_comments_used)
5722 if(!(stderror_file= freopen(log_error_file,
"a+", stderr)))
5729 if (connect_to_db(current_host, current_user, opt_password))
5735 write_header(md_result_file, *argv);
5737 if (opt_slave_data && do_stop_slave_sql(mysql))
5740 if ((opt_lock_all_tables || opt_master_data ||
5741 (opt_single_transaction && flush_logs)) &&
5742 do_flush_tables_read_lock(mysql))
5749 if (opt_lock_all_tables || opt_master_data ||
5750 (opt_single_transaction && flush_logs) ||
5751 opt_delete_master_logs)
5753 if (flush_logs || opt_delete_master_logs)
5755 if (mysql_refresh(mysql, REFRESH_LOG))
5757 verbose_msg(
"-- main : logs flushed successfully!\n");
5764 if (opt_delete_master_logs)
5766 if (get_bin_log_name(mysql, bin_log_name,
sizeof(bin_log_name)))
5770 if (opt_single_transaction && start_transaction(mysql))
5774 if (opt_slave_apply && add_stop_slave())
5779 if (process_set_gtid_purged(mysql))
5783 if (opt_master_data && do_show_master_status(mysql))
5785 if (opt_slave_data && do_show_slave_status(mysql))
5787 if (opt_single_transaction && do_unlock_tables(mysql))
5791 dump_all_tablespaces();
5795 if (!opt_alltspcs && !opt_notspcs)
5796 dump_all_tablespaces();
5797 dump_all_databases();
5799 else if (argc > 1 && !opt_databases)
5802 if (!opt_alltspcs && !opt_notspcs)
5803 dump_tablespaces_for_tables(*argv, (argv + 1), (argc -1));
5804 dump_selected_tables(*argv, (argv + 1), (argc - 1));
5809 if (!opt_alltspcs && !opt_notspcs)
5810 dump_tablespaces_for_databases(argv);
5811 dump_databases(argv);
5815 if (opt_slave_data && do_start_slave_sql(mysql))
5822 set_session_binlog(TRUE);
5825 if (opt_slave_apply && add_slave_statements())
5829 if (md_result_file && fflush(md_result_file))
5832 first_error= EX_MYSQLERR;
5836 if (opt_delete_master_logs && purge_bin_logs_to(mysql, bin_log_name))
5840 my_free(shared_memory_base_name);
5849 dbDisconnect(current_host);
5851 write_footer(md_result_file);
5855 fclose(stderror_file);
5857 return(first_error);