1
/* Copyright (C) 2000 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
/* mysqldump.c - Dump a tables contents and format to an ASCII file
18
** The author's original notes follow :-
20
** AUTHOR: Igor Romanenko (igor@frog.kiev.ua)
21
** DATE: December 3, 1994
22
** WARRANTY: None, expressed, impressed, implied
24
** STATUS: Public domain
25
** Adapted and optimized for MySQL by
26
** Michael Widenius, Sinisa Milivojevic, Jani Tolonen
27
** -w --where added 9/10/98 by Jim Faucette
28
** slave code by David Saez Padros <david@ols.es>
29
** master/autocommit code by Brian Aker <brian@tangent.org>
31
** Andrei Errapart <andreie@no.spam.ee>
32
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
33
** XML by Gary Huntress <ghuntress@mediaone.net> 10/10/01, cleaned up
34
** and adapted to mysqldump 05/11/01 by Jani Tolonen
35
** Added --single-transaction option 06/06/2002 by Peter Zaitsev
36
** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov
39
#define DUMP_VERSION "10.13"
41
#include <my_global.h>
49
#include "client_priv.h"
51
#include "mysql_version.h"
52
#include "mysqld_error.h"
58
#define EX_CONSCHECK 3
60
#define EX_EOF 5 /* ferror for output file was got */
61
#define EX_ILLEGAL_TABLE 6
63
/* index into 'show fields from table' */
65
#define SHOW_FIELDNAME 0
68
#define SHOW_DEFAULT 4
71
/* Size of buffer for dump's select query */
72
#define QUERY_LENGTH 1536
74
/* ignore table flags */
75
#define IGNORE_NONE 0x00 /* no ignore */
76
#define IGNORE_DATA 0x01 /* don't dump data for this table */
77
#define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */
79
static void add_load_option(DYNAMIC_STRING *str, const char *option,
80
const char *option_value);
81
static ulong find_set(TYPELIB *lib, const char *x, uint length,
82
char **err_pos, uint *err_len);
83
static char *alloc_query_str(ulong size);
85
static void field_escape(DYNAMIC_STRING* in, const char *from);
86
static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
87
quick= 1, extended_insert= 1,
88
lock_tables=1,ignore_errors=0,flush_logs=0,flush_privileges=0,
89
opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0,
90
opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0,
91
opt_alldbs=0,opt_create_db=0,opt_lock_all_tables=0,
92
opt_set_charset=0, opt_dump_date=1,
93
opt_autocommit=0,opt_disable_keys=1,opt_xml=0,
94
opt_delete_master_logs=0, tty_password=0,
95
opt_single_transaction=0, opt_comments= 0, opt_compact= 0,
96
opt_hex_blob=0, opt_order_by_primary=0, opt_ignore=0,
97
opt_complete_insert= 0, opt_drop_database= 0,
99
opt_routines=0, opt_tz_utc=1,
101
opt_include_master_host_port= 0,
103
opt_alltspcs=0, opt_notspcs= 0;
104
static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
105
static ulong opt_max_allowed_packet, opt_net_buffer_length;
106
static MYSQL mysql_connection,*mysql=0;
107
static DYNAMIC_STRING insert_pat;
108
static char *opt_password=0,*current_user=0,
109
*current_host=0,*path=0,*fields_terminated=0,
110
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
111
*where=0, *order_by=0,
112
*opt_compatible_mode_str= 0,
114
*log_error_file= NULL;
115
static char **defaults_argv= 0;
116
static char compatible_mode_normal_str[255];
117
/* Server supports character_set_results session variable? */
118
static my_bool server_supports_switching_charsets= TRUE;
119
static ulong opt_compatible_mode= 0;
120
#define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
121
#define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
122
#define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
123
#define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2
124
static uint opt_mysql_port= 0, opt_master_data;
125
static uint opt_slave_data;
126
static uint my_end_arg;
127
static char * opt_mysql_unix_port=0;
128
static int first_error=0;
129
static DYNAMIC_STRING extended_row;
130
FILE *md_result_file= 0;
131
FILE *stderror_file=0;
134
static char *shared_memory_base_name=0;
136
static uint opt_protocol= 0;
139
Dynamic_string wrapper functions. In this file use these
140
wrappers, they will terminate the process if there is
141
an allocation failure.
143
static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str,
144
uint init_alloc, uint alloc_increment);
145
static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src);
146
static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str);
147
static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append,
149
static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size);
151
Constant for detection of default value of default_charset.
152
If default_charset is equal to mysql_universal_client_charset, then
153
it is the default value which assigned at the very beginning of main().
155
static const char *mysql_universal_client_charset=
156
MYSQL_UNIVERSAL_CLIENT_CHARSET;
157
static char *default_charset;
158
static CHARSET_INFO *charset_info= &my_charset_latin1;
159
const char *default_dbug_option="d:t:o,/tmp/mysqldump.trace";
160
/* have we seen any VIEWs during table scanning? */
161
my_bool seen_views= 0;
162
const char *compatible_mode_names[]=
164
"MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2",
165
"MAXDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS",
169
#define MASK_ANSI_QUOTES \
171
(1<<2) | /* POSTGRESQL */\
172
(1<<3) | /* ORACLE */\
173
(1<<4) | /* MSSQL */\
175
(1<<6) | /* MAXDB */\
178
TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
179
"", compatible_mode_names, NULL};
183
static struct my_option my_long_options[] =
185
{"all", 'a', "Deprecated. Use --create-options instead.",
186
(uchar**) &create_options, (uchar**) &create_options, 0, GET_BOOL, NO_ARG, 1,
188
{"all-databases", 'A',
189
"Dump all the databases. This will be same as --databases with all databases selected.",
190
(uchar**) &opt_alldbs, (uchar**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
192
{"all-tablespaces", 'Y',
193
"Dump all the tablespaces.",
194
(uchar**) &opt_alltspcs, (uchar**) &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
196
{"no-tablespaces", 'y',
197
"Do not dump any tablespace information.",
198
(uchar**) &opt_notspcs, (uchar**) &opt_notspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
200
{"add-drop-database", OPT_DROP_DATABASE, "Add a 'DROP DATABASE' before each create.",
201
(uchar**) &opt_drop_database, (uchar**) &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
203
{"add-drop-table", OPT_DROP, "Add a 'drop table' before each create.",
204
(uchar**) &opt_drop, (uchar**) &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
206
{"add-locks", OPT_LOCKS, "Add locks around insert statements.",
207
(uchar**) &opt_lock, (uchar**) &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
209
{"allow-keywords", OPT_KEYWORDS,
210
"Allow creation of column names that are keywords.", (uchar**) &opt_keywords,
211
(uchar**) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
212
{"apply-slave-statements", OPT_MYSQLDUMP_SLAVE_APPLY,
213
"Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
214
(uchar**) &opt_slave_apply, (uchar**) &opt_slave_apply, 0, GET_BOOL, NO_ARG,
217
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
218
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
220
{"character-sets-dir", OPT_CHARSETS_DIR,
221
"Directory where character sets are.", (uchar**) &charsets_dir,
222
(uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
223
{"comments", 'i', "Write additional information.",
224
(uchar**) &opt_comments, (uchar**) &opt_comments, 0, GET_BOOL, NO_ARG,
226
{"compatible", OPT_COMPATIBLE,
227
"Change the dump to be compatible with a given mode. By default tables are dumped in a format optimized for MySQL. Legal modes are: ansi, mysql323, mysql40, postgresql, oracle, mssql, db2, maxdb, no_key_options, no_table_options, no_field_options. One can use several modes separated by commas. Note: Requires MySQL server version 4.1.0 or higher. This option is ignored with earlier server versions.",
228
(uchar**) &opt_compatible_mode_str, (uchar**) &opt_compatible_mode_str, 0,
229
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
230
{"compact", OPT_COMPACT,
231
"Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables options --skip-add-drop-table --no-set-names --skip-disable-keys --skip-add-locks",
232
(uchar**) &opt_compact, (uchar**) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
234
{"complete-insert", 'c', "Use complete insert statements.",
235
(uchar**) &opt_complete_insert, (uchar**) &opt_complete_insert, 0, GET_BOOL,
236
NO_ARG, 0, 0, 0, 0, 0, 0},
237
{"compress", 'C', "Use compression in server/client protocol.",
238
(uchar**) &opt_compress, (uchar**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
240
{"create-options", OPT_CREATE_OPTIONS,
241
"Include all MySQL specific create options.",
242
(uchar**) &create_options, (uchar**) &create_options, 0, GET_BOOL, NO_ARG, 1,
245
"To dump several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames. 'USE db_name;' will be included in the output.",
246
(uchar**) &opt_databases, (uchar**) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
249
{"debug", '#', "This is a non-debug version. Catch this and exit",
250
0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
252
{"debug", '#', "Output debug log", (uchar**) &default_dbug_option,
253
(uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
255
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
256
(uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0,
257
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
258
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
259
(uchar**) &debug_info_flag, (uchar**) &debug_info_flag,
260
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
261
{"default-character-set", OPT_DEFAULT_CHARSET,
262
"Set the default character set.", (uchar**) &default_charset,
263
(uchar**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
264
{"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED; ",
265
(uchar**) &opt_delayed, (uchar**) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
267
{"delete-master-logs", OPT_DELETE_MASTER_LOGS,
268
"Delete logs on master after backup. This automatically enables --master-data.",
269
(uchar**) &opt_delete_master_logs, (uchar**) &opt_delete_master_logs, 0,
270
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
271
{"disable-keys", 'K',
272
"'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (uchar**) &opt_disable_keys,
273
(uchar**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
274
{"dump-slave", OPT_MYSQLDUMP_SLAVE_DATA,
275
"This causes the binary log position and filename of the master to be "
276
"appended to the dumped data output. Setting the value to 1, will print"
277
"it as a CHANGE MASTER command in the dumped data output; if equal"
278
" to 2, that command will be prefixed with a comment symbol. "
279
"This option will turn --lock-all-tables on, unless "
280
"--single-transaction is specified too (in which case a "
281
"global read lock is only taken a short time at the beginning of the dump "
282
"- don't forget to read about --single-transaction below). In all cases "
283
"any action on logs will happen at the exact moment of the dump."
284
"Option automatically turns --lock-tables off.",
285
(uchar**) &opt_slave_data, (uchar**) &opt_slave_data, 0,
286
GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
287
{"events", 'E', "Dump events.",
288
(uchar**) &opt_events, (uchar**) &opt_events, 0, GET_BOOL,
289
NO_ARG, 0, 0, 0, 0, 0, 0},
290
{"extended-insert", 'e',
291
"Allows utilization of the new, much faster INSERT syntax.",
292
(uchar**) &extended_insert, (uchar**) &extended_insert, 0, GET_BOOL, NO_ARG,
294
{"fields-terminated-by", OPT_FTB,
295
"Fields in the textfile are terminated by ...", (uchar**) &fields_terminated,
296
(uchar**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
297
{"fields-enclosed-by", OPT_ENC,
298
"Fields in the importfile are enclosed by ...", (uchar**) &enclosed,
299
(uchar**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
300
{"fields-optionally-enclosed-by", OPT_O_ENC,
301
"Fields in the i.file are opt. enclosed by ...", (uchar**) &opt_enclosed,
302
(uchar**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
303
{"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
304
(uchar**) &escaped, (uchar**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
305
{"first-slave", 'x', "Deprecated, renamed to --lock-all-tables.",
306
(uchar**) &opt_lock_all_tables, (uchar**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
308
{"flush-logs", 'F', "Flush logs file in server before starting dump. "
309
"Note that if you dump many databases at once (using the option "
310
"--databases= or --all-databases), the logs will be flushed for "
311
"each database dumped. The exception is when using --lock-all-tables "
313
"in this case the logs will be flushed only once, corresponding "
314
"to the moment all tables are locked. So if you want your dump and "
315
"the log flush to happen at the same exact moment you should use "
316
"--lock-all-tables or --master-data with --flush-logs",
317
(uchar**) &flush_logs, (uchar**) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
319
{"flush-privileges", OPT_ESC, "Emit a FLUSH PRIVILEGES statement "
320
"after dumping the mysql database. This option should be used any "
321
"time the dump contains the mysql database and any other database "
322
"that depends on the data in the mysql database for proper restore. ",
323
(uchar**) &flush_privileges, (uchar**) &flush_privileges, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
325
{"force", 'f', "Continue even if we get an sql-error.",
326
(uchar**) &ignore_errors, (uchar**) &ignore_errors, 0, GET_BOOL, NO_ARG,
328
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
329
NO_ARG, 0, 0, 0, 0, 0, 0},
330
{"hex-blob", OPT_HEXBLOB, "Dump binary strings (BINARY, "
331
"VARBINARY, BLOB) in hexadecimal format.",
332
(uchar**) &opt_hex_blob, (uchar**) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
333
{"host", 'h', "Connect to host.", (uchar**) ¤t_host,
334
(uchar**) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
335
{"ignore-table", OPT_IGNORE_TABLE,
336
"Do not dump the specified table. To specify more than one table to ignore, "
337
"use the directive multiple times, once for each table. Each table must "
338
"be specified with both database and table names, e.g. --ignore-table=database.table",
339
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
340
{"include-master-host-port", OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT,
341
"Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' in dump produced with --dump-slave.",
342
(uchar**) &opt_include_master_host_port,
343
(uchar**) &opt_include_master_host_port,
346
{"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
347
(uchar**) &opt_ignore, (uchar**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
349
{"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
350
(uchar**) &lines_terminated, (uchar**) &lines_terminated, 0, GET_STR,
351
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
352
{"lock-all-tables", 'x', "Locks all tables across all databases. This "
353
"is achieved by taking a global read lock for the duration of the whole "
354
"dump. Automatically turns --single-transaction and --lock-tables off.",
355
(uchar**) &opt_lock_all_tables, (uchar**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
357
{"lock-tables", 'l', "Lock all tables for read.", (uchar**) &lock_tables,
358
(uchar**) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
359
{"log-error", OPT_ERROR_LOG_FILE, "Append warnings and errors to given file.",
360
(uchar**) &log_error_file, (uchar**) &log_error_file, 0, GET_STR,
361
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
362
{"master-data", OPT_MASTER_DATA,
363
"This causes the binary log position and filename to be appended to the "
364
"output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
365
" to 2, that command will be prefixed with a comment symbol. "
366
"This option will turn --lock-all-tables on, unless "
367
"--single-transaction is specified too (in which case a "
368
"global read lock is only taken a short time at the beginning of the dump "
369
"- don't forget to read about --single-transaction below). In all cases "
370
"any action on logs will happen at the exact moment of the dump."
371
"Option automatically turns --lock-tables off.",
372
(uchar**) &opt_master_data, (uchar**) &opt_master_data, 0,
373
GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_MASTER_DATA_COMMENTED_SQL, 0, 0, 0},
374
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "",
375
(uchar**) &opt_max_allowed_packet, (uchar**) &opt_max_allowed_packet, 0,
376
GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096,
377
(longlong) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
378
{"net_buffer_length", OPT_NET_BUFFER_LENGTH, "",
379
(uchar**) &opt_net_buffer_length, (uchar**) &opt_net_buffer_length, 0,
380
GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L,
381
MALLOC_OVERHEAD-1024, 1024, 0},
382
{"no-autocommit", OPT_AUTOCOMMIT,
383
"Wrap tables with autocommit/commit statements.",
384
(uchar**) &opt_autocommit, (uchar**) &opt_autocommit, 0, GET_BOOL, NO_ARG,
386
{"no-create-db", 'n',
387
"'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.}.",
388
(uchar**) &opt_create_db, (uchar**) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
390
{"no-create-info", 't', "Don't write table creation info.",
391
(uchar**) &opt_no_create_info, (uchar**) &opt_no_create_info, 0, GET_BOOL,
392
NO_ARG, 0, 0, 0, 0, 0, 0},
393
{"no-data", 'd', "No row information.", (uchar**) &opt_no_data,
394
(uchar**) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
395
{"no-set-names", 'N',
396
"Deprecated. Use --skip-set-charset instead.",
397
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
398
{"opt", OPT_OPTIMIZE,
399
"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.",
400
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
401
{"order-by-primary", OPT_ORDER_BY_PRIMARY,
402
"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.",
403
(uchar**) &opt_order_by_primary, (uchar**) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
405
"Password to use when connecting to server. If password is not given it's solicited on the tty.",
406
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
408
{"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
409
NO_ARG, 0, 0, 0, 0, 0, 0},
411
{"port", 'P', "Port number to use for connection.", (uchar**) &opt_mysql_port,
412
(uchar**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
414
{"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
415
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
416
{"quick", 'q', "Don't buffer query, dump directly to stdout.",
417
(uchar**) &quick, (uchar**) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
418
{"quote-names",'Q', "Quote table and column names with backticks (`).",
419
(uchar**) &opt_quoted, (uchar**) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
421
{"replace", OPT_MYSQL_REPLACE_INTO, "Use REPLACE INTO instead of INSERT INTO.",
422
(uchar**) &opt_replace_into, (uchar**) &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
425
"Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).",
426
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
427
{"routines", 'R', "Dump stored routines (functions and procedures).",
428
(uchar**) &opt_routines, (uchar**) &opt_routines, 0, GET_BOOL,
429
NO_ARG, 0, 0, 0, 0, 0, 0},
430
{"set-charset", OPT_SET_CHARSET,
431
"Add 'SET NAMES default_character_set' to the output.",
432
(uchar**) &opt_set_charset, (uchar**) &opt_set_charset, 0, GET_BOOL, NO_ARG, 1,
434
{"set-variable", 'O',
435
"Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
436
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
438
{"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
439
"Base name of shared memory.", (uchar**) &shared_memory_base_name, (uchar**) &shared_memory_base_name,
440
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
443
Note that the combination --single-transaction --master-data
444
will give bullet-proof binlog position only if server >=4.1.3. That's the
445
old "FLUSH TABLES WITH READ LOCK does not block commit" fixed bug.
447
{"single-transaction", OPT_TRANSACTION,
448
"Creates a consistent snapshot by dumping all tables in a single "
449
"transaction. Works ONLY for tables stored in storage engines which "
450
"support multiversioning (currently only InnoDB does); the dump is NOT "
451
"guaranteed to be consistent for other storage engines. "
452
"While a --single-transaction dump is in process, to ensure a valid "
453
"dump file (correct table contents and binary log position), no other "
454
"connection should use the following statements: ALTER TABLE, DROP "
455
"TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not "
456
"isolated from them. Option automatically turns off --lock-tables.",
457
(uchar**) &opt_single_transaction, (uchar**) &opt_single_transaction, 0,
458
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
459
{"dump-date", OPT_DUMP_DATE, "Put a dump date to the end of the output.",
460
(uchar**) &opt_dump_date, (uchar**) &opt_dump_date, 0,
461
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
462
{"skip-opt", OPT_SKIP_OPTIMIZATION,
463
"Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.",
464
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
465
{"socket", 'S', "Socket file to use for connection.",
466
(uchar**) &opt_mysql_unix_port, (uchar**) &opt_mysql_unix_port, 0, GET_STR,
467
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
469
"Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if mysqldump is run on the same machine as the mysqld daemon.",
470
(uchar**) &path, (uchar**) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
471
{"tables", OPT_TABLES, "Overrides option --databases (-B).",
472
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
473
{"tz-utc", OPT_TZ_UTC,
474
"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.",
475
(uchar**) &opt_tz_utc, (uchar**) &opt_tz_utc, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
476
#ifndef DONT_ALLOW_USER_CHANGE
477
{"user", 'u', "User for login if not current user.",
478
(uchar**) ¤t_user, (uchar**) ¤t_user, 0, GET_STR, REQUIRED_ARG,
481
{"verbose", 'v', "Print info about the various stages.",
482
(uchar**) &verbose, (uchar**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
483
{"version",'V', "Output version information and exit.", 0, 0, 0,
484
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
485
{"where", 'w', "Dump only selected records; QUOTES mandatory!",
486
(uchar**) &where, (uchar**) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
487
{"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
488
NO_ARG, 0, 0, 0, 0, 0, 0},
489
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
492
static const char *load_default_groups[]= { "mysqldump","client",0 };
494
static void maybe_exit(int error);
495
static void die(int error, const char* reason, ...);
496
static void maybe_die(int error, const char* reason, ...);
497
static void write_header(FILE *sql_file, char *db_name);
498
static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
499
const char *prefix,const char *name,
501
static int dump_selected_tables(char *db, char **table_names, int tables);
502
static int dump_all_tables_in_db(char *db);
503
static int init_dumping_views(char *);
504
static int init_dumping_tables(char *);
505
static int init_dumping(char *, int init_func(char*));
506
static int dump_databases(char **);
507
static int dump_all_databases();
508
static char *quote_name(const char *name, char *buff, my_bool force);
509
char check_if_ignore_table(const char *table_name, char *table_type);
510
static char *primary_key_fields(const char *table_name);
511
static my_bool get_view_structure(char *table, char* db);
512
static my_bool dump_all_views_in_db(char *database);
513
static int dump_all_tablespaces();
514
static int dump_tablespaces_for_tables(char *db, char **table_names, int tables);
515
static int dump_tablespaces_for_databases(char** databases);
516
static int dump_tablespaces(char* ts_where);
518
#include <help_start.h>
521
Print the supplied message if in verbose mode
526
... variable number of parameters
529
static void verbose_msg(const char *fmt, ...)
532
DBUG_ENTER("verbose_msg");
538
vfprintf(stderr, fmt, args);
545
exit with message if ferror(file)
552
void check_io(FILE *file)
555
die(EX_EOF, "Got errno %d on write", errno);
558
static void print_version(void)
560
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,DUMP_VERSION,
561
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
562
NETWARE_SET_SCREEN_MODE(1);
563
} /* print_version */
566
static void short_usage_sub(void)
568
printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
569
printf("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n",
571
printf("OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname);
572
NETWARE_SET_SCREEN_MODE(1);
576
static void usage(void)
579
puts("By Igor Romanenko, Monty, Jani & Sinisa");
580
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
581
puts("Dumping definition and data mysql database or table");
583
print_defaults("my",load_default_groups);
584
my_print_help(my_long_options);
585
my_print_variables(my_long_options);
589
static void short_usage(void)
592
printf("For more options, use %s --help\n", my_progname);
595
#include <help_end.h>
598
static void write_header(FILE *sql_file, char *db_name)
602
fputs("<?xml version=\"1.0\"?>\n", sql_file);
604
Schema reference. Allows use of xsi:nil for NULL values and
605
xsi:type to define an element's data type.
607
fputs("<mysqldump ", sql_file);
608
fputs("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"",
610
fputs(">\n", sql_file);
613
else if (!opt_compact)
618
"-- MySQL dump %s Distrib %s, for %s (%s)\n--\n",
619
DUMP_VERSION, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
620
fprintf(sql_file, "-- Host: %s Database: %s\n",
621
current_host ? current_host : "localhost", db_name ? db_name :
623
fputs("-- ------------------------------------------------------\n",
625
fprintf(sql_file, "-- Server version\t%s\n",
626
mysql_get_server_info(&mysql_connection));
630
"\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;"
631
"\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;"
632
"\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;"
633
"\n/*!40101 SET NAMES %s */;\n",default_charset);
637
fprintf(sql_file, "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;\n");
638
fprintf(sql_file, "/*!40103 SET TIME_ZONE='+00:00' */;\n");
643
fprintf(md_result_file,"\
644
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n\
645
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;\n\
653
static void write_footer(FILE *sql_file)
657
fputs("</mysqldump>\n", sql_file);
660
else if (!opt_compact)
663
fprintf(sql_file,"/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;\n");
667
fprintf(md_result_file,"\
668
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n\
669
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;\n");
673
"/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n"
674
"/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n"
675
"/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
677
"/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\n");
678
fputs("\n", sql_file);
684
get_date(time_str, GETDATE_DATE_TIME, 0);
685
fprintf(sql_file, "-- Dump completed on %s\n",
689
fprintf(sql_file, "-- Dump completed\n");
696
static void free_table_ent(char *key)
698
my_free(key, MYF(0));
702
uchar* get_table_key(const char *entry, size_t *length,
703
my_bool not_used __attribute__((unused)))
705
*length= strlen(entry);
706
return (uchar*) entry;
711
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
717
setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
723
char *start=argument;
724
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
725
opt_password=my_strdup(argument,MYF(MY_FAE));
726
while (*argument) *argument++= 'x'; /* Destroy argument */
728
start[1]=0; /* Cut length of argument */
735
if (!(md_result_file= my_fopen(argument, O_WRONLY | FILE_BINARY,
741
opt_protocol= MYSQL_PROTOCOL_PIPE;
750
if (strlen(argument) >= FN_REFLEN)
753
This check is made because the some the file functions below
754
have FN_REFLEN sized stack allocated buffers and will cause
755
a crash even if the input destination buffer is large enough
758
die(EX_USAGE, "Input filename too long: %s", argument);
763
DBUG_PUSH(argument ? argument : default_dbug_option);
766
case 'V': print_version(); exit(0);
769
extended_insert= opt_drop= opt_lock=
770
opt_disable_keys= opt_autocommit= opt_create_db= 0;
776
case (int) OPT_MASTER_DATA:
777
if (!argument) /* work like in old versions */
778
opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL;
780
case (int) OPT_MYSQLDUMP_SLAVE_DATA:
781
if (!argument) /* work like in old versions */
782
opt_slave_data= MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL;
784
case (int) OPT_OPTIMIZE:
785
extended_insert= opt_drop= opt_lock= quick= create_options=
786
opt_disable_keys= lock_tables= opt_set_charset= 1;
788
case (int) OPT_SKIP_OPTIMIZATION:
789
extended_insert= opt_drop= opt_lock= quick= create_options=
790
opt_disable_keys= lock_tables= opt_set_charset= 0;
792
case (int) OPT_COMPACT:
795
opt_comments= opt_drop= opt_disable_keys= opt_lock= 0;
798
case (int) OPT_TABLES:
801
case (int) OPT_IGNORE_TABLE:
803
if (!strchr(argument, '.'))
805
fprintf(stderr, "Illegal use of option --ignore-table=<database>.<table>\n");
808
if (my_hash_insert(&ignore_table, (uchar*)my_strdup(argument, MYF(0))))
812
case (int) OPT_COMPATIBLE:
815
char *end= compatible_mode_normal_str;
822
opt_compatible_mode_str= argument;
823
opt_compatible_mode= find_set(&compatible_mode_typelib,
824
argument, strlen(argument),
828
strmake(buff, err_ptr, min(sizeof(buff), err_len));
829
fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
832
#if !defined(DBUG_OFF)
834
uint size_for_sql_mode= 0;
836
for (ptr= compatible_mode_names; *ptr; ptr++)
837
size_for_sql_mode+= strlen(*ptr);
838
size_for_sql_mode+= sizeof(compatible_mode_names)-1;
839
DBUG_ASSERT(sizeof(compatible_mode_normal_str)>=size_for_sql_mode);
842
mode= opt_compatible_mode;
843
for (i= 0, mode= opt_compatible_mode; mode; mode>>= 1, i++)
847
end= strmov(end, compatible_mode_names[i]);
848
end= strmov(end, ",");
851
if (end!=compatible_mode_normal_str)
854
Set charset to the default compiled value if it hasn't
855
been reset yet by --default-character-set=xxx.
857
if (default_charset == mysql_universal_client_charset)
858
default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
861
case (int) OPT_MYSQL_PROTOCOL:
862
opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
869
static int get_options(int *argc, char ***argv)
872
MYSQL_PARAMETERS *mysql_params= mysql_get_parameters();
874
opt_max_allowed_packet= *mysql_params->p_max_allowed_packet;
875
opt_net_buffer_length= *mysql_params->p_net_buffer_length;
877
md_result_file= stdout;
878
load_defaults("my",load_default_groups,argc,argv);
879
defaults_argv= *argv;
881
if (hash_init(&ignore_table, charset_info, 16, 0, 0,
882
(hash_get_key) get_table_key,
883
(hash_free_key) free_table_ent, 0))
885
/* Don't copy internal log tables */
886
if (my_hash_insert(&ignore_table,
887
(uchar*) my_strdup("mysql.apply_status", MYF(MY_WME))) ||
888
my_hash_insert(&ignore_table,
889
(uchar*) my_strdup("mysql.schema", MYF(MY_WME))) ||
890
my_hash_insert(&ignore_table,
891
(uchar*) my_strdup("mysql.general_log", MYF(MY_WME))) ||
892
my_hash_insert(&ignore_table,
893
(uchar*) my_strdup("mysql.slow_log", MYF(MY_WME))) ||
894
my_hash_insert(&ignore_table,
895
(uchar*) my_strdup("mysql.online_backup", MYF(MY_WME))) ||
896
my_hash_insert(&ignore_table,
897
(uchar*) my_strdup("mysql.online_backup_progress", MYF(MY_WME))))
900
if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
903
*mysql_params->p_max_allowed_packet= opt_max_allowed_packet;
904
*mysql_params->p_net_buffer_length= opt_net_buffer_length;
906
my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
907
if (debug_check_flag)
908
my_end_arg= MY_CHECK_ERROR;
911
opt_lock=0; /* Can't have lock with delayed */
912
if (!path && (enclosed || opt_enclosed || escaped || lines_terminated ||
916
"%s: You must use option --tab with --fields-...\n", my_progname);
920
/* We don't delete master logs if slave data option */
923
opt_lock_all_tables= !opt_single_transaction;
925
opt_delete_master_logs= 0;
928
/* Ensure consistency of the set of binlog & locking options */
929
if (opt_delete_master_logs && !opt_master_data)
930
opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL;
931
if (opt_single_transaction && opt_lock_all_tables)
933
fprintf(stderr, "%s: You can't use --single-transaction and "
934
"--lock-all-tables at the same time.\n", my_progname);
939
opt_lock_all_tables= !opt_single_transaction;
942
if (opt_single_transaction || opt_lock_all_tables)
944
if (enclosed && opt_enclosed)
946
fprintf(stderr, "%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n", my_progname);
949
if ((opt_databases || opt_alldbs) && path)
952
"%s: --databases or --all-databases can't be used with --tab.\n",
956
if (strcmp(default_charset, charset_info->csname) &&
957
!(charset_info= get_charset_by_csname(default_charset,
958
MY_CS_PRIMARY, MYF(MY_WME))))
960
if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs))
966
opt_password=get_tty_password(NullS);
972
** DB_error -- prints mysql error message and exits the program.
974
static void DB_error(MYSQL *mysql_arg, const char *when)
976
DBUG_ENTER("DB_error");
977
maybe_die(EX_MYSQLERR, "Got error: %d: %s %s",
978
mysql_errno(mysql_arg), mysql_error(mysql_arg), when);
985
Prints out an error message and kills the process.
989
error_num - process return value
990
fmt_reason - a format string for use by my_vsnprintf.
991
... - variable arguments for above fmt_reason string
994
This call prints out the formatted error message to stderr and then
995
terminates the process.
997
static void die(int error_num, const char* fmt_reason, ...)
1001
va_start(args,fmt_reason);
1002
my_vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
1005
fprintf(stderr, "%s: %s\n", my_progname, buffer);
1008
ignore_errors= 0; /* force the exit */
1009
maybe_exit(error_num);
1014
Prints out an error message and maybe kills the process.
1018
error_num - process return value
1019
fmt_reason - a format string for use by my_vsnprintf.
1020
... - variable arguments for above fmt_reason string
1023
This call prints out the formatted error message to stderr and then
1024
terminates the process, unless the --force command line option is used.
1026
This call should be used for non-fatal errors (such as database
1027
errors) that the code may still be able to continue to the next unit
1031
static void maybe_die(int error_num, const char* fmt_reason, ...)
1035
va_start(args,fmt_reason);
1036
my_vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
1039
fprintf(stderr, "%s: %s\n", my_progname, buffer);
1042
maybe_exit(error_num);
1048
Sends a query to server, optionally reads result, prints error message if
1052
mysql_query_with_error_report()
1053
mysql_con connection to use
1054
res if non zero, result will be put there with
1055
mysql_store_result()
1056
query query to send to server
1059
0 query sending and (if res!=0) result reading went ok
1063
static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res,
1066
if (mysql_query(mysql_con, query) ||
1067
(res && !((*res)= mysql_store_result(mysql_con))))
1069
maybe_die(EX_MYSQLERR, "Couldn't execute '%s': %s (%d)",
1070
query, mysql_error(mysql_con), mysql_errno(mysql_con));
1077
static int fetch_db_collation(const char *db_name,
1081
my_bool err_status= FALSE;
1082
char query[QUERY_LENGTH];
1083
MYSQL_RES *db_cl_res;
1084
MYSQL_ROW db_cl_row;
1085
char quoted_database_buf[NAME_LEN*2+3];
1086
char *qdatabase= quote_name(db_name, quoted_database_buf, 1);
1088
my_snprintf(query, sizeof (query), "use %s", qdatabase);
1090
if (mysql_query_with_error_report(mysql, NULL, query))
1093
if (mysql_query_with_error_report(mysql, &db_cl_res,
1094
"select @@collation_database"))
1099
if (mysql_num_rows(db_cl_res) != 1)
1105
if (!(db_cl_row= mysql_fetch_row(db_cl_res)))
1111
strncpy(db_cl_name, db_cl_row[0], db_cl_size);
1112
db_cl_name[db_cl_size - 1]= 0; /* just in case. */
1116
mysql_free_result(db_cl_res);
1118
return err_status ? 1 : 0;
1122
static char *my_case_str(const char *str,
1129
uint status= my_charset_latin1.coll->instr(&my_charset_latin1,
1134
return status ? (char *) str + match.end : NULL;
1138
static int switch_db_collation(FILE *sql_file,
1139
const char *db_name,
1140
const char *delimiter,
1141
const char *current_db_cl_name,
1142
const char *required_db_cl_name,
1145
if (strcmp(current_db_cl_name, required_db_cl_name) != 0)
1147
CHARSET_INFO *db_cl= get_charset_by_name(required_db_cl_name, MYF(0));
1153
"ALTER DATABASE %s CHARACTER SET %s COLLATE %s %s\n",
1154
(const char *) db_name,
1155
(const char *) db_cl->csname,
1156
(const char *) db_cl->name,
1157
(const char *) delimiter);
1170
static int restore_db_collation(FILE *sql_file,
1171
const char *db_name,
1172
const char *delimiter,
1173
const char *db_cl_name)
1175
CHARSET_INFO *db_cl= get_charset_by_name(db_cl_name, MYF(0));
1181
"ALTER DATABASE %s CHARACTER SET %s COLLATE %s %s\n",
1182
(const char *) db_name,
1183
(const char *) db_cl->csname,
1184
(const char *) db_cl->name,
1185
(const char *) delimiter);
1191
static void switch_cs_variables(FILE *sql_file,
1192
const char *delimiter,
1193
const char *character_set_client,
1194
const char *character_set_results,
1195
const char *collation_connection)
1198
"/*!50003 SET @saved_cs_client = @@character_set_client */ %s\n"
1199
"/*!50003 SET @saved_cs_results = @@character_set_results */ %s\n"
1200
"/*!50003 SET @saved_col_connection = @@collation_connection */ %s\n"
1201
"/*!50003 SET character_set_client = %s */ %s\n"
1202
"/*!50003 SET character_set_results = %s */ %s\n"
1203
"/*!50003 SET collation_connection = %s */ %s\n",
1204
(const char *) delimiter,
1205
(const char *) delimiter,
1206
(const char *) delimiter,
1208
(const char *) character_set_client,
1209
(const char *) delimiter,
1211
(const char *) character_set_results,
1212
(const char *) delimiter,
1214
(const char *) collation_connection,
1215
(const char *) delimiter);
1219
static void restore_cs_variables(FILE *sql_file,
1220
const char *delimiter)
1223
"/*!50003 SET character_set_client = @saved_cs_client */ %s\n"
1224
"/*!50003 SET character_set_results = @saved_cs_results */ %s\n"
1225
"/*!50003 SET collation_connection = @saved_col_connection */ %s\n",
1226
(const char *) delimiter,
1227
(const char *) delimiter,
1228
(const char *) delimiter);
1232
static void switch_sql_mode(FILE *sql_file,
1233
const char *delimiter,
1234
const char *sql_mode)
1237
"/*!50003 SET @saved_sql_mode = @@sql_mode */ %s\n"
1238
"/*!50003 SET sql_mode = '%s' */ %s\n",
1239
(const char *) delimiter,
1241
(const char *) sql_mode,
1242
(const char *) delimiter);
1246
static void restore_sql_mode(FILE *sql_file,
1247
const char *delimiter)
1250
"/*!50003 SET sql_mode = @saved_sql_mode */ %s\n",
1251
(const char *) delimiter);
1255
static void switch_time_zone(FILE *sql_file,
1256
const char *delimiter,
1257
const char *time_zone)
1260
"/*!50003 SET @saved_time_zone = @@time_zone */ %s\n"
1261
"/*!50003 SET time_zone = '%s' */ %s\n",
1262
(const char *) delimiter,
1264
(const char *) time_zone,
1265
(const char *) delimiter);
1269
static void restore_time_zone(FILE *sql_file,
1270
const char *delimiter)
1273
"/*!50003 SET time_zone = @saved_time_zone */ %s\n",
1274
(const char *) delimiter);
1279
Switch charset for results to some specified charset. If the server does not
1280
support character_set_results variable, nothing can be done here. As for
1281
whether something should be done here, future new callers of this function
1282
should be aware that the server lacking the facility of switching charsets is
1285
@note If the server lacks support, then nothing is changed and no error
1286
condition is returned.
1288
@returns whether there was an error or not
1290
static int switch_character_set_results(MYSQL *mysql, const char *cs_name)
1292
char query_buffer[QUERY_LENGTH];
1293
size_t query_length;
1295
/* Server lacks facility. This is not an error, by arbitrary decision . */
1296
if (!server_supports_switching_charsets)
1299
query_length= my_snprintf(query_buffer,
1300
sizeof (query_buffer),
1301
"SET SESSION character_set_results = '%s'",
1302
(const char *) cs_name);
1304
return mysql_real_query(mysql, query_buffer, query_length);
1308
Rewrite CREATE FUNCTION or CREATE PROCEDURE statement, enclosing DEFINER
1309
clause in version-specific comment.
1311
This function parses the CREATE FUNCTION | PROCEDURE statement and
1312
encloses DEFINER-clause in version-specific comment:
1313
input query: CREATE DEFINER=a@b FUNCTION ...
1314
rewritten query: CREATE * / / *!50020 DEFINER=a@b * / / *!50003 FUNCTION ...
1316
@note This function will go away when WL#3995 is implemented.
1318
@param[in] def_str CREATE FUNCTION|PROCEDURE statement string.
1319
@param[in] def_str_length length of the def_str.
1321
@return pointer to the new allocated query string.
1324
static char *cover_definer_clause_in_sp(const char *def_str,
1325
uint def_str_length)
1327
char *query_str= NULL;
1328
char *definer_begin= my_case_str(def_str, def_str_length,
1329
C_STRING_WITH_LEN(" DEFINER"));
1335
definer_end= my_case_str(definer_begin, strlen(definer_begin),
1336
C_STRING_WITH_LEN(" PROCEDURE"));
1340
definer_end= my_case_str(definer_begin, strlen(definer_begin),
1341
C_STRING_WITH_LEN(" FUNCTION"));
1346
char *query_str_tail;
1349
Allocate memory for new query string: original string
1350
from SHOW statement and version-specific comments.
1352
query_str= alloc_query_str(def_str_length + 23);
1354
query_str_tail= strnmov(query_str, def_str, definer_begin - def_str);
1355
query_str_tail= strmov(query_str_tail, "*/ /*!50020");
1356
query_str_tail= strnmov(query_str_tail, definer_begin,
1357
definer_end - definer_begin);
1358
query_str_tail= strxmov(query_str_tail, "*/ /*!50003",
1359
definer_end, NullS);
1366
Open a new .sql file to dump the table or view into
1369
open_sql_file_for_table
1370
name name of the table or view
1373
0 Failed to open file
1374
> 0 Handle of the open file
1376
static FILE* open_sql_file_for_table(const char* table)
1379
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
1380
convert_dirname(tmp_path,path,NullS);
1381
res= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
1382
O_WRONLY, MYF(MY_WME));
1387
static void free_resources()
1389
if (md_result_file && md_result_file != stdout)
1390
my_fclose(md_result_file, MYF(0));
1391
my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
1392
if (hash_inited(&ignore_table))
1393
hash_free(&ignore_table);
1394
if (extended_insert)
1395
dynstr_free(&extended_row);
1396
if (insert_pat_inited)
1397
dynstr_free(&insert_pat);
1399
free_defaults(defaults_argv);
1404
static void maybe_exit(int error)
1418
db_connect -- connects to the host and selects DB.
1421
static int connect_to_db(char *host, char *user,char *passwd)
1423
char buff[20+FN_REFLEN];
1424
DBUG_ENTER("connect_to_db");
1426
verbose_msg("-- Connecting to %s...\n", host ? host : "localhost");
1427
mysql_init(&mysql_connection);
1429
mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS);
1432
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
1433
opt_ssl_capath, opt_ssl_cipher);
1434
mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
1435
(char*)&opt_ssl_verify_server_cert);
1438
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
1440
if (shared_memory_base_name)
1441
mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
1443
mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
1444
if (!(mysql= mysql_real_connect(&mysql_connection,host,user,passwd,
1445
NULL,opt_mysql_port,opt_mysql_unix_port,
1448
DB_error(&mysql_connection, "when trying to connect");
1451
if (mysql_get_server_version(&mysql_connection) < 40100)
1453
/* Don't dump SET NAMES with a pre-4.1 server (bug#7997). */
1456
/* Don't switch charsets for 4.1 and earlier. (bug#34192). */
1457
server_supports_switching_charsets= FALSE;
1460
set time_zone to UTC to allow dumping date types between servers with
1461
different time zone settings
1465
my_snprintf(buff, sizeof(buff), "/*!40103 SET TIME_ZONE='+00:00' */");
1466
if (mysql_query_with_error_report(mysql, 0, buff))
1470
} /* connect_to_db */
1474
** dbDisconnect -- disconnects from the host.
1476
static void dbDisconnect(char *host)
1478
verbose_msg("-- Disconnecting from %s...\n", host ? host : "localhost");
1480
} /* dbDisconnect */
1483
static void unescape(FILE *file,char *pos,uint length)
1486
DBUG_ENTER("unescape");
1487
if (!(tmp=(char*) my_malloc(length*2+1, MYF(MY_WME))))
1488
die(EX_MYSQLERR, "Couldn't allocate memory");
1490
mysql_real_escape_string(&mysql_connection, tmp, pos, length);
1495
my_free(tmp, MYF(MY_WME));
1500
static my_bool test_if_special_chars(const char *str)
1502
#if MYSQL_VERSION_ID >= 32300
1503
for ( ; *str ; str++)
1504
if (!my_isvar(charset_info,*str) && *str != '$')
1508
} /* test_if_special_chars */
1513
quote_name(name, buff, force)
1515
Quotes char string, taking into account compatible mode
1519
name Unquoted string containing that which will be quoted
1520
buff The buffer that contains the quoted value, also returned
1521
force Flag to make it ignore 'test_if_special_chars'
1528
static char *quote_name(const char *name, char *buff, my_bool force)
1531
char qtype= (opt_compatible_mode & MASK_ANSI_QUOTES) ? '\"' : '`';
1533
if (!force && !opt_quoted && !test_if_special_chars(name))
1534
return (char*) name;
1549
Quote a table name so it can be used in "SHOW TABLES LIKE <tabname>"
1553
name name of the table
1554
buff quoted name of the table
1557
Quote \, _, ' and % characters
1559
Note: Because MySQL uses the C escape syntax in strings
1560
(for example, '\n' to represent newline), you must double
1561
any '\' that you use in your LIKE strings. For example, to
1562
search for '\n', specify it as '\\n'. To search for '\', specify
1563
it as '\\\\' (the backslashes are stripped once by the parser
1564
and another time when the pattern match is done, leaving a
1565
single backslash to be matched).
1567
Example: "t\1" => "t\\\\1"
1570
static char *quote_for_like(const char *name, char *buff)
1582
else if (*name == '\'' || *name == '_' || *name == '%')
1593
Quote and print a string.
1597
xml_file - output file
1598
str - string to print
1602
Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
1605
static void print_quoted_xml(FILE *xml_file, const char *str, ulong len)
1609
for (end= str + len; str != end; str++)
1613
fputs("<", xml_file);
1616
fputs(">", xml_file);
1619
fputs("&", xml_file);
1622
fputs(""", xml_file);
1625
fputc(*str, xml_file);
1634
Print xml tag. Optionally add attribute(s).
1637
print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
1638
..., attribute_name_n, attribute_value_n, NullS)
1639
xml_file - output file
1640
sbeg - line beginning
1641
line_end - line ending
1642
tag_name - XML tag name.
1643
first_attribute_name - tag and first attribute
1644
first_attribute_value - (Implied) value of first attribute
1645
attribute_name_n - attribute n
1646
attribute_value_n - value of attribute n
1649
Print XML tag with any number of attribute="value" pairs to the xml_file.
1652
sbeg<tag_name first_attribute_name="first_attribute_value" ...
1653
attribute_name_n="attribute_value_n">send
1655
Additional arguments must be present in attribute/value pairs.
1656
The last argument should be the null character pointer.
1657
All attribute_value arguments MUST be NULL terminated strings.
1658
All attribute_value arguments will be quoted before output.
1661
static void print_xml_tag(FILE * xml_file, const char* sbeg,
1662
const char* line_end,
1663
const char* tag_name,
1664
const char* first_attribute_name, ...)
1667
const char *attribute_name, *attribute_value;
1669
fputs(sbeg, xml_file);
1670
fputc('<', xml_file);
1671
fputs(tag_name, xml_file);
1673
va_start(arg_list, first_attribute_name);
1674
attribute_name= first_attribute_name;
1675
while (attribute_name != NullS)
1677
attribute_value= va_arg(arg_list, char *);
1678
DBUG_ASSERT(attribute_value != NullS);
1680
fputc(' ', xml_file);
1681
fputs(attribute_name, xml_file);
1682
fputc('\"', xml_file);
1684
print_quoted_xml(xml_file, attribute_value, strlen(attribute_value));
1685
fputc('\"', xml_file);
1687
attribute_name= va_arg(arg_list, char *);
1691
fputc('>', xml_file);
1692
fputs(line_end, xml_file);
1698
Print xml tag with for a field that is null
1701
print_xml_null_tag()
1702
xml_file - output file
1703
sbeg - line beginning
1704
stag_atr - tag and attribute
1705
sval - value of attribute
1706
line_end - line ending
1709
Print tag with one attribute to the xml_file. Format is:
1710
<stag_atr="sval" xsi:nil="true"/>
1712
sval MUST be a NULL terminated string.
1713
sval string will be qouted before output.
1716
static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
1717
const char* stag_atr, const char* sval,
1718
const char* line_end)
1720
fputs(sbeg, xml_file);
1721
fputs("<", xml_file);
1722
fputs(stag_atr, xml_file);
1723
fputs("\"", xml_file);
1724
print_quoted_xml(xml_file, sval, strlen(sval));
1725
fputs("\" xsi:nil=\"true\" />", xml_file);
1726
fputs(line_end, xml_file);
1732
Print xml tag with many attributes.
1736
xml_file - output file
1737
row_name - xml tag name
1738
tableRes - query result
1742
Print tag with many attribute to the xml_file. Format is:
1743
\t\t<row_name Atr1="Val1" Atr2="Val2"... />
1745
All atributes and values will be quoted before output.
1748
static void print_xml_row(FILE *xml_file, const char *row_name,
1749
MYSQL_RES *tableRes, MYSQL_ROW *row)
1753
ulong *lengths= mysql_fetch_lengths(tableRes);
1755
fprintf(xml_file, "\t\t<%s", row_name);
1757
mysql_field_seek(tableRes, 0);
1758
for (i= 0; (field= mysql_fetch_field(tableRes)); i++)
1762
fputc(' ', xml_file);
1763
print_quoted_xml(xml_file, field->name, field->name_length);
1764
fputs("=\"", xml_file);
1765
print_quoted_xml(xml_file, (*row)[i], lengths[i]);
1766
fputc('"', xml_file);
1770
fputs(" />\n", xml_file);
1777
Generate a new (null-terminated) string that does not exist in query
1778
and is therefore suitable for use as a query delimiter. Store this
1779
delimiter in delimiter_buff .
1781
This is quite simple in that it doesn't even try to parse statements as an
1782
interpreter would. It merely returns a string that is not in the query, which
1783
is much more than adequate for constructing a delimiter.
1786
ptr to the delimiter on Success
1789
static char *create_delimiter(char *query, char *delimiter_buff,
1790
int delimiter_max_size)
1792
int proposed_length;
1795
delimiter_buff[0]= ';'; /* start with one semicolon, and */
1797
for (proposed_length= 2; proposed_length < delimiter_max_size;
1798
delimiter_max_size++) {
1800
delimiter_buff[proposed_length-1]= ';'; /* add semicolons, until */
1801
delimiter_buff[proposed_length]= '\0';
1803
presence = strstr(query, delimiter_buff);
1804
if (presence == NULL) { /* the proposed delimiter is not in the query. */
1805
return delimiter_buff;
1809
return NULL; /* but if we run out of space, return nothing at all. */
1815
-- retrieves list of events for a given db, and prints out
1816
the CREATE EVENT statement into the output (the dump).
1822
static uint dump_events_for_db(char *db)
1824
char query_buff[QUERY_LENGTH];
1825
char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
1827
char delimiter[QUERY_LENGTH];
1828
FILE *sql_file= md_result_file;
1829
MYSQL_RES *event_res, *event_list_res;
1830
MYSQL_ROW row, event_list_row;
1832
char db_cl_name[MY_CS_NAME_SIZE];
1833
int db_cl_altered= FALSE;
1835
DBUG_ENTER("dump_events_for_db");
1836
DBUG_PRINT("enter", ("db: '%s'", db));
1838
mysql_real_escape_string(mysql, db_name_buff, db, strlen(db));
1842
fprintf(sql_file, "\n--\n-- Dumping events for database '%s'\n--\n", db);
1845
not using "mysql_query_with_error_report" because we may have not
1846
enough privileges to lock mysql.events.
1849
mysql_query(mysql, "LOCK TABLES mysql.event READ");
1851
if (mysql_query_with_error_report(mysql, &event_list_res, "show events"))
1854
strcpy(delimiter, ";");
1855
if (mysql_num_rows(event_list_res) > 0)
1857
fprintf(sql_file, "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;\n");
1859
/* Get database collation. */
1861
if (fetch_db_collation(db_name_buff, db_cl_name, sizeof (db_cl_name)))
1864
if (switch_character_set_results(mysql, "binary"))
1867
while ((event_list_row= mysql_fetch_row(event_list_res)) != NULL)
1869
event_name= quote_name(event_list_row[1], name_buff, 0);
1870
DBUG_PRINT("info", ("retrieving CREATE EVENT for %s", name_buff));
1871
my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE EVENT %s",
1874
if (mysql_query_with_error_report(mysql, &event_res, query_buff))
1877
while ((row= mysql_fetch_row(event_res)) != NULL)
1880
if the user has EXECUTE privilege he can see event names, but not the
1883
if (strlen(row[3]) != 0)
1886
fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */%s\n",
1887
event_name, delimiter);
1889
if (create_delimiter(row[3], delimiter, sizeof(delimiter)) == NULL)
1891
fprintf(stderr, "%s: Warning: Can't create delimiter for event '%s'\n",
1892
my_progname, event_name);
1896
fprintf(sql_file, "DELIMITER %s\n", delimiter);
1898
if (mysql_num_fields(event_res) >= 7)
1900
if (switch_db_collation(sql_file, db_name_buff, delimiter,
1901
db_cl_name, row[6], &db_cl_altered))
1906
switch_cs_variables(sql_file, delimiter,
1907
row[4], /* character_set_client */
1908
row[4], /* character_set_results */
1909
row[5]); /* collation_connection */
1914
mysqldump is being run against the server, that does not
1915
provide character set information in SHOW CREATE
1918
NOTE: the dump may be incorrect, since character set
1919
information is required in order to restore event properly.
1924
"-- WARNING: old server version. "
1925
"The following dump may be incomplete.\n"
1929
switch_sql_mode(sql_file, delimiter, row[1]);
1931
switch_time_zone(sql_file, delimiter, row[2]);
1934
"/*!50106 %s */ %s\n",
1935
(const char *) row[3],
1936
(const char *) delimiter);
1938
restore_time_zone(sql_file, delimiter);
1939
restore_sql_mode(sql_file, delimiter);
1941
if (mysql_num_fields(event_res) >= 7)
1943
restore_cs_variables(sql_file, delimiter);
1947
if (restore_db_collation(sql_file, db_name_buff, delimiter,
1953
} /* end of event printing */
1954
mysql_free_result(event_res);
1956
} /* end of list of events */
1957
fprintf(sql_file, "DELIMITER ;\n");
1958
fprintf(sql_file, "/*!50106 SET TIME_ZONE= @save_time_zone */ ;\n");
1960
if (switch_character_set_results(mysql, default_charset))
1963
mysql_free_result(event_list_res);
1966
VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
1972
Print hex value for blob data.
1976
output_file - output file
1977
str - string to print
1981
Print hex value for blob data.
1984
static void print_blob_as_hex(FILE *output_file, const char *str, ulong len)
1986
/* sakaik got the idea to to provide blob's in hex notation. */
1987
const char *ptr= str, *end= ptr + len;
1988
for (; ptr < end ; ptr++)
1989
fprintf(output_file, "%02X", *((uchar *)ptr));
1990
check_io(output_file);
1994
dump_routines_for_db
1995
-- retrieves list of routines for a given db, and prints out
1996
the CREATE PROCEDURE definition into the output (the dump).
1998
This function has logic to print the appropriate syntax depending on whether
1999
this is a procedure or functions
2006
static uint dump_routines_for_db(char *db)
2008
char query_buff[QUERY_LENGTH];
2009
const char *routine_type[]= {"FUNCTION", "PROCEDURE"};
2010
char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
2013
FILE *sql_file= md_result_file;
2014
MYSQL_RES *routine_res, *routine_list_res;
2015
MYSQL_ROW row, routine_list_row;
2017
char db_cl_name[MY_CS_NAME_SIZE];
2018
int db_cl_altered= FALSE;
2020
DBUG_ENTER("dump_routines_for_db");
2021
DBUG_PRINT("enter", ("db: '%s'", db));
2023
mysql_real_escape_string(mysql, db_name_buff, db, strlen(db));
2027
fprintf(sql_file, "\n--\n-- Dumping routines for database '%s'\n--\n", db);
2030
not using "mysql_query_with_error_report" because we may have not
2031
enough privileges to lock mysql.proc.
2034
mysql_query(mysql, "LOCK TABLES mysql.proc READ");
2036
/* Get database collation. */
2038
if (fetch_db_collation(db_name_buff, db_cl_name, sizeof (db_cl_name)))
2041
if (switch_character_set_results(mysql, "binary"))
2044
/* 0, retrieve and dump functions, 1, procedures */
2045
for (i= 0; i <= 1; i++)
2047
my_snprintf(query_buff, sizeof(query_buff),
2048
"SHOW %s STATUS WHERE Db = '%s'",
2049
routine_type[i], db_name_buff);
2051
if (mysql_query_with_error_report(mysql, &routine_list_res, query_buff))
2054
if (mysql_num_rows(routine_list_res))
2057
while ((routine_list_row= mysql_fetch_row(routine_list_res)))
2059
routine_name= quote_name(routine_list_row[1], name_buff, 0);
2060
DBUG_PRINT("info", ("retrieving CREATE %s for %s", routine_type[i],
2062
my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s",
2063
routine_type[i], routine_name);
2065
if (mysql_query_with_error_report(mysql, &routine_res, query_buff))
2068
while ((row= mysql_fetch_row(routine_res)))
2071
if the user has EXECUTE privilege he see routine names, but NOT the
2072
routine body of other routines that are not the creator of!
2074
DBUG_PRINT("info",("length of body for %s row[2] '%s' is %d",
2075
routine_name, row[2] ? row[2] : "(null)",
2076
row[2] ? (int) strlen(row[2]) : 0));
2079
fprintf(sql_file, "\n-- insufficient privileges to %s\n", query_buff);
2080
fprintf(sql_file, "-- does %s have permissions on mysql.proc?\n\n", current_user);
2081
maybe_die(EX_MYSQLERR,"%s has insufficent privileges to %s!", current_user, query_buff);
2083
else if (strlen(row[2]))
2087
fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;\n",
2088
routine_type[i], routine_name);
2090
query_str= cover_definer_clause_in_sp(row[2], strlen(row[2]));
2092
if (mysql_num_fields(routine_res) >= 6)
2094
if (switch_db_collation(sql_file, db_name_buff, ";",
2095
db_cl_name, row[5], &db_cl_altered))
2100
switch_cs_variables(sql_file, ";",
2101
row[3], /* character_set_client */
2102
row[3], /* character_set_results */
2103
row[4]); /* collation_connection */
2108
mysqldump is being run against the server, that does not
2109
provide character set information in SHOW CREATE
2112
NOTE: the dump may be incorrect, since character set
2113
information is required in order to restore stored
2114
procedure/function properly.
2119
"-- WARNING: old server version. "
2120
"The following dump may be incomplete.\n"
2125
switch_sql_mode(sql_file, ";", row[1]);
2129
"/*!50003 %s */;;\n"
2131
(const char *) (query_str != NULL ? query_str : row[2]));
2133
restore_sql_mode(sql_file, ";");
2135
if (mysql_num_fields(routine_res) >= 6)
2137
restore_cs_variables(sql_file, ";");
2141
if (restore_db_collation(sql_file, db_name_buff, ";", db_cl_name))
2146
my_free(query_str, MYF(MY_ALLOW_ZERO_PTR));
2148
} /* end of routine printing */
2149
mysql_free_result(routine_res);
2151
} /* end of list of routines */
2153
mysql_free_result(routine_list_res);
2154
} /* end of for i (0 .. 1) */
2156
if (switch_character_set_results(mysql, default_charset))
2160
VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
2165
get_table_structure -- retrievs database structure, prints out corresponding
2166
CREATE statement and fills out insert_pat if the table is the type we will
2172
table_type - table type, e.g. "MyISAM" or "InnoDB", but also "VIEW"
2173
ignore_flag - what we must particularly ignore - see IGNORE_ defines above
2176
number of fields in table, 0 if error
2179
static uint get_table_structure(char *table, char *db, char *table_type,
2182
my_bool init=0, delayed, write_data, complete_insert;
2183
my_ulonglong num_fields;
2184
char *result_table, *opt_quoted_table;
2185
const char *insert_option;
2186
char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
2187
char table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
2188
FILE *sql_file= md_result_file;
2192
DBUG_ENTER("get_table_structure");
2193
DBUG_PRINT("enter", ("db: %s table: %s", db, table));
2195
*ignore_flag= check_if_ignore_table(table, table_type);
2197
delayed= opt_delayed;
2198
if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
2201
verbose_msg("-- Warning: Unable to use delayed inserts for table '%s' "
2202
"because it's of type %s\n", table, table_type);
2206
if ((write_data= !(*ignore_flag & IGNORE_DATA)))
2208
complete_insert= opt_complete_insert;
2209
if (!insert_pat_inited)
2211
insert_pat_inited= 1;
2212
init_dynamic_string_checked(&insert_pat, "", 1024, 1024);
2215
dynstr_set_checked(&insert_pat, "");
2218
insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
2219
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : "");
2221
verbose_msg("-- Retrieving table structure for table %s...\n", table);
2223
len= my_snprintf(query_buff, sizeof(query_buff),
2224
"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
2225
(opt_quoted || opt_keywords));
2227
result_table= quote_name(table, table_buff, 1);
2228
opt_quoted_table= quote_name(table, table_buff2, 0);
2230
if (opt_order_by_primary)
2232
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
2233
order_by= primary_key_fields(result_table);
2236
if (!opt_xml && !mysql_query_with_error_report(mysql, 0, query_buff))
2238
/* using SHOW CREATE statement */
2239
if (!opt_no_create_info)
2241
/* Make an sql-file, if path was given iow. option -T was given */
2242
char buff[20+FN_REFLEN];
2245
my_snprintf(buff, sizeof(buff), "show create table %s", result_table);
2247
if (switch_character_set_results(mysql, "binary") ||
2248
mysql_query_with_error_report(mysql, &result, buff) ||
2249
switch_character_set_results(mysql, default_charset))
2254
if (!(sql_file= open_sql_file_for_table(table)))
2257
write_header(sql_file, db);
2259
if (!opt_xml && opt_comments)
2261
if (strcmp (table_type, "VIEW") == 0) /* view */
2262
fprintf(sql_file, "\n--\n-- Temporary table structure for view %s\n--\n\n",
2265
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
2272
Even if the "table" is a view, we do a DROP TABLE here. The
2273
view-specific code below fills in the DROP VIEW.
2275
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",
2280
field= mysql_fetch_field_direct(result, 0);
2281
if (strcmp(field->name, "View") == 0)
2283
char *scv_buff= NULL;
2285
verbose_msg("-- It's a view, create dummy table for view\n");
2287
/* save "show create" statement for later */
2288
if ((row= mysql_fetch_row(result)) && (scv_buff=row[1]))
2289
scv_buff= my_strdup(scv_buff, MYF(0));
2291
mysql_free_result(result);
2294
Create a table with the same name as the view and with columns of
2295
the same name in order to satisfy views that depend on this view.
2296
The table will be removed when the actual view is created.
2298
The properties of each column, aside from the data type, are not
2299
preserved in this temporary table, because they are not necessary.
2301
This will not be necessary once we can determine dependencies
2302
between views and can simply dump them in the appropriate order.
2304
my_snprintf(query_buff, sizeof(query_buff),
2305
"SHOW FIELDS FROM %s", result_table);
2306
if (switch_character_set_results(mysql, "binary") ||
2307
mysql_query_with_error_report(mysql, &result, query_buff) ||
2308
switch_character_set_results(mysql, default_charset))
2311
View references invalid or privileged table/col/fun (err 1356),
2312
so we cannot create a stand-in table. Be defensive and dump
2313
a comment with the view's 'show create' statement. (Bug #17371)
2316
if (mysql_errno(mysql) == ER_VIEW_INVALID)
2317
fprintf(sql_file, "\n-- failed on view %s: %s\n\n", result_table, scv_buff ? scv_buff : "");
2319
my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR));
2324
my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR));
2326
if (mysql_num_rows(result))
2331
We have already dropped any table of the same name above, so
2332
here we just drop the view.
2335
fprintf(sql_file, "/*!50001 DROP VIEW IF EXISTS %s*/;\n",
2341
"SET @saved_cs_client = @@character_set_client;\n"
2342
"SET character_set_client = utf8;\n"
2343
"/*!50001 CREATE TABLE %s (\n",
2347
Get first row, following loop will prepend comma - keeps from
2348
having to know if the row being printed is last to determine if
2349
there should be a _trailing_ comma.
2352
row= mysql_fetch_row(result);
2354
fprintf(sql_file, " %s %s", quote_name(row[0], name_buff, 0),
2357
while((row= mysql_fetch_row(result)))
2359
/* col name, col type */
2360
fprintf(sql_file, ",\n %s %s",
2361
quote_name(row[0], name_buff, 0), row[1]);
2365
"SET character_set_client = @saved_cs_client;\n");
2370
mysql_free_result(result);
2373
my_fclose(sql_file, MYF(MY_WME));
2379
row= mysql_fetch_row(result);
2382
"SET @saved_cs_client = @@character_set_client;\n"
2383
"SET character_set_client = utf8;\n"
2385
"SET character_set_client = @saved_cs_client;\n",
2389
mysql_free_result(result);
2391
my_snprintf(query_buff, sizeof(query_buff), "show fields from %s",
2393
if (mysql_query_with_error_report(mysql, &result, query_buff))
2396
my_fclose(sql_file, MYF(MY_WME));
2401
If write_data is true, then we build up insert statements for
2402
the table's data. Note: in subsequent lines of code, this test
2403
will have to be performed each time we are appending to
2408
if (opt_replace_into)
2409
dynstr_append_checked(&insert_pat, "REPLACE ");
2411
dynstr_append_checked(&insert_pat, "INSERT ");
2412
dynstr_append_checked(&insert_pat, insert_option);
2413
dynstr_append_checked(&insert_pat, "INTO ");
2414
dynstr_append_checked(&insert_pat, opt_quoted_table);
2415
if (complete_insert)
2417
dynstr_append_checked(&insert_pat, " (");
2421
dynstr_append_checked(&insert_pat, " VALUES ");
2422
if (!extended_insert)
2423
dynstr_append_checked(&insert_pat, "(");
2427
while ((row= mysql_fetch_row(result)))
2429
if (complete_insert)
2433
dynstr_append_checked(&insert_pat, ", ");
2436
dynstr_append_checked(&insert_pat,
2437
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
2440
num_fields= mysql_num_rows(result);
2441
mysql_free_result(result);
2445
verbose_msg("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n",
2446
my_progname, mysql_error(mysql));
2448
my_snprintf(query_buff, sizeof(query_buff), "show fields from %s",
2450
if (mysql_query_with_error_report(mysql, &result, query_buff))
2453
/* Make an sql-file, if path was given iow. option -T was given */
2454
if (!opt_no_create_info)
2458
if (!(sql_file= open_sql_file_for_table(table)))
2460
write_header(sql_file, db);
2462
if (!opt_xml && opt_comments)
2463
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
2466
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
2468
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
2470
print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
2477
if (opt_replace_into)
2478
dynstr_append_checked(&insert_pat, "REPLACE ");
2480
dynstr_append_checked(&insert_pat, "INSERT ");
2481
dynstr_append_checked(&insert_pat, insert_option);
2482
dynstr_append_checked(&insert_pat, "INTO ");
2483
dynstr_append_checked(&insert_pat, result_table);
2484
if (complete_insert)
2485
dynstr_append_checked(&insert_pat, " (");
2488
dynstr_append_checked(&insert_pat, " VALUES ");
2489
if (!extended_insert)
2490
dynstr_append_checked(&insert_pat, "(");
2494
while ((row= mysql_fetch_row(result)))
2496
ulong *lengths= mysql_fetch_lengths(result);
2499
if (!opt_xml && !opt_no_create_info)
2501
fputs(",\n",sql_file);
2504
if (complete_insert)
2505
dynstr_append_checked(&insert_pat, ", ");
2508
if (complete_insert)
2509
dynstr_append_checked(&insert_pat,
2510
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
2511
if (!opt_no_create_info)
2515
print_xml_row(sql_file, "field", result, &row);
2520
fprintf(sql_file, " %s.%s %s", result_table,
2521
quote_name(row[SHOW_FIELDNAME],name_buff, 0),
2524
fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME],
2527
if (row[SHOW_DEFAULT])
2529
fputs(" DEFAULT ", sql_file);
2530
unescape(sql_file, row[SHOW_DEFAULT], lengths[SHOW_DEFAULT]);
2532
if (!row[SHOW_NULL][0])
2533
fputs(" NOT NULL", sql_file);
2534
if (row[SHOW_EXTRA][0])
2535
fprintf(sql_file, " %s",row[SHOW_EXTRA]);
2539
num_fields= mysql_num_rows(result);
2540
mysql_free_result(result);
2541
if (!opt_no_create_info)
2543
/* Make an sql-file, if path was given iow. option -T was given */
2544
char buff[20+FN_REFLEN];
2545
uint keynr,primary_key;
2546
my_snprintf(buff, sizeof(buff), "show keys from %s", result_table);
2547
if (mysql_query_with_error_report(mysql, &result, buff))
2549
if (mysql_errno(mysql) == ER_WRONG_OBJECT)
2552
fputs("\t\t<options Comment=\"view\" />\n", sql_file);
2555
fprintf(stderr, "%s: Can't get keys for table %s (%s)\n",
2556
my_progname, result_table, mysql_error(mysql));
2558
my_fclose(sql_file, MYF(MY_WME));
2562
/* Find first which key is primary key */
2564
primary_key=INT_MAX;
2565
while ((row= mysql_fetch_row(result)))
2567
if (atoi(row[3]) == 1)
2570
#ifdef FORCE_PRIMARY_KEY
2571
if (atoi(row[1]) == 0 && primary_key == INT_MAX)
2574
if (!strcmp(row[2],"PRIMARY"))
2581
mysql_data_seek(result,0);
2583
while ((row= mysql_fetch_row(result)))
2587
print_xml_row(sql_file, "key", result, &row);
2591
if (atoi(row[3]) == 1)
2594
putc(')', sql_file);
2595
if (atoi(row[1])) /* Test if duplicate key */
2596
/* Duplicate allowed */
2597
fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff,0));
2598
else if (keynr == primary_key)
2599
fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
2601
fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,
2605
putc(',', sql_file);
2606
fputs(quote_name(row[4], name_buff, 0), sql_file);
2608
fprintf(sql_file, " (%s)",row[7]); /* Sub key */
2611
mysql_free_result(result);
2615
putc(')', sql_file);
2616
fputs("\n)",sql_file);
2620
/* Get MySQL specific create options */
2623
char show_name_buff[NAME_LEN*2+2+24];
2625
/* Check memory for quote_for_like() */
2626
my_snprintf(buff, sizeof(buff), "show table status like %s",
2627
quote_for_like(table, show_name_buff));
2629
if (mysql_query_with_error_report(mysql, &result, buff))
2631
if (mysql_errno(mysql) != ER_PARSE_ERROR)
2632
{ /* If old MySQL version */
2633
verbose_msg("-- Warning: Couldn't get status information for " \
2634
"table %s (%s)\n", result_table,mysql_error(mysql));
2637
else if (!(row= mysql_fetch_row(result)))
2640
"Error: Couldn't read status information for table %s (%s)\n",
2641
result_table,mysql_error(mysql));
2646
print_xml_row(sql_file, "options", result, &row);
2649
fputs("/*!",sql_file);
2650
print_value(sql_file,result,row,"engine=","Engine",0);
2651
print_value(sql_file,result,row,"","Create_options",0);
2652
print_value(sql_file,result,row,"comment=","Comment",1);
2653
fputs(" */",sql_file);
2657
mysql_free_result(result); /* Is always safe to free */
2661
fputs(";\n", sql_file);
2663
fputs("\t</table_structure>\n", sql_file);
2667
if (complete_insert)
2669
dynstr_append_checked(&insert_pat, ") VALUES ");
2670
if (!extended_insert)
2671
dynstr_append_checked(&insert_pat, "(");
2673
if (sql_file != md_result_file)
2675
fputs("\n", sql_file);
2676
write_footer(sql_file);
2677
my_fclose(sql_file, MYF(MY_WME));
2679
DBUG_RETURN((uint) num_fields);
2680
} /* get_table_structure */
2682
static void add_load_option(DYNAMIC_STRING *str, const char *option,
2683
const char *option_value)
2687
/* Null value means we don't add this option. */
2691
dynstr_append_checked(str, option);
2693
if (strncmp(option_value, "0x", sizeof("0x")-1) == 0)
2695
/* It's a hex constant, don't escape */
2696
dynstr_append_checked(str, option_value);
2700
/* char constant; escape */
2701
field_escape(str, option_value);
2707
Allow the user to specify field terminator strings like:
2708
"'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
2709
This is done by doubling ' and add a end -\ if needed to avoid
2710
syntax errors from the SQL parser.
2713
static void field_escape(DYNAMIC_STRING* in, const char *from)
2715
uint end_backslashes= 0;
2717
dynstr_append_checked(in, "'");
2721
dynstr_append_mem_checked(in, from, 1);
2724
end_backslashes^=1; /* find odd number of backslashes */
2727
if (*from == '\'' && !end_backslashes)
2729
/* We want a duplicate of "'" for MySQL */
2730
dynstr_append_checked(in, "\'");
2736
/* Add missing backslashes if user has specified odd number of backs.*/
2737
if (end_backslashes)
2738
dynstr_append_checked(in, "\\");
2740
dynstr_append_checked(in, "'");
2745
static char *alloc_query_str(ulong size)
2749
if (!(query= (char*) my_malloc(size, MYF(MY_WME))))
2750
die(EX_MYSQLERR, "Couldn't allocate a query string.");
2761
dump_table saves database contents as a series of INSERT statements.
2772
static void dump_table(char *table, char *db)
2775
char buf[200], table_buff[NAME_LEN+3];
2776
DYNAMIC_STRING query_string;
2777
char table_type[NAME_LEN];
2778
char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
2780
ulong rownr, row_break, total_length, init_length;
2785
DBUG_ENTER("dump_table");
2788
Make sure you get the create table info before the following check for
2789
--no-data flag below. Otherwise, the create table info won't be printed.
2791
num_fields= get_table_structure(table, db, table_type, &ignore_flag);
2794
The "table" could be a view. If so, we don't do anything here.
2796
if (strcmp(table_type, "VIEW") == 0)
2799
/* Check --no-data flag */
2802
verbose_msg("-- Skipping dump data for table '%s', --no-data was used\n",
2808
("ignore_flag: %x num_fields: %d", (int) ignore_flag,
2811
If the table type is a merge table or any type that has to be
2812
_completely_ ignored and no data dumped
2814
if (ignore_flag & IGNORE_DATA)
2816
verbose_msg("-- Warning: Skipping data for table '%s' because " \
2817
"it's of type %s\n", table, table_type);
2820
/* Check that there are any fields in the table */
2821
if (num_fields == 0)
2823
verbose_msg("-- Skipping dump data for table '%s', it has no fields\n",
2829
Check --skip-events flag: it is not enough to skip creation of events
2830
discarding SHOW CREATE EVENT statements generation. The myslq.event
2831
table data should be skipped too.
2833
if (!opt_events && !my_strcasecmp(&my_charset_latin1, db, "mysql") &&
2834
!my_strcasecmp(&my_charset_latin1, table, "event"))
2836
verbose_msg("-- Skipping data table mysql.event, --skip-events was used\n");
2840
result_table= quote_name(table,table_buff, 1);
2841
opt_quoted_table= quote_name(table, table_buff2, 0);
2843
verbose_msg("-- Sending SELECT query...\n");
2845
init_dynamic_string_checked(&query_string, "", 1024, 1024);
2849
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
2852
Convert the path to native os format
2853
and resolve to the full filepath.
2855
convert_dirname(tmp_path,path,NullS);
2856
my_load_path(tmp_path, tmp_path, NULL);
2857
fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
2859
/* Must delete the file that 'INTO OUTFILE' will write to */
2860
my_delete(filename, MYF(0));
2862
/* convert to a unix path name to stick into the query */
2863
to_unix_path(filename);
2865
/* now build the query string */
2867
dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '");
2868
dynstr_append_checked(&query_string, filename);
2869
dynstr_append_checked(&query_string, "'");
2871
if (fields_terminated || enclosed || opt_enclosed || escaped)
2872
dynstr_append_checked(&query_string, " FIELDS");
2874
add_load_option(&query_string, " TERMINATED BY ", fields_terminated);
2875
add_load_option(&query_string, " ENCLOSED BY ", enclosed);
2876
add_load_option(&query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed);
2877
add_load_option(&query_string, " ESCAPED BY ", escaped);
2878
add_load_option(&query_string, " LINES TERMINATED BY ", lines_terminated);
2880
dynstr_append_checked(&query_string, " FROM ");
2881
dynstr_append_checked(&query_string, result_table);
2885
dynstr_append_checked(&query_string, " WHERE ");
2886
dynstr_append_checked(&query_string, where);
2891
dynstr_append_checked(&query_string, " ORDER BY ");
2892
dynstr_append_checked(&query_string, order_by);
2895
if (mysql_real_query(mysql, query_string.str, query_string.length))
2897
DB_error(mysql, "when executing 'SELECT INTO OUTFILE'");
2898
dynstr_free(&query_string);
2904
if (!opt_xml && opt_comments)
2906
fprintf(md_result_file,"\n--\n-- Dumping data for table %s\n--\n",
2908
check_io(md_result_file);
2911
dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM ");
2912
dynstr_append_checked(&query_string, result_table);
2916
if (!opt_xml && opt_comments)
2918
fprintf(md_result_file, "-- WHERE: %s\n", where);
2919
check_io(md_result_file);
2922
dynstr_append_checked(&query_string, " WHERE ");
2923
dynstr_append_checked(&query_string, where);
2927
if (!opt_xml && opt_comments)
2929
fprintf(md_result_file, "-- ORDER BY: %s\n", order_by);
2930
check_io(md_result_file);
2932
dynstr_append_checked(&query_string, " ORDER BY ");
2933
dynstr_append_checked(&query_string, order_by);
2936
if (!opt_xml && !opt_compact)
2938
fputs("\n", md_result_file);
2939
check_io(md_result_file);
2941
if (mysql_query_with_error_report(mysql, 0, query_string.str))
2943
DB_error(mysql, "when retrieving data from server");
2947
res=mysql_use_result(mysql);
2949
res=mysql_store_result(mysql);
2952
DB_error(mysql, "when retrieving data from server");
2956
verbose_msg("-- Retrieving rows...\n");
2957
if (mysql_num_fields(res) != num_fields)
2959
fprintf(stderr,"%s: Error in field count for table: %s ! Aborting.\n",
2960
my_progname, result_table);
2961
error= EX_CONSCHECK;
2967
fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table);
2968
check_io(md_result_file);
2970
/* Moved disable keys to after lock per bug 15977 */
2971
if (opt_disable_keys)
2973
fprintf(md_result_file, "/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",
2975
check_io(md_result_file);
2978
total_length= opt_net_buffer_length; /* Force row break */
2981
init_length=(uint) insert_pat.length+4;
2983
print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table,
2987
fprintf(md_result_file, "set autocommit=0;\n");
2988
check_io(md_result_file);
2991
while ((row= mysql_fetch_row(res)))
2994
ulong *lengths= mysql_fetch_lengths(res);
2996
if (!extended_insert && !opt_xml)
2998
fputs(insert_pat.str,md_result_file);
2999
check_io(md_result_file);
3001
mysql_field_seek(res,0);
3005
fputs("\t<row>\n", md_result_file);
3006
check_io(md_result_file);
3009
for (i= 0; i < mysql_num_fields(res); i++)
3012
ulong length= lengths[i];
3014
if (!(field= mysql_fetch_field(res)))
3016
"Not enough fields from table %s! Aborting.\n",
3020
63 is my_charset_bin. If charsetnr is not 63,
3021
we have not a BLOB but a TEXT column.
3022
we'll dump in hex only BLOB columns.
3024
is_blob= (opt_hex_blob && field->charsetnr == 63 &&
3025
(field->type == MYSQL_TYPE_BIT ||
3026
field->type == MYSQL_TYPE_STRING ||
3027
field->type == MYSQL_TYPE_VAR_STRING ||
3028
field->type == MYSQL_TYPE_VARCHAR ||
3029
field->type == MYSQL_TYPE_BLOB ||
3030
field->type == MYSQL_TYPE_LONG_BLOB ||
3031
field->type == MYSQL_TYPE_MEDIUM_BLOB ||
3032
field->type == MYSQL_TYPE_TINY_BLOB)) ? 1 : 0;
3033
if (extended_insert && !opt_xml)
3036
dynstr_set_checked(&extended_row,"(");
3038
dynstr_append_checked(&extended_row,",");
3044
if (!IS_NUM_FIELD(field))
3047
"length * 2 + 2" is OK for both HEX and non-HEX modes:
3048
- In HEX mode we need exactly 2 bytes per character
3049
plus 2 bytes for '0x' prefix.
3050
- In non-HEX mode we need up to 2 bytes per character,
3051
plus 2 bytes for leading and trailing '\'' characters.
3052
Also we need to reserve 1 byte for terminating '\0'.
3054
dynstr_realloc_checked(&extended_row,length * 2 + 2 + 1);
3055
if (opt_hex_blob && is_blob)
3057
dynstr_append_checked(&extended_row, "0x");
3058
extended_row.length+= mysql_hex_string(extended_row.str +
3059
extended_row.length,
3061
DBUG_ASSERT(extended_row.length+1 <= extended_row.max_length);
3062
/* mysql_hex_string() already terminated string by '\0' */
3063
DBUG_ASSERT(extended_row.str[extended_row.length] == '\0');
3067
dynstr_append_checked(&extended_row,"'");
3068
extended_row.length +=
3069
mysql_real_escape_string(&mysql_connection,
3070
&extended_row.str[extended_row.length],
3072
extended_row.str[extended_row.length]='\0';
3073
dynstr_append_checked(&extended_row,"'");
3078
/* change any strings ("inf", "-inf", "nan") into NULL */
3080
if (my_isalpha(charset_info, *ptr) || (*ptr == '-' &&
3081
my_isalpha(charset_info, ptr[1])))
3082
dynstr_append_checked(&extended_row, "NULL");
3085
if (field->type == MYSQL_TYPE_DECIMAL)
3087
/* add " signs around */
3088
dynstr_append_checked(&extended_row, "'");
3089
dynstr_append_checked(&extended_row, ptr);
3090
dynstr_append_checked(&extended_row, "'");
3093
dynstr_append_checked(&extended_row, ptr);
3098
dynstr_append_checked(&extended_row,"''");
3101
dynstr_append_checked(&extended_row,"NULL");
3107
fputc(',', md_result_file);
3108
check_io(md_result_file);
3112
if (!IS_NUM_FIELD(field))
3116
if (opt_hex_blob && is_blob && length)
3118
/* Define xsi:type="xs:hexBinary" for hex encoded data */
3119
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
3120
field->name, "xsi:type=", "xs:hexBinary", NullS);
3121
print_blob_as_hex(md_result_file, row[i], length);
3125
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
3126
field->name, NullS);
3127
print_quoted_xml(md_result_file, row[i], length);
3129
fputs("</field>\n", md_result_file);
3131
else if (opt_hex_blob && is_blob && length)
3133
fputs("0x", md_result_file);
3134
print_blob_as_hex(md_result_file, row[i], length);
3137
unescape(md_result_file, row[i], length);
3141
/* change any strings ("inf", "-inf", "nan") into NULL */
3145
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
3146
field->name, NullS);
3147
fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
3149
fputs("</field>\n", md_result_file);
3151
else if (my_isalpha(charset_info, *ptr) ||
3152
(*ptr == '-' && my_isalpha(charset_info, ptr[1])))
3153
fputs("NULL", md_result_file);
3154
else if (field->type == MYSQL_TYPE_DECIMAL)
3156
/* add " signs around */
3157
fputc('\'', md_result_file);
3158
fputs(ptr, md_result_file);
3159
fputc('\'', md_result_file);
3162
fputs(ptr, md_result_file);
3167
/* The field value is NULL */
3169
fputs("NULL", md_result_file);
3171
print_xml_null_tag(md_result_file, "\t\t", "field name=",
3174
check_io(md_result_file);
3180
fputs("\t</row>\n", md_result_file);
3181
check_io(md_result_file);
3184
if (extended_insert)
3187
dynstr_append_checked(&extended_row,")");
3188
row_length= 2 + extended_row.length;
3189
if (total_length + row_length < opt_net_buffer_length)
3191
total_length+= row_length;
3192
fputc(',',md_result_file); /* Always row break */
3193
fputs(extended_row.str,md_result_file);
3198
fputs(";\n", md_result_file);
3199
row_break=1; /* This is first row */
3201
fputs(insert_pat.str,md_result_file);
3202
fputs(extended_row.str,md_result_file);
3203
total_length= row_length+init_length;
3205
check_io(md_result_file);
3209
fputs(");\n", md_result_file);
3210
check_io(md_result_file);
3214
/* XML - close table tag and supress regular output */
3216
fputs("\t</table_data>\n", md_result_file);
3217
else if (extended_insert && row_break)
3218
fputs(";\n", md_result_file); /* If not empty table */
3219
fflush(md_result_file);
3220
check_io(md_result_file);
3221
if (mysql_errno(mysql))
3223
my_snprintf(buf, sizeof(buf),
3224
"%s: Error %d: %s when dumping table %s at row: %ld\n",
3231
error= EX_CONSCHECK;
3235
/* Moved enable keys to before unlock per bug 15977 */
3236
if (opt_disable_keys)
3238
fprintf(md_result_file,"/*!40000 ALTER TABLE %s ENABLE KEYS */;\n",
3240
check_io(md_result_file);
3244
fputs("UNLOCK TABLES;\n", md_result_file);
3245
check_io(md_result_file);
3249
fprintf(md_result_file, "commit;\n");
3250
check_io(md_result_file);
3252
mysql_free_result(res);
3254
dynstr_free(&query_string);
3258
dynstr_free(&query_string);
3264
static char *getTableName(int reset)
3266
static MYSQL_RES *res= NULL;
3271
if (!(res= mysql_list_tables(mysql,NullS)))
3274
if ((row= mysql_fetch_row(res)))
3275
return((char*) row[0]);
3278
mysql_data_seek(res,0); /* We want to read again */
3281
mysql_free_result(res);
3285
} /* getTableName */
3289
dump all logfile groups and tablespaces
3292
static int dump_all_tablespaces()
3294
return dump_tablespaces(NULL);
3297
static int dump_tablespaces_for_tables(char *db, char **table_names, int tables)
3299
DYNAMIC_STRING where;
3302
char name_buff[NAME_LEN*2+3];
3304
mysql_real_escape_string(mysql, name_buff, db, strlen(db));
3306
init_dynamic_string_checked(&where, " AND TABLESPACE_NAME IN ("
3307
"SELECT DISTINCT TABLESPACE_NAME FROM"
3308
" INFORMATION_SCHEMA.PARTITIONS"
3310
" TABLE_SCHEMA='", 256, 1024);
3311
dynstr_append_checked(&where, name_buff);
3312
dynstr_append_checked(&where, "' AND TABLE_NAME IN (");
3314
for (i=0 ; i<tables ; i++)
3316
mysql_real_escape_string(mysql, name_buff,
3317
table_names[i], strlen(table_names[i]));
3319
dynstr_append_checked(&where, "'");
3320
dynstr_append_checked(&where, name_buff);
3321
dynstr_append_checked(&where, "',");
3323
dynstr_trunc(&where, 1);
3324
dynstr_append_checked(&where,"))");
3326
DBUG_PRINT("info",("Dump TS for Tables where: %s",where.str));
3327
r= dump_tablespaces(where.str);
3328
dynstr_free(&where);
3332
static int dump_tablespaces_for_databases(char** databases)
3334
DYNAMIC_STRING where;
3338
init_dynamic_string_checked(&where, " AND TABLESPACE_NAME IN ("
3339
"SELECT DISTINCT TABLESPACE_NAME FROM"
3340
" INFORMATION_SCHEMA.PARTITIONS"
3342
" TABLE_SCHEMA IN (", 256, 1024);
3344
for (i=0 ; databases[i]!=NULL ; i++)
3346
char db_name_buff[NAME_LEN*2+3];
3347
mysql_real_escape_string(mysql, db_name_buff,
3348
databases[i], strlen(databases[i]));
3349
dynstr_append_checked(&where, "'");
3350
dynstr_append_checked(&where, db_name_buff);
3351
dynstr_append_checked(&where, "',");
3353
dynstr_trunc(&where, 1);
3354
dynstr_append_checked(&where,"))");
3356
DBUG_PRINT("info",("Dump TS for DBs where: %s",where.str));
3357
r= dump_tablespaces(where.str);
3358
dynstr_free(&where);
3362
static int dump_tablespaces(char* ts_where)
3365
MYSQL_RES *tableres;
3366
char buf[FN_REFLEN];
3367
DYNAMIC_STRING sqlbuf;
3370
The following are used for parsing the EXTRA field
3372
char extra_format[]= "UNDO_BUFFER_SIZE=";
3375
DBUG_ENTER("dump_tablespaces");
3377
init_dynamic_string_checked(&sqlbuf,
3378
"SELECT LOGFILE_GROUP_NAME,"
3384
" FROM INFORMATION_SCHEMA.FILES"
3385
" WHERE FILE_TYPE = 'UNDO LOG'"
3386
" AND FILE_NAME IS NOT NULL",
3390
dynstr_append_checked(&sqlbuf,
3391
" AND LOGFILE_GROUP_NAME IN ("
3392
"SELECT DISTINCT LOGFILE_GROUP_NAME"
3393
" FROM INFORMATION_SCHEMA.FILES"
3394
" WHERE FILE_TYPE = 'DATAFILE'"
3396
dynstr_append_checked(&sqlbuf, ts_where);
3397
dynstr_append_checked(&sqlbuf, ")");
3399
dynstr_append_checked(&sqlbuf,
3400
" GROUP BY LOGFILE_GROUP_NAME, FILE_NAME"
3402
" ORDER BY LOGFILE_GROUP_NAME");
3404
if (mysql_query(mysql, sqlbuf.str) ||
3405
!(tableres = mysql_store_result(mysql)))
3407
dynstr_free(&sqlbuf);
3408
if (mysql_errno(mysql) == ER_BAD_TABLE_ERROR ||
3409
mysql_errno(mysql) == ER_BAD_DB_ERROR ||
3410
mysql_errno(mysql) == ER_UNKNOWN_TABLE)
3412
fprintf(md_result_file,
3413
"\n--\n-- Not dumping tablespaces as no INFORMATION_SCHEMA.FILES"
3414
" table on this server\n--\n");
3415
check_io(md_result_file);
3419
my_printf_error(0, "Error: '%s' when trying to dump tablespaces",
3420
MYF(0), mysql_error(mysql));
3425
while ((row= mysql_fetch_row(tableres)))
3427
if (strcmp(buf, row[0]) != 0)
3431
if (!opt_xml && opt_comments)
3433
fprintf(md_result_file,"\n--\n-- Logfile group: %s\n--\n", row[0]);
3434
check_io(md_result_file);
3436
fprintf(md_result_file, "\nCREATE");
3440
fprintf(md_result_file, "\nALTER");
3442
fprintf(md_result_file,
3443
" LOGFILE GROUP %s\n"
3444
" ADD UNDOFILE '%s'\n",
3449
ubs= strstr(row[5],extra_format);
3452
ubs+= strlen(extra_format);
3453
endsemi= strstr(ubs,";");
3456
fprintf(md_result_file,
3457
" UNDO_BUFFER_SIZE %s\n",
3460
fprintf(md_result_file,
3461
" INITIAL_SIZE %s\n"
3465
check_io(md_result_file);
3469
strxmov(buf, row[0], NullS);
3472
dynstr_free(&sqlbuf);
3473
mysql_free_result(tableres);
3474
init_dynamic_string_checked(&sqlbuf,
3475
"SELECT DISTINCT TABLESPACE_NAME,"
3477
" LOGFILE_GROUP_NAME,"
3481
" FROM INFORMATION_SCHEMA.FILES"
3482
" WHERE FILE_TYPE = 'DATAFILE'",
3486
dynstr_append_checked(&sqlbuf, ts_where);
3488
dynstr_append_checked(&sqlbuf, " ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME");
3490
if (mysql_query_with_error_report(mysql, &tableres, sqlbuf.str))
3492
dynstr_free(&sqlbuf);
3497
while ((row= mysql_fetch_row(tableres)))
3499
if (strcmp(buf, row[0]) != 0)
3503
if (!opt_xml && opt_comments)
3505
fprintf(md_result_file,"\n--\n-- Tablespace: %s\n--\n", row[0]);
3506
check_io(md_result_file);
3508
fprintf(md_result_file, "\nCREATE");
3512
fprintf(md_result_file, "\nALTER");
3514
fprintf(md_result_file,
3516
" ADD DATAFILE '%s'\n",
3521
fprintf(md_result_file,
3522
" USE LOGFILE GROUP %s\n"
3523
" EXTENT_SIZE %s\n",
3527
fprintf(md_result_file,
3528
" INITIAL_SIZE %s\n"
3532
check_io(md_result_file);
3536
strxmov(buf, row[0], NullS);
3540
mysql_free_result(tableres);
3541
dynstr_free(&sqlbuf);
3545
static int dump_all_databases()
3548
MYSQL_RES *tableres;
3551
if (mysql_query_with_error_report(mysql, &tableres, "SHOW DATABASES"))
3553
while ((row= mysql_fetch_row(tableres)))
3555
if (dump_all_tables_in_db(row[0]))
3560
if (mysql_query(mysql, "SHOW DATABASES") ||
3561
!(tableres= mysql_store_result(mysql)))
3563
my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s",
3564
MYF(0), mysql_error(mysql));
3567
while ((row= mysql_fetch_row(tableres)))
3569
if (dump_all_views_in_db(row[0]))
3575
/* dump_all_databases */
3578
static int dump_databases(char **db_names)
3582
DBUG_ENTER("dump_databases");
3584
for (db= db_names ; *db ; db++)
3586
if (dump_all_tables_in_db(*db))
3589
if (!result && seen_views)
3591
for (db= db_names ; *db ; db++)
3593
if (dump_all_views_in_db(*db))
3597
DBUG_RETURN(result);
3598
} /* dump_databases */
3602
View Specific database initalization.
3606
qdatabase quoted name of the database
3612
int init_dumping_views(char *qdatabase __attribute__((unused)))
3615
} /* init_dumping_views */
3619
Table Specific database initalization.
3623
qdatabase quoted name of the database
3630
int init_dumping_tables(char *qdatabase)
3632
DBUG_ENTER("init_dumping_tables");
3640
my_snprintf(qbuf, sizeof(qbuf),
3641
"SHOW CREATE DATABASE IF NOT EXISTS %s",
3644
if (mysql_query(mysql, qbuf) || !(dbinfo = mysql_store_result(mysql)))
3646
/* Old server version, dump generic CREATE DATABASE */
3647
if (opt_drop_database)
3648
fprintf(md_result_file,
3649
"\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n",
3651
fprintf(md_result_file,
3652
"\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n",
3657
if (opt_drop_database)
3658
fprintf(md_result_file,
3659
"\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n",
3661
row = mysql_fetch_row(dbinfo);
3664
fprintf(md_result_file,"\n%s;\n",row[1]);
3666
mysql_free_result(dbinfo);
3670
} /* init_dumping_tables */
3673
static int init_dumping(char *database, int init_func(char*))
3675
if (mysql_get_server_version(mysql) >= 50003 &&
3676
!my_strcasecmp(&my_charset_latin1, database, "information_schema"))
3679
if (mysql_select_db(mysql, database))
3681
DB_error(mysql, "when selecting the database");
3682
return 1; /* If --force */
3684
if (!path && !opt_xml)
3686
if (opt_databases || opt_alldbs)
3689
length of table name * 2 (if name contains quotes), 2 quotes and 0
3691
char quoted_database_buf[NAME_LEN*2+3];
3692
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
3695
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
3696
check_io(md_result_file);
3699
/* Call the view or table specific function */
3700
init_func(qdatabase);
3702
fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
3703
check_io(md_result_file);
3706
if (extended_insert)
3707
init_dynamic_string_checked(&extended_row, "", 1024, 1024);
3709
} /* init_dumping */
3712
/* Return 1 if we should copy the table */
3714
my_bool include_table(const uchar *hash_key, size_t len)
3716
return !hash_search(&ignore_table, hash_key, len);
3720
static int dump_all_tables_in_db(char *database)
3724
char table_buff[NAME_LEN*2+3];
3725
char hash_key[2*NAME_LEN+2]; /* "db.tablename" */
3727
int using_mysql_db= my_strcasecmp(&my_charset_latin1, database, "mysql");
3728
DBUG_ENTER("dump_all_tables_in_db");
3730
afterdot= strmov(hash_key, database);
3733
if (init_dumping(database, init_dumping_tables))
3736
print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
3739
DYNAMIC_STRING query;
3740
init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);
3741
for (numrows= 0 ; (table= getTableName(1)) ; )
3743
char *end= strmov(afterdot, table);
3744
if (include_table((uchar*) hash_key,end - hash_key))
3747
dynstr_append_checked(&query, quote_name(table, table_buff, 1));
3748
dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
3751
if (numrows && mysql_real_query(mysql, query.str, query.length-1))
3752
DB_error(mysql, "when using LOCK TABLES");
3753
/* We shall continue here, if --force was given */
3754
dynstr_free(&query);
3758
if (mysql_refresh(mysql, REFRESH_LOG))
3759
DB_error(mysql, "when doing refresh");
3760
/* We shall continue here, if --force was given */
3762
while ((table= getTableName(0)))
3764
char *end= strmov(afterdot, table);
3765
if (include_table((uchar*) hash_key, end - hash_key))
3767
dump_table(table,database);
3768
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
3772
if (opt_events && !opt_xml &&
3773
mysql_get_server_version(mysql) >= 50106)
3775
DBUG_PRINT("info", ("Dumping events for database %s", database));
3776
dump_events_for_db(database);
3778
if (opt_routines && !opt_xml &&
3779
mysql_get_server_version(mysql) >= 50009)
3781
DBUG_PRINT("info", ("Dumping routines for database %s", database));
3782
dump_routines_for_db(database);
3786
fputs("</database>\n", md_result_file);
3787
check_io(md_result_file);
3790
VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
3791
if (flush_privileges && using_mysql_db == 0)
3793
fprintf(md_result_file,"\n--\n-- Flush Grant Tables \n--\n");
3794
fprintf(md_result_file,"\n/*! FLUSH PRIVILEGES */;\n");
3797
} /* dump_all_tables_in_db */
3801
dump structure of views of database
3804
dump_all_views_in_db()
3805
database database name
3812
static my_bool dump_all_views_in_db(char *database)
3816
char table_buff[NAME_LEN*2+3];
3817
char hash_key[2*NAME_LEN+2]; /* "db.tablename" */
3820
afterdot= strmov(hash_key, database);
3823
if (init_dumping(database, init_dumping_views))
3826
print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
3829
DYNAMIC_STRING query;
3830
init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);
3831
for (numrows= 0 ; (table= getTableName(1)); )
3833
char *end= strmov(afterdot, table);
3834
if (include_table((uchar*) hash_key,end - hash_key))
3837
dynstr_append_checked(&query, quote_name(table, table_buff, 1));
3838
dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
3841
if (numrows && mysql_real_query(mysql, query.str, query.length-1))
3842
DB_error(mysql, "when using LOCK TABLES");
3843
/* We shall continue here, if --force was given */
3844
dynstr_free(&query);
3848
if (mysql_refresh(mysql, REFRESH_LOG))
3849
DB_error(mysql, "when doing refresh");
3850
/* We shall continue here, if --force was given */
3852
while ((table= getTableName(0)))
3854
char *end= strmov(afterdot, table);
3855
if (include_table((uchar*) hash_key, end - hash_key))
3856
get_view_structure(table, database);
3860
fputs("</database>\n", md_result_file);
3861
check_io(md_result_file);
3864
VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
3866
} /* dump_all_tables_in_db */
3870
get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
3871
table name from the server for the table name given on the command line.
3872
we do this because the table name given on the command line may be a
3873
different case (e.g. T1 vs t1)
3876
pointer to the table name
3880
static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root)
3883
MYSQL_RES *table_res;
3885
char query[50 + 2*NAME_LEN];
3886
char show_name_buff[FN_REFLEN];
3887
DBUG_ENTER("get_actual_table_name");
3889
/* Check memory for quote_for_like() */
3890
DBUG_ASSERT(2*sizeof(old_table_name) < sizeof(show_name_buff));
3891
my_snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
3892
quote_for_like(old_table_name, show_name_buff));
3894
if (mysql_query_with_error_report(mysql, 0, query))
3897
if ((table_res= mysql_store_result(mysql)))
3899
my_ulonglong num_rows= mysql_num_rows(table_res);
3905
TODO: Return all matching rows
3907
row= mysql_fetch_row(table_res);
3908
lengths= mysql_fetch_lengths(table_res);
3909
name= strmake_root(root, row[0], lengths[0]);
3911
mysql_free_result(table_res);
3913
DBUG_PRINT("exit", ("new_table_name: %s", name));
3918
static int dump_selected_tables(char *db, char **table_names, int tables)
3920
char table_buff[NAME_LEN*2+3];
3921
DYNAMIC_STRING lock_tables_query;
3923
char **dump_tables, **pos, **end;
3924
DBUG_ENTER("dump_selected_tables");
3926
if (init_dumping(db, init_dumping_tables))
3929
init_alloc_root(&root, 8192, 0);
3930
if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
3931
die(EX_EOM, "alloc_root failure.");
3933
init_dynamic_string_checked(&lock_tables_query, "LOCK TABLES ", 256, 1024);
3934
for (; tables > 0 ; tables-- , table_names++)
3936
/* the table name passed on commandline may be wrong case */
3937
if ((*pos= get_actual_table_name(*table_names, &root)))
3939
/* Add found table name to lock_tables_query */
3942
dynstr_append_checked(&lock_tables_query, quote_name(*pos, table_buff, 1));
3943
dynstr_append_checked(&lock_tables_query, " READ /*!32311 LOCAL */,");
3951
dynstr_free(&lock_tables_query);
3952
free_root(&root, MYF(0));
3954
maybe_die(EX_ILLEGAL_TABLE, "Couldn't find table: \"%s\"", *table_names);
3955
/* We shall countinue here, if --force was given */
3962
if (mysql_real_query(mysql, lock_tables_query.str,
3963
lock_tables_query.length-1))
3967
dynstr_free(&lock_tables_query);
3968
free_root(&root, MYF(0));
3970
DB_error(mysql, "when doing LOCK TABLES");
3971
/* We shall countinue here, if --force was given */
3974
dynstr_free(&lock_tables_query);
3977
if (mysql_refresh(mysql, REFRESH_LOG))
3980
free_root(&root, MYF(0));
3981
DB_error(mysql, "when doing refresh");
3983
/* We shall countinue here, if --force was given */
3986
print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS);
3988
/* Dump each selected table */
3989
for (pos= dump_tables; pos < end; pos++)
3991
DBUG_PRINT("info",("Dumping table %s", *pos));
3992
dump_table(*pos, db);
3995
/* Dump each selected view */
3998
for (pos= dump_tables; pos < end; pos++)
3999
get_view_structure(*pos, db);
4001
if (opt_events && !opt_xml &&
4002
mysql_get_server_version(mysql) >= 50106)
4004
DBUG_PRINT("info", ("Dumping events for database %s", db));
4005
dump_events_for_db(db);
4007
/* obtain dump of routines (procs/functions) */
4008
if (opt_routines && !opt_xml &&
4009
mysql_get_server_version(mysql) >= 50009)
4011
DBUG_PRINT("info", ("Dumping routines for database %s", db));
4012
dump_routines_for_db(db);
4014
free_root(&root, MYF(0));
4015
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
4019
fputs("</database>\n", md_result_file);
4020
check_io(md_result_file);
4023
VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
4025
} /* dump_selected_tables */
4028
static int do_show_master_status(MYSQL *mysql_con)
4032
const char *comment_prefix=
4033
(opt_master_data == MYSQL_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : "";
4034
if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS"))
4040
row= mysql_fetch_row(master);
4041
if (row && row[0] && row[1])
4043
/* SHOW MASTER STATUS reports file and position */
4045
fprintf(md_result_file,
4046
"\n--\n-- Position to start replication or point-in-time "
4047
"recovery from\n--\n\n");
4048
fprintf(md_result_file,
4049
"%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
4050
comment_prefix, row[0], row[1]);
4051
check_io(md_result_file);
4053
else if (!ignore_errors)
4055
/* SHOW MASTER STATUS reports nothing and --force is not enabled */
4056
my_printf_error(0, "Error: Binlogging on server not active",
4058
mysql_free_result(master);
4059
maybe_exit(EX_MYSQLERR);
4062
mysql_free_result(master);
4067
static int do_stop_slave_sql(MYSQL *mysql_con)
4070
/* We need to check if the slave sql is running in the first place */
4071
if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
4075
MYSQL_ROW row= mysql_fetch_row(slave);
4078
/* if SLAVE SQL is not running, we don't stop it */
4079
if (!strcmp(row[11],"No"))
4081
mysql_free_result(slave);
4082
/* Silently assume that they don't have the slave running */
4087
mysql_free_result(slave);
4089
/* now, stop slave if running */
4090
if (mysql_query_with_error_report(mysql_con, 0, "STOP SLAVE SQL_THREAD"))
4096
static int add_stop_slave(void)
4099
fprintf(md_result_file,
4100
"\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
4101
fprintf(md_result_file, "STOP SLAVE;\n");
4105
static int add_slave_statements(void)
4108
fprintf(md_result_file,
4109
"\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
4110
fprintf(md_result_file, "START SLAVE;\n");
4114
static int do_show_slave_status(MYSQL *mysql_con)
4117
const char *comment_prefix=
4118
(opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
4119
if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
4123
/* SHOW SLAVE STATUS reports nothing and --force is not enabled */
4124
my_printf_error(0, "Error: Slave not set up", MYF(0));
4130
MYSQL_ROW row= mysql_fetch_row(slave);
4131
if (row && row[9] && row[21])
4133
/* SHOW MASTER STATUS reports file and position */
4135
fprintf(md_result_file,
4136
"\n--\n-- Position to start replication or point-in-time "
4137
"recovery from (the master of this slave)\n--\n\n");
4139
fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
4141
if (opt_include_master_host_port)
4144
fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
4146
fprintf(md_result_file, "MASTER_PORT='%s', ", row[3]);
4148
fprintf(md_result_file,
4149
"MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
4151
check_io(md_result_file);
4153
mysql_free_result(slave);
4158
static int do_start_slave_sql(MYSQL *mysql_con)
4161
/* We need to check if the slave sql is stopped in the first place */
4162
if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
4166
MYSQL_ROW row= mysql_fetch_row(slave);
4169
/* if SLAVE SQL is not running, we don't start it */
4170
if (!strcmp(row[11],"Yes"))
4172
mysql_free_result(slave);
4173
/* Silently assume that they don't have the slave running */
4178
mysql_free_result(slave);
4180
/* now, start slave if stopped */
4181
if (mysql_query_with_error_report(mysql_con, 0, "START SLAVE"))
4183
my_printf_error(0, "Error: Unable to start slave", MYF(0));
4191
static int do_flush_tables_read_lock(MYSQL *mysql_con)
4194
We do first a FLUSH TABLES. If a long update is running, the FLUSH TABLES
4195
will wait but will not stall the whole mysqld, and when the long update is
4196
done the FLUSH TABLES WITH READ LOCK will start and succeed quickly. So,
4197
FLUSH TABLES is to lower the probability of a stage where both mysqldump
4198
and most client connections are stalled. Of course, if a second long
4199
update starts between the two FLUSHes, we have that bad stall.
4202
( mysql_query_with_error_report(mysql_con, 0, "FLUSH TABLES") ||
4203
mysql_query_with_error_report(mysql_con, 0,
4204
"FLUSH TABLES WITH READ LOCK") );
4208
static int do_unlock_tables(MYSQL *mysql_con)
4210
return mysql_query_with_error_report(mysql_con, 0, "UNLOCK TABLES");
4213
static int get_bin_log_name(MYSQL *mysql_con,
4214
char* buff_log_name, uint buff_len)
4219
if (mysql_query(mysql_con, "SHOW MASTER STATUS") ||
4220
!(res= mysql_store_result(mysql)))
4223
if (!(row= mysql_fetch_row(res)))
4225
mysql_free_result(res);
4229
Only one row is returned, and the first column is the name of the
4232
strmake(buff_log_name, row[0], buff_len - 1);
4234
mysql_free_result(res);
4238
static int purge_bin_logs_to(MYSQL *mysql_con, char* log_name)
4242
init_dynamic_string_checked(&str, "PURGE BINARY LOGS TO '", 1024, 1024);
4243
dynstr_append_checked(&str, log_name);
4244
dynstr_append_checked(&str, "'");
4245
err = mysql_query_with_error_report(mysql_con, 0, str.str);
4251
static int start_transaction(MYSQL *mysql_con)
4254
We use BEGIN for old servers. --single-transaction --master-data will fail
4255
on old servers, but that's ok as it was already silently broken (it didn't
4256
do a consistent read, so better tell people frankly, with the error).
4258
We want the first consistent read to be used for all tables to dump so we
4259
need the REPEATABLE READ level (not anything lower, for example READ
4260
COMMITTED would give one new consistent read per dumped table).
4262
if ((mysql_get_server_version(mysql_con) < 40100) && opt_master_data)
4264
fprintf(stderr, "-- %s: the combination of --single-transaction and "
4265
"--master-data requires a MySQL server version of at least 4.1 "
4266
"(current server's version is %s). %s\n",
4267
ignore_errors ? "Warning" : "Error",
4268
mysql_con->server_version ? mysql_con->server_version : "unknown",
4269
ignore_errors ? "Continuing due to --force, backup may not be consistent across all tables!" : "Aborting.");
4274
return (mysql_query_with_error_report(mysql_con, 0,
4275
"SET SESSION TRANSACTION ISOLATION "
4276
"LEVEL REPEATABLE READ") ||
4277
mysql_query_with_error_report(mysql_con, 0,
4278
"START TRANSACTION "
4279
"/*!40100 WITH CONSISTENT SNAPSHOT */"));
4283
static ulong find_set(TYPELIB *lib, const char *x, uint length,
4284
char **err_pos, uint *err_len)
4286
const char *end= x + length;
4291
*err_pos= 0; /* No error yet */
4292
while (end > x && my_isspace(charset_info, end[-1]))
4298
const char *start= x;
4301
const char *pos= start;
4304
for (; pos != end && *pos != ','; pos++) ;
4305
var_len= (uint) (pos - start);
4306
strmake(buff, start, min(sizeof(buff), var_len));
4307
find= find_type(buff, lib, var_len);
4310
*err_pos= (char*) start;
4314
found|= ((longlong) 1 << (find - 1));
4324
/* Print a value with a prefix on file */
4325
static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
4326
const char *prefix, const char *name,
4330
mysql_field_seek(result, 0);
4332
for ( ; (field= mysql_fetch_field(result)) ; row++)
4334
if (!strcmp(field->name,name))
4336
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
4339
fputs(prefix, file);
4341
unescape(file,row[0],(uint) strlen(row[0]));
4343
fputs(row[0], file);
4349
return; /* This shouldn't happen */
4356
Check if we the table is one of the table types that should be ignored:
4357
MRG_ISAM, MRG_MYISAM, if opt_delayed, if that table supports delayed inserts.
4358
If the table should be altogether ignored, it returns a TRUE, FALSE if it
4359
should not be ignored. If the user has selected to use INSERT DELAYED, it
4360
sets the value of the bool pointer supports_delayed_inserts to 0 if not
4361
supported, 1 if it is supported.
4365
check_if_ignore_table()
4366
table_name Table name to check
4367
table_type Type of table
4370
mysql MySQL connection
4371
verbose Write warning messages
4374
char (bit value) See IGNORE_ values at top
4377
char check_if_ignore_table(const char *table_name, char *table_type)
4379
char result= IGNORE_NONE;
4380
char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
4381
MYSQL_RES *res= NULL;
4383
DBUG_ENTER("check_if_ignore_table");
4385
/* Check memory for quote_for_like() */
4386
DBUG_ASSERT(2*sizeof(table_name) < sizeof(show_name_buff));
4387
my_snprintf(buff, sizeof(buff), "show table status like %s",
4388
quote_for_like(table_name, show_name_buff));
4389
if (mysql_query_with_error_report(mysql, &res, buff))
4391
if (mysql_errno(mysql) != ER_PARSE_ERROR)
4392
{ /* If old MySQL version */
4393
verbose_msg("-- Warning: Couldn't get status information for "
4394
"table %s (%s)\n", table_name, mysql_error(mysql));
4395
DBUG_RETURN(result); /* assume table is ok */
4398
if (!(row= mysql_fetch_row(res)))
4401
"Error: Couldn't read status information for table %s (%s)\n",
4402
table_name, mysql_error(mysql));
4403
mysql_free_result(res);
4404
DBUG_RETURN(result); /* assume table is ok */
4407
strmake(table_type, "VIEW", NAME_LEN-1);
4411
If the table type matches any of these, we do support delayed inserts.
4412
Note: we do not want to skip dumping this table if if is not one of
4413
these types, but we do want to use delayed inserts in the dump if
4414
the table type is _NOT_ one of these types
4416
strmake(table_type, row[1], NAME_LEN-1);
4419
if (strcmp(table_type,"MyISAM") &&
4420
strcmp(table_type,"ISAM") &&
4421
strcmp(table_type,"ARCHIVE") &&
4422
strcmp(table_type,"HEAP") &&
4423
strcmp(table_type,"MEMORY"))
4424
result= IGNORE_INSERT_DELAYED;
4428
If these two types, we do want to skip dumping the table
4431
(!my_strcasecmp(&my_charset_latin1, table_type, "MRG_MyISAM") ||
4432
!strcmp(table_type,"MRG_ISAM")))
4433
result= IGNORE_DATA;
4435
mysql_free_result(res);
4436
DBUG_RETURN(result);
4441
Get string of comma-separated primary key field names
4444
char *primary_key_fields(const char *table_name)
4445
RETURNS pointer to allocated buffer (must be freed by caller)
4446
table_name quoted table name
4449
Use SHOW KEYS FROM table_name, allocate a buffer to hold the
4450
field names, and then build that string and return the pointer
4453
Returns NULL if there is no PRIMARY or UNIQUE key on the table,
4454
or if there is some failure. It is better to continue to dump
4455
the table unsorted, rather than exit without dumping the data.
4458
static char *primary_key_fields(const char *table_name)
4460
MYSQL_RES *res= NULL;
4462
/* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */
4463
char show_keys_buff[15 + NAME_LEN * 2 + 3];
4464
uint result_length= 0;
4466
char buff[NAME_LEN * 2 + 3];
4469
my_snprintf(show_keys_buff, sizeof(show_keys_buff),
4470
"SHOW KEYS FROM %s", table_name);
4471
if (mysql_query(mysql, show_keys_buff) ||
4472
!(res= mysql_store_result(mysql)))
4474
fprintf(stderr, "Warning: Couldn't read keys from table %s;"
4475
" records are NOT sorted (%s)\n",
4476
table_name, mysql_error(mysql));
4477
/* Don't exit, because it's better to print out unsorted records */
4482
* Figure out the length of the ORDER BY clause result.
4483
* Note that SHOW KEYS is ordered: a PRIMARY key is always the first
4484
* row, and UNIQUE keys come before others. So we only need to check
4485
* the first key, not all keys.
4487
if ((row= mysql_fetch_row(res)) && atoi(row[1]) == 0)
4492
quoted_field= quote_name(row[4], buff, 0);
4493
result_length+= strlen(quoted_field) + 1; /* + 1 for ',' or \0 */
4494
} while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1);
4497
/* Build the ORDER BY clause result */
4501
/* result (terminating \0 is already in result_length) */
4502
result= my_malloc(result_length + 10, MYF(MY_WME));
4505
fprintf(stderr, "Error: Not enough memory to store ORDER BY clause\n");
4508
mysql_data_seek(res, 0);
4509
row= mysql_fetch_row(res);
4510
quoted_field= quote_name(row[4], buff, 0);
4511
end= strmov(result, quoted_field);
4512
while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1)
4514
quoted_field= quote_name(row[4], buff, 0);
4515
end= strxmov(end, ",", quoted_field, NullS);
4521
mysql_free_result(res);
4532
ds_str The string to search and perform the replace in
4533
search_str The string to search for
4534
search_len Length of the string to search for
4535
replace_str The string to replace with
4536
replace_len Length of the string to replace with
4540
1 Could not find search_str in str
4543
static int replace(DYNAMIC_STRING *ds_str,
4544
const char *search_str, ulong search_len,
4545
const char *replace_str, ulong replace_len)
4547
DYNAMIC_STRING ds_tmp;
4548
const char *start= strstr(ds_str->str, search_str);
4551
init_dynamic_string_checked(&ds_tmp, "",
4552
ds_str->length + replace_len, 256);
4553
dynstr_append_mem_checked(&ds_tmp, ds_str->str, start - ds_str->str);
4554
dynstr_append_mem_checked(&ds_tmp, replace_str, replace_len);
4555
dynstr_append_checked(&ds_tmp, start + search_len);
4556
dynstr_set_checked(ds_str, ds_tmp.str);
4557
dynstr_free(&ds_tmp);
4563
Getting VIEW structure
4566
get_view_structure()
4575
static my_bool get_view_structure(char *table, char* db)
4577
MYSQL_RES *table_res;
4580
char *result_table, *opt_quoted_table;
4581
char table_buff[NAME_LEN*2+3];
4582
char table_buff2[NAME_LEN*2+3];
4583
char query[QUERY_LENGTH];
4584
FILE *sql_file= md_result_file;
4585
DBUG_ENTER("get_view_structure");
4587
if (opt_no_create_info) /* Don't write table creation info */
4590
verbose_msg("-- Retrieving view structure for table %s...\n", table);
4592
#ifdef NOT_REALLY_USED_YET
4593
sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
4594
(opt_quoted || opt_keywords));
4597
result_table= quote_name(table, table_buff, 1);
4598
opt_quoted_table= quote_name(table, table_buff2, 0);
4600
if (switch_character_set_results(mysql, "binary"))
4603
my_snprintf(query, sizeof(query), "SHOW CREATE TABLE %s", result_table);
4605
if (mysql_query_with_error_report(mysql, &table_res, query))
4607
switch_character_set_results(mysql, default_charset);
4611
/* Check if this is a view */
4612
field= mysql_fetch_field_direct(table_res, 0);
4613
if (strcmp(field->name, "View") != 0)
4615
switch_character_set_results(mysql, default_charset);
4616
verbose_msg("-- It's base table, skipped\n");
4620
/* If requested, open separate .sql file for this view */
4623
if (!(sql_file= open_sql_file_for_table(table)))
4626
write_header(sql_file, db);
4629
if (!opt_xml && opt_comments)
4631
fprintf(sql_file, "\n--\n-- Final view structure for view %s\n--\n\n",
4635
fprintf(sql_file, "/*!50001 DROP TABLE %s*/;\n", opt_quoted_table);
4638
fprintf(sql_file, "/*!50001 DROP VIEW IF EXISTS %s*/;\n",
4644
my_snprintf(query, sizeof(query),
4645
"SELECT CHECK_OPTION, DEFINER, SECURITY_TYPE, "
4646
" CHARACTER_SET_CLIENT, COLLATION_CONNECTION "
4647
"FROM information_schema.views "
4648
"WHERE table_name=\"%s\" AND table_schema=\"%s\"", table, db);
4650
if (mysql_query(mysql, query))
4653
Use the raw output from SHOW CREATE TABLE if
4654
information_schema query fails.
4656
row= mysql_fetch_row(table_res);
4657
fprintf(sql_file, "/*!50001 %s */;\n", row[1]);
4659
mysql_free_result(table_res);
4665
char search_buf[256], replace_buf[256];
4666
ulong search_len, replace_len;
4667
DYNAMIC_STRING ds_view;
4669
/* Save the result of SHOW CREATE TABLE in ds_view */
4670
row= mysql_fetch_row(table_res);
4671
lengths= mysql_fetch_lengths(table_res);
4672
init_dynamic_string_checked(&ds_view, row[1], lengths[1] + 1, 1024);
4673
mysql_free_result(table_res);
4675
/* Get the result from "select ... information_schema" */
4676
if (!(table_res= mysql_store_result(mysql)) ||
4677
!(row= mysql_fetch_row(table_res)))
4680
mysql_free_result(table_res);
4681
dynstr_free(&ds_view);
4682
DB_error(mysql, "when trying to save the result of SHOW CREATE TABLE in ds_view.");
4686
lengths= mysql_fetch_lengths(table_res);
4689
"WITH %s CHECK OPTION" is available from 5.0.2
4690
Surround it with !50002 comments
4692
if (strcmp(row[0], "NONE"))
4696
search_len= (ulong)(strxmov(ptr, "WITH ", row[0],
4697
" CHECK OPTION", NullS) - ptr);
4699
replace_len=(ulong)(strxmov(ptr, "*/\n/*!50002 WITH ", row[0],
4700
" CHECK OPTION", NullS) - ptr);
4701
replace(&ds_view, search_buf, search_len, replace_buf, replace_len);
4705
"DEFINER=%s SQL SECURITY %s" is available from 5.0.13
4706
Surround it with !50013 comments
4709
size_t user_name_len;
4710
char user_name_str[USERNAME_LENGTH + 1];
4711
char quoted_user_name_str[USERNAME_LENGTH * 2 + 3];
4712
size_t host_name_len;
4713
char host_name_str[HOSTNAME_LENGTH + 1];
4714
char quoted_host_name_str[HOSTNAME_LENGTH * 2 + 3];
4716
parse_user(row[1], lengths[1], user_name_str, &user_name_len,
4717
host_name_str, &host_name_len);
4721
(ulong)(strxmov(ptr, "DEFINER=",
4722
quote_name(user_name_str, quoted_user_name_str, FALSE),
4724
quote_name(host_name_str, quoted_host_name_str, FALSE),
4725
" SQL SECURITY ", row[2], NullS) - ptr);
4728
(ulong)(strxmov(ptr, "*/\n/*!50013 DEFINER=",
4729
quote_name(user_name_str, quoted_user_name_str, FALSE),
4731
quote_name(host_name_str, quoted_host_name_str, FALSE),
4732
" SQL SECURITY ", row[2],
4733
" */\n/*!50001", NullS) - ptr);
4734
replace(&ds_view, search_buf, search_len, replace_buf, replace_len);
4737
/* Dump view structure to file */
4740
"/*!50001 SET @saved_cs_client = @@character_set_client */;\n"
4741
"/*!50001 SET @saved_cs_results = @@character_set_results */;\n"
4742
"/*!50001 SET @saved_col_connection = @@collation_connection */;\n"
4743
"/*!50001 SET character_set_client = %s */;\n"
4744
"/*!50001 SET character_set_results = %s */;\n"
4745
"/*!50001 SET collation_connection = %s */;\n"
4747
"/*!50001 SET character_set_client = @saved_cs_client */;\n"
4748
"/*!50001 SET character_set_results = @saved_cs_results */;\n"
4749
"/*!50001 SET collation_connection = @saved_col_connection */;\n",
4750
(const char *) row[3],
4751
(const char *) row[3],
4752
(const char *) row[4],
4753
(const char *) ds_view.str);
4756
mysql_free_result(table_res);
4757
dynstr_free(&ds_view);
4760
if (switch_character_set_results(mysql, default_charset))
4763
/* If a separate .sql file was opened, close it now */
4764
if (sql_file != md_result_file)
4766
fputs("\n", sql_file);
4767
write_footer(sql_file);
4768
my_fclose(sql_file, MYF(MY_WME));
4774
The following functions are wrappers for the dynamic string functions
4775
and if they fail, the wrappers will terminate the current process.
4778
#define DYNAMIC_STR_ERROR_MSG "Couldn't perform DYNAMIC_STRING operation"
4780
static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str,
4781
uint init_alloc, uint alloc_increment)
4783
if (init_dynamic_string(str, init_str, init_alloc, alloc_increment))
4784
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
4787
static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src)
4789
if (dynstr_append(dest, src))
4790
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
4793
static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str)
4795
if (dynstr_set(str, init_str))
4796
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
4799
static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append,
4802
if (dynstr_append_mem(str, append, length))
4803
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
4806
static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size)
4808
if (dynstr_realloc(str, additional_size))
4809
die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG);
4813
int main(int argc, char **argv)
4815
char bin_log_name[FN_REFLEN];
4817
MY_INIT("mysqldump");
4819
compatible_mode_normal_str[0]= 0;
4820
default_charset= (char *)mysql_universal_client_charset;
4821
bzero((char*) &ignore_table, sizeof(ignore_table));
4823
exit_code= get_options(&argc, &argv);
4832
if(!(stderror_file= freopen(log_error_file, "a+", stderr)))
4839
if (connect_to_db(current_host, current_user, opt_password))
4845
write_header(md_result_file, *argv);
4847
if (opt_slave_data && do_stop_slave_sql(mysql))
4850
if ((opt_lock_all_tables || opt_master_data) &&
4851
do_flush_tables_read_lock(mysql))
4853
if (opt_single_transaction && start_transaction(mysql))
4855
if (opt_delete_master_logs)
4857
if (mysql_refresh(mysql, REFRESH_LOG) ||
4858
get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name)))
4862
if (opt_lock_all_tables || opt_master_data)
4864
if (flush_logs && mysql_refresh(mysql, REFRESH_LOG))
4866
flush_logs= 0; /* not anymore; that would not be sensible */
4868
/* Add 'STOP SLAVE to beginning of dump */
4869
if (opt_slave_apply && add_stop_slave())
4871
if (opt_master_data && do_show_master_status(mysql))
4873
if (opt_slave_data && do_show_slave_status(mysql))
4875
if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */
4879
dump_all_tablespaces();
4883
if (!opt_alltspcs && !opt_notspcs)
4884
dump_all_tablespaces();
4885
dump_all_databases();
4887
else if (argc > 1 && !opt_databases)
4889
/* Only one database and selected table(s) */
4890
if (!opt_alltspcs && !opt_notspcs)
4891
dump_tablespaces_for_tables(*argv, (argv + 1), (argc -1));
4892
dump_selected_tables(*argv, (argv + 1), (argc - 1));
4896
/* One or more databases, all tables */
4897
if (!opt_alltspcs && !opt_notspcs)
4898
dump_tablespaces_for_databases(argv);
4899
dump_databases(argv);
4902
/* if --dump-slave , start the slave sql thread */
4903
if (opt_slave_data && do_start_slave_sql(mysql))
4906
/* add 'START SLAVE' to end of dump */
4907
if (opt_slave_apply && add_slave_statements())
4910
/* ensure dumped data flushed */
4911
if (md_result_file && fflush(md_result_file))
4914
first_error= EX_MYSQLERR;
4917
/* everything successful, purge the old logs files */
4918
if (opt_delete_master_logs && purge_bin_logs_to(mysql, bin_log_name))
4922
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
4925
No reason to explicitely COMMIT the transaction, neither to explicitely
4926
UNLOCK TABLES: these will be automatically be done by the server when we
4927
disconnect now. Saves some code here, some network trips, adds nothing to
4931
dbDisconnect(current_host);
4933
write_footer(md_result_file);
4937
fclose(stderror_file);
4939
return(first_error);