mcpField
M
mysql-to-mariadb

mysql-to-mariadb

github.com/mariadb数据与数据库17120 次安装2 周前更新
代码仓库

关于 mysql-to-mariadb

面向将 MySQL 数据库迁移到 MariaDB 的开发者与管理员,说明两者在语法、功能、认证和存储上的差异,并给出迁移时的适配要点。

主要功能

  1. 01梳理 SQL 与 JSON 差异
  2. 02说明认证和复制兼容性
  3. 03对比两者专有功能
  4. 04指导逻辑导出与导入
  5. 05提示迁移后的查询计划检查

适用场景

  1. 01评估 MySQL 8.0 迁移影响
  2. 02调整不兼容的 SQL 和 JSON 用法
  3. 03规划逻辑备份与恢复
  4. 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 中使用 RETURNINGMariaDB 10.5+ 支持 RETURNING——使用它即可获取插入、更新或删除的行,无需再执行第二次查询
未推荐使用 CREATE SEQUENCEMariaDB 提供原生序列对象;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 的处理方式不同:

方面MySQLMariaDB
存储带路径索引的二进制格式带有效性检查的 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.55.5是
5.610.0–10.1大致可以
5.710.2–10.4有限
8.010.5+否——存在显著差异

来源

如需了解此处未涵盖的主题,请参阅 MariaDB 官方文档:mariadb.com/docs。

评论

支持 Markdown