登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  数据库 >  MySQL

MySQL 9.4 的 MD5 和 SHA1 弃用会影响哪些旧 SQL:先区分哈希用途再迁移

来源:17golang原创

时间:2026-09-04 09:35:18 298浏览 收藏

MySQL 9.4 升级清单里多了一项容易被忽略的 SQL 兼容检查:MD5()SHA1() 已被标记为弃用。真正麻烦的不是把函数名批量替换掉,而是旧 SQL 可能在做文件校验、业务去重,也可能被误用来保存口令;这三种场景的迁移结果完全不同。

先按用途分组,再决定保留、替换还是移出数据库;迁移验收要同时看结果长度、存储列、索引和旧数据读取,不要把“换成 SHA2()”当成通用答案。

要点速览
  • MySQL 9.4 的弃用信号首先要求找全调用点,而不是立即改函数名。
  • 校验值、业务指纹和口令字段要分别处理,算法选择不能脱离读取方与字段契约。
  • 函数替换后必须回归长度、字符集、二进制存储、索引和新旧数据双读。

先从旧 SQL 和字段用途定位 MD5()、SHA1()

先搜调用点,再看它的输入和结果去向。除了应用仓库,还要检查视图、存储过程、触发器、定时任务和报表 SQL。一个实用的登记表至少保留四列:调用位置、输入字段、结果列、业务用途;如果结果列实际承担文件校验,应明确记成“校验结果”,不要只写一个含义模糊的 hash

SELECT ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_DEFINITION
FROM information_schema.ROUTINES
WHERE ROUTINE_DEFINITION REGEXP 'MD5\\(|SHA1\\('; 

SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLUMN_TYPE
FROM information_schema.COLUMNS
WHERE COLUMN_NAME REGEXP 'hash|digest|password|token';

应用侧还要用代码搜索补齐参数化 SQL。重点不是列名里有没有 password,而是结果是否参与登录校验、对象去重、缓存键、签名比对或文件完整性检查。这个分类决定了后面能否保留历史值,以及是否需要让新旧算法并存一段时间。

MySQL 9.4 中 MD5 和 SHA1 SQL 调用按校验、业务指纹与口令字段分组的静态关系图
图1:先沿着 SQL 调用边界查看 MD5() 与 SHA1(),再对照结果去向边界区分校验、业务指纹和口令字段。

按结果语义决定保留、替换还是移出数据库

MySQL 9.4 发布说明只给出弃用信号,没有替你决定业务迁移。校验文件或外部对象指纹通常要优先保证跨版本可读;业务去重键则要评估重复概率、索引长度和所有调用方;口令字段更不能把原始 MD5、SHA1 或裸 SHA2 当成密码存储方案。

用途迁移动作先验收什么
文件/内容校验保留旧读路径,新增算法并行生成历史文件仍可核对,外部协议不被悄悄改变
业务指纹/去重键评估新列或版本化键,再切写入索引长度、冲突处理和缓存命中
口令字段移交应用层密码哈希流程登录验证、重置和旧用户升级路径

建议把迁移动作写成数据字典,而不是写在一条替换脚本里。例如 MD5(file_bytes) 可能是外部校验协议的一部分,直接改成 SHA-256 会让历史清单失配;而 MD5(order_id) 如果只是内部短键,则要先确认是否真的需要固定 32 位文本。两者都叫“哈希”,兼容边界却不同。

核对返回长度、字符集与存储列的兼容性

函数替换最容易在列定义处留下隐性问题。MySQL 文档中,MD5() 的十六进制文本结果是 32 个字符,SHA1() 是 40 个字符;如果使用 UNHEX() 存二进制,则对应 BINARY(16)BINARY(20)。这不是简单的“长度越长越安全”,而是结果表示和存储契约发生了变化。

SELECT
  LENGTH(MD5('order-1001')) AS md5_text_len,
  LENGTH(SHA1('order-1001')) AS sha1_text_len,
  LENGTH(UNHEX(MD5('order-1001'))) AS md5_binary_len,
  LENGTH(SHA2('order-1001', 256)) AS sha2_text_len;

SHOW CREATE TABLE order_fingerprints;

回归时至少覆盖普通文本、中文输入、空值和超长输入。若列使用了 CHAR,还要观察尾部空格比较;若改成二进制列,则检查应用序列化是否仍按十六进制字符串传输。不要只在一条样例上比较结果相等,因为更换算法的目标通常就是让结果不再相等。

MySQL MD5 SHA1 SHA2 与 UNHEX 二进制存储列之间的长度和兼容边界关系图
图2:沿着函数结果边界核对 MD5()、SHA1() 与 SHA2(),再检查 UNHEX() 和 BINARY 列的长度契约。

用双读回归和分阶段发布确认迁移结果

不要在同一个发布里完成“改函数、改列、删旧数据”。更稳妥的做法是先增加新列或新版本标记,写入阶段同时保留旧值,读取阶段先做双读比较;确认接口、索引、缓存和历史数据都能解释后,再切换默认读取。

  • 校验场景:旧算法只负责识别历史对象,新算法负责新对象,外部交换格式写清版本。
  • 业务指纹:对重复键、分页排序和缓存失效做回归,尤其检查新列是否进入唯一索引。
  • 口令场景:保留旧用户的升级路径,登录成功后再按应用层规则更新凭据,不在 SQL 里拼接替代哈希。

观察窗口内要能回答两个问题:还有哪些请求在读取旧算法,以及新算法失败时能否回滚到旧值。旧列的清理放在这两个答案都明确之后,迁移才算真正收口。

常见问题

MySQL 9.4 会立刻删除 MD5() 和 SHA1() 吗?

当前发布说明给出的是弃用信号,并注明未来版本计划移除。迁移应尽早完成,但不能把“已弃用”写成“当前版本已经不可调用”。

所有 MD5() 都应该改成 SHA2() 吗?

不应该。先确认它是外部校验、业务指纹还是口令相关逻辑,再处理结果契约;口令存储也不等于在 SQL 中换一个裸哈希函数。

用 UNHEX() 存哈希值有什么坑?

要同步调整列类型、长度、索引和接口编码。十六进制文本与二进制值的比较、排序和序列化方式不同,不能只改 SELECT 表达式。

这次迁移真正要交付的是一张用途清单和一组可回滚的兼容检查,而不是一条全局替换命令。把算法、结果表示、字段和读取方放在同一张变更记录里,后续 MySQL 版本继续调整时才有清晰的落点。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>