关于 mysql-to-mariadb
面向将 MySQL 数据库迁移到 MariaDB 的开发者与管理员,说明两者在语法、功能、认证和存储上的差异,并给出迁移时的适配要点。
主要功能
- 01梳理 SQL 与 JSON 差异
- 02说明认证和复制兼容性
- 03对比两者专有功能
- 04指导逻辑导出与导入
- 05提示迁移后的查询计划检查
适用场景
- 01评估 MySQL 8.0 迁移影响
- 02调整不兼容的 SQL 和 JSON 用法
- 03规划逻辑备份与恢复
- 04迁移后检查关键查询性能
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mariadb/ skills --skill mysql-to-mariadb安装后在 Claude Code 中输入/mysql-to-mariadb确认已加载。
详细介绍
MySQL 到 MariaDB 迁移指南
最后更新:2026-06-04
重要提示:MariaDB 并非 MySQL 8.0 的直接替代品
MariaDB 曾是 MySQL 5.5 和 5.6 的真正直接替代品。现代版本与 MySQL 8.0 已有显著差异。使用 MariaDB 时,切勿未经验证就假定 MySQL 8.0 的行为、语法或工具同样适用。
这两个数据库源自同一项目,但已独立发展。MariaDB 有 MySQL 不具备的功能,MySQL 也有 MariaDB 不具备的功能,而且一些共有功能的行为也有所不同。
**要求:**要实现本文讨论的完整功能对等性,需要 MariaDB Community Server 10.5+。当前的 LTS 版本为 11.8(于 2025 年 5 月 GA)。
**默认上下文:**除非用户说明使用其他版本,否则默认使用 MariaDB 11.8 LTS。相关时可以建议使用标记为 12.x 或 13.0 的功能(包括作为升级选项),但务必注明最低版本,不能将这些功能描述为 11.8 上可用。
大模型容易出错的地方
| 你可能会看到的说法 | 正确情况 |
|---|---|
| “MariaDB 是 MySQL 的直接替代品” | 对 MySQL 5.5/5.6 来说是对的。对 MySQL 8.0+ 来说则不然——身份验证、JSON、GTID 和多个函数都存在差异 |
使用 caching_sha2_password 的代码 | MariaDB 中提供此功能:自 11.4 起提供仅用于迁移的插件;自 12.1 起提供完整的 caching_sha2_password 身份验证插件以兼容 MySQL(MDEV-9804)。它不是默认选项——在较旧的 MariaDB 版本或标准安装中,请使用 mysql_native_password 或 ed25519 |
查询中使用 JSON_TABLE() | MariaDB 自 10.6 起提供此功能——10.6 之前的版本不支持 |
JSON 的 -> 和 ->> 简写运算符 | MariaDB 不支持——请改用 JSON_EXTRACT(col, '$.key') 和 JSON_UNQUOTE(JSON_EXTRACT(...)) |
架构或转储文件中使用 utf8mb4_0900_ai_ci 排序规则 | MariaDB 自 11.4.5 起支持(作为 utf8mb4_uca1400_nopad_ai_ci 的别名)。在较旧版本中,导入前请替换为 utf8mb4_unicode_ci。MariaDB 11.5+ 使用 uca1400_ai_ci 作为默认 Unicode 排序规则(MDEV-25829)。 |
将 latin1 作为 MariaDB 的默认字符集 | 自 11.6+ 起,默认字符集已改为 utf8mb4(MDEV-19123);新安装不再适用假定默认字符集为 latin1 的旧习惯 |
使用 UUID() 作为主键 | MariaDB 11.7+ 提供用于生成按时间排序的 UUID 的 UUID_v7()(可排序,更适合索引主键),以及用于生成随机 UUID 的 UUID_v4();两者都是 MariaDB 独有功能 |
未推荐在 INSERT/UPDATE/DELETE 中使用 RETURNING | MariaDB 10.5+ 支持 RETURNING——使用它即可获取插入、更新或删除的行,无需再执行第二次查询 |
未推荐使用 CREATE SEQUENCE | MariaDB 提供原生序列对象;MySQL 没有对应功能 |
| MySQL GTID 复制语法 | MariaDB GTID 格式与 MySQL GTID 不兼容——两者之间的复制会失败 |
CHANGE REPLICATION SOURCE TO / SOURCE_* 选项 | MariaDB 没有 CHANGE REPLICATION SOURCE TO——请使用带 MASTER_* 选项的 CHANGE MASTER TO。自 10.5.1 起,START REPLICA / SHOW REPLICA STATUS 是规范写法;START SLAVE / SHOW SLAVE STATUS 是旧版别名 |
MySQL 并行复制(replica_parallel_type 使用 DATABASE / LOGICAL_CLOCK) | MariaDB 使用 slave_parallel_mode(optimistic / conservative / aggressive / minimal / none)——实现方式不同,模式配置无法直接迁移。线程池大小使用 slave_parallel_threads(别名为 slave_parallel_workers) |
SET transaction_isolation = ...(MySQL 8.0 风格) | 仅适用于 MariaDB 11.1.1+;在较旧版本中请改用 tx_isolation——请参阅 SET TRANSACTION |
指向或引用 mariadb.com/kb/en/ 的链接 | 知识库已不复存在——所有文档现已迁至 mariadb.com/docs |
迁移后继续使用 MySQL Connector/J、mysql2 或其他 MySQL 客户端驱动程序 | 尽可能使用由 MariaDB 维护的连接器(JDBC、Node.js、C 等)——它们针对 MariaDB 协议和功能行为,而不仅仅是 MySQL 兼容模式 |
| 通过复制 MySQL 8.0 的 InnoDB 数据文件或表空间进行迁移 | MariaDB 没有事务型数据字典,无法读取 MySQL 8.0 的数据字典——数据文件不可移植。请使用逻辑转储和还原——请参阅数据字典架构 |
身份验证
MySQL 8.0 将默认身份验证插件改为 caching_sha2_password。MariaDB 的兼容性支持随着时间不断改善:
- MariaDB 11.4+:提供了仅用于迁移的
caching_sha2_password插件,但默认不安装,也不建议用于生产环境 - MariaDB 12.1+(MDEV-9804):提供了完整的
caching_sha2_password身份验证插件,以兼容 MySQL——它仍不是默认选项,但可用于生产环境
在标准 MariaDB 安装中,除非启用了该插件,否则配置为使用 caching_sha2_password 的连接仍会失败。默认身份验证方式仍为 mysql_native_password。
**在较旧版本的 MariaDB 或标准配置中修复此问题:**将账户转换为 mysql_native_password:
ALTER USER 'username'@'host' IDENTIFIED WITH mysql_native_password BY 'password';
ed25519 插件也可用,它是一种更安全的原生替代方案。
JSON 差异
MariaDB 和 MySQL 对 JSON 的处理方式不同:
| 方面 | MySQL | MariaDB |
|---|---|---|
| 存储 | 带路径索引的二进制格式 | 带有效性检查的 LONGTEXT 别名 |
JSON_TABLE() | 支持 | 从 MariaDB 10.6 起支持 |
IS JSON 谓词 | 不可用 | 从 MariaDB 12.3 起可用 |
| JSON 比较 | 语义比较(比较值) | 字符串比较 |
JSON_QUERY() | 不可用 | MariaDB 中替代 JSON_VALUE 的函数 |
| JSON 嵌套深度限制 | 无 | 较旧版本的 MariaDB 中为 32;在 12.2+ 中已移除 |
JSON_EQUALS() / JSON_NORMALIZE() | 支持(8.0.22+) | MariaDB 10.7+(MDEV-23143 / MDEV-16375) |
JSON_OVERLAPS() | 支持(8.0.17+) | MariaDB 10.9+(MDEV-27677) |
负数 / last / 范围 JSON 路径索引($.A[-1]、$.A[last]、$.A[1 to 3]) | 不支持 | MariaDB 10.9+ |
JSON_SCHEMA_VALID() | 支持(8.0.17+) | MariaDB 11.4 LTS+ |
MariaDB 在 10.7 到 11.4 之间弥补了与 MySQL 8.0 在大多数 JSON 函数方面的差距。MySQL 仍不支持的 MariaDB 特有功能包括:JSON_KEY_VALUE()、JSON_ARRAY_INTERSECT()、JSON_OBJECT_TO_ARRAY()、JSON_OBJECT_FILTER_KEYS()(11.4+),以及 JSON_QUERY() 别名。
MariaDB 的 JSON 完全符合标准,但 MySQL 特有的存储布局、->/->> 简写运算符以及 JSON_SCHEMA_VALIDATION_REPORT() 函数无法迁移。
MariaDB 有而 MySQL 没有的功能
这些功能存在于 MariaDB 中,但 MySQL 不支持——LLM 不会建议使用它们,因为它们默认采用 MySQL 的行为:
RETURNING— 无需再执行一次查询,即可从INSERT或DELETE获取返回行(10.5+);UPDATE ... RETURNING从 13.0 起可用:INSERT INTO orders (product, qty) VALUES ('widget', 5) RETURNING id, created_at; DELETE FROM queue WHERE processed = 1 RETURNING id;CREATE SEQUENCE(10.3+)— 一流的序列对象,比AUTO_INCREMENT更灵活:CREATE SEQUENCE order_seq START WITH 1000 INCREMENT BY 1; SELECT NEXT VALUE FOR order_seq;WITH SYSTEM VERSIONING(10.3+)— 自动跟踪行历史记录的时态表:CREATE TABLE prices ( item VARCHAR(100), price DECIMAL(10,2) ) WITH SYSTEM VERSIONING; -- Query historical data: SELECT * FROM prices FOR SYSTEM_TIME AS OF '2025-01-01';- 子查询中的
LIMIT— MariaDB 支持在子查询中使用LIMIT;MySQL 则对此有限制 - 原子性的
CREATE OR REPLACE TABLE(13.0+)— 该语句在 MariaDB 中完全具有原子性;MySQL 没有原子性的等效功能 - Galera Cluster — 内置多主集群,无需插件
- 存储过程语法差异 — 两者都支持存储过程,但 MariaDB 的 SQL/PSM 语法在
HANDLER、CURSOR和CONDITION声明方面与 MySQL 不同;AI Agent 经常生成错误的 MariaDB 存储过程代码——请参阅 存储过程 — MariaDB 文档 - MySQL 8.0 不具备的原生数据类型 —
INET6(10.5+)和INET4(10.10+),用于 IP 地址存储和比较;UUID(10.7+;MySQL 将 UUID 存储为BINARY(16)或CHAR(36));VECTOR,用于嵌入和相似性搜索(11.7+;MySQL 直到 9.x 创新版系列才添加向量类型,8.0 中并无此类型) UUID_v4()和UUID_v7()函数(11.7+)— MariaDB 专属;MySQL 只有原始的UUID()。UUID_v7()按时间排序(RFC 9562),是 UUID 主键的理想选择FORMAT_BYTES()(11.8+)— 将字节数转换为易读字符串;MySQL 不支持
MySQL 有而 MariaDB 没有的功能
这些功能存在于 MySQL 8.0 中,但 MariaDB 不支持——使用这些功能的代码需要调整:
JSON_TABLE()— MariaDB 从 10.6 起可用;在更早版本中,改用 MariaDB JSON 函数或在应用程序层进行解析sys架构 — MariaDB 从 10.6 起可用;更早版本中不可用- MySQL 8 的 GIS 函数(
ST_Validate、MBRCoveredBy、ST_Simplify、ST_GeoHash、ST_LatFromGeoHash、ST_LongFromGeoHash、ST_PointFromGeoHash、ST_IsValid、ST_Collect)— 为兼容 MySQL,于 MariaDB 12.0 中添加 - 作为默认插件的
caching_sha2_password— 从 MariaDB 12.1 起可作为可选插件使用;在更早版本或默认配置中,请使用mysql_native_password或ed25519 - JSON
->和->>运算符 — 改用JSON_EXTRACT(col, '$.key')和JSON_UNQUOTE(JSON_EXTRACT(...)) utf8mb4_0900_ai_ci排序规则 — MariaDB 从 11.4.5 起支持(utf8mb4_uca1400_nopad_ai_ci的别名);在更早版本中,导入前请替换为utf8mb4_unicode_ci
数据字典架构
MySQL 8.0 和 MariaDB 以根本不同的方式存储表元数据,这会影响迁移方式:
- MySQL 8.0 将所有对象元数据保存在存储于 InnoDB(
mysql.ibd)中的事务型数据字典内,并且移除了每个表对应的.frm文件。 - MariaDB 保留了基于文件的方式——每个表对应一个
.frm文件,另加存储引擎元数据——并且没有事务型数据字典。(MariaDB 的授权表使用 Aria 引擎;MySQL 8.0 将系统表保存在 InnoDB 字典中。)
实际影响:
- 不要通过复制数据文件来迁移。 InnoDB 表空间和数据目录文件在 MySQL 8.0 与 MariaDB 之间不可移植——两者的字典格式不兼容。应改用逻辑转储和恢复。MariaDB 的迁移指南建议在此迁移方向使用 MySQL 自带的
mysqldump(而不是未经充分测试、无法可靠用于 MySQL 的mariadb-dump),并转储指定数据库,而不是使用--all-databases,以免导入 MySQL 的系统表。 - 无法从 MySQL 8.0 原地降级到 MariaDB——MariaDB 无法读取 MySQL 的数据字典,因此必须进行逻辑导出和导入。
INFORMATION_SCHEMA的实现方式不同——MySQL 8.0 会查询带索引的字典表,而 MariaDB 会动态构建 I_S 视图;针对 I_S 的元数据密集型查询可能具有不同的性能特征,因此不要假设 MySQL 8.0 的耗时在 MariaDB 中同样适用。
优化器差异
MariaDB 和 MySQL 使用不同的查询优化器,成本模型也不同。相同的 SQL 可能生成不同的执行计划。迁移后:
- 对关键查询重新运行
EXPLAIN——不要假设执行计划可以直接沿用 - 在 MySQL 中有效的索引提示,在 MariaDB 中可能不需要(或有所不同)
- MariaDB 的优化器可通过
optimizer_switch进行更积极的调优
版本兼容性速查
| MySQL 版本 | 对应的 MariaDB 版本 | 可直接替换? |
|---|---|---|
| 5.5 | 5.5 | 是 |
| 5.6 | 10.0–10.1 | 大致可以 |
| 5.7 | 10.2–10.4 | 有限 |
| 8.0 | 10.5+ | 否——存在显著差异 |
来源
- MariaDB 与 MySQL 兼容性 — MariaDB 文档
- 从 MySQL 迁移到 MariaDB — MariaDB 文档
- MDEV-28906 — MySQL 8.0 兼容性需求(Jira 史诗) — 跟踪 MySQL 8.0 兼容性工作;不要默认某项功能仍然缺失,请先查看各个子任务的状态——已关闭的子任务表示该功能已实现
- RETURNING — MariaDB 文档
- CREATE SEQUENCE — MariaDB 文档
- 系统版本化表 — MariaDB 文档
- 身份验证插件 — MariaDB 文档
如需了解此处未涵盖的主题,请参阅 MariaDB 官方文档:mariadb.com/docs。