Bug #107675 mysql_upgrade fails with unicode characters in database name
Submitted: 27 Jun 2022 15:24 Modified: 27 Jun 2022 15:52
Reporter: Rayan Dasoriya Email Updates:
Status: Unsupported Impact on me:
None 
Category:MySQL Server: Command-line Clients Severity:S3 (Non-critical)
Version:5.6 OS:Any
Assigned to: CPU Architecture:Any
Tags: mysql_upgrade, mysql5.6

[27 Jun 2022 15:24] Rayan Dasoriya
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
[27 Jun 2022 15:52] MySQL Verification Team
Hello Rayan Dasoriya,

Thank you for the report and feedback.
However, please note that MySQL 5.6 is off the maintenance for a long time.

Quoting from official EOL announcement - 
"MySQL 5.6 is covered under Oracle Lifetime Sustaining Support.

Per Oracle's Lifetime Support policy, as of February 1, 2021, MySQL 5.6 is covered under Oracle Sustaining Support.

Users are encouraged to upgrade to MySQL 8.0.". https://www.mysql.com/support/eol-notice.html

regards,
Umesh