MariaDB Community Server 13.0 已进入正式可用(GA)阶段,意味着它不再只是供尝鲜的开发版本,而是可以进入生产升级评估。这个版本继续扩展 Oracle 兼容能力和过程式 SQL 支持,同时带来新的 DML 能力、性能优化、弃用项,以及面向开发体验与可观测性的改进。
对现有团队来说,重点不只是“多了哪些语法”,而是这些变化能否降低 Oracle 迁移成本、简化数据库逻辑,并让升级后的性能变化更容易定位。
GA 改变的是采用门槛,而不是升级风险
GA 表示版本已经达到官方稳定状态,但不等于可以跳过验证直接替换生产数据库。MariaDB 13.0 涉及 SQL 行为、存储过程、DML、性能与弃用项,升级测试至少应覆盖以下资产:
- 应用实际执行的 SQL,而不只是 ORM 自动生成的简单查询;
- 存储过程、函数、触发器和事件调度任务;
- 批量写入、更新、删除以及事务回滚路径;
- JDBC、ODBC 或语言驱动的连接与类型映射;
- 依赖旧行为、已弃用配置或兼容模式的运维脚本;
- 慢查询、锁等待、连接数和高频 SQL 等可观测性指标。
尤其是 Oracle 迁移项目,“语法可以执行”只是第一关。日期计算、空值处理、隐式类型转换、异常处理和事务边界都可能影响最终结果。扩展兼容性可以减少改写工作,但不能替代业务级回归测试。
Oracle 兼容与过程式 SQL:用真实语料验证
MariaDB 13.0 进一步扩展了过程式 SQL 和 Oracle 兼容能力。它对两类团队尤其有意义:一类正在把 Oracle 工作负载迁移到 MariaDB,另一类希望把部分数据密集型逻辑保留在数据库端。
评估兼容性时,不要只准备几个孤立的函数调用。更有效的做法是从生产系统抽取一组代表性对象:
- 包含游标、条件分支和异常处理的过程;
- 使用 Oracle 风格空值函数、日期函数和伪表的查询;
- 带有多次写操作和显式事务控制的业务流程;
- 依赖特定错误码或受影响行数的调用代码。
下面的查询可以作为最小兼容模式探针。它并不代表这些语法都是 13.0 才新增的功能,而是用于确认目标环境中的 Oracle 模式、函数行为和客户端调用链是否符合预期:
SET SESSION sql_mode = 'ORACLE';
SELECT NVL(NULL, 'fallback') AS null_result
FROM DUAL;
SELECT CURRENT_TIMESTAMP AS database_time
FROM DUAL;
兼容测试应同时记录结果值、返回类型、警告和错误,而不是只检查语句是否成功。
搭一个可重复运行的升级冒烟环境
可以先用容器建立隔离环境,再把应用 SQL、过程和观测查询纳入同一套脚本。运行前请把示例密码替换为本地测试密码;如果镜像仓库使用不同标签,也需要相应调整版本号。
docker run --name mariadb13 \
-e MARIADB_ROOT_PASSWORD=change-me \
-p 3306:3306 \
-d mariadb:13.0
docker exec mariadb13 mariadb-admin \
-uroot -pchange-me ping --wait=30
docker exec mariadb13 mariadb \
-uroot -pchange-me \
-e "SELECT VERSION();"
接着保存下面的内容为 smoke.sql。这个例子用一个存储过程验证条件更新、受影响行数、异常抛出和事务提交,适合改造成现有系统的最小业务回归用例:
CREATE DATABASE IF NOT EXISTS upgrade_test;
USE upgrade_test;
DROP TABLE IF EXISTS account;
CREATE TABLE account (
id BIGINT PRIMARY KEY,
balance DECIMAL(12, 2) NOT NULL
) ENGINE=InnoDB;
INSERT INTO account (id, balance)
VALUES (1, 100.00), (2, 50.00);
DELIMITER //
DROP PROCEDURE IF EXISTS transfer_money//
CREATE PROCEDURE transfer_money(
IN p_from BIGINT,
IN p_to BIGINT,
IN p_amount DECIMAL(12, 2)
)
BEGIN
START TRANSACTION;
UPDATE account
SET balance = balance - p_amount
WHERE id = p_from
AND balance >= p_amount;
IF ROW_COUNT() <> 1 THEN
ROLLBACK;
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'insufficient funds or missing source account';
END IF;
UPDATE account
SET balance = balance + p_amount
WHERE id = p_to;
IF ROW_COUNT() <> 1 THEN
ROLLBACK;
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'missing destination account';
END IF;
COMMIT;
END//
DELIMITER ;
CALL transfer_money(1, 2, 25.00);
SELECT id, balance FROM account ORDER BY id;
执行脚本:
docker exec -i mariadb13 mariadb \
-uroot -pchange-me < smoke.sql
预期余额是账户 1 为 75.00,账户 2 为 75.00。进一步测试时,应增加余额不足、目标账户不存在、并发转账和客户端主动断开等失败场景。
把可观测性纳入验收标准
性能改进只有在相同数据、相同查询和相同并发下对比才有意义。升级前后应使用同一份数据快照与压测脚本,并保存延迟分位数、吞吐量、慢查询数量和资源消耗。
以下命令可作为轻量级检查起点:
docker exec mariadb13 mariadb -uroot -pchange-me -e "
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Slow_queries';
SHOW GLOBAL STATUS LIKE 'Questions';
EXPLAIN FORMAT=JSON
SELECT id, balance
FROM upgrade_test.account
WHERE id = 1;
"
如果环境启用了 Performance Schema,还可以查看高频语句摘要:
SELECT
DIGEST_TEXT,
COUNT_STAR,
ROUND(SUM_TIMER_WAIT / 1000000000000, 3) AS total_seconds
FROM performance_schema.events_statements_summary_by_digest
WHERE DIGEST_TEXT IS NOT NULL
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;
这里的关键不是某一条查询,而是建立升级前后的统一基线。否则,即使 13.0 提供了更多观测能力,也很难判断一次延迟变化来自数据库版本、执行计划、数据分布,还是连接池配置。
上线前的决策清单
MariaDB 13.0 已达到 GA,适合进入测试和分阶段采用,但建议按以下顺序推进:
- 阅读与当前版本之间的完整发行说明,逐项识别弃用和默认行为变化;
- 在备份副本或匿名化数据上执行真实 SQL、存储过程和迁移脚本;
- 对 Oracle 兼容代码比较结果值、类型、异常和事务行为;
- 为关键 DML 建立正确性、并发性与回滚测试;
- 固定数据集和压测参数,对比升级前后的执行计划与性能指标;
- 验证备份、恢复、复制、监控和回滚流程,而不只验证正常查询;
- 先部署到影子流量或低风险实例,再逐步扩大范围。
这次发布的价值在于把兼容性、开发体验和可观测性放在同一次演进中。但真正决定升级是否成功的,仍然是可重复的测试、明确的性能基线,以及随时可执行的回滚方案。