MariaDB与MySQL权限体系表面相似但存在三处关键差异:host表在MariaDB 10.4+中失效、认证插件默认不兼容(caching_sha2_password)、动态权限机制未实现;权限字段、插件契约及底层机制不一致,易致跨库迁移时静默降权。

权限表结构差异:user 表仍是核心,但 host 表实际失效
MariaDB 保留了 mysql.host 表的定义,但自 MariaDB 10.4 起已完全不读取它;MySQL 5.6 起则直接移除了该表。这意味着:无论你用 GRANT ... ON *.* TO 'u'@'%' 还是 INSERT INTO mysql.host 手动写入,MariaDB 都不会据此做权限判定。
真实生效的只有三张表:mysql.user(全局权限)、mysql.db(库级)、mysql.tables_priv(表级)。权限叠加逻辑和 MySQL 一致:更细粒度的权限会覆盖粗粒度的“N”值,但不能绕过 user 表里被设为 N 的管理权限(如 super_priv)。
-
USAGE权限在两者中行为一致:仅表示可登录,且GRANT USAGE ON *.* TO 'u'@'h' IDENTIFIED BY 'pw'不会清空已有权限 - MariaDB 的
user表多出password_expired、password_last_changed等字段,MySQL 5.7+ 才逐步补全 - MySQL 8.0 引入的
role_edges和default_roles表,MariaDB 目前(10.11)仍无原生支持,需靠应用层模拟角色继承
认证插件默认行为不同:caching_sha2_password 不兼容 MariaDB
MySQL 8.0 默认启用 caching_sha2_password 插件,而 MariaDB 10.4+ 仍默认用 mysql_native_password。如果你从 MySQL 8.0 导出用户并导入 MariaDB,会遇到 ERROR 1045 (28000): Access denied for user —— 并非密码错,而是认证协议不匹配。
修复方式不是改密码,而是显式指定插件:
ALTER USER 'u'@'h' IDENTIFIED WITH mysql_native_password BY 'pw';
- 若客户端报
Client does not support authentication protocol requested by server,基本可断定是这个原因 - MariaDB 10.6+ 支持
caching_sha2_password插件,但需手动安装并启用,且不作为默认 - PHP PDO 或旧版 MySQL Connector/J 8.0 以下版本无法直连启用了
caching_sha2_password的 MySQL 8.0 实例,这点在迁移时极易被忽略
权限验证顺序一致,但 SUPER 权限的实际约束范围有偏差
两者都走“先匹配 user 表,再查 db 表,最后落到 tables_priv”的路径,但对 SUPER 类管理权限的落地控制点不同。
例如 read_only=ON 在 MySQL 中只拦普通用户,SUPER 用户仍可写;而 MariaDB 10.5+ 引入了 super_read_only=ON 才真正禁止 SUPER 用户写入——但注意,MariaDB 的 super_read_only 是独立变量,MySQL 8.0.12+ 才跟进同名变量,且行为细节仍有出入(比如对临时表、存储过程创建的拦截粒度)。
-
SHOW DATABASES权限:MySQL 8.0 要求显式授予或super_priv=Y;MariaDB 中只要show_db_priv=Y即可,哪怕super_priv=N -
CREATE TABLESPACE权限在 MariaDBuser表中存在对应字段,在 MySQL 中仅企业版支持,社区版无此权限列 - MySQL 的
REPLICATION CLIENT权限在 MariaDB 中叫REPLICATION_SLAVE_ADMIN,名称不一致会导致脚本迁移失败
动态权限(Dynamic Privileges)在 MariaDB 中尚未落地
MySQL 8.0 推出动态权限机制,把部分管理权限(如 BACKUP_ADMIN、CLONE_ADMIN)从 user 表字段中剥离,改为运行时注册/授予权限。MariaDB 当前(10.11)仍未实现该机制,所有权限仍硬编码在 user 表字段中。
这意味着:任何依赖 GRANT BACKUP_ADMIN ON *.* TO 'u'@'h' 的自动化运维脚本,在 MariaDB 上会直接报 Unknown privilege 错误。
- 等效方案只能退回到传统权限组合,比如用
SELECT+LOCK TABLES+RELOAD模拟备份权限 - MariaDB 的
SYSTEM_VARIABLES_ADMIN权限在user表中对应set_user_variables_priv字段,命名和语义都与 MySQL 动态权限不兼容 - 如果你用 Ansible 或 Terraform 管理数据库权限,必须按
server_type == "mariadb"分支处理权限声明逻辑
权限体系表面相似,但底层字段、插件契约、动态机制三处不一致,足以让一套权限初始化脚本在跨库迁移时静默失效。最危险的是那些没报错、只降权的场景——比如 SHOW DATABASES 权限丢失导致监控告警失灵,或者 REPLICATION_SLAVE_ADMIN 缺失让主从切换流程卡在半途。


















