summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/mysql_upgrade.c77
-rw-r--r--client/mysqlbinlog.cc59
-rw-r--r--client/mysqltest.c35
3 files changed, 136 insertions, 35 deletions
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index e1372b2dbbd..15f105fd8fe 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -470,7 +470,12 @@ int main(int argc, char **argv)
load_defaults("my", load_default_groups, &argc, &argv);
- if (handle_options(&argc, &argv, my_long_options, get_one_option))
+ /*
+ Must init_dynamic_string before handle_options because string is freed
+ at error label.
+ */
+ if (init_dynamic_string(&cmdline, NULL, 2 * FN_REFLEN + 128, FN_REFLEN) ||
+ handle_options(&argc, &argv, my_long_options, get_one_option))
{
ret= 1;
goto error;
@@ -478,11 +483,6 @@ int main(int argc, char **argv)
if (tty_password)
opt_password= get_tty_password(NullS);
- if (init_dynamic_string(&cmdline, NULL, 2 * FN_REFLEN + 128, FN_REFLEN))
- {
- ret= 1;
- goto error;
- }
if (!basedir)
{
my_getwd(path, sizeof(path), MYF(0));
@@ -565,17 +565,34 @@ int main(int argc, char **argv)
goto error;
}
else
- dynstr_set(&cmdline, path);
+ {
+#ifdef __WIN__
+ /* Windows requires an extra pair of quotes around the entire string. */
+ dynstr_set(&cmdline, "\"");
+#else
+ dynstr_set(&cmdline, "");
+#endif /* __WIN__ */
+ dynstr_append_os_quoted(&cmdline, path, NullS);
+ }
if (defaults_to_use)
{
- dynstr_append(&cmdline, " --defaults-extra-file=");
- dynstr_append(&cmdline, defaults_to_use);
+ dynstr_append(&cmdline, " ");
+ dynstr_append_os_quoted(&cmdline, "--defaults-extra-file=",
+ defaults_to_use, NullS);
}
-
- dynstr_append(&cmdline, " --check-upgrade --all-databases"
- " --auto-repair --user=");
- dynstr_append(&cmdline, user);
+
+ dynstr_append(&cmdline, " ");
+ dynstr_append_os_quoted(&cmdline, "--check-upgrade", NullS);
+ dynstr_append(&cmdline, " ");
+ dynstr_append_os_quoted(&cmdline, "--all-databases", NullS);
+ dynstr_append(&cmdline, " ");
+ dynstr_append_os_quoted(&cmdline, "--auto-repair", NullS);
+ dynstr_append(&cmdline, " ");
+ dynstr_append_os_quoted(&cmdline, "--user=", user, NullS);
+#ifdef __WIN__
+ dynstr_append(&cmdline, "\"");
+#endif /* __WIN__ */
if (opt_verbose)
printf("Running %s\n", cmdline.str);
@@ -604,7 +621,15 @@ fix_priv_tables:
goto error;
}
else
- dynstr_set(&cmdline, path);
+ {
+#ifdef __WIN__
+ /* Windows requires an extra pair of quotes around the entire string. */
+ dynstr_set(&cmdline, "\"");
+#else
+ dynstr_set(&cmdline, "");
+#endif /* __WIN__ */
+ dynstr_append_os_quoted(&cmdline, path, NullS);
+ }
if (find_file(MYSQL_FIX_PRIV_TABLES_NAME, basedir, MYF(0),
path, sizeof(path),
@@ -626,13 +651,25 @@ fix_priv_tables:
if (defaults_to_use)
{
- dynstr_append(&cmdline, " --defaults-extra-file=");
- dynstr_append(&cmdline, defaults_to_use);
+ dynstr_append(&cmdline, " ");
+ dynstr_append_os_quoted(&cmdline, "--defaults-extra-file=",
+ defaults_to_use, NullS);
}
- dynstr_append(&cmdline, " --force --no-auto-rehash --batch --user=");
- dynstr_append(&cmdline, user);
- dynstr_append(&cmdline, " mysql < ");
- dynstr_append(&cmdline, script_line);
+ dynstr_append(&cmdline, " ");
+ dynstr_append_os_quoted(&cmdline, "--force", NullS);
+ dynstr_append(&cmdline, " ");
+ dynstr_append_os_quoted(&cmdline, "--no-auto-rehash", NullS);
+ dynstr_append(&cmdline, " ");
+ dynstr_append_os_quoted(&cmdline, "--batch", NullS);
+ dynstr_append(&cmdline, " ");
+ dynstr_append_os_quoted(&cmdline, "--user=", user, NullS);
+ dynstr_append(&cmdline, " ");
+ dynstr_append_os_quoted(&cmdline, "--database=mysql", NullS);
+ dynstr_append(&cmdline, " < ");
+ dynstr_append_os_quoted(&cmdline, script_line, NullS);
+#ifdef __WIN__
+ dynstr_append(&cmdline, "\"");
+#endif /* __WIN__ */
if (opt_verbose)
printf("Running %s\n", cmdline.str);
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index a95f3d3b836..8242a481c5b 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -66,6 +66,7 @@ static bool opt_hexdump= 0;
static bool opt_base64_output= 0;
static const char* database= 0;
static my_bool force_opt= 0, short_form= 0, remote_opt= 0, info_flag;
+static my_bool force_if_open_opt= 1;
static ulonglong offset = 0;
static const char* host = 0;
static int port= 0;
@@ -85,6 +86,7 @@ static short binlog_flags = 0;
static MYSQL* mysql = NULL;
static const char* dirname_for_local_load= 0;
static bool stop_passed= 0;
+static my_bool file_not_closed_error= 0;
/*
check_header() will set the pointer below.
@@ -94,8 +96,10 @@ static bool stop_passed= 0;
*/
Format_description_log_event* description_event;
-static int dump_local_log_entries(const char* logname);
-static int dump_remote_log_entries(const char* logname);
+static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
+ const char* logname);
+static int dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
+ const char* logname);
static int dump_log_entries(const char* logname);
static int dump_remote_file(NET* net, const char* fname);
static void die(const char* fmt, ...);
@@ -645,6 +649,12 @@ Create_file event for file_id: %u\n",exv->file_id);
later.
*/
ev= 0;
+ if (!force_if_open_opt &&
+ (description_event->flags & LOG_EVENT_BINLOG_IN_USE_F))
+ {
+ file_not_closed_error= 1;
+ DBUG_RETURN(1);
+ }
break;
case BEGIN_LOAD_QUERY_EVENT:
ev->print(result_file, print_event_info);
@@ -724,6 +734,9 @@ static struct my_option my_long_options[] =
"already have. NOTE: you will need a SUPER privilege to use this option.",
(gptr*) &disable_log_bin, (gptr*) &disable_log_bin, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"force-if-open", 'F', "Force if binlog was not closed properly.",
+ (gptr*) &force_if_open_opt, (gptr*) &force_if_open_opt, 0, GET_BOOL, NO_ARG,
+ 1, 0, 0, 0, 0, 0},
{"force-read", 'f', "Force reading unknown binlog events.",
(gptr*) &force_opt, (gptr*) &force_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
@@ -1001,8 +1014,22 @@ static MYSQL* safe_connect()
static int dump_log_entries(const char* logname)
{
- return (remote_opt ? dump_remote_log_entries(logname) :
- dump_local_log_entries(logname));
+ int rc;
+ PRINT_EVENT_INFO print_event_info;
+ /*
+ Set safe delimiter, to dump things
+ like CREATE PROCEDURE safely
+ */
+ fprintf(result_file, "DELIMITER /*!*/;\n");
+ strcpy(print_event_info.delimiter, "/*!*/;");
+
+ rc= (remote_opt ? dump_remote_log_entries(&print_event_info, logname) :
+ dump_local_log_entries(&print_event_info, logname));
+
+ /* Set delimiter back to semicolon */
+ fprintf(result_file, "DELIMITER ;\n");
+ strcpy(print_event_info.delimiter, ";");
+ return rc;
}
@@ -1067,11 +1094,11 @@ static int check_master_version(MYSQL* mysql,
}
-static int dump_remote_log_entries(const char* logname)
+static int dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
+ const char* logname)
{
char buf[128];
- PRINT_EVENT_INFO print_event_info;
ulong len;
uint logname_len;
NET* net;
@@ -1194,7 +1221,7 @@ could be out of memory");
len= 1; // fake Rotate, so don't increment old_off
}
}
- if ((error= process_event(&print_event_info, ev, old_off)))
+ if ((error= process_event(print_event_info, ev, old_off)))
{
error= ((error < 0) ? 0 : 1);
goto err;
@@ -1213,7 +1240,7 @@ could be out of memory");
goto err;
}
- if ((error= process_event(&print_event_info, ev, old_off)))
+ if ((error= process_event(print_event_info, ev, old_off)))
{
my_close(file,MYF(MY_WME));
error= ((error < 0) ? 0 : 1);
@@ -1339,11 +1366,11 @@ at offset %lu ; this could be a log format error or read error",
}
-static int dump_local_log_entries(const char* logname)
+static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
+ const char* logname)
{
File fd = -1;
IO_CACHE cache,*file= &cache;
- PRINT_EVENT_INFO print_event_info;
byte tmp_buff[BIN_LOG_HEADER_SIZE];
int error= 0;
@@ -1430,7 +1457,7 @@ static int dump_local_log_entries(const char* logname)
// file->error == 0 means EOF, that's OK, we break in this case
break;
}
- if ((error= process_event(&print_event_info, ev, old_off)))
+ if ((error= process_event(print_event_info, ev, old_off)))
{
if (error < 0)
error= 0;
@@ -1547,6 +1574,16 @@ int main(int argc, char** argv)
my_free_open_file_info();
/* We cannot free DBUG, it is used in global destructors after exit(). */
my_end((info_flag ? MY_CHECK_ERROR : 0) | MY_DONT_FREE_DBUG);
+
+ if (file_not_closed_error)
+ {
+ fprintf(stderr,
+"\nError: attempting to dump binlog '%s' which was not closed properly.\n"
+"Most probably mysqld is still writting it, or crashed.\n"
+"Your current options specify --disable-force-if-open\n"
+"which means to abort on this problem.\n"
+"You can rerun using --force-if-open to ignore this problem.\n\n", argv[-1]);
+ }
exit(exit_value);
DBUG_RETURN(exit_value); // Keep compilers happy
}
diff --git a/client/mysqltest.c b/client/mysqltest.c
index a61f77aa1ca..1dc04d008e7 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -725,6 +725,20 @@ void close_connections()
}
+void close_statements()
+{
+ struct st_connection *con;
+ DBUG_ENTER("close_statements");
+ for (con= connections; con < next_con; con++)
+ {
+ if (con->stmt)
+ mysql_stmt_close(con->stmt);
+ con->stmt= 0;
+ }
+ DBUG_VOID_RETURN;
+}
+
+
void close_files()
{
DBUG_ENTER("close_files");
@@ -2908,6 +2922,10 @@ void do_close_connection(struct st_command *command)
}
}
#endif
+ if (next_con->stmt)
+ mysql_stmt_close(next_con->stmt);
+ next_con->stmt= 0;
+
mysql_close(&con->mysql);
if (con->util_mysql)
mysql_close(con->util_mysql);
@@ -5112,6 +5130,14 @@ end:
dynstr_free(&ds_execute_warnings);
}
+
+ /* Close the statement if - no reconnect, need new prepare */
+ if (mysql->reconnect)
+ {
+ mysql_stmt_close(stmt);
+ cur_con->stmt= NULL;
+ }
+
/*
We save the return code (mysql_stmt_errno(stmt)) from the last call sent
to the server into the mysqltest builtin variable $mysql_errno. This
@@ -5119,10 +5145,7 @@ end:
*/
var_set_errno(mysql_stmt_errno(stmt));
-#ifndef BUG15518_FIXED
- mysql_stmt_close(stmt);
- cur_con->stmt= NULL;
-#endif
+
DBUG_VOID_RETURN;
}
@@ -5909,6 +5932,8 @@ int main(int argc, char **argv)
break;
case Q_DISABLE_PS_PROTOCOL:
ps_protocol_enabled= 0;
+ /* Close any open statements */
+ close_statements();
break;
case Q_ENABLE_PS_PROTOCOL:
ps_protocol_enabled= ps_protocol;
@@ -5918,6 +5943,8 @@ int main(int argc, char **argv)
break;
case Q_ENABLE_RECONNECT:
set_reconnect(&cur_con->mysql, 1);
+ /* Close any open statements - no reconnect, need new prepare */
+ close_statements();
break;
case Q_DISABLE_PARSING:
if (parsing_disabled == 0)