-
-
Notifications
You must be signed in to change notification settings - Fork 2k
MDEV-37442 Fix collation error in mariadb-dump --system=user #4549
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
MooSayed1
wants to merge
1
commit into
MariaDB:10.11
Choose a base branch
from
MooSayed1:MDEV-37442-collation-fix
base: 10.11
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+161
−13
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| # | ||
| # MDEV-37442: Illegal mix of collations during "mariadb-dump --system=user" | ||
| # | ||
| # When a server is migrated from MySQL 8.0, the mysql.user, mysql.role_edges | ||
| # and mysql.default_roles tables retain their original utf8mb4 collations. | ||
| # If the user and role tables end up with different utf8mb4 collations | ||
| # (e.g. utf8mb4_general_ci vs utf8mb4_unicode_ci), MariaDB's mysqldump | ||
| # --system=user fails with "Illegal mix of collations" when joining the | ||
| # tables because no explicit collation was specified on the JOIN keys. | ||
| # | ||
| # Fix: Added COLLATE utf8mb4_bin on every JOIN key so the explicit | ||
| # collation always wins over any implicit column collation. | ||
| # | ||
| # Simulate the mismatch: a user table with utf8mb4_general_ci joined | ||
| # against role_edges with utf8mb4_unicode_ci. Both have IMPLICIT | ||
| # coercibility, so MariaDB cannot resolve the conflict automatically. | ||
| # This is the same type of error that mysqldump triggered on a migrated | ||
| # server. COLLATE utf8mb4_bin (EXPLICIT coercibility) resolves it. | ||
| CREATE TEMPORARY TABLE t_mysql_user ( | ||
| User char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| Host char(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' | ||
| ); | ||
| CREATE TEMPORARY TABLE t_role_edges ( | ||
| FROM_HOST char(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', | ||
| FROM_USER char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' | ||
| ); | ||
| INSERT INTO t_mysql_user VALUES ('mdev37442_user', '%'); | ||
| INSERT INTO t_role_edges VALUES ('', 'mdev37442_role'); | ||
| # Without COLLATE: utf8mb4_general_ci (IMPLICIT) vs utf8mb4_unicode_ci (IMPLICIT) | ||
| # -> ERROR 1267: Illegal mix of collations | ||
| SELECT u.User FROM t_mysql_user u | ||
| JOIN t_role_edges e ON u.User = e.FROM_USER; | ||
| ERROR HY000: Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_unicode_ci,IMPLICIT) for operation '=' | ||
| # With COLLATE utf8mb4_bin: EXPLICIT coercibility wins on both sides -> OK | ||
| SELECT u.User FROM t_mysql_user u | ||
| JOIN t_role_edges e ON u.User = e.FROM_USER COLLATE utf8mb4_bin; | ||
| User | ||
| DROP TEMPORARY TABLE t_mysql_user, t_role_edges; | ||
| # | ||
| # Create the full MySQL-origin role tables and verify that | ||
| # mysqldump --system=user completes without error. | ||
| DROP TABLE IF EXISTS mysql.role_edges; | ||
| DROP TABLE IF EXISTS mysql.default_roles; | ||
| CREATE TABLE mysql.role_edges ( | ||
| FROM_HOST char(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| FROM_USER char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| TO_HOST char(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| TO_USER char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| WITH_ADMIN_OPTION enum('N','Y') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'N', | ||
| PRIMARY KEY (FROM_HOST, FROM_USER, TO_HOST, TO_USER) | ||
| ) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | ||
| CREATE TABLE mysql.default_roles ( | ||
| HOST char(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| USER char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| DEFAULT_ROLE_HOST char(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| DEFAULT_ROLE_USER char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| PRIMARY KEY (HOST, USER, DEFAULT_ROLE_HOST, DEFAULT_ROLE_USER) | ||
| ) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | ||
| INSERT INTO mysql.role_edges VALUES ('', 'mdev37442_role', '%', 'mdev37442_user', 'N'); | ||
| INSERT INTO mysql.default_roles VALUES ('%', 'mdev37442_user', '', 'mdev37442_role'); | ||
| # mysqldump --system=user must succeed despite the collation difference. | ||
| # Cleanup | ||
| DROP TABLE mysql.role_edges; | ||
| DROP TABLE mysql.default_roles; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| --source include/not_embedded.inc | ||
|
|
||
| --echo # | ||
| --echo # MDEV-37442: Illegal mix of collations during "mariadb-dump --system=user" | ||
| --echo # | ||
| --echo # When a server is migrated from MySQL 8.0, the mysql.user, mysql.role_edges | ||
| --echo # and mysql.default_roles tables retain their original utf8mb4 collations. | ||
| --echo # If the user and role tables end up with different utf8mb4 collations | ||
| --echo # (e.g. utf8mb4_general_ci vs utf8mb4_unicode_ci), MariaDB's mysqldump | ||
| --echo # --system=user fails with "Illegal mix of collations" when joining the | ||
| --echo # tables because no explicit collation was specified on the JOIN keys. | ||
| --echo # | ||
| --echo # Fix: Added COLLATE utf8mb4_bin on every JOIN key so the explicit | ||
| --echo # collation always wins over any implicit column collation. | ||
| --echo # | ||
|
|
||
| --echo # Simulate the mismatch: a user table with utf8mb4_general_ci joined | ||
| --echo # against role_edges with utf8mb4_unicode_ci. Both have IMPLICIT | ||
| --echo # coercibility, so MariaDB cannot resolve the conflict automatically. | ||
| --echo # This is the same type of error that mysqldump triggered on a migrated | ||
| --echo # server. COLLATE utf8mb4_bin (EXPLICIT coercibility) resolves it. | ||
|
|
||
| CREATE TEMPORARY TABLE t_mysql_user ( | ||
| User char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| Host char(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' | ||
| ); | ||
| CREATE TEMPORARY TABLE t_role_edges ( | ||
| FROM_HOST char(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', | ||
| FROM_USER char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' | ||
| ); | ||
| INSERT INTO t_mysql_user VALUES ('mdev37442_user', '%'); | ||
| INSERT INTO t_role_edges VALUES ('', 'mdev37442_role'); | ||
|
|
||
| --echo # Without COLLATE: utf8mb4_general_ci (IMPLICIT) vs utf8mb4_unicode_ci (IMPLICIT) | ||
| --echo # -> ERROR 1267: Illegal mix of collations | ||
| --error ER_CANT_AGGREGATE_2COLLATIONS | ||
| SELECT u.User FROM t_mysql_user u | ||
| JOIN t_role_edges e ON u.User = e.FROM_USER; | ||
|
|
||
| --echo # With COLLATE utf8mb4_bin: EXPLICIT coercibility wins on both sides -> OK | ||
| SELECT u.User FROM t_mysql_user u | ||
| JOIN t_role_edges e ON u.User = e.FROM_USER COLLATE utf8mb4_bin; | ||
|
|
||
| DROP TEMPORARY TABLE t_mysql_user, t_role_edges; | ||
|
|
||
| --echo # | ||
| --echo # Create the full MySQL-origin role tables and verify that | ||
| --echo # mysqldump --system=user completes without error. | ||
|
|
||
| --disable_warnings | ||
| DROP TABLE IF EXISTS mysql.role_edges; | ||
| DROP TABLE IF EXISTS mysql.default_roles; | ||
| --enable_warnings | ||
|
|
||
| CREATE TABLE mysql.role_edges ( | ||
| FROM_HOST char(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| FROM_USER char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| TO_HOST char(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| TO_USER char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| WITH_ADMIN_OPTION enum('N','Y') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'N', | ||
| PRIMARY KEY (FROM_HOST, FROM_USER, TO_HOST, TO_USER) | ||
| ) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | ||
|
|
||
| CREATE TABLE mysql.default_roles ( | ||
| HOST char(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| USER char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| DEFAULT_ROLE_HOST char(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| DEFAULT_ROLE_USER char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', | ||
| PRIMARY KEY (HOST, USER, DEFAULT_ROLE_HOST, DEFAULT_ROLE_USER) | ||
| ) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | ||
|
|
||
| INSERT INTO mysql.role_edges VALUES ('', 'mdev37442_role', '%', 'mdev37442_user', 'N'); | ||
| INSERT INTO mysql.default_roles VALUES ('%', 'mdev37442_user', '', 'mdev37442_role'); | ||
|
|
||
| --echo # mysqldump --system=user must succeed despite the collation difference. | ||
| --exec $MYSQL_DUMP --skip-comments --system=user > $MYSQLTEST_VARDIR/tmp/mdev37442.sql | ||
|
|
||
| --echo # Cleanup | ||
| DROP TABLE mysql.role_edges; | ||
| DROP TABLE mysql.default_roles; | ||
| --remove_file $MYSQLTEST_VARDIR/tmp/mdev37442.sql | ||
|
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.