summaryrefslogtreecommitdiff
path: root/client/mysqldump.c
diff options
context:
space:
mode:
Diffstat (limited to 'client/mysqldump.c')
-rw-r--r--client/mysqldump.c763
1 files changed, 497 insertions, 266 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 27582260cb9..c20d4947185 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -12,7 +12,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* mysqldump.c - Dump a tables contents and format to an ASCII file
@@ -52,7 +52,8 @@
#include "mysql.h"
#include "mysql_version.h"
#include "mysqld_error.h"
-#include "../sql/ha_ndbcluster_tables.h"
+
+#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
/* Exit codes */
@@ -85,6 +86,15 @@
/* Chars needed to store LONGLONG, excluding trailing '\0'. */
#define LONGLONG_LEN 20
+/* general_log or slow_log tables under mysql database */
+static inline my_bool general_log_or_slow_log_tables(const char *db,
+ const char *table)
+{
+ return (strcmp(db, "mysql") == 0) &&
+ ((strcmp(table, "general_log") == 0) ||
+ (strcmp(table, "slow_log") == 0));
+}
+
static void add_load_option(DYNAMIC_STRING *str, const char *option,
const char *option_value);
static ulong find_set(TYPELIB *lib, const char *x, uint length,
@@ -106,6 +116,8 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
opt_complete_insert= 0, opt_drop_database= 0,
opt_replace_into= 0,
opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
+ opt_slave_apply= 0,
+ opt_include_master_host_port= 0,
opt_events= 0, opt_comments_used= 0,
opt_alltspcs=0, opt_notspcs= 0;
static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
@@ -126,7 +138,10 @@ static my_bool server_supports_switching_charsets= TRUE;
static ulong opt_compatible_mode= 0;
#define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
#define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
+#define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
+#define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2
static uint opt_mysql_port= 0, opt_master_data;
+static uint opt_slave_data;
static uint my_end_arg;
static char * opt_mysql_unix_port=0;
static int first_error=0;
@@ -139,6 +154,7 @@ FILE *stderror_file=0;
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol= 0;
+static char *opt_plugin_dir= 0, *opt_default_auth= 0;
/*
Dynamic_string wrapper functions. In this file use these
@@ -187,9 +203,6 @@ HASH ignore_table;
static struct my_option my_long_options[] =
{
- {"all", OPT_ALL, "Deprecated. Use --create-options instead.",
- &create_options, &create_options, 0, GET_BOOL, NO_ARG, 1,
- 0, 0, 0, 0, 0},
{"all-databases", 'A',
"Dump all the databases. This will be same as --databases with all databases selected.",
&opt_alldbs, &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
@@ -214,10 +227,10 @@ static struct my_option my_long_options[] =
{"allow-keywords", OPT_KEYWORDS,
"Allow creation of column names that are keywords.", &opt_keywords,
&opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef __NETWARE__
- {"autoclose", OPT_AUTO_CLOSE, "Automatically close the screen on exit for Netware.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif
+ {"apply-slave-statements", OPT_MYSQLDUMP_SLAVE_APPLY,
+ "Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
+ &opt_slave_apply, &opt_slave_apply, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory for character set files.", (char**) &charsets_dir,
(char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -225,13 +238,20 @@ static struct my_option my_long_options[] =
&opt_comments, &opt_comments, 0, GET_BOOL, NO_ARG,
1, 0, 0, 0, 0, 0},
{"compatible", OPT_COMPATIBLE,
- "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.",
+ "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.",
&opt_compatible_mode_str, &opt_compatible_mode_str, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"compact", OPT_COMPACT,
- "Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables options --skip-add-drop-table --skip-add-locks --skip-comments --skip-disable-keys --skip-set-charset.",
- &opt_compact, &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
- 0, 0},
+ "Give less verbose output (useful for debugging). Disables structure "
+ "comments and header/footer constructs. Enables options --skip-add-"
+ "drop-table --skip-add-locks --skip-comments --skip-disable-keys "
+ "--skip-set-charset.",
+ &opt_compact, &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"complete-insert", 'c', "Use complete insert statements.",
&opt_complete_insert, &opt_complete_insert, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -270,8 +290,22 @@ static struct my_option my_long_options[] =
&opt_delete_master_logs, &opt_delete_master_logs, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"disable-keys", 'K',
- "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", &opt_disable_keys,
+ "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER "
+ "TABLE tb_name ENABLE KEYS */; will be put in the output.", &opt_disable_keys,
&opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"dump-slave", OPT_MYSQLDUMP_SLAVE_DATA,
+ "This causes the binary log position and filename of the master to be "
+ "appended to the dumped data output. Setting the value to 1, will print"
+ "it as a CHANGE MASTER command in the dumped data output; if equal"
+ " to 2, that command will be prefixed with a comment symbol. "
+ "This option will turn --lock-all-tables on, unless "
+ "--single-transaction is specified too (in which case a "
+ "global read lock is only taken a short time at the beginning of the dump "
+ "- don't forget to read about --single-transaction below). In all cases "
+ "any action on logs will happen at the exact moment of the dump."
+ "Option automatically turns --lock-tables off.",
+ &opt_slave_data, &opt_slave_data, 0,
+ GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
{"events", 'E', "Dump events.",
&opt_events, &opt_events, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -280,24 +314,18 @@ static struct my_option my_long_options[] =
&extended_insert, &extended_insert, 0, GET_BOOL, NO_ARG,
1, 0, 0, 0, 0, 0},
{"fields-terminated-by", OPT_FTB,
- "Fields in the output file are terminated by the given string.",
- &fields_terminated, &fields_terminated, 0,
+ "Fields in the output file are terminated by the given string.",
+ &fields_terminated, &fields_terminated, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"fields-enclosed-by", OPT_ENC,
- "Fields in the output file are enclosed by the given character.",
- &enclosed, &enclosed, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
+ "Fields in the output file are enclosed by the given character.",
+ &enclosed, &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
{"fields-optionally-enclosed-by", OPT_O_ENC,
- "Fields in the output file are optionally enclosed by the given character.",
- &opt_enclosed, &opt_enclosed, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
- {"fields-escaped-by", OPT_ESC,
+ "Fields in the output file are optionally enclosed by the given character.",
+ &opt_enclosed, &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
+ {"fields-escaped-by", OPT_ESC,
"Fields in the output file are escaped by the given character.",
- &escaped, &escaped, 0,
- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"first-slave", OPT_FIRST_SLAVE, "Deprecated, renamed to --lock-all-tables.",
- &opt_lock_all_tables, &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
- 0, 0, 0, 0, 0, 0},
+ &escaped, &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"flush-logs", 'F', "Flush logs file in server before starting dump. "
"Note that if you dump many databases at once (using the option "
"--databases= or --all-databases), the logs will be flushed for "
@@ -331,10 +359,15 @@ static struct my_option my_long_options[] =
"be specified with both database and table names, e.g., "
"--ignore-table=database.table.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"include-master-host-port", OPT_MYSQLDUMP_INCLUDE_MASTER_HOST_PORT,
+ "Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' "
+ "in dump produced with --dump-slave.", &opt_include_master_host_port,
+ &opt_include_master_host_port, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
{"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
&opt_ignore, &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
- {"lines-terminated-by", OPT_LTB,
+ {"lines-terminated-by", OPT_LTB,
"Lines in the output file are terminated by the given string.",
&lines_terminated, &lines_terminated, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -385,7 +418,7 @@ static struct my_option my_long_options[] =
NO_ARG, 0, 0, 0, 0, 0, 0},
{"no-data", 'd', "No row information.", &opt_no_data,
&opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"no-set-names", 'N',"Suppress the SET NAMES statement",
+ {"no-set-names", 'N', "Same as --skip-set-charset.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"opt", OPT_OPTIMIZE,
"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.",
@@ -415,18 +448,17 @@ static struct my_option my_long_options[] =
&opt_replace_into, &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
{"result-file", 'r',
- "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).",
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ "Direct output to a given file. This option should be used in systems "
+ "(e.g., DOS, Windows) that use carriage-return linefeed pairs (\\r\\n) "
+ "to separate text lines. This option ensures that only a single newline "
+ "is used.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"routines", 'R', "Dump stored routines (functions and procedures).",
- &opt_routines, &opt_routines, 0, GET_BOOL,
- NO_ARG, 0, 0, 0, 0, 0, 0},
+ &opt_routines, &opt_routines, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
{"set-charset", OPT_SET_CHARSET,
- "Add 'SET NAMES default_character_set' to the output. Enabled by default; suppress with --skip-set-charset.",
+ "Add 'SET NAMES default_character_set' to the output.",
&opt_set_charset, &opt_set_charset, 0, GET_BOOL, NO_ARG, 1,
0, 0, 0, 0, 0},
- {"set-variable", 'O',
- "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_SMEM
{"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
"Base name of shared memory.", &shared_memory_base_name, &shared_memory_base_name,
@@ -485,6 +517,13 @@ static struct my_option my_long_options[] =
&where, &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"plugin_dir", OPT_PLUGIN_DIR, "Directory for client-side plugins.",
+ &opt_plugin_dir, &opt_plugin_dir, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"default_auth", OPT_DEFAULT_AUTH,
+ "Default authentication client-side plugin to use.",
+ &opt_default_auth, &opt_default_auth, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -517,7 +556,6 @@ static int dump_tablespaces(char* ts_where);
static void print_comment(FILE *sql_file, my_bool is_error, const char *format,
...);
-#include <help_start.h>
/*
Print the supplied message if in verbose mode
@@ -540,6 +578,8 @@ static void verbose_msg(const char *fmt, ...)
vfprintf(stderr, fmt, args);
va_end(args);
+ fflush(stderr);
+
DBUG_VOID_RETURN;
}
@@ -559,19 +599,17 @@ void check_io(FILE *file)
static void print_version(void)
{
- printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,DUMP_VERSION,
+ printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname_short,DUMP_VERSION,
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
- NETWARE_SET_SCREEN_MODE(1);
} /* print_version */
static void short_usage_sub(void)
{
- printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
+ printf("Usage: %s [OPTIONS] database [tables]\n", my_progname_short);
printf("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n",
- my_progname);
- printf("OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname);
- NETWARE_SET_SCREEN_MODE(1);
+ my_progname_short);
+ printf("OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname_short);
}
@@ -591,11 +629,9 @@ static void usage(void)
static void short_usage(void)
{
short_usage_sub();
- printf("For more options, use %s --help\n", my_progname);
+ printf("For more options, use %s --help\n", my_progname_short);
}
-#include <help_end.h>
-
static void write_header(FILE *sql_file, char *db_name)
{
@@ -708,12 +744,6 @@ static void write_footer(FILE *sql_file)
} /* write_footer */
-static void free_table_ent(char *key)
-{
- my_free(key, MYF(0));
-}
-
-
uchar* get_table_key(const char *entry, size_t *length,
my_bool not_used __attribute__((unused)))
{
@@ -727,18 +757,13 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument)
{
switch (optid) {
-#ifdef __NETWARE__
- case OPT_AUTO_CLOSE:
- setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
- break;
-#endif
case 'p':
if (argument == disabled_my_option)
argument= (char*) ""; /* Don't require password */
if (argument)
{
char *start=argument;
- my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(opt_password);
opt_password=my_strdup(argument,MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
if (*start)
@@ -794,19 +819,14 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case '?':
usage();
exit(0);
- case 'O':
- WARN_DEPRECATED(VER_CELOSIA, "--set-variable", "--variable-name=value");
- break;
- case (int) OPT_ALL:
- WARN_DEPRECATED(VER_CELOSIA, "--all", "--create-options");
- break;
- case (int) OPT_FIRST_SLAVE:
- WARN_DEPRECATED(VER_CELOSIA, "--first-slave", "--lock-all-tables");
- break;
case (int) OPT_MASTER_DATA:
if (!argument) /* work like in old versions */
opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL;
break;
+ case (int) OPT_MYSQLDUMP_SLAVE_DATA:
+ if (!argument) /* work like in old versions */
+ opt_slave_data= MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL;
+ break;
case (int) OPT_OPTIMIZE:
extended_insert= opt_drop= opt_lock= quick= create_options=
opt_disable_keys= lock_tables= opt_set_charset= 1;
@@ -902,12 +922,12 @@ static int get_options(int *argc, char ***argv)
opt_net_buffer_length= *mysql_params->p_net_buffer_length;
md_result_file= stdout;
- load_defaults("my",load_default_groups,argc,argv);
+ if (load_defaults("my",load_default_groups,argc,argv))
+ return 1;
defaults_argv= *argv;
- if (hash_init(&ignore_table, charset_info, 16, 0, 0,
- (hash_get_key) get_table_key,
- (hash_free_key) free_table_ent, 0))
+ if (my_hash_init(&ignore_table, charset_info, 16, 0, 0,
+ (my_hash_get_key) get_table_key, my_free, 0))
return(EX_EOM);
/* Don't copy internal log tables */
if (my_hash_insert(&ignore_table,
@@ -936,33 +956,44 @@ static int get_options(int *argc, char ***argv)
fields_terminated))
{
fprintf(stderr,
- "%s: You must use option --tab with --fields-...\n", my_progname);
+ "%s: You must use option --tab with --fields-...\n", my_progname_short);
return(EX_USAGE);
}
+ /* We don't delete master logs if slave data option */
+ if (opt_slave_data)
+ {
+ opt_lock_all_tables= !opt_single_transaction;
+ opt_master_data= 0;
+ opt_delete_master_logs= 0;
+ }
+
/* Ensure consistency of the set of binlog & locking options */
if (opt_delete_master_logs && !opt_master_data)
opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL;
if (opt_single_transaction && opt_lock_all_tables)
{
fprintf(stderr, "%s: You can't use --single-transaction and "
- "--lock-all-tables at the same time.\n", my_progname);
+ "--lock-all-tables at the same time.\n", my_progname_short);
return(EX_USAGE);
}
if (opt_master_data)
+ {
opt_lock_all_tables= !opt_single_transaction;
+ opt_slave_data= 0;
+ }
if (opt_single_transaction || opt_lock_all_tables)
lock_tables= 0;
if (enclosed && opt_enclosed)
{
- fprintf(stderr, "%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n", my_progname);
+ fprintf(stderr, "%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n", my_progname_short);
return(EX_USAGE);
}
if ((opt_databases || opt_alldbs) && path)
{
fprintf(stderr,
"%s: --databases or --all-databases can't be used with --tab.\n",
- my_progname);
+ my_progname_short);
return(EX_USAGE);
}
if (strcmp(default_charset, charset_info->csname) &&
@@ -1014,7 +1045,7 @@ static void die(int error_num, const char* fmt_reason, ...)
my_vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
va_end(args);
- fprintf(stderr, "%s: %s\n", my_progname, buffer);
+ fprintf(stderr, "%s: %s\n", my_progname_short, buffer);
fflush(stderr);
ignore_errors= 0; /* force the exit */
@@ -1048,7 +1079,7 @@ static void maybe_die(int error_num, const char* fmt_reason, ...)
my_vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
va_end(args);
- fprintf(stderr, "%s: %s\n", my_progname, buffer);
+ fprintf(stderr, "%s: %s\n", my_progname_short, buffer);
fflush(stderr);
maybe_exit(error_num);
@@ -1361,120 +1392,68 @@ static int switch_character_set_results(MYSQL *mysql, const char *cs_name)
}
/**
- Rewrite CREATE TRIGGER statement, enclosing DEFINER clause in
- version-specific comment.
-
- This function parses the CREATE TRIGGER statement and encloses
- DEFINER-clause in version-specific comment:
- input query: CREATE DEFINER=a@b TRIGGER ...
- rewritten query: CREATE * / / *!50017 DEFINER=a@b * / / *!50003 TRIGGER ...
-
- @note This function will go away when WL#3995 is implemented.
-
- @param[in] trigger_def_str CREATE TRIGGER statement string.
- @param[in] trigger_def_length length of the trigger_def_str.
-
- @return pointer to the new allocated query string.
-*/
-
-static char *cover_definer_clause_in_trigger(const char *trigger_def_str,
- uint trigger_def_length)
-{
- char *query_str= NULL;
- char *definer_begin= my_case_str(trigger_def_str, trigger_def_length,
- C_STRING_WITH_LEN(" DEFINER"));
- char *definer_end;
-
- if (!definer_begin)
- return NULL;
-
- definer_end= my_case_str(definer_begin, strlen(definer_begin),
- C_STRING_WITH_LEN(" TRIGGER"));
-
- if (definer_end)
- {
- char *query_str_tail;
-
- /*
- Allocate memory for new query string: original string
- from SHOW statement and version-specific comments.
- */
- query_str= alloc_query_str(trigger_def_length + 23);
-
- query_str_tail= strnmov(query_str,
- trigger_def_str,
- definer_begin - trigger_def_str);
-
- query_str_tail= strmov(query_str_tail,
- "*/ /*!50017");
-
- query_str_tail= strnmov(query_str_tail,
- definer_begin,
- definer_end - definer_begin);
-
- query_str_tail= strxmov(query_str_tail,
- "*/ /*!50003",
- definer_end,
- NullS);
- }
-
- return query_str;
-}
-
-/**
- Rewrite CREATE FUNCTION or CREATE PROCEDURE statement, enclosing DEFINER
- clause in version-specific comment.
+ Rewrite statement, enclosing DEFINER clause in version-specific comment.
- This function parses the CREATE FUNCTION | PROCEDURE statement and
- encloses DEFINER-clause in version-specific comment:
+ This function parses any CREATE statement and encloses DEFINER-clause in
+ version-specific comment:
input query: CREATE DEFINER=a@b FUNCTION ...
rewritten query: CREATE * / / *!50020 DEFINER=a@b * / / *!50003 FUNCTION ...
@note This function will go away when WL#3995 is implemented.
- @param[in] def_str CREATE FUNCTION|PROCEDURE statement string.
- @param[in] def_str_length length of the def_str.
+ @param[in] stmt_str CREATE statement string.
+ @param[in] stmt_length Length of the stmt_str.
+ @param[in] definer_version_str Minimal MySQL version number when
+ DEFINER clause is supported in the
+ given statement.
+ @param[in] definer_version_length Length of definer_version_str.
+ @param[in] stmt_version_str Minimal MySQL version number when the
+ given statement is supported.
+ @param[in] stmt_version_length Length of stmt_version_str.
+ @param[in] keyword_str Keyword to look for after CREATE.
+ @param[in] keyword_length Length of keyword_str.
@return pointer to the new allocated query string.
*/
-static char *cover_definer_clause_in_sp(const char *def_str,
- uint def_str_length)
+static char *cover_definer_clause(const char *stmt_str,
+ uint stmt_length,
+ const char *definer_version_str,
+ uint definer_version_length,
+ const char *stmt_version_str,
+ uint stmt_version_length,
+ const char *keyword_str,
+ uint keyword_length)
{
- char *query_str= NULL;
- char *definer_begin= my_case_str(def_str, def_str_length,
+ char *definer_begin= my_case_str(stmt_str, stmt_length,
C_STRING_WITH_LEN(" DEFINER"));
- char *definer_end;
+ char *definer_end= NULL;
+
+ char *query_str= NULL;
+ char *query_ptr;
if (!definer_begin)
return NULL;
definer_end= my_case_str(definer_begin, strlen(definer_begin),
- C_STRING_WITH_LEN(" PROCEDURE"));
+ keyword_str, keyword_length);
if (!definer_end)
- {
- definer_end= my_case_str(definer_begin, strlen(definer_begin),
- C_STRING_WITH_LEN(" FUNCTION"));
- }
+ return NULL;
- if (definer_end)
- {
- char *query_str_tail;
+ /*
+ Allocate memory for new query string: original string
+ from SHOW statement and version-specific comments.
+ */
+ query_str= alloc_query_str(stmt_length + 23);
- /*
- Allocate memory for new query string: original string
- from SHOW statement and version-specific comments.
- */
- query_str= alloc_query_str(def_str_length + 23);
-
- query_str_tail= strnmov(query_str, def_str, definer_begin - def_str);
- query_str_tail= strmov(query_str_tail, "*/ /*!50020");
- query_str_tail= strnmov(query_str_tail, definer_begin,
- definer_end - definer_begin);
- query_str_tail= strxmov(query_str_tail, "*/ /*!50003",
- definer_end, NullS);
- }
+ query_ptr= strnmov(query_str, stmt_str, definer_begin - stmt_str);
+ query_ptr= strnmov(query_ptr, C_STRING_WITH_LEN("*/ /*!"));
+ query_ptr= strnmov(query_ptr, definer_version_str, definer_version_length);
+ query_ptr= strnmov(query_ptr, definer_begin, definer_end - definer_begin);
+ query_ptr= strnmov(query_ptr, C_STRING_WITH_LEN("*/ /*!"));
+ query_ptr= strnmov(query_ptr, stmt_version_str, stmt_version_length);
+ query_ptr= strxmov(query_ptr, definer_end, NullS);
return query_str;
}
@@ -1506,16 +1485,17 @@ static void free_resources()
{
if (md_result_file && md_result_file != stdout)
my_fclose(md_result_file, MYF(0));
- my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
- my_free(current_host, MYF(MY_ALLOW_ZERO_PTR));
- if (hash_inited(&ignore_table))
- hash_free(&ignore_table);
+ my_free(opt_password);
+ my_free(current_host);
+ if (my_hash_inited(&ignore_table))
+ my_hash_free(&ignore_table);
if (extended_insert)
dynstr_free(&extended_row);
if (insert_pat_inited)
dynstr_free(&insert_pat);
if (defaults_argv)
free_defaults(defaults_argv);
+ mysql_library_end();
my_end(my_end_arg);
}
@@ -1560,9 +1540,16 @@ static int connect_to_db(char *host, char *user,char *passwd)
mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
#endif
mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
- if (!(mysql= mysql_real_connect(&mysql_connection,host,user,passwd,
- NULL,opt_mysql_port,opt_mysql_unix_port,
- 0)))
+
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(&mysql_connection, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
+ if (opt_default_auth && *opt_default_auth)
+ mysql_options(&mysql_connection, MYSQL_DEFAULT_AUTH, opt_default_auth);
+
+ mysql= &mysql_connection; /* So we can mysql_close() it properly */
+ if (!mysql_real_connect(&mysql_connection,host,user,passwd,
+ NULL,opt_mysql_port,opt_mysql_unix_port, 0))
{
DB_error(&mysql_connection, "when trying to connect");
DBUG_RETURN(1);
@@ -1621,7 +1608,7 @@ static void unescape(FILE *file,char *pos,uint length)
fputs(tmp, file);
fputc('\'', file);
check_io(file);
- my_free(tmp, MYF(MY_WME));
+ my_free(tmp);
DBUG_VOID_RETURN;
} /* unescape */
@@ -2165,6 +2152,8 @@ static uint dump_events_for_db(char *db)
*/
if (strlen(row[3]) != 0)
{
+ char *query_str;
+
if (opt_drop)
fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */%s\n",
event_name, delimiter);
@@ -2172,7 +2161,7 @@ static uint dump_events_for_db(char *db)
if (create_delimiter(row[3], delimiter, sizeof(delimiter)) == NULL)
{
fprintf(stderr, "%s: Warning: Can't create delimiter for event '%s'\n",
- my_progname, event_name);
+ my_progname_short, event_name);
DBUG_RETURN(1);
}
@@ -2191,31 +2180,36 @@ static uint dump_events_for_db(char *db)
row[4], /* character_set_results */
row[5]); /* collation_connection */
}
- else
- {
- /*
- mysqldump is being run against the server, that does not
- provide character set information in SHOW CREATE
- statements.
+ else
+ {
+ /*
+ mysqldump is being run against the server, that does not
+ provide character set information in SHOW CREATE
+ statements.
- NOTE: the dump may be incorrect, since character set
- information is required in order to restore event properly.
- */
+ NOTE: the dump may be incorrect, since character set
+ information is required in order to restore event properly.
+ */
- fprintf(sql_file,
- "--\n"
- "-- WARNING: old server version. "
- "The following dump may be incomplete.\n"
- "--\n");
- }
+ fprintf(sql_file,
+ "--\n"
+ "-- WARNING: old server version. "
+ "The following dump may be incomplete.\n"
+ "--\n");
+ }
switch_sql_mode(sql_file, delimiter, row[1]);
switch_time_zone(sql_file, delimiter, row[2]);
+ query_str= cover_definer_clause(row[3], strlen(row[3]),
+ C_STRING_WITH_LEN("50117"),
+ C_STRING_WITH_LEN("50106"),
+ C_STRING_WITH_LEN(" EVENT"));
+
fprintf(sql_file,
"/*!50106 %s */ %s\n",
- (const char *) row[3],
+ (const char *) (query_str != NULL ? query_str : row[3]),
(const char *) delimiter);
restore_time_zone(sql_file, delimiter);
@@ -2254,7 +2248,7 @@ static uint dump_events_for_db(char *db)
mysql_free_result(event_list_res);
if (lock_tables)
- VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+ (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES");
DBUG_RETURN(0);
}
@@ -2394,7 +2388,16 @@ static uint dump_routines_for_db(char *db)
fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;\n",
routine_type[i], routine_name);
- query_str= cover_definer_clause_in_sp(row[2], strlen(row[2]));
+ query_str= cover_definer_clause(row[2], strlen(row[2]),
+ C_STRING_WITH_LEN("50020"),
+ C_STRING_WITH_LEN("50003"),
+ C_STRING_WITH_LEN(" FUNCTION"));
+
+ if (!query_str)
+ query_str= cover_definer_clause(row[2], strlen(row[2]),
+ C_STRING_WITH_LEN("50020"),
+ C_STRING_WITH_LEN("50003"),
+ C_STRING_WITH_LEN(" PROCEDURE"));
if (mysql_num_fields(routine_res) >= 6)
{
@@ -2450,7 +2453,7 @@ static uint dump_routines_for_db(char *db)
}
}
- my_free(query_str, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(query_str);
}
} /* end of routine printing */
mysql_free_result(routine_res);
@@ -2470,7 +2473,7 @@ static uint dump_routines_for_db(char *db)
DBUG_RETURN(1);
if (lock_tables)
- VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+ (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES");
DBUG_RETURN(0);
}
@@ -2509,6 +2512,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
"TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s'";
FILE *sql_file= md_result_file;
int len;
+ my_bool is_log_table;
MYSQL_RES *result;
MYSQL_ROW row;
DBUG_ENTER("get_table_structure");
@@ -2593,9 +2597,12 @@ static uint get_table_structure(char *table, char *db, char *table_type,
/*
Even if the "table" is a view, we do a DROP TABLE here. The
view-specific code below fills in the DROP VIEW.
+ We will skip the DROP TABLE for general_log and slow_log, since
+ those stmts will fail, in case we apply dump by enabling logging.
*/
- fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",
- opt_quoted_table);
+ if (!general_log_or_slow_log_tables(db, table))
+ fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",
+ opt_quoted_table);
check_io(sql_file);
}
@@ -2603,6 +2610,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
if (strcmp(field->name, "View") == 0)
{
char *scv_buff= NULL;
+ my_ulonglong n_cols;
verbose_msg("-- It's a view, create dummy table for view\n");
@@ -2617,8 +2625,8 @@ static uint get_table_structure(char *table, char *db, char *table_type,
the same name in order to satisfy views that depend on this view.
The table will be removed when the actual view is created.
- The properties of each column, aside from the data type, are not
- preserved in this temporary table, because they are not necessary.
+ The properties of each column, are not preserved in this temporary
+ table, because they are not necessary.
This will not be necessary once we can determine dependencies
between views and can simply dump them in the appropriate order.
@@ -2638,15 +2646,30 @@ static uint get_table_structure(char *table, char *db, char *table_type,
if (mysql_errno(mysql) == ER_VIEW_INVALID)
fprintf(sql_file, "\n-- failed on view %s: %s\n\n", result_table, scv_buff ? scv_buff : "");
- my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(scv_buff);
DBUG_RETURN(0);
}
else
- my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(scv_buff);
- if (mysql_num_rows(result))
+ n_cols= mysql_num_rows(result);
+ if (0 != n_cols)
{
+
+ /*
+ The actual formula is based on the column names and how the .FRM
+ files are stored and is too volatile to be repeated here.
+ Thus we simply warn the user if the columns exceed a limit we
+ know works most of the time.
+ */
+ if (n_cols >= 1000)
+ fprintf(stderr,
+ "-- Warning: Creating a stand-in table for view %s may"
+ " fail when replaying the dump file produced because "
+ "of the number of columns exceeding 1000. Exercise "
+ "caution when replaying the produced dump file.\n",
+ table);
if (opt_drop)
{
/*
@@ -2673,14 +2696,19 @@ static uint get_table_structure(char *table, char *db, char *table_type,
row= mysql_fetch_row(result);
- fprintf(sql_file, " %s %s", quote_name(row[0], name_buff, 0),
- row[1]);
+ /*
+ The actual column type doesn't matter anyway, since the table will
+ be dropped at run time.
+ We do tinyint to avoid hitting the row size limit.
+ */
+ fprintf(sql_file, " %s tinyint NOT NULL",
+ quote_name(row[0], name_buff, 0));
while((row= mysql_fetch_row(result)))
{
/* col name, col type */
- fprintf(sql_file, ",\n %s %s",
- quote_name(row[0], name_buff, 0), row[1]);
+ fprintf(sql_file, ",\n %s tinyint NOT NULL",
+ quote_name(row[0], name_buff, 0));
}
/*
@@ -2707,12 +2735,25 @@ static uint get_table_structure(char *table, char *db, char *table_type,
row= mysql_fetch_row(result);
- fprintf(sql_file, (opt_compatible_mode & 3) ? "%s;\n" :
- "/*!40101 SET @saved_cs_client = @@character_set_client */;\n"
- "/*!40101 SET character_set_client = utf8 */;\n"
- "%s;\n"
- "/*!40101 SET character_set_client = @saved_cs_client */;\n",
- row[1]);
+ is_log_table= general_log_or_slow_log_tables(db, table);
+ if (is_log_table)
+ row[1]+= 13; /* strlen("CREATE TABLE ")= 13 */
+ if (opt_compatible_mode & 3)
+ {
+ fprintf(sql_file,
+ is_log_table ? "CREATE TABLE IF NOT EXISTS %s;\n" : "%s;\n",
+ row[1]);
+ }
+ else
+ {
+ fprintf(sql_file,
+ "/*!40101 SET @saved_cs_client = @@character_set_client */;\n"
+ "/*!40101 SET character_set_client = utf8 */;\n"
+ "%s%s;\n"
+ "/*!40101 SET character_set_client = @saved_cs_client */;\n",
+ is_log_table ? "CREATE TABLE IF NOT EXISTS " : "",
+ row[1]);
+ }
check_io(sql_file);
mysql_free_result(result);
@@ -2772,7 +2813,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
else
{
verbose_msg("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n",
- my_progname, mysql_error(mysql));
+ my_progname_short, mysql_error(mysql));
my_snprintf(query_buff, sizeof(query_buff), show_fields_stmt, db, table);
@@ -2883,7 +2924,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
goto continue_xml;
}
fprintf(stderr, "%s: Can't get keys for table %s (%s)\n",
- my_progname, result_table, mysql_error(mysql));
+ my_progname_short, result_table, mysql_error(mysql));
if (path)
my_fclose(sql_file, MYF(MY_WME));
DBUG_RETURN(0);
@@ -3108,9 +3149,10 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
continue;
}
- query_str= cover_definer_clause_in_trigger(row[2], strlen(row[2]));
-
-
+ query_str= cover_definer_clause(row[2], strlen(row[2]),
+ C_STRING_WITH_LEN("50017"),
+ C_STRING_WITH_LEN("50003"),
+ C_STRING_WITH_LEN(" TRIGGER"));
if (switch_db_collation(sql_file, db_name, ";",
db_cl_name, row[5], &db_cl_altered))
DBUG_RETURN(TRUE);
@@ -3137,7 +3179,7 @@ static int dump_trigger(FILE *sql_file, MYSQL_RES *show_create_trigger_rs,
DBUG_RETURN(TRUE);
}
- my_free(query_str, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(query_str);
}
DBUG_RETURN(FALSE);
@@ -3538,7 +3580,7 @@ static void dump_table(char *table, char *db)
if (mysql_num_fields(res) != num_fields)
{
fprintf(stderr,"%s: Error in field count for table: %s ! Aborting.\n",
- my_progname, result_table);
+ my_progname_short, result_table);
error= EX_CONSCHECK;
goto err;
}
@@ -3622,7 +3664,7 @@ static void dump_table(char *table, char *db)
{
if (length)
{
- if (!IS_NUM_FIELD(field))
+ if (!(field->flags & NUM_FLAG))
{
/*
"length * 2 + 2" is OK for both HEX and non-HEX modes:
@@ -3690,7 +3732,7 @@ static void dump_table(char *table, char *db)
}
if (row[i])
{
- if (!IS_NUM_FIELD(field))
+ if (!(field->flags & NUM_FLAG))
{
if (opt_xml)
{
@@ -3803,7 +3845,7 @@ static void dump_table(char *table, char *db)
{
my_snprintf(buf, sizeof(buf),
"%s: Error %d: %s when dumping table %s at row: %ld\n",
- my_progname,
+ my_progname_short,
mysql_errno(mysql),
mysql_error(mysql),
result_table,
@@ -3997,8 +4039,8 @@ static int dump_tablespaces(char* ts_where)
DBUG_RETURN(0);
}
- my_printf_error(0, "Error: '%s' when trying to dump tablespaces",
- MYF(0), mysql_error(mysql));
+ fprintf(stderr, "%s: Error: '%s' when trying to dump tablespaces\n",
+ my_progname_short, mysql_error(mysql));
DBUG_RETURN(1);
}
@@ -4127,8 +4169,12 @@ static int dump_all_databases()
return 1;
while ((row= mysql_fetch_row(tableres)))
{
- if (mysql_get_server_version(mysql) >= 50003 &&
- !my_strcasecmp(&my_charset_latin1, row[0], "information_schema"))
+ if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, row[0], INFORMATION_SCHEMA_DB_NAME))
+ continue;
+
+ if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME))
continue;
if (dump_all_tables_in_db(row[0]))
@@ -4139,14 +4185,18 @@ static int dump_all_databases()
if (mysql_query(mysql, "SHOW DATABASES") ||
!(tableres= mysql_store_result(mysql)))
{
- my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s",
- MYF(0), mysql_error(mysql));
+ fprintf(stderr, "%s: Error: Couldn't execute 'SHOW DATABASES': %s\n",
+ my_progname_short, mysql_error(mysql));
return 1;
}
while ((row= mysql_fetch_row(tableres)))
{
- if (mysql_get_server_version(mysql) >= 50003 &&
- !my_strcasecmp(&my_charset_latin1, row[0], "information_schema"))
+ if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, row[0], INFORMATION_SCHEMA_DB_NAME))
+ continue;
+
+ if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME))
continue;
if (dump_all_views_in_db(row[0]))
@@ -4290,7 +4340,7 @@ static int init_dumping(char *database, int init_func(char*))
my_bool include_table(const uchar *hash_key, size_t len)
{
- return !hash_search(&ignore_table, hash_key, len);
+ return ! my_hash_search(&ignore_table, hash_key, len);
}
@@ -4312,6 +4362,22 @@ static int dump_all_tables_in_db(char *database)
if (opt_xml)
print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
+ if (strcmp(database, "mysql") == 0)
+ {
+ char table_type[NAME_LEN];
+ char ignore_flag;
+ uint num_fields;
+ num_fields= get_table_structure((char *) "general_log",
+ database, table_type, &ignore_flag);
+ if (num_fields == 0)
+ verbose_msg("-- Warning: get_table_structure() failed with some internal "
+ "error for 'general_log' table\n");
+ num_fields= get_table_structure((char *) "slow_log",
+ database, table_type, &ignore_flag);
+ if (num_fields == 0)
+ verbose_msg("-- Warning: get_table_structure() failed with some internal "
+ "error for 'slow_log' table\n");
+ }
if (lock_tables)
{
DYNAMIC_STRING query;
@@ -4336,6 +4402,8 @@ static int dump_all_tables_in_db(char *database)
if (mysql_refresh(mysql, REFRESH_LOG))
DB_error(mysql, "when doing refresh");
/* We shall continue here, if --force was given */
+ else
+ verbose_msg("-- dump_all_tables_in_db : logs flushed successfully!\n");
}
while ((table= getTableName(0)))
{
@@ -4343,7 +4411,7 @@ static int dump_all_tables_in_db(char *database)
if (include_table((uchar*) hash_key, end - hash_key))
{
dump_table(table,database);
- my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(order_by);
order_by= 0;
if (opt_dump_triggers && mysql_get_server_version(mysql) >= 50009)
{
@@ -4372,7 +4440,7 @@ static int dump_all_tables_in_db(char *database)
check_io(md_result_file);
}
if (lock_tables)
- VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+ (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES");
if (flush_privileges && using_mysql_db == 0)
{
fprintf(md_result_file,"\n--\n-- Flush Grant Tables \n--\n");
@@ -4433,6 +4501,8 @@ static my_bool dump_all_views_in_db(char *database)
if (mysql_refresh(mysql, REFRESH_LOG))
DB_error(mysql, "when doing refresh");
/* We shall continue here, if --force was given */
+ else
+ verbose_msg("-- dump_all_views_in_db : logs flushed successfully!\n");
}
while ((table= getTableName(0)))
{
@@ -4446,7 +4516,7 @@ static my_bool dump_all_views_in_db(char *database)
check_io(md_result_file);
}
if (lock_tables)
- VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+ (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES");
return 0;
} /* dump_all_tables_in_db */
@@ -4495,7 +4565,7 @@ static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root)
}
mysql_free_result(table_res);
}
- DBUG_PRINT("exit", ("new_table_name: %s", val_or_null(name)));
+ DBUG_PRINT("exit", ("new_table_name: %s", name));
DBUG_RETURN(name);
}
@@ -4542,10 +4612,12 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
}
end= pos;
- /* Can't LOCK TABLES in INFORMATION_SCHEMA, so don't try. */
+ /* Can't LOCK TABLES in I_S / P_S, so don't try. */
if (lock_tables &&
- !(mysql_get_server_version(mysql) >= 50003 &&
- !my_strcasecmp(&my_charset_latin1, db, "information_schema")))
+ !(mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, db, INFORMATION_SCHEMA_DB_NAME)) &&
+ !(mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION &&
+ !my_strcasecmp(&my_charset_latin1, db, PERFORMANCE_SCHEMA_DB_NAME)))
{
if (mysql_real_query(mysql, lock_tables_query.str,
lock_tables_query.length-1))
@@ -4569,6 +4641,8 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
DB_error(mysql, "when doing refresh");
}
/* We shall countinue here, if --force was given */
+ else
+ verbose_msg("-- dump_selected_tables : logs flushed successfully!\n");
}
if (opt_xml)
print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS);
@@ -4608,7 +4682,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
dump_routines_for_db(db);
}
free_root(&root, MYF(0));
- my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(order_by);
order_by= 0;
if (opt_xml)
{
@@ -4616,7 +4690,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
check_io(md_result_file);
}
if (lock_tables)
- VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+ (void) mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES");
DBUG_RETURN(0);
} /* dump_selected_tables */
@@ -4624,7 +4698,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos)
{
MYSQL_ROW row;
- MYSQL_RES *master;
+ MYSQL_RES *UNINIT_VAR(master);
char binlog_pos_file[FN_REFLEN];
char binlog_pos_offset[LONGLONG_LEN+1];
char *file, *offset;
@@ -4655,8 +4729,8 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos)
if (!ignore_errors)
{
/* SHOW MASTER STATUS reports nothing and --force is not enabled */
- my_printf_error(0, "Error: Binlogging on server not active",
- MYF(0));
+ fprintf(stderr, "%s: Error: Binlogging on server not active\n",
+ my_progname_short);
maybe_exit(EX_MYSQLERR);
return 1;
}
@@ -4668,10 +4742,9 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos)
}
/* SHOW MASTER STATUS reports file and position */
- if (opt_comments)
- print_comment(md_result_file, 0,
- "\n--\n-- Position to start replication or point-in-time "
- "recovery from\n--\n\n");
+ print_comment(md_result_file, 0,
+ "\n--\n-- Position to start replication or point-in-time "
+ "recovery from\n--\n\n");
fprintf(md_result_file,
"%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
comment_prefix, file, offset);
@@ -4683,6 +4756,130 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos)
return 0;
}
+static int do_stop_slave_sql(MYSQL *mysql_con)
+{
+ MYSQL_RES *slave;
+ /* We need to check if the slave sql is running in the first place */
+ if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+ return(1);
+ else
+ {
+ MYSQL_ROW row= mysql_fetch_row(slave);
+ if (row && row[11])
+ {
+ /* if SLAVE SQL is not running, we don't stop it */
+ if (!strcmp(row[11],"No"))
+ {
+ mysql_free_result(slave);
+ /* Silently assume that they don't have the slave running */
+ return(0);
+ }
+ }
+ }
+ mysql_free_result(slave);
+
+ /* now, stop slave if running */
+ if (mysql_query_with_error_report(mysql_con, 0, "STOP SLAVE SQL_THREAD"))
+ return(1);
+
+ return(0);
+}
+
+static int add_stop_slave(void)
+{
+ if (opt_comments)
+ fprintf(md_result_file,
+ "\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
+ fprintf(md_result_file, "STOP SLAVE;\n");
+ return(0);
+}
+
+static int add_slave_statements(void)
+{
+ if (opt_comments)
+ fprintf(md_result_file,
+ "\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
+ fprintf(md_result_file, "START SLAVE;\n");
+ return(0);
+}
+
+static int do_show_slave_status(MYSQL *mysql_con)
+{
+ MYSQL_RES *slave= 0;
+ const char *comment_prefix=
+ (opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
+ if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+ {
+ if (!ignore_errors)
+ {
+ /* SHOW SLAVE STATUS reports nothing and --force is not enabled */
+ fprintf(stderr, "%s: Error: Slave not set up\n", my_progname_short);
+ }
+ mysql_free_result(slave);
+ return 1;
+ }
+ else
+ {
+ MYSQL_ROW row= mysql_fetch_row(slave);
+ if (row && row[9] && row[21])
+ {
+ /* SHOW MASTER STATUS reports file and position */
+ if (opt_comments)
+ fprintf(md_result_file,
+ "\n--\n-- Position to start replication or point-in-time "
+ "recovery from (the master of this slave)\n--\n\n");
+
+ fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
+
+ if (opt_include_master_host_port)
+ {
+ if (row[1])
+ fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
+ if (row[3])
+ fprintf(md_result_file, "MASTER_PORT=%s, ", row[3]);
+ }
+ fprintf(md_result_file,
+ "MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
+
+ check_io(md_result_file);
+ }
+ mysql_free_result(slave);
+ }
+ return 0;
+}
+
+static int do_start_slave_sql(MYSQL *mysql_con)
+{
+ MYSQL_RES *slave;
+ /* We need to check if the slave sql is stopped in the first place */
+ if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+ return(1);
+ else
+ {
+ MYSQL_ROW row= mysql_fetch_row(slave);
+ if (row && row[11])
+ {
+ /* if SLAVE SQL is not running, we don't start it */
+ if (!strcmp(row[11],"Yes"))
+ {
+ mysql_free_result(slave);
+ /* Silently assume that they don't have the slave running */
+ return(0);
+ }
+ }
+ }
+ mysql_free_result(slave);
+
+ /* now, start slave if stopped */
+ if (mysql_query_with_error_report(mysql_con, 0, "START SLAVE"))
+ {
+ fprintf(stderr, "%s: Error: Unable to start slave\n", my_progname_short);
+ return 1;
+ }
+ return(0);
+}
+
+
static int do_flush_tables_read_lock(MYSQL *mysql_con)
{
@@ -4749,6 +4946,7 @@ static int purge_bin_logs_to(MYSQL *mysql_con, char* log_name)
static int start_transaction(MYSQL *mysql_con)
{
+ verbose_msg("-- Starting transaction...\n");
/*
We use BEGIN for old servers. --single-transaction --master-data will fail
on old servers, but that's ok as it was already silently broken (it didn't
@@ -4803,7 +5001,7 @@ static ulong find_set(TYPELIB *lib, const char *x, uint length,
for (; pos != end && *pos != ','; pos++) ;
var_len= (uint) (pos - start);
strmake(buff, start, min(sizeof(buff) - 1, var_len));
- find= find_type(buff, lib, var_len);
+ find= find_type(buff, lib, FIND_TYPE_BASIC);
if (!find)
{
*err_pos= (char*) start;
@@ -5317,8 +5515,9 @@ int main(int argc, char **argv)
char bin_log_name[FN_REFLEN];
int exit_code;
int consistent_binlog_pos= 0;
- MY_INIT("mysqldump");
+ MY_INIT(argv[0]);
+ sf_leaking_memory=1; /* don't report memory leaks on early exits */
compatible_mode_normal_str[0]= 0;
default_charset= (char *)mysql_universal_client_charset;
bzero((char*) &ignore_table, sizeof(ignore_table));
@@ -5329,6 +5528,7 @@ int main(int argc, char **argv)
free_resources();
exit(exit_code);
}
+ sf_leaking_memory=0; /* from now on we cleanup properly */
/*
Disable comments in xml mode if 'comments' option is not explicitly used.
@@ -5353,32 +5553,55 @@ int main(int argc, char **argv)
if (!path)
write_header(md_result_file, *argv);
+ if (opt_slave_data && do_stop_slave_sql(mysql))
+ goto err;
+
if (opt_single_transaction && opt_master_data)
{
/* See if we can avoid FLUSH TABLES WITH READ LOCK (MariaDB 5.3+). */
consistent_binlog_pos= check_consistent_binlog_pos(NULL, NULL);
}
- if ((opt_lock_all_tables || (opt_master_data && !consistent_binlog_pos)) &&
+ if ((opt_lock_all_tables || (opt_master_data && !consistent_binlog_pos) ||
+ (opt_single_transaction && flush_logs)) &&
do_flush_tables_read_lock(mysql))
goto err;
- if (opt_single_transaction && start_transaction(mysql))
- goto err;
- if (opt_delete_master_logs)
+
+ /*
+ Flush logs before starting transaction since
+ this causes implicit commit starting mysql-5.5.
+ */
+ if (opt_lock_all_tables || opt_master_data ||
+ (opt_single_transaction && flush_logs) ||
+ opt_delete_master_logs)
{
- if (mysql_refresh(mysql, REFRESH_LOG) ||
- get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name)))
- goto err;
+ if (flush_logs || opt_delete_master_logs)
+ {
+ if (mysql_refresh(mysql, REFRESH_LOG))
+ goto err;
+ verbose_msg("-- main : logs flushed successfully!\n");
+ }
+
+ /* Not anymore! That would not be sensible. */
flush_logs= 0;
}
- if (opt_lock_all_tables || opt_master_data)
+
+ if (opt_delete_master_logs)
{
- if (flush_logs && mysql_refresh(mysql, REFRESH_LOG))
+ if (get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name)))
goto err;
- flush_logs= 0; /* not anymore; that would not be sensible */
}
+
+ if (opt_single_transaction && start_transaction(mysql))
+ goto err;
+
+ /* Add 'STOP SLAVE to beginning of dump */
+ if (opt_slave_apply && add_stop_slave())
+ goto err;
if (opt_master_data && do_show_master_status(mysql, consistent_binlog_pos))
goto err;
+ if (opt_slave_data && do_show_slave_status(mysql))
+ goto err;
if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */
goto err;
@@ -5406,6 +5629,14 @@ int main(int argc, char **argv)
dump_databases(argv);
}
+ /* if --dump-slave , start the slave sql thread */
+ if (opt_slave_data && do_start_slave_sql(mysql))
+ goto err;
+
+ /* add 'START SLAVE' to end of dump */
+ if (opt_slave_apply && add_slave_statements())
+ goto err;
+
/* ensure dumped data flushed */
if (md_result_file && fflush(md_result_file))
{
@@ -5418,7 +5649,7 @@ int main(int argc, char **argv)
goto err;
#ifdef HAVE_SMEM
- my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(shared_memory_base_name);
#endif
/*
No reason to explicitely COMMIT the transaction, neither to explicitely