Skip to content
/ server Public

Comments

MDEV-37442 Fix collation error in mariadb-dump --system=user#4549

Open
MooSayed1 wants to merge 1 commit intoMariaDB:mainfrom
MooSayed1:MDEV-37442-collation-fix
Open

MDEV-37442 Fix collation error in mariadb-dump --system=user#4549
MooSayed1 wants to merge 1 commit intoMariaDB:mainfrom
MooSayed1:MDEV-37442-collation-fix

Conversation

@MooSayed1
Copy link

@MooSayed1 MooSayed1 commented Jan 16, 2026

The Jira issue number for this PR is: MDEV-37442

Description

mariadb-dump --system=user fails with an "Illegal mix of collations" error after upgrading MariaDB when the mysql.user view retains the old collation (e.g. utf8mb4_general_ci) while the server now defaults to a different one (e.g. utf8mb4_uca1400_ai_ci).

The root cause is in the SQL queries built by dump_all_users_roles_and_grants() in client/mysqldump.cc. The is_role column (from the mysql.user view) has IMPLICIT coercibility and the string literals 'N'/'Y' also have IMPLICIT coercibility. When the collations differ at the same coercibility level, the server cannot resolve the mismatch and raises an error.

The fix adds BINARY casts to all four is_role comparisons. BINARY has EXPLICIT coercibility (level 0), which always wins over IMPLICIT (level 2), resolving the conflict regardless of the column's character set. Additionally, COLLATE utf8mb4_bin is added to the role_edges and default_roles JOIN conditions inside /*!80001 ... */ versioned comments (MySQL 8.0+ only) for correctness.

Release Notes

mariadb-dump --system=user no longer fails with "Illegal mix of collations" after a server upgrade that changes the default collation.

How can this PR be tested?

./mtr main.mysqldump-system-collation

The new test simulates a post-upgrade collation mismatch by recreating the mysql.user view under a utf8mb4_general_ci collation context, then runs mariadb-dump --system=user and verifies it succeeds.

Basing the PR against the correct MariaDB version

This is a bug fix, and the PR is based against main. The bug was introduced when MariaDB changed the default collation (11.2+), so main is the appropriate target.

PR quality check

  • I checked the CODING_STANDARDS.md file and my PR conforms to this where appropriate.
  • For any trivial modifications to the PR, I am ok with the reviewer making the changes themselves.

@MooSayed1 MooSayed1 force-pushed the MDEV-37442-collation-fix branch from b4849b5 to 06986fa Compare January 16, 2026 16:06
@github-actions github-actions bot added the External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements. label Jan 17, 2026
Copy link
Member

@gkodinov gkodinov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a preliminary review.

First of all, please follow the https://github.com/MariaDB/server/blob/main/CODING_STANDARDS.md#git-commit-messages for the format of the commit message.

Secondly: this needs a test case according to https://mariadb.com/docs/general-resources/community/contributing-participating/contributing-code#testing. A basic rule of thumb is that the test added should fail without the fix and succeed with it.

Also, this definitely can benefit from a better explanation.

The root cause is that, when MySQL role tables are present, these tables are most probably using a collation that is not compatible with the collation after the mariaDB upgrade. And, since these tables are not present in a new database, there's no issue with this.

Note that this is not the only place to fix this. role_edges is used in many other places too. I'd review all of these, make sure they're executed, and try to fix all of them as well.

And, I believe that for this particular fix to make any difference, you also need to be running a MySQL server for this line to actually kick in. I've tried it on the command line as it is against a recent mariadbd and the role_edges didn't get into the explain at all!

I would ask the reporter what is their exact setup: are they getting this while running their "script" that they mention against a MySQL server binary (which I guess they do, since this particular conditional join seems to be kicking in according to the error message). And what tables do they have in their database (SHOW CREATE TABLE would be nice). It's good to confirm this. Especially if you are trying to make a test case for it.

@gkodinov gkodinov self-assigned this Jan 23, 2026
@MooSayed1
Copy link
Author

@gkodinov Thank you for the review feedback.

I’ve asked the reporter on JIRA for clarification about their setup, specifically:

Whether they’re running against MySQL or MariaDB server
The output of SHOW CREATE TABLE for the affected tables
Their migration history
Once I understand the exact scenario, I’ll:

Review all role_edges usages in the codebase
Create a proper test case
Update the commit message to follow the 50/72 format
Will update the PR once I have more information.

Copy link
Member

@gkodinov gkodinov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have moved the jira into "need feedback" now. Let's hope they reply.

FWIW, their log contains answers to some of your questions:

What server and version: -- Server version 11.8.2-MariaDB-ubu2404-log

Did you migrate from mysql to Mariadb at some point? - definitely role_edges is a MySQL table and not a MariaDB one.

In the meanwhile, until they reply, I would ask you to consider addressing my previous review: check all queries where role_edges is joined to one of the mariaDB tables and add an explicit collation. Then fix the commit message and add tests. This should keep you going until they reply. Or until we arrive to a fix that me and the final reviewer deem sufficient.

@MooSayed1 MooSayed1 force-pushed the MDEV-37442-collation-fix branch from 06986fa to f800d93 Compare February 21, 2026 15:49
@MooSayed1
Copy link
Author

@gkodinov Thank you for the guidance. I've addressed all points from your review:

  • Added BINARY to all 4 is_role comparisons (the actual cause on MariaDB — used BINARY instead of COLLATE since is_role may be latin1 on older setups).
  • Added COLLATE utf8mb4_bin to all 3 role_edges/default_roles JOINs inside /*!80001 ... */ for correctness.
    Updated commit message to 50/72 format.
  • Added test mysqldump-system-collation — recreates mysql.user view with old collation, runs dump, verifies success. Fails without fix, passes with it.
  • And updated the description.

@MooSayed1 MooSayed1 requested a review from gkodinov February 22, 2026 01:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements.

Development

Successfully merging this pull request may close these issues.

2 participants