summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysql_upgrade.c27
-rw-r--r--client/mysqlcheck.c19
-rw-r--r--mysql-test/include/have_mysql_upgrade.inc4
-rw-r--r--mysql-test/suite/rpl/r/rpl_mysql_upgrade.result13
-rw-r--r--mysql-test/suite/rpl/t/rpl_mysql_upgrade.test56
5 files changed, 119 insertions, 0 deletions
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index cfd7ed4ea56..52c3636219d 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -54,6 +54,8 @@ static char **defaults_argv;
static my_bool not_used; /* Can't use GET_BOOL without a value pointer */
+static my_bool opt_write_binlog;
+
#include <help_start.h>
static struct my_option my_long_options[]=
@@ -124,6 +126,11 @@ static struct my_option my_long_options[]=
{"verbose", 'v', "Display more output about the process",
(uchar**) &opt_verbose, (uchar**) &opt_verbose, 0,
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"write-binlog", OPT_WRITE_BINLOG,
+ "All commands including mysqlcheck are binlogged. Enabled by default;"
+ "use --skip-write-binlog when commands should not be sent to replication slaves.",
+ (uchar**) &opt_write_binlog, (uchar**) &opt_write_binlog, 0, GET_BOOL, NO_ARG,
+ 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -448,6 +455,8 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
int ret;
File fd;
char query_file_path[FN_REFLEN];
+ const uchar sql_log_bin[]= "SET SQL_LOG_BIN=0;";
+
DBUG_ENTER("run_query");
DBUG_PRINT("enter", ("query: %s", query));
if ((fd= create_temp_file(query_file_path, opt_tmpdir,
@@ -455,6 +464,22 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
MYF(MY_WME))) < 0)
die("Failed to create temporary file for defaults");
+ /*
+ Master and slave should be upgraded separately. All statements executed
+ by mysql_upgrade will not be binlogged.
+ 'SET SQL_LOG_BIN=0' is executed before any other statements.
+ */
+ if (!opt_write_binlog)
+ {
+ if (my_write(fd, sql_log_bin, sizeof(sql_log_bin)-1,
+ MYF(MY_FNABP | MY_WME)))
+ {
+ my_close(fd, MYF(0));
+ my_delete(query_file_path, MYF(0));
+ die("Failed to write to '%s'", query_file_path);
+ }
+ }
+
if (my_write(fd, (uchar*) query, strlen(query),
MYF(MY_FNABP | MY_WME)))
{
@@ -648,6 +673,7 @@ static int run_mysqlcheck_upgrade(void)
"--check-upgrade",
"--all-databases",
"--auto-repair",
+ opt_write_binlog ? "--write-binlog" : "--skip-write-binlog",
NULL);
}
@@ -662,6 +688,7 @@ static int run_mysqlcheck_fixnames(void)
"--all-databases",
"--fix-db-names",
"--fix-table-names",
+ opt_write_binlog ? "--write-binlog" : "--skip-write-binlog",
NULL);
}
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 82aabd77b24..1533e602639 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -652,6 +652,17 @@ static int use_db(char *database)
return 0;
} /* use_db */
+static int disable_binlog()
+{
+ const char *stmt= "SET SQL_LOG_BIN=0";
+ if (mysql_query(sock, stmt))
+ {
+ fprintf(stderr, "Failed to %s\n", stmt);
+ fprintf(stderr, "Error: %s\n", mysql_error(sock));
+ return 1;
+ }
+ return 0;
+}
static int handle_request_for_tables(char *tables, uint length)
{
@@ -844,6 +855,14 @@ int main(int argc, char **argv)
if (dbConnect(current_host, current_user, opt_password))
exit(EX_MYSQLERR);
+ if (!opt_write_binlog)
+ {
+ if (disable_binlog()) {
+ first_error= 1;
+ goto end;
+ }
+ }
+
if (opt_auto_repair &&
my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64))
{
diff --git a/mysql-test/include/have_mysql_upgrade.inc b/mysql-test/include/have_mysql_upgrade.inc
new file mode 100644
index 00000000000..8f486176018
--- /dev/null
+++ b/mysql-test/include/have_mysql_upgrade.inc
@@ -0,0 +1,4 @@
+--require r/have_mysql_upgrade.result
+--disable_query_log
+select LENGTH("$MYSQL_UPGRADE")>0 as have_mysql_upgrade;
+--enable_query_log
diff --git a/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result b/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result
new file mode 100644
index 00000000000..09a9121d22c
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result
@@ -0,0 +1,13 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP DATABASE IF EXISTS `#mysql50#mysqltest-1`;
+CREATE DATABASE `#mysql50#mysqltest-1`;
+Master position is not changed
+STOP SLAVE SQL_THREAD;
+Master position has been changed
+DROP DATABASE `mysqltest-1`;
+DROP DATABASE `#mysql50#mysqltest-1`;
diff --git a/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test
new file mode 100644
index 00000000000..bf5c6d2b921
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test
@@ -0,0 +1,56 @@
+#############################################################################
+# BUG#43579 mysql_upgrade tries to alter log tables on replicated database
+# Master and slave should be upgraded separately. All statements executed by
+# mysql_upgrade will not be binlogged. --write-binlog and --skip-write-binlog
+# options are added into mysql_upgrade. These options control whether sql
+# statements are binlogged or not.
+#############################################################################
+--source include/master-slave.inc
+
+# Only run test if "mysql_upgrade" is found
+--source include/have_mysql_upgrade.inc
+
+connection master;
+--disable_warnings
+DROP DATABASE IF EXISTS `#mysql50#mysqltest-1`;
+CREATE DATABASE `#mysql50#mysqltest-1`;
+--enable_warnings
+sync_slave_with_master;
+
+connection master;
+let $before_position= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+#With '--force' option, mysql_upgrade always executes all sql statements for upgrading.
+#--skip-write-binlog option disables binlog.
+--exec $MYSQL_UPGRADE --skip-write-binlog --skip-verbose --force --user=root > $MYSQLTEST_VARDIR/log/mysql_upgrade.log 2>&1
+sync_slave_with_master;
+
+connection master;
+let $after_position= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+if (`SELECT '$before_position'='$after_position'`)
+{
+ echo Master position is not changed;
+}
+
+#Some log events of the mysql_upgrade's will cause errors on slave.
+connection slave;
+STOP SLAVE SQL_THREAD;
+source include/wait_for_slave_sql_to_stop.inc;
+
+connection master;
+#With '--force' option, mysql_upgrade always executes all sql statements for upgrading.
+--exec $MYSQL_UPGRADE --skip-verbose --force --user=root > $MYSQLTEST_VARDIR/log/mysql_upgrade.log 2>&1
+
+connection master;
+let $after_file= query_get_value(SHOW MASTER STATUS, File, 1);
+let $after_position= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+if (!`SELECT '$before_position'='$after_position'`)
+{
+ echo Master position has been changed;
+}
+
+DROP DATABASE `mysqltest-1`;
+connection slave;
+DROP DATABASE `#mysql50#mysqltest-1`;