Description:
mysql_upgrade fails when unicode characters are present in the database name. The failure comes when it tries to execute mysqlcheck and uses the default value of default-character-set to perform the upgrade. This works fine on version 5.7+.
How to repeat:
1. Create s mysql instance(v5.6) with the default settings.
2. Create a database with unicode characters (I used 你好).
CREATE DATABASE 你好;
3. Perform mysql_upgrade.
mysql_upgrade -u root --force
The mysql_upgrade will fail in mysqlcheck utility with this error:
/usr/bin/mysqlcheck: Got error: 1049: Unknown database '??' when selecting the database
Suggested fix:
From 721e6ae49db51c8cb2034db88f5bf3bb1fa3f09e Mon Sep 17 00:00:00 2001
From: Rayan Dasoriya <dasoriya@google.com>
Date: Mon, 27 Jun 2022 15:13:42 +0000
Subject: [PATCH] Enable fix-table-names and fix-db-names on check-upgarde in
mysqlcheck
mysql-upgrade operations fails during mysqlcheck with check-upgrade option when the database name consist of unicode characters. This is because the default value of default-character-set in MySQL 5.6 is latin1.
In 5.6, when the mysql-upgrade is executed, there's a step where this command is executed(https://dev.mysql.com/doc/refman/5.6/en/mysql-upgrade.html):
mysqlcheck --no-defaults --check-upgrade --all-databases
--skip-database=mysql --auto-repair
And as per the documentation (https://dev.mysql.com/doc/refman/5.6/en/mysqlcheck.html#option_mysqlcheck_check-upgrade), the --check upgrade option should enable fix-db-names and fix-table-names. If these options were actually enabled, then the value of default-character-set would have been utf8 (since the codebase is setting this value when no default-charset is passed with mysql-upgrade). To get the right value of default-charset as utf8, we have to actually enable fix-db-names and fix-table-names when check-upgrade is passed as mentioned in the documentation to successfully perform the mysql-upgrade operation.
In 5.7, the default value of charset is utf8mb4 which is set during the mysql-connections steps due to which mysql-upgrade works fine even when unicode literals are present.
---
client/mysqlcheck.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 8e09ccbe185..503bfb55332 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -333,6 +333,8 @@ get_one_option(int optid, const struct my_option *opt MY_ATTRIBUTE((unused)),
case 'g':
what_to_do= DO_CHECK;
opt_upgrade= 1;
+ opt_fix_db_names= 1;
+ opt_fix_table_names= 1;
break;
case 'W':
#ifdef __WIN__
--
2.37.0.rc0.161.g10f37bed90-goog