Commit 0fd4d6d3 authored by Monty's avatar Monty

MDEV-27068 running mariadb-upgrade in parallel make it hangs forever

MDEV-27107 prevent two mariadb-upgrade running in parallel
MDEV-27279 mariadb_upgrade add --check-if-upgrade-is-needed /
           restrict tests to major version

Code is based of pull request from Daniel Black, but with a several
extensions.

- mysql_upgrade now locks the mysql_upgrade file with my_lock()
  (Advisory record locking). This ensures that two mysql_upgrades
   cannot be run in parallel.
- Added --check-if-upgrade-is-needed to mysql_upgrade. This will return
  0 if one has to run mysql_upgrade.

Other changes:
- mysql_upgrade will now immediately exit if the major version and minor
  version  (two first numbers in the version string) is same as last run.
  Before this change mysql_upgrade was run if the version string was different
  from last run.
- Better messages when there is no need to run mysql_upgrade.
- mysql_upgrade --verbose now prints out a lot more information about
  the version checking.
- mysql_upgrade --debug now uses default debug arguments if there is no
  option to --debug
- "MySQL" is renamed to MariaDB in the messages
- mysql_upgrade version increased to 2.0

Notes
Verifying "prevent two mariadb-upgrade running in parallel" was
done in a debugger as it would be a bit complex to do that in mtr.

Reviewer: Danial Black <daniel@mariadb.org>
parent d28d3aee
...@@ -99,6 +99,7 @@ enum options_client ...@@ -99,6 +99,7 @@ enum options_client
OPT_SKIP_ANNOTATE_ROWS_EVENTS, OPT_SKIP_ANNOTATE_ROWS_EVENTS,
OPT_SSL_CRL, OPT_SSL_CRLPATH, OPT_SSL_CRL, OPT_SSL_CRLPATH,
OPT_IGNORE_DATA, OPT_IGNORE_DATA,
OPT_CHECK_IF_UPGRADE_NEEDED,
OPT_MAX_CLIENT_OPTION /* should be always the last */ OPT_MAX_CLIENT_OPTION /* should be always the last */
}; };
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ #include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
#define VER "1.4" #define VER "2.0"
#ifdef HAVE_SYS_WAIT_H #ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h> #include <sys/wait.h>
...@@ -37,13 +37,15 @@ ...@@ -37,13 +37,15 @@
#endif #endif
static int phase = 0; static int phase = 0;
static int info_file= -1;
static const int phases_total = 7; static const int phases_total = 7;
static char mysql_path[FN_REFLEN]; static char mysql_path[FN_REFLEN];
static char mysqlcheck_path[FN_REFLEN]; static char mysqlcheck_path[FN_REFLEN];
static my_bool opt_force, opt_verbose, debug_info_flag, debug_check_flag, static my_bool debug_info_flag, debug_check_flag,
opt_systables_only, opt_version_check; opt_systables_only, opt_version_check;
static my_bool opt_not_used, opt_silent; static my_bool opt_not_used, opt_silent, opt_check_upgrade;
static uint opt_force, opt_verbose;
static uint my_end_arg= 0; static uint my_end_arg= 0;
static char *opt_user= (char*)"root"; static char *opt_user= (char*)"root";
...@@ -69,7 +71,7 @@ static char **defaults_argv; ...@@ -69,7 +71,7 @@ static char **defaults_argv;
static my_bool not_used; /* Can't use GET_BOOL without a value pointer */ static my_bool not_used; /* Can't use GET_BOOL without a value pointer */
char upgrade_from_version[sizeof("10.20.456-MariaDB")+1]; char upgrade_from_version[sizeof("10.20.456-MariaDB")+30];
static my_bool opt_write_binlog; static my_bool opt_write_binlog;
...@@ -95,8 +97,8 @@ static struct my_option my_long_options[]= ...@@ -95,8 +97,8 @@ static struct my_option my_long_options[]=
{"debug", '#', "This is a non-debug version. Catch this and exit.", {"debug", '#', "This is a non-debug version. Catch this and exit.",
0, 0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
#else #else
{"debug", '#', "Output debug log.", &default_dbug_option, {"debug", '#', "Output debug log.",
&default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif #endif
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.", {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
&debug_check_flag, &debug_check_flag, &debug_check_flag, &debug_check_flag,
...@@ -110,9 +112,13 @@ static struct my_option my_long_options[]= ...@@ -110,9 +112,13 @@ static struct my_option my_long_options[]=
"Default authentication client-side plugin to use.", "Default authentication client-side plugin to use.",
&opt_default_auth, &opt_default_auth, 0, &opt_default_auth, &opt_default_auth, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"check-if-upgrade-is-needed", OPT_CHECK_IF_UPGRADE_NEEDED,
"Exits with status 0 if an upgrades is required, 1 otherwise.",
&opt_check_upgrade, &opt_check_upgrade,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"force", 'f', "Force execution of mysqlcheck even if mysql_upgrade " {"force", 'f', "Force execution of mysqlcheck even if mysql_upgrade "
"has already been executed for the current version of MySQL.", "has already been executed for the current version of MariaDB.",
&opt_force, &opt_force, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, &opt_not_used, &opt_not_used, 0 , GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"host", 'h', "Connect to host.", 0, {"host", 'h', "Connect to host.", 0,
0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#define PASSWORD_OPT 12 #define PASSWORD_OPT 12
...@@ -193,6 +199,12 @@ static void free_used_memory(void) ...@@ -193,6 +199,12 @@ static void free_used_memory(void)
dynstr_free(&conn_args); dynstr_free(&conn_args);
if (cnf_file_path) if (cnf_file_path)
my_delete(cnf_file_path, MYF(MY_WME)); my_delete(cnf_file_path, MYF(MY_WME));
if (info_file >= 0)
{
(void) my_lock(info_file, F_UNLCK, 0, 1, MYF(0));
my_close(info_file, MYF(MY_WME));
info_file= -1;
}
} }
...@@ -238,6 +250,13 @@ static void verbose(const char *fmt, ...) ...@@ -238,6 +250,13 @@ static void verbose(const char *fmt, ...)
} }
static void print_error(const char *error_msg, DYNAMIC_STRING *output)
{
fprintf(stderr, "%s\n", error_msg);
fprintf(stderr, "%s", output->str);
}
/* /*
Add one option - passed to mysql_upgrade on command line Add one option - passed to mysql_upgrade on command line
or by defaults file(my.cnf) - to a dynamic string, in or by defaults file(my.cnf) - to a dynamic string, in
...@@ -271,6 +290,7 @@ static void add_one_option_cnf_file(DYNAMIC_STRING *ds, ...@@ -271,6 +290,7 @@ static void add_one_option_cnf_file(DYNAMIC_STRING *ds,
dynstr_append(ds, "\n"); dynstr_append(ds, "\n");
} }
static my_bool static my_bool
get_one_option(int optid, const struct my_option *opt, get_one_option(int optid, const struct my_option *opt,
char *argument) char *argument)
...@@ -339,11 +359,17 @@ get_one_option(int optid, const struct my_option *opt, ...@@ -339,11 +359,17 @@ get_one_option(int optid, const struct my_option *opt,
my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
die(0); die(0);
break; break;
case 'f': /* --force */
opt_force++;
if (argument == disabled_my_option)
opt_force= 0;
add_option= 0;
break;
case OPT_SILENT: case OPT_SILENT:
opt_verbose= 0; opt_verbose= 0;
add_option= 0; add_option= 0;
break; break;
case 'f': /* --force */ case OPT_CHECK_IF_UPGRADE_NEEDED: /* --check-if-upgrade-needed */
case 's': /* --upgrade-system-tables */ case 's': /* --upgrade-system-tables */
case OPT_WRITE_BINLOG: /* --write-binlog */ case OPT_WRITE_BINLOG: /* --write-binlog */
add_option= FALSE; add_option= FALSE;
...@@ -374,6 +400,18 @@ get_one_option(int optid, const struct my_option *opt, ...@@ -374,6 +400,18 @@ get_one_option(int optid, const struct my_option *opt,
} }
/* Convert the specified version string into the numeric format. */
static ulong STDCALL calc_server_version(char *some_version)
{
uint major, minor, version;
char *point= some_version, *end_point;
major= (uint) strtoul(point, &end_point, 10); point=end_point+1;
minor= (uint) strtoul(point, &end_point, 10); point=end_point+1;
version= (uint) strtoul(point, &end_point, 10);
return (ulong) major * 10000L + (ulong)(minor * 100 + version);
}
/** /**
Run a command using the shell, storing its output in the supplied dynamic Run a command using the shell, storing its output in the supplied dynamic
string. string.
...@@ -572,7 +610,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res, ...@@ -572,7 +610,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
if (my_write(fd, sql_log_bin, sizeof(sql_log_bin)-1, if (my_write(fd, sql_log_bin, sizeof(sql_log_bin)-1,
MYF(MY_FNABP | MY_WME))) MYF(MY_FNABP | MY_WME)))
{ {
my_close(fd, MYF(0)); my_close(fd, MYF(MY_WME));
my_delete(query_file_path, MYF(0)); my_delete(query_file_path, MYF(0));
die("Failed to write to '%s'", query_file_path); die("Failed to write to '%s'", query_file_path);
} }
...@@ -581,7 +619,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res, ...@@ -581,7 +619,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
if (my_write(fd, (uchar*) query, strlen(query), if (my_write(fd, (uchar*) query, strlen(query),
MYF(MY_FNABP | MY_WME))) MYF(MY_FNABP | MY_WME)))
{ {
my_close(fd, MYF(0)); my_close(fd, MYF(MY_WME));
my_delete(query_file_path, MYF(0)); my_delete(query_file_path, MYF(0));
die("Failed to write to '%s'", query_file_path); die("Failed to write to '%s'", query_file_path);
} }
...@@ -598,7 +636,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res, ...@@ -598,7 +636,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
"2>&1", "2>&1",
NULL); NULL);
my_close(fd, MYF(0)); my_close(fd, MYF(MY_WME));
my_delete(query_file_path, MYF(0)); my_delete(query_file_path, MYF(0));
DBUG_RETURN(ret); DBUG_RETURN(ret);
...@@ -645,6 +683,9 @@ static int get_upgrade_info_file_name(char* name) ...@@ -645,6 +683,9 @@ static int get_upgrade_info_file_name(char* name)
&ds_datadir, FALSE) || &ds_datadir, FALSE) ||
extract_variable_from_show(&ds_datadir, name)) extract_variable_from_show(&ds_datadir, name))
{ {
print_error("Reading datadir from the MariaDB server failed. Got the "
"following error when executing the 'mysql' command line client",
&ds_datadir);
dynstr_free(&ds_datadir); dynstr_free(&ds_datadir);
DBUG_RETURN(1); /* Query failed */ DBUG_RETURN(1); /* Query failed */
} }
...@@ -656,6 +697,83 @@ static int get_upgrade_info_file_name(char* name) ...@@ -656,6 +697,83 @@ static int get_upgrade_info_file_name(char* name)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
static char upgrade_info_file[FN_REFLEN]= {0};
/*
Open or create mysql_upgrade_info file in servers data dir.
Take a lock to ensure there cannot be any other mysql_upgrades
runninc concurrently
*/
const char *create_error_message=
"%sCould not open or create the upgrade info file '%s' in "
"the MariaDB Servers data directory, errno: %d (%s)\n";
static void open_mysql_upgrade_file()
{
char errbuff[80];
if (get_upgrade_info_file_name(upgrade_info_file))
{
die("Upgrade failed");
}
if ((info_file= my_create(upgrade_info_file, 0,
O_RDWR | O_NOFOLLOW,
MYF(0))) < 0)
{
if (opt_force >= 2)
{
fprintf(stdout, create_error_message,
"", upgrade_info_file, errno,
my_strerror(errbuff, sizeof(errbuff)-1, errno));
fprintf(stdout,
"--force --force used, continuing without using the %s file.\n"
"Note that this means that there is no protection against "
"concurrent mysql_upgrade executions and next mysql_upgrade run "
"will do a full upgrade again!\n",
upgrade_info_file);
return;
}
fprintf(stdout, create_error_message,
"FATAL ERROR: ",
upgrade_info_file, errno,
my_strerror(errbuff, sizeof(errbuff)-1, errno));
if (errno == EACCES)
{
fprintf(stderr,
"Note that mysql_upgrade should be run as the same user as the "
"MariaDB server binary, normally 'mysql' or 'root'.\n"
"Alternatively you can use mysql_upgrade --force --force. "
"Please check the documentation if you decide to use the force "
"option!\n");
}
fflush(stderr);
die(0);
}
if (my_lock(info_file, F_WRLCK, 0, 1, MYF(0)))
{
die("Could not exclusively lock on file '%s'. Error %d: %s\n",
upgrade_info_file, my_errno,
my_strerror(errbuff, sizeof(errbuff)-1, my_errno));
}
}
/**
Place holder for versions that require a major upgrade
@return 0 upgrade has alredy been run on this version
@return 1 upgrade has to be run
*/
static int faulty_server_versions(const char *version)
{
return 0;
}
/* /*
Read the content of mysql_upgrade_info file and Read the content of mysql_upgrade_info file and
...@@ -665,79 +783,111 @@ static int get_upgrade_info_file_name(char* name) ...@@ -665,79 +783,111 @@ static int get_upgrade_info_file_name(char* name)
NOTE NOTE
This is an optimization to avoid running mysql_upgrade This is an optimization to avoid running mysql_upgrade
when it's already been performed for the particular when it's already been performed for the particular
version of MySQL. version of MariaDB.
In case the MySQL server can't return the upgrade info In case the MariaDBL server can't return the upgrade info
file it's always better to report that the upgrade hasn't file it's always better to report that the upgrade hasn't
been performed. been performed.
@return 0 Upgrade has alredy been run on this version
@return > 0 Upgrade has to be run
*/ */
static int upgrade_already_done(void) static int upgrade_already_done(int silent)
{ {
FILE *in; const char *version = MYSQL_SERVER_VERSION;
char upgrade_info_file[FN_REFLEN]= {0}; const char *s;
char *pos;
if (get_upgrade_info_file_name(upgrade_info_file)) my_off_t length;
return 0; /* Could not get filename => not sure */
if (!(in= my_fopen(upgrade_info_file, O_RDONLY, MYF(0))))
return 0; /* Could not open file => not sure */
bzero(upgrade_from_version, sizeof(upgrade_from_version)); if (info_file < 0)
if (!fgets(upgrade_from_version, sizeof(upgrade_from_version), in))
{ {
/* Ignore, will be detected by strncmp() below */ DBUG_ASSERT(opt_force > 1);
return 1; /* No info file and --force */
} }
my_fclose(in, MYF(0)); bzero(upgrade_from_version, sizeof(upgrade_from_version));
return (strncmp(upgrade_from_version, MYSQL_SERVER_VERSION,
sizeof(MYSQL_SERVER_VERSION)-1)==0);
}
/* (void) my_seek(info_file, 0, SEEK_SET, MYF(0));
Write mysql_upgrade_info file in servers data dir indicating that /* We have -3 here to make calc_server_version() safe */
upgrade has been done for this version length= my_read(info_file, (uchar*) upgrade_from_version,
sizeof(upgrade_from_version)-3,
MYF(MY_WME));
NOTE if (!length)
This might very well fail but since it's just an optimization {
to run mysql_upgrade only when necessary the error can be if (opt_verbose)
ignored. verbose("Empty or non existent %s. Assuming mysql_upgrade has to be run!",
upgrade_info_file);
return 1;
}
*/ /* Remove possible \ŋ that may end in output */
if ((pos= strchr(upgrade_from_version, '\n')))
*pos= 0;
static void create_mysql_upgrade_info_file(void) if (faulty_server_versions(upgrade_from_version))
{ {
FILE *out; if (opt_verbose)
char upgrade_info_file[FN_REFLEN]= {0}; verbose("Upgrading from version %s requires mysql_upgrade to be run!",
upgrade_from_version);
return 2;
}
if (get_upgrade_info_file_name(upgrade_info_file)) s= strchr(version, '.');
return; /* Could not get filename => skip */ s= strchr(s + 1, '.');
if (!(out= my_fopen(upgrade_info_file, O_TRUNC | O_WRONLY, MYF(0)))) if (strncmp(upgrade_from_version, version,
(size_t)(s - version + 1)))
{ {
fprintf(stderr, if (calc_server_version(upgrade_from_version) <= MYSQL_VERSION_ID)
"Could not create the upgrade info file '%s' in " {
"the MySQL Servers datadir, errno: %d\n", verbose("Major version upgrade detected from %s to %s. Check required!",
upgrade_info_file, errno); upgrade_from_version, version);
return; return 3;
}
die("Version mismatch (%s -> %s): Trying to downgrade from a higher to "
"lower version is not supported!",
upgrade_from_version, version);
} }
if (!silent)
{
verbose("This installation of MariaDB is already upgraded to %s.\n"
"There is no need to run mysql_upgrade again for %s.",
upgrade_from_version, version);
if (!opt_check_upgrade)
verbose("You can use --force if you still want to run mysql_upgrade",
upgrade_from_version, version);
}
return 0;
}
static void finish_mysql_upgrade_info_file(void)
{
if (info_file < 0)
return;
/* Write new version to file */ /* Write new version to file */
fputs(MYSQL_SERVER_VERSION, out); (void) my_seek(info_file, 0, SEEK_CUR, MYF(0));
my_fclose(out, MYF(0)); (void) my_chsize(info_file, 0, 0, MYF(0));
(void) my_seek(info_file, 0, 0, MYF(0));
(void) my_write(info_file, (uchar*) MYSQL_SERVER_VERSION,
sizeof(MYSQL_SERVER_VERSION)-1, MYF(MY_WME));
(void) my_write(info_file, (uchar*) "\n", 1, MYF(MY_WME));
(void) my_lock(info_file, F_UNLCK, 0, 1, MYF(0));
/* /*
Check if the upgrad_info_file was properly created/updated Check if the upgrade_info_file was properly created/updated
It's not a fatal error -> just print a message if it fails It's not a fatal error -> just print a message if it fails
*/ */
if (!upgrade_already_done()) if (upgrade_already_done(1))
fprintf(stderr, fprintf(stderr,
"Could not write to the upgrade info file '%s' in " "Could not write to the upgrade info file '%s' in "
"the MySQL Servers datadir, errno: %d\n", "the MariaDB Servers datadir, errno: %d\n",
upgrade_info_file, errno); upgrade_info_file, errno);
my_close(info_file, MYF(MY_WME));
info_file= -1;
return; return;
} }
...@@ -808,7 +958,7 @@ static my_bool is_mysql() ...@@ -808,7 +958,7 @@ static my_bool is_mysql()
strstr(ds_events_struct.str, "IGNORE_BAD_TABLE_OPTIONS") != NULL) strstr(ds_events_struct.str, "IGNORE_BAD_TABLE_OPTIONS") != NULL)
ret= FALSE; ret= FALSE;
else else
verbose("MySQL upgrade detected"); verbose("MariaDB upgrade detected");
dynstr_free(&ds_events_struct); dynstr_free(&ds_events_struct);
return(ret); return(ret);
...@@ -1059,7 +1209,7 @@ static int check_slave_repositories(void) ...@@ -1059,7 +1209,7 @@ static int check_slave_repositories(void)
} }
/* /*
Update all system tables in MySQL Server to current Update all system tables in MariaDB Server to current
version using "mysql" to execute all the SQL commands version using "mysql" to execute all the SQL commands
compiled into the mysql_fix_privilege_tables array compiled into the mysql_fix_privilege_tables array
*/ */
...@@ -1128,24 +1278,6 @@ static int run_sql_fix_privilege_tables(void) ...@@ -1128,24 +1278,6 @@ static int run_sql_fix_privilege_tables(void)
} }
static void print_error(const char *error_msg, DYNAMIC_STRING *output)
{
fprintf(stderr, "%s\n", error_msg);
fprintf(stderr, "%s", output->str);
}
/* Convert the specified version string into the numeric format. */
static ulong STDCALL calc_server_version(char *some_version)
{
uint major, minor, version;
char *point= some_version, *end_point;
major= (uint) strtoul(point, &end_point, 10); point=end_point+1;
minor= (uint) strtoul(point, &end_point, 10); point=end_point+1;
version= (uint) strtoul(point, &end_point, 10);
return (ulong) major * 10000L + (ulong)(minor * 100 + version);
}
/** /**
Check if the server version matches with the server version mysql_upgrade Check if the server version matches with the server version mysql_upgrade
was compiled with. was compiled with.
...@@ -1181,8 +1313,7 @@ static int check_version_match(void) ...@@ -1181,8 +1313,7 @@ static int check_version_match(void)
"check.\n", version_str, MYSQL_SERVER_VERSION); "check.\n", version_str, MYSQL_SERVER_VERSION);
return 1; return 1;
} }
else return 0;
return 0;
} }
...@@ -1191,6 +1322,8 @@ int main(int argc, char **argv) ...@@ -1191,6 +1322,8 @@ int main(int argc, char **argv)
char self_name[FN_REFLEN + 1]; char self_name[FN_REFLEN + 1];
MY_INIT(argv[0]); MY_INIT(argv[0]);
DBUG_PROCESS(argv[0]);
load_defaults_or_exit("my", load_default_groups, &argc, &argv); load_defaults_or_exit("my", load_default_groups, &argc, &argv);
defaults_argv= argv; /* Must be freed by 'free_defaults' */ defaults_argv= argv; /* Must be freed by 'free_defaults' */
...@@ -1231,12 +1364,17 @@ int main(int argc, char **argv) ...@@ -1231,12 +1364,17 @@ int main(int argc, char **argv)
die(NULL); die(NULL);
my_write(fd, USTRING_WITH_LEN( "[client]\n"), MYF(MY_FAE)); my_write(fd, USTRING_WITH_LEN( "[client]\n"), MYF(MY_FAE));
my_write(fd, (uchar*)ds_args.str, ds_args.length, MYF(MY_FAE)); my_write(fd, (uchar*)ds_args.str, ds_args.length, MYF(MY_FAE));
my_close(fd, MYF(0)); my_close(fd, MYF(MY_WME));
} }
/* Find mysql */ /* Find mysql */
find_tool(mysql_path, IF_WIN("mysql.exe", "mysql"), self_name); find_tool(mysql_path, IF_WIN("mysql.exe", "mysql"), self_name);
open_mysql_upgrade_file();
if (opt_check_upgrade)
exit(upgrade_already_done(0) == 0);
/* Find mysqlcheck */ /* Find mysqlcheck */
find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"), self_name); find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"), self_name);
...@@ -1245,15 +1383,10 @@ int main(int argc, char **argv) ...@@ -1245,15 +1383,10 @@ int main(int argc, char **argv)
/* /*
Read the mysql_upgrade_info file to check if mysql_upgrade Read the mysql_upgrade_info file to check if mysql_upgrade
already has been run for this installation of MySQL already has been run for this installation of MariaDB
*/ */
if (!opt_force && upgrade_already_done()) if (!opt_force && !upgrade_already_done(0))
{ goto end; /* Upgrade already done */
printf("This installation of MySQL is already upgraded to %s, "
"use --force if you still need to run mysql_upgrade\n",
MYSQL_SERVER_VERSION);
goto end;
}
if (opt_version_check && check_version_match()) if (opt_version_check && check_version_match())
die("Upgrade failed"); die("Upgrade failed");
...@@ -1278,8 +1411,8 @@ int main(int argc, char **argv) ...@@ -1278,8 +1411,8 @@ int main(int argc, char **argv)
verbose("OK"); verbose("OK");
/* Create a file indicating upgrade has been performed */ /* Finish writing indicating upgrade has been performed */
create_mysql_upgrade_info_file(); finish_mysql_upgrade_info_file();
DBUG_ASSERT(phase == phases_total); DBUG_ASSERT(phase == phases_total);
......
...@@ -239,6 +239,21 @@ Old option accepted for backward compatibility but ignored\&. ...@@ -239,6 +239,21 @@ Old option accepted for backward compatibility but ignored\&.
.sp -1 .sp -1
.IP \(bu 2.3 .IP \(bu 2.3
.\} .\}
.\" mysql_upgrade: check-if-upgrade-is-needed option
.\" check-if-upgrade-is-needed option: mysql_upgrade
\fB\-\-check\-if\-upgrade\-is\-needed\fR
.sp
Exit with a status code indicating if an upgrade is needed\&. Returns 0 if upgrade needed or current version couldn't be determined, 1 when no action required\&.
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
.\" mysql_upgrade: datadir option .\" mysql_upgrade: datadir option
.\" datadir option: mysql_upgrade .\" datadir option: mysql_upgrade
\fB\-\-datadir=\fR\fB\fIpath\fR\fR \fB\-\-datadir=\fR\fB\fIpath\fR\fR
......
...@@ -46,7 +46,9 @@ test ...@@ -46,7 +46,9 @@ test
Phase 7/7: Running 'FLUSH PRIVILEGES' Phase 7/7: Running 'FLUSH PRIVILEGES'
OK OK
Run it again - should say already completed Run it again - should say already completed
This installation of MySQL is already upgraded to VERSION, use --force if you still need to run mysql_upgrade This installation of MariaDB is already upgraded to VERSION.
There is no need to run mysql_upgrade again for VERSION.
You can use --force if you still want to run mysql_upgrade
Force should run it regardless of whether it has been run before Force should run it regardless of whether it has been run before
Phase 1/7: Checking and upgrading mysql database Phase 1/7: Checking and upgrading mysql database
Processing databases Processing databases
...@@ -142,11 +144,12 @@ test ...@@ -142,11 +144,12 @@ test
Phase 7/7: Running 'FLUSH PRIVILEGES' Phase 7/7: Running 'FLUSH PRIVILEGES'
OK OK
DROP USER mysqltest1@'%'; DROP USER mysqltest1@'%';
Version check failed. Got the following error when calling the 'mysql' command line client Reading datadir from the MariaDB server failed. Got the following error when executing the 'mysql' command line client
ERROR 1045 (28000): Access denied for user 'mysqltest1'@'localhost' (using password: YES) ERROR 1045 (28000): Access denied for user 'mysqltest1'@'localhost' (using password: YES)
FATAL ERROR: Upgrade failed FATAL ERROR: Upgrade failed
Run mysql_upgrade with a non existing server socket Run mysql_upgrade with a non existing server socket
mysqlcheck: Got error: 2005: Unknown MySQL server host 'not_existing_host' (errno) when trying to connect Reading datadir from the MariaDB server failed. Got the following error when executing the 'mysql' command line client
ERROR 2005 (HY000): Unknown MySQL server host 'not_existing_host' (errno)
FATAL ERROR: Upgrade failed FATAL ERROR: Upgrade failed
set GLOBAL sql_mode='STRICT_ALL_TABLES,ANSI_QUOTES,NO_ZERO_DATE'; set GLOBAL sql_mode='STRICT_ALL_TABLES,ANSI_QUOTES,NO_ZERO_DATE';
Phase 1/7: Checking and upgrading mysql database Phase 1/7: Checking and upgrading mysql database
...@@ -405,9 +408,12 @@ OK ...@@ -405,9 +408,12 @@ OK
# Bug #21489398: MYSQL_UPGRADE: FATAL ERROR: UPGRADE FAILED - IMPROVE ERROR # Bug #21489398: MYSQL_UPGRADE: FATAL ERROR: UPGRADE FAILED - IMPROVE ERROR
# #
Run mysql_upgrade with unauthorized access Run mysql_upgrade with unauthorized access
Version check failed. Got the following error when calling the 'mysql' command line client Reading datadir from the MariaDB server failed. Got the following error when executing the 'mysql' command line client
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
FATAL ERROR: Upgrade failed FATAL ERROR: Upgrade failed
Reading datadir from the MariaDB server failed. Got the following error when executing the 'mysql' command line client
ERROR 1045 (errno): Access denied for user 'root'@'localhost' (using password: YES)
FATAL ERROR: Upgrade failed
# #
# MDEV-4332 Increase username length from 16 characters # MDEV-4332 Increase username length from 16 characters
# MDEV-6068, MDEV-6178 mysql_upgrade breaks databases with long user names # MDEV-6068, MDEV-6178 mysql_upgrade breaks databases with long user names
...@@ -854,4 +860,32 @@ GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION ...@@ -854,4 +860,32 @@ GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION
GRANT USAGE ON *.* TO 'aRole' GRANT USAGE ON *.* TO 'aRole'
DROP ROLE `aRole`; DROP ROLE `aRole`;
FLUSH PRIVILEGES; FLUSH PRIVILEGES;
#
# MDEV-27279: mariadb_upgrade add --check-if-upgrade-is-needed
#
This installation of MariaDB is already upgraded to MariaDB .
There is no need to run mysql_upgrade again for MariaDB .
Looking for 'mysql' as: mysql
This installation of MariaDB is already upgraded to MariaDB .
There is no need to run mysql_upgrade again for MariaDB .
#
# MDEV-27279: mariadb_upgrade check-if-upgrade absence is do it
#
Looking for 'mysql' as: mysql
Empty or non existent ...mysql_upgrade_info. Assuming mysql_upgrade has to be run!
#
# MDEV-27279: mariadb_upgrade check-if-upgrade with minor version change
#
Looking for 'mysql' as: mysql
This installation of MariaDB is already upgraded to MariaDB .
There is no need to run mysql_upgrade again for MariaDB .
This installation of MariaDB is already upgraded to MariaDB .
There is no need to run mysql_upgrade again for MariaDB .
You can use --force if you still want to run mysql_upgrade
#
# MDEV-27279: mariadb_upgrade check-if-upgrade with major version change
#
Major version upgrade detected from MariaDB to MariaDB . Check required!
Looking for 'mysql' as: mysql
Major version upgrade detected from MariaDB to MariaDB . Check required!
End of 10.2 tests End of 10.2 tests
...@@ -50,6 +50,7 @@ Message Unknown storage engine 'BLACKHOLE' ...@@ -50,6 +50,7 @@ Message Unknown storage engine 'BLACKHOLE'
Level Warning Level Warning
Code 1286 Code 1286
Message Unknown storage engine 'ARCHIVE' Message Unknown storage engine 'ARCHIVE'
# upgrade from 10.1 - engines aren't enabled
Phase 1/7: Checking and upgrading mysql database Phase 1/7: Checking and upgrading mysql database
Processing databases Processing databases
mysql mysql
...@@ -136,6 +137,8 @@ Level Warning ...@@ -136,6 +137,8 @@ Level Warning
Code 1286 Code 1286
Message Unknown storage engine 'ARCHIVE' Message Unknown storage engine 'ARCHIVE'
alter table mysql.user drop column default_role, drop column max_statement_time; alter table mysql.user drop column default_role, drop column max_statement_time;
# still upgrade from 10.1
Major version upgrade detected from MariaDB to MariaDB . Check required!
Phase 1/7: Checking and upgrading mysql database Phase 1/7: Checking and upgrading mysql database
Processing databases Processing databases
mysql mysql
...@@ -222,6 +225,7 @@ Level Warning ...@@ -222,6 +225,7 @@ Level Warning
Code 1286 Code 1286
Message Unknown storage engine 'ARCHIVE' Message Unknown storage engine 'ARCHIVE'
alter table mysql.user drop column default_role, drop column max_statement_time; alter table mysql.user drop column default_role, drop column max_statement_time;
# upgrade from 10.0 - engines are enabled
Phase 1/7: Checking and upgrading mysql database Phase 1/7: Checking and upgrading mysql database
Processing databases Processing databases
mysql mysql
......
...@@ -205,7 +205,7 @@ v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VI ...@@ -205,7 +205,7 @@ v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VI
show create view v4; show create view v4;
View Create View character_set_client collation_connection View Create View character_set_client collation_connection
v4 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `t1`.`a` AS `a` from `t1` latin1 latin1_swedish_ci v4 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `t1`.`a` AS `a` from `t1` latin1 latin1_swedish_ci
MySQL upgrade detected MariaDB upgrade detected
Phase 1/7: Checking and upgrading mysql database Phase 1/7: Checking and upgrading mysql database
Processing databases Processing databases
mysql mysql
...@@ -324,7 +324,7 @@ drop view v1,v2,v3,v4; ...@@ -324,7 +324,7 @@ drop view v1,v2,v3,v4;
rename table mysql.event to mysql.ev_bk; rename table mysql.event to mysql.ev_bk;
flush tables; flush tables;
The --upgrade-system-tables option was used, user tables won't be touched. The --upgrade-system-tables option was used, user tables won't be touched.
MySQL upgrade detected MariaDB upgrade detected
Phase 1/7: Checking and upgrading mysql database Phase 1/7: Checking and upgrading mysql database
Processing databases Processing databases
mysql mysql
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
update mysql.user set password=password("foo") where user='root'; update mysql.user set password=password("foo") where user='root';
--replace_regex /[^ ]*mysql_upgrade_info/...mysql_upgrade_info/
--exec $MYSQL_UPGRADE --exec $MYSQL_UPGRADE
connect(con1,localhost,root,foo,,,); connect(con1,localhost,root,foo,,,);
...@@ -21,3 +22,6 @@ update mysql.user set password='' where user='root'; ...@@ -21,3 +22,6 @@ update mysql.user set password='' where user='root';
flush privileges; flush privileges;
# Load event table # Load event table
set global event_scheduler=OFF; set global event_scheduler=OFF;
let MYSQLD_DATADIR= `select @@datadir`;
--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
...@@ -17,7 +17,7 @@ let $MYSQLD_DATADIR= `select @@datadir`; ...@@ -17,7 +17,7 @@ let $MYSQLD_DATADIR= `select @@datadir`;
file_exists $MYSQLD_DATADIR/mysql_upgrade_info; file_exists $MYSQLD_DATADIR/mysql_upgrade_info;
--echo Run it again - should say already completed --echo Run it again - should say already completed
--replace_result $MYSQL_SERVER_VERSION VERSION --replace_regex /upgraded to [^\n]*/upgraded to VERSION./ /again for [^\n]*/again for VERSION./
--exec $MYSQL_UPGRADE 2>&1 --exec $MYSQL_UPGRADE 2>&1
# It should have created a file in the MySQL Servers datadir # It should have created a file in the MySQL Servers datadir
...@@ -126,7 +126,7 @@ let $MYSQLD_DATADIR= `select @@datadir`; ...@@ -126,7 +126,7 @@ let $MYSQLD_DATADIR= `select @@datadir`;
--remove_file $MYSQLD_DATADIR/mysql_upgrade_info --remove_file $MYSQLD_DATADIR/mysql_upgrade_info
--echo # Running mysql_upgrade with --skip-write-binlog.. --echo # Running mysql_upgrade with --skip-write-binlog..
--replace_result $MYSQLTEST_VARDIR var --replace_regex /[^ ]*mysql_upgrade_info/...mysql_upgrade_info/
--exec $MYSQL_UPGRADE --skip-write-binlog --exec $MYSQL_UPGRADE --skip-write-binlog
# mysql_upgrade must have created mysql_upgrade_info file, # mysql_upgrade must have created mysql_upgrade_info file,
...@@ -140,6 +140,9 @@ let $MYSQLD_DATADIR= `select @@datadir`; ...@@ -140,6 +140,9 @@ let $MYSQLD_DATADIR= `select @@datadir`;
--echo Run mysql_upgrade with unauthorized access --echo Run mysql_upgrade with unauthorized access
--error 1 --error 1
--exec $MYSQL_UPGRADE --skip-verbose --user=root --password=wrong_password 2>&1 --exec $MYSQL_UPGRADE --skip-verbose --user=root --password=wrong_password 2>&1
--replace_regex /.*mysqlcheck.*: Got/mysqlcheck: Got/ /\([0-9|-]*\)/(errno)/
--error 1
--exec $MYSQL_UPGRADE --skip-verbose --skip-version-check --user=root --password=wrong_password 2>&1
--echo # --echo #
--echo # MDEV-4332 Increase username length from 16 characters --echo # MDEV-4332 Increase username length from 16 characters
...@@ -235,6 +238,7 @@ FLUSH TABLES mysql.user; ...@@ -235,6 +238,7 @@ FLUSH TABLES mysql.user;
FLUSH PRIVILEGES; FLUSH PRIVILEGES;
SHOW CREATE TABLE mysql.user; SHOW CREATE TABLE mysql.user;
--replace_result $MYSQLTEST_VARDIR var
--exec $MYSQL_UPGRADE --force 2>&1 --exec $MYSQL_UPGRADE --force 2>&1
SHOW CREATE TABLE mysql.user; SHOW CREATE TABLE mysql.user;
...@@ -279,6 +283,79 @@ SHOW GRANTS; ...@@ -279,6 +283,79 @@ SHOW GRANTS;
DROP ROLE `aRole`; DROP ROLE `aRole`;
--exec $MYSQL mysql < $MYSQLTEST_VARDIR/tmp/user.sql --exec $MYSQL mysql < $MYSQLTEST_VARDIR/tmp/user.sql
FLUSH PRIVILEGES; FLUSH PRIVILEGES;
--echo #
--echo # MDEV-27279: mariadb_upgrade add --check-if-upgrade-is-needed
--echo #
--error 1
--exec $MYSQL_UPGRADE --check-if-upgrade-is-needed --silent
--replace_regex /\d\d\.\d*\.\d*[^ .\n]*/MariaDB /
--error 1
--exec $MYSQL_UPGRADE --check-if-upgrade-is-needed
--replace_regex /\d\d\.\d*\.\d*[^ .\n]*/MariaDB / /'mysql.* as:[^\n]*/'mysql' as: mysql/
--error 1
--exec $MYSQL_UPGRADE --check-if-upgrade-is-needed --verbose
--echo #
--echo # MDEV-27279: mariadb_upgrade check-if-upgrade absence is do it
--echo #
--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
--replace_regex /[^ ]*mysql_upgrade_info/...mysql_upgrade_info/
--exec $MYSQL_UPGRADE --check-if-upgrade-is-needed
--replace_regex /'mysql.* as:[^\n]*/'mysql' as: mysql/ /open .* Assuming/open XXX. Assuming/ /[^ ]*mysql_upgrade_info/...mysql_upgrade_info/
--exec $MYSQL_UPGRADE --check-if-upgrade-is-needed --verbose
--echo #
--echo # MDEV-27279: mariadb_upgrade check-if-upgrade with minor version change
--echo #
# take 3rd number of version and change to 0
let DATADIR= $MYSQLD_DATADIR;
perl;
my $ver= $ENV{'MYSQL_SERVER_VERSION'} or die "MYSQL_SERVER_VERSION not set";
my $file= $ENV{'DATADIR'} or die "MYSQLD_DATADIR not set";
$ver =~ s/^(\d*)\.(\d*).(\d*)(.*)/$1.$2.0$4/;
open(FILE, ">$file/mysql_upgrade_info") or die "Failed to open $file";
print FILE "$ver\n";
close(FILE);
EOF
--error 1
--exec $MYSQL_UPGRADE --check-if-upgrade-is-needed --silent
--replace_regex /\d\d\.\d*\.\d*[^ .\n]*/MariaDB / /'mysql.* as:[^\n]*/'mysql' as: mysql/
--error 1
--exec $MYSQL_UPGRADE --check-if-upgrade-is-needed --verbose
--replace_regex /\d\d\.\d*\.\d*[^ .\n]*/MariaDB /
--exec $MYSQL_UPGRADE
--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
--echo #
--echo # MDEV-27279: mariadb_upgrade check-if-upgrade with major version change
--echo #
# take 2rd number of version and change to 0
let DATADIR= $MYSQLD_DATADIR;
perl;
my $ver= $ENV{'MYSQL_SERVER_VERSION'} or die "MYSQL_SERVER_VERSION not set";
my $file= $ENV{'DATADIR'} or die "MYSQLD_DATADIR not set";
$ver =~ s/^(\d*)\.(\d*).(\d*)(.*)/$1.0.$3$4/;
open(FILE, ">$file/mysql_upgrade_info") or die "Failed to open $file";
print FILE "$ver\n";
close(FILE);
EOF
--exec $MYSQL_UPGRADE --check-if-upgrade-is-needed --silent
--replace_regex /\d\d\.\d*\.\d*[^ .\n]*/MariaDB /
--exec $MYSQL_UPGRADE --check-if-upgrade-is-needed
--replace_regex /\d\d\.\d*\.\d*[^ .\n]*/MariaDB / /'mysql.* as:[^\n]*/'mysql' as: mysql/
--exec $MYSQL_UPGRADE --check-if-upgrade-is-needed --verbose
--remove_file $MYSQLD_DATADIR/mysql_upgrade_info --remove_file $MYSQLD_DATADIR/mysql_upgrade_info
--echo End of 10.2 tests --echo End of 10.2 tests
...@@ -26,7 +26,8 @@ uninstall plugin blackhole; ...@@ -26,7 +26,8 @@ uninstall plugin blackhole;
uninstall plugin archive; uninstall plugin archive;
select table_catalog, table_schema, table_name, table_type, engine, row_format, table_rows, data_length, table_comment from information_schema.tables where table_schema='test'; select table_catalog, table_schema, table_name, table_type, engine, row_format, table_rows, data_length, table_comment from information_schema.tables where table_schema='test';
# upgrade from 10.1 - engines aren't enabled --echo # upgrade from 10.1 - engines aren't enabled
--replace_regex /\d\d\.\d*\.\d*[^ .\n]*/MariaDB /
exec $MYSQL_UPGRADE 2>&1; exec $MYSQL_UPGRADE 2>&1;
select table_catalog, table_schema, table_name, table_type, engine, row_format, table_rows, data_length, table_comment from information_schema.tables where table_schema='test'; select table_catalog, table_schema, table_name, table_type, engine, row_format, table_rows, data_length, table_comment from information_schema.tables where table_schema='test';
...@@ -39,14 +40,16 @@ write_file $datadir/mysql_upgrade_info; ...@@ -39,14 +40,16 @@ write_file $datadir/mysql_upgrade_info;
10.1.10-MariaDB 10.1.10-MariaDB
EOF EOF
# still upgrade from 10.1 --echo # still upgrade from 10.1
--replace_regex /\d\d\.\d*\.\d*[^ .\n]*/MariaDB /
exec $MYSQL_UPGRADE 2>&1; exec $MYSQL_UPGRADE 2>&1;
select table_catalog, table_schema, table_name, table_type, engine, row_format, table_rows, data_length, table_comment from information_schema.tables where table_schema='test'; select table_catalog, table_schema, table_name, table_type, engine, row_format, table_rows, data_length, table_comment from information_schema.tables where table_schema='test';
alter table mysql.user drop column default_role, drop column max_statement_time; alter table mysql.user drop column default_role, drop column max_statement_time;
remove_file $datadir/mysql_upgrade_info; remove_file $datadir/mysql_upgrade_info;
# upgrade from 10.0 - engines are enabled --echo # upgrade from 10.0 - engines are enabled
--replace_regex /\d\d\.\d*\.\d*[^ .\n]*/MariaDB /
exec $MYSQL_UPGRADE 2>&1; exec $MYSQL_UPGRADE 2>&1;
select table_catalog, table_schema, table_name, table_type, engine, row_format, table_rows, data_length, table_comment from information_schema.tables where table_schema='test'; select table_catalog, table_schema, table_name, table_type, engine, row_format, table_rows, data_length, table_comment from information_schema.tables where table_schema='test';
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment