简介:这份资源是 MySQL 5.7 官方中文文档的离线打包版,面向数据库初学者、后端开发者和运维人员,用于系统查阅 5.7 版本的功能特性与使用说明,解决在线文档检索不便、版本内容分散的问题。压缩包共 785 个文件,以 768 个 html 页面为主体,构成完整的文档章节与索引,另含少量 jpg 插图、css 样式表及 ncx、opf、xml 等电子书结构文件,整体约 8.79MB,体积轻便,解压后可直接用浏览器离线翻阅。内容覆盖 InnoDB 存储引擎、性能优化、JSON 数据类型、查询优化器改进、分区表增强、安全与复制机制、存储过程与触发器、性能 Schema 监控等核心知识点,章节组织完整,便于按主题定位查阅。目前已有 3691 人学习下载,适合需要随时对照官方说明排查配置、理解特性或准备升级迁移的读者作为案头参考。
1. 中文文档不是翻译件:MySQL 5.7 文档到底该怎么读
很多人第一次打开 MySQL 5.7 中文文档,是带着「查一个参数就关掉」的心态去的,结果翻了三页还在讲存储引擎的历史。这份文档真正的价值不在「翻译得顺不顺」,而在于它把 5.7 这个已经进入维护末期、却仍大量跑在生产环境里的版本,所有行为边界都写死了:sql_mode默认值改了什么、GROUP BY为什么突然报错、utf8mb4索引长度卡在 767 字节是怎么回事。这些不是知识点,是上线前必须核对的清单。适合两类人:一类是还在维护 5.7 实例、被升级和兼容性折腾的运维与后端;另一类是想把官方手册当查询字典用、而不是当教材通读的开发者。下面按「怎么定位条目 → 怎么把文档结论落到配置和 SQL → 哪些地方文档没写透要靠实测」推下去。
2. 把中文文档当查询字典:定位条目的三条路径
2.1 先分清「参考手册」和「教程」两类条目
MySQL 5.7 中文文档主体是参考手册(Reference Manual),它的组织逻辑是按「服务器管理 → SQL 语句 → 存储引擎 → 复制 → 优化」分卷,而不是按「我想实现某个功能」组织。所以直接搜中文关键词经常命中不到,因为条目名是英文术语的中文译法,比如你想找「慢查询」,条目可能叫「慢查询日志」,而参数名仍然是slow_query_log。我的习惯是:先用英文参数名或语句名搜,命中后再看中文解释;只有完全不知道术语时才用中文搜。这个顺序反过来,十次有六次会翻车。
判断一个条目是不是你要的,看它开头有没有「语法」小节。参考手册里凡是讲 SQL 语句的条目,第一段一定是语法形式,比如ALTER TABLE tbl_name [alter_option ...]。有语法块的条目是操作型条目,可以直接抄;没有语法块、通篇散文的,多半是概念说明,适合理解不适合照做。
2.2 用参数名反查:从报错信息回到文档条目
生产上最常见的场景是日志里蹦出一句报错,你得在文档里找到它对应的参数。做法是把报错里的关键词抠出来,去掉具体值,只留参数名或错误码。比如Expression #1 of SELECT list is not in GROUP BY clause,关键词是GROUP BY和ONLY_FULL_GROUP_BY,直接搜后者,能落到「SQL 模式」条目下的服务端 SQL 模式一节。这一步的关键是别搜整句报错,中文文档里报错原文是英文,整句搜命中率极低。
# 在本地拉一份文档源码或离线 HTML,用 grep 定位参数名出现的条目 # 假设离线文档解压在 ./mysql-docs-5.7-zh grep -rl "ONLY_FULL_GROUP_BY" ./mysql-docs-5.7-zh/sql-mode/ | head -5 # 输出示例:./mysql-docs-5.7-zh/sql-mode/server-sql-mode.html这段命令的逻辑是:文档离线包按章节分目录,grep -rl只列文件名不列匹配行,避免刷屏;head -5防止一个参数在几十个页面里被引用时输出过长。参数说明:-r递归子目录,-l只输出文件名,路径按你实际解压位置改。拿到文件名后直接打开,比在浏览器里点目录快得多。我一般会把常用章节的路径记在一个文本文件里,下次直接跳。
2.3 版本差异要先看「变更历史」小节
5.7 文档里每个参数条目末尾几乎都有「变更历史」或散落在正文里的版本标注,比如「从 MySQL 5.7.x 起,该参数默认值改为…」。这一节是整份文档里最容易被跳过、又最值钱的部分。因为 5.7 内部小版本之间行为也有变化,你照着某篇博客配了参数,结果实例是小版本偏早的,默认值对不上,排查半天。我的做法是:任何要改的参数,先在文档里确认它标注的引入版本和默认值变更点,再对照SELECT VERSION();的实际输出。
| 文档里要看的字段 | 为什么关键 | 常见误读 |
|---|---|---|
| 参数作用域(Global/Session) | 决定SET还是改配置文件 | 以为SET GLOBAL永久生效 |
| 动态与否(Dynamic) | 决定能否不重启修改 | 对静态参数执行SET报错 |
| 默认值 | 决定不配时的行为 | 拿旧版本默认值套 5.7 |
| 引入/变更版本 | 决定小版本兼容性 | 忽略小版本差异 |
这张表不是让你背,是让你每次改参数前扫一眼。尤其是「动态与否」,静态参数在 5.7 里执行SET GLOBAL会直接报Variable 'xxx' is a read only variable,这个报错在文档对应条目里写得很清楚,但很多人是先撞报错再回来查。
3. 把文档结论落成配置:5.7 三个高频参数的核对与改写
3.1 sql_mode:文档说默认变严格,你得知道严在哪
5.7 文档在「服务端 SQL 模式」条目里明确写了默认sql_mode包含ONLY_FULL_GROUP_BY、STRICT_TRANS_TABLES等。很多人从 5.6 迁过来,第一条挂掉的 SQL 就是SELECT里带了不在GROUP BY中的列。文档给的解释是「拒绝选择列表、HAVING 条件或 ORDER BY 列表中引用非聚合列、且这些列不在 GROUP BY 中」的查询。理解这句话的关键是「非聚合列」——如果你那列套了MAX()、COUNT(),就不受限制。
-- 先看当前实例实际生效的模式,别信配置文件里写了什么 SELECT @@GLOBAL.sql_mode, @@SESSION.sql_mode; -- 临时放宽(仅当前会话),用于验证某条 SQL 是不是被 ONLY_FULL_GROUP_BY 拦下 SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION'; -- 改完再跑一次原 SQL,能过就说明是模式问题,不是数据问题 SELECT dept_id, emp_name, COUNT(*) FROM emp GROUP BY dept_id;逻辑说明:第一条查全局和会话两层,因为会话可能被连接池初始化语句覆盖过,只看全局会误判。第二条只改会话,不动全局,避免影响其他连接,这是排查时的安全做法。第三条是复现用的最小 SQL,emp_name不在GROUP BY里也没聚合,严格模式下必报错。参数说明:STRICT_TRANS_TABLES控制插入时的严格校验,NO_ENGINE_SUBSTITUTION控制引擎不可用时的行为,这两个和ONLY_FULL_GROUP_BY是 5.7 默认组合里最常被单独摘出来的。真要长期改,落到my.cnf的[mysqld]段,改完重启或用SET GLOBAL加配置文件双写,别只做一半。
3.2 utf8mb4 与索引长度:文档里的 767 字节到底卡谁
5.7 文档在字符集和 InnoDB 索引两处都提到:utf8mb4每字符最多 4 字节,而早期 InnoDB 行格式下单列索引前缀上限是 767 字节。换算下来VARCHAR(191)是安全线(191×4=764),VARCHAR(255)就会超。文档写的是「取决于行格式和innodb_large_prefix」,这句话信息量很大:行格式是DYNAMIC或COMPRESSED且innodb_large_prefix=ON时,上限提到 3072 字节。所以不是所有 5.7 实例都卡 767,得看实际行格式。
-- 查表的行格式,决定索引前缀上限是 767 还是 3072 SELECT TABLE_NAME, ROW_FORMAT FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'your_db' AND TABLE_NAME = 'your_table'; -- 查全局 large_prefix 开关(5.7 默认 ON,但老库可能被关过) SHOW VARIABLES LIKE 'innodb_large_prefix'; -- 建索引时显式给前缀长度,避免整列索引超限 ALTER TABLE your_table ADD INDEX idx_name (name(191));逻辑说明:先确认行格式再决定前缀长度,顺序不能反。如果ROW_FORMAT是COMPACT或REDUNDANT,即使large_prefix开着也按 767 算。第三条的name(191)是前缀索引写法,只索引前 191 个字符,够区分大部分业务数据。参数说明:191是utf8mb4下 767÷4 向下取整的安全值;如果你的列确定只存 ASCII,可以放宽,但别拿业务假设赌。文档没写透的一点是:前缀索引对ORDER BY name整列排序没用,只对等值和前缀匹配有效,这个边界得自己记。
3.3 慢查询日志:文档给了参数,没给「先开哪个」
5.7 文档「慢查询日志」条目列了slow_query_log、long_query_time、log_queries_not_using_indexes等一串参数。新手容易一次全开,结果日志暴涨把磁盘写满。文档其实在条目里提示了log_queries_not_using_indexes在表数据量小时会记录大量「看似没走索引」的查询,但这句话藏在段落中间,不显眼。我的落地顺序是:先只开slow_query_log和long_query_time,跑一天看量,再决定要不要加「未使用索引」记录。
# my.cnf 的 [mysqld] 段,最小可用慢日志配置 slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 1 # 先不开 log_queries_not_using_indexes,观察一天再定逻辑说明:long_query_time = 1是秒为单位,5.7 支持小数如0.5,但先给 1 秒能过滤掉大部分噪声。slow_query_log_file要给绝对路径且目录对 MySQL 进程可写,否则启动时静默不生效——这个坑文档提了但很容易漏。参数说明:改完my.cnf需要重启或用SET GLOBAL slow_query_log = 1动态开,但slow_query_log_file是静态的,改路径必须重启。验证是否生效,跑一条SELECT SLEEP(2);再看日志文件有没有新记录,比看参数值可靠。
4. 文档没写透的地方:5.7 中文文档避坑四条
4.1 现象:照文档配了参数,SHOW VARIABLES却没变
原因通常是配置文件位置不对,或者[mysqld]段写成了[mysql]段。5.7 在部分系统上会读多个my.cnf路径,文档「使用选项文件」条目列了读取顺序,但中文版把顺序表放在很靠后的位置。解决:用mysqld --verbose --help | grep -A1 "Default options"看实际读取的配置文件列表,确认你改的那个在列表里且优先级最高。改完用SHOW VARIABLES LIKE '参数名'核对,别只看文件内容。
4.2 现象:GROUP BY报错,按文档关了严格模式还是报
原因是只改了SESSION没改GLOBAL,或者连接池在建立连接时执行了自己的SET sql_mode,把你的会话级设置覆盖了。文档在 SQL 模式条目里讲了作用域,但没讲连接池这个场景。解决:先SELECT @@SESSION.sql_mode在业务连接里查实际值,如果和你在客户端手敲的不一样,就是连接池初始化语句在作怪,去连接池配置里找connectionInitSql之类的项。
4.3 现象:utf8mb4建表成功,插入 emoji 仍报错
原因是列级字符集没跟着表走,或者客户端连接字符集不是utf8mb4。文档在字符集条目里强调了三层:服务端默认、库/表/列、连接。很多人只改了库默认,列上还留着utf8。解决:SHOW FULL COLUMNS FROM 表名看Collation列,不是utf8mb4_*的就是漏改的列;连接层用SET NAMES utf8mb4或在连接串里指定characterEncoding=utf8mb4。
4.4 现象:按文档开了慢日志,文件一直空
原因是long_query_time设太大,或者查询走了缓存没真正执行。5.7 的查询缓存虽然默认关,但老实例可能开着,命中缓存的查询不计入慢日志。文档在慢日志条目提了「不记录缓存命中」,但一笔带过。解决:先SHOW VARIABLES LIKE 'query_cache_type'确认缓存状态,排查阶段可临时关缓存;再把long_query_time调到0跑几条测试 SQL,确认日志管道通了再调回正常值。
提示:这四条的共同点是「文档写了,但写在你不一定会翻到的段落」。所以查文档时养成看条目末尾「注意」和「变更历史」的习惯,比通读正文效率高。
5. 把文档变成可复用的核对清单:一个具体技巧
文档读多了会发现,真正高频用到的条目其实集中在少数几卷:SQL 模式、字符集、InnoDB 索引、慢日志、复制。与其每次从头翻,不如把这些条目的关键结论抽成一张自己的核对表,按「上线前 / 排错时 / 升级前」三个场景分组。我自己的做法是维护一个 Markdown 文件,每条只写三样:参数名或语句名、文档里的关键一句(原文摘录,不转述)、我实测过的边界值。转述会丢信息,原文摘录能保证下次还能对回文档。
下面是一个最小示例,展示怎么把「字符集」这一块抽成可执行核对项:
-- 上线前字符集核对:三层都要是 utf8mb4 -- 1) 服务端默认 SHOW VARIABLES LIKE 'character_set_server'; -- 2) 库默认 SELECT DEFAULT_CHARACTER_SET_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'your_db'; -- 3) 列级(找出不是 utf8mb4 的漏网列) SELECT TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'your_db' AND CHARACTER_SET_NAME <> 'utf8mb4';逻辑说明:三条查询对应文档里字符集的三层结构,缺一层就可能出现「建表成功、插入失败」。第三条用<>反查漏网列,比逐表SHOW CREATE TABLE快。参数说明:information_schema.COLUMNS的CHARACTER_SET_NAME对非字符类型(如INT)为NULL,所以结果里出现NULL行是正常的,别当成漏改。这个查询在库表多的时候会慢,加AND TABLE_NAME IN (...)缩小范围。
再补一个验证习惯:任何从文档抄来的配置,改完必须用一条「能触发该配置行为」的 SQL 验证,而不是只看参数值。比如改了sql_mode,就跑一条会被严格模式拦下的插入;改了索引前缀,就EXPLAIN看是否真的用上了索引。文档给的是「应该怎样」,实测给的是「实际怎样」,两者对不上时,以实测为准,再回文档找为什么——往往就是前面说的版本差异或作用域问题。
我踩过最深的一次坑,是把文档里某个参数的默认值当成「所有 5.7 小版本都一样」,结果在一个偏早的小版本上行为完全不同,排查了大半天才想起翻「变更历史」。从那以后,凡是文档里带版本标注的条目,我都先看标注再动手。希望这个习惯能帮到你。
本文还有配套的精品资源,点击获取