MySQL 8 配置参数详解
系统讲解 MySQL 8(8.0/8.4)服务端核心配置参数,覆盖每个参数的详细说明、取值范围、使用方法与影响范围,并给出可直接落地的生产配置模板。所有默认值均在 MySQL 8.4.11 真实环境中实测
MySQL 8 配置参数详解
目标:系统讲解 MySQL 8(8.0/8.4)服务端核心配置参数,覆盖每个参数的详细说明、取值范围、使用方法与影响范围,并给出可直接落地的生产配置模板。所有默认值均在 MySQL 8.4.11 真实环境中实测。
环境信息
- 操作系统:Ubuntu 22.04.5 LTS
- MySQL 版本:8.4.11 MySQL Community Server(官方 APT 仓库安装)
- 配置文件:
/etc/mysql/mysql.conf.d/mysqld.cnf - 参数采集方式:
SHOW VARIABLES(全部为实测默认值,非文档抄录)
前置条件
- 已安装 MySQL 8.0/8.4 并可本地登录(
sudo mysql) - 了解配置文件体系:主入口
/etc/mysql/my.cnfincludeconf.d/(客户端配置)与mysql.conf.d/(服务端配置),服务端参数统一写在[mysqld]段下 - 修改静态参数前做好重启窗口准备;生产环境修改前先在测试环境验证
参数查看与修改方式
查看参数
-- 查看指定参数
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
-- 模糊查询
SHOW VARIABLES LIKE '%binlog%';
-- 查看全部参数(600+ 个)
SHOW VARIABLES;
修改方式对比
| 方式 | 命令 | 是否即时生效 | 是否持久化 | 适用参数 |
|---|---|---|---|---|
| 配置文件 | 编辑 mysqld.cnf | 需重启 | 是(重启后仍生效) | 所有参数 |
| SET GLOBAL | SET GLOBAL max_connections=500; | 是 | 否(重启丢失) | 仅动态参数 |
| SET PERSIST | SET PERSIST max_connections=500; | 是 | 是(写入 mysqld-auto.cnf) | 仅动态参数 |
💡 说明:
SET PERSIST(8.0+)将参数写入数据目录下的mysqld-auto.cnf,重启后依然生效,且该文件优先级高于 my.cnf。判断参数是否动态:SHOW VARIABLES结果中查看官方文档 Dynamic 属性,或执行SET GLOBAL试错(静态参数会报Variable 'xxx' is a read only variable)。
参数总览
本文档覆盖的全部参数汇总如下表(默认值均为 MySQL 8.4.11 实测):
| 分类 | 参数名称 | 默认值(实测) | 配置值示例 | 动态 | 说明 |
|---|---|---|---|---|---|
| 连接与网络 | port | 3306 | port = 3307 | 否 | 服务监听的 TCP 端口 |
| 连接与网络 | bind_address | * | bind_address = 192.168.1.100 | 是 | 监听网卡地址,改内网 IP 可隔离公网 |
| 连接与网络 | max_connections | 151 | max_connections = 1000 | 是 | 最大并发连接数,超出报 Too many connections |
| 连接与网络 | max_connect_errors | 100 | max_connect_errors = 1000 | 是 | 同主机握手失败上限,超限拉黑该主机 |
| 连接与网络 | wait_timeout / interactive_timeout | 28800 | wait_timeout = 600 | 是 | 空闲连接超时(非交互/交互),生产建议 300~1800 |
| 连接与网络 | max_allowed_packet | 64MB | max_allowed_packet = 256M | 是 | 单包最大长度,影响大事务与批量导入 |
| 内存与缓冲 | innodb_buffer_pool_size | 128MB | innodb_buffer_pool_size = 10G | 是 | InnoDB 缓冲池,最重要的性能参数,建议物理内存 50%~70% |
| 内存与缓冲 | innodb_buffer_pool_instances | 1 | innodb_buffer_pool_instances = 8 | 是 | 缓冲池实例数,≥1GB 时设 2~8 减少锁竞争 |
| 内存与缓冲 | innodb_redo_log_capacity | 100MB | innodb_redo_log_capacity = 2G | 是 | redo log 总容量(8.0.30+ 取代 log_file_size) |
| 内存与缓冲 | tmp_table_size / max_heap_table_size | 16MB / 16MB | tmp_table_size = 64M | 是 | 内存临时表上限(取较小者),溢出转磁盘 |
| 内存与缓冲 | sort_buffer_size / join_buffer_size / read_buffer_size | 256KB / 256KB / 128KB | sort_buffer_size = 1M | 是 | 会话级排序/JOIN/读缓冲,每连接分配,勿调大 |
| 内存与缓冲 | key_buffer_size | 8MB | — | 是 | MyISAM 索引缓存,8.0 默认 InnoDB 后保持默认 |
| 内存与缓冲 | table_open_cache / thread_cache_size | 4000 / 9 | thread_cache_size = 64 | 是 | 表句柄缓存/线程句柄缓存 |
| 字符集 | character_set_server / collation_server | utf8mb4 / utf8mb4_0900_ai_ci | character_set_server = utf8mb4 | 是 | 服务端默认字符集与排序规则 |
| 日志 | log_error | /var/log/mysql/error.log | log_error = /var/log/mysql/error.log | 否 | 错误日志路径,排障第一入口 |
| 日志 | log_bin | ON(8.0 起默认) | log_bin = mysql-bin | 否 | binlog 开关,用于复制与 PITR |
| 日志 | binlog_expire_logs_seconds | 2592000(30天) | binlog_expire_logs_seconds = 604800 | 是 | binlog 自动清理期限,防磁盘写满 |
| 日志 | sync_binlog | 1 | sync_binlog = 1 | 是 | binlog 刷盘策略,1=每事务 fsync 最安全 |
| 日志 | slow_query_log / long_query_time | OFF / 10s | slow_query_log = ON | 是 | 慢查询日志开关与阈值,生产建议常开 |
| InnoDB 核心 | innodb_flush_log_at_trx_commit | 1 | innodb_flush_log_at_trx_commit = 1 | 是 | redo 刷盘策略,与 sync_binlog 组成"双 1" |
| InnoDB 核心 | innodb_flush_method | O_DIRECT | — | 否 | 刷盘方式,O_DIRECT 避免 OS 双重缓存 |
| InnoDB 核心 | innodb_io_capacity / innodb_io_capacity_max | 10000 / 20000 | innodb_io_capacity = 4000 | 是 | 后台刷脏 IOPS 参考,按磁盘类型设定 |
| InnoDB 核心 | innodb_file_per_table | ON | — | 否 | 独立表空间,支持 DROP/TRUNCATE 回收磁盘 |
| InnoDB 核心 | transaction_isolation | REPEATABLE-READ | transaction_isolation = READ-COMMITTED | 是 | 默认事务隔离级别,高并发写常改 RC |
| InnoDB 核心 | skip_name_resolve | OFF | skip_name_resolve = ON | 否 | 跳过 DNS 反查,内网生产建议开启 |
| 安全与 SQL 模式 | sql_mode | 严格模式集合 | sql_mode = 'STRICT_TRANS_TABLES,...' | 是 | SQL 行为模式,8.0 默认严格模式 |
| 安全与 SQL 模式 | validate_password 组件 | MEDIUM 策略 | validate_password.length = 12 | 是 | 密码强度策略,弱密码报 ERROR 1819 |
| 安全与 SQL 模式 | local_infile | OFF | — | 是 | 禁用 LOAD DATA LOCAL 防客户端文件读取风险 |
一、连接与网络参数
port
| 属性 | 值 |
|---|---|
| 默认值(实测) | 3306 |
| 取值范围 | 1 ~ 65535 |
| 动态 | 否(需重启) |
说明: MySQL 主服务(经典 MySQL 协议)监听的 TCP 端口。
使用示例:
[mysqld]
port = 3307
影响范围: 修改后所有客户端连接串、防火墙规则、应用配置(JDBC/ORM)都要同步修改。生产环境出于安全考虑常用非默认端口减少扫描暴露面,但不能替代认证与防火墙防护。
bind_address
| 属性 | 值 |
|---|---|
| 默认值(实测) | *(所有 IPv4/IPv6 地址) |
| 取值范围 | * / 0.0.0.0 / 具体 IP / :: |
| 动态 | 是(8.0.13+ 支持动态修改) |
说明: 服务监听的网卡地址。默认监听所有网卡,即远程可达(前提是用户授权了远程主机)。
使用示例:
[mysqld]
bind_address = 192.168.1.100 # 只监听内网 IP
影响范围: 改为内网 IP 后公网完全无法连接,是最有效的"仅内网访问"手段。设错 IP(本机不存在该地址)会导致 MySQL 启动失败。
max_connections
| 属性 | 值 |
|---|---|
| 默认值(实测) | 151 |
| 取值范围 | 1 ~ 100000 |
| 动态 | 是 |
说明: 允许的最大并发客户端连接数。默认 151 仅适合开发环境,超出后新连接报 Too many connections 错误。
使用示例:
SET PERSIST max_connections = 1000;
影响范围: 每个连接消耗内存(连接缓冲 + 线程栈约 256KB数 MB),盲目调大会导致内存耗尽。经验公式:50 连接)而不是依赖超大 max_connections。最大连接数 × 单连接平均内存 < 物理内存的 60%。应用侧应同时配置连接池(如应用容器 20
max_connect_errors
| 属性 | 值 |
|---|---|
| 默认值(实测) | 100 |
| 取值范围 | 1 ~ 4294967295 |
| 动态 | 是 |
说明: 同一主机连续连接失败(握手阶段中断,非密码错误)超过该次数后,该主机被拉黑,报 Host 'xxx' is blocked。这是防暴力连接的保护机制。
使用示例:
SET PERSIST max_connect_errors = 1000;
-- 解除已拉黑的主机
FLUSH HOSTS; -- 8.0.23+ 改用:TRUNCATE TABLE performance_schema.host_cache;
影响范围: 调大可避免网络抖动/监控探活异常导致误封;应用服务器 NAT 出口共享 IP 时尤其注意。密码错误不计入该计数。
wait_timeout / interactive_timeout
| 属性 | 值 |
|---|---|
| 默认值(实测) | 28800(8 小时) |
| 取值范围 | 1 ~ 31536000 |
| 动态 | 是 |
说明: 空闲连接超时时间。wait_timeout 针对非交互连接(应用连接池),interactive_timeout 针对交互式客户端(mysql 命令行)。空闲超过该秒数后服务端主动断开。
使用示例:
SET PERSIST wait_timeout = 600;
SET PERSIST interactive_timeout = 600;
影响范围: 8 小时默认值偏长,空闲连接占用连接数配额与内存。生产建议 300~1800 秒,且要小于应用侧连接池的最大存活时间/空闲回收时间,避免应用拿到已被服务端断开的"死连接"。
max_allowed_packet
| 属性 | 值 |
|---|---|
| 默认值(实测) | 67108864(64MB) |
| 取值范围 | 1024 ~ 1073741824(1GB) |
| 动态 | 是 |
说明: 单个数据包(SQL 语句、行数据、binlog 事件)的最大长度。超过报 Packet for query is too large。
使用示例:
SET PERSIST max_allowed_packet = 256*1024*1024; -- 256MB
影响范围: 影响大事务(批量 INSERT、大 BLOB、大字段批量更新)。8.0 默认 64MB 通常够用;批量导入大字段时按需调大。服务端与客户端建议保持一致(客户端默认 1GB 上限内自行设置)。
二、内存与缓冲参数
innodb_buffer_pool_size(最重要参数)
| 属性 | 值 |
|---|---|
| 默认值(实测) | 134217728(128MB) |
| 取值范围 | 5242880(5MB)~ 物理内存上限 |
| 动态 | 是(在线调整,8.0 起支持) |
说明: InnoDB 缓冲池大小,缓存热数据页(表数据 + 索引)。数据库读性能的第一决定因素:命中缓冲池是内存级速度,未命中则读磁盘。
使用示例:
-- 在线扩容(16GB 内存服务器设为 12GB)
SET PERSIST innodb_buffer_pool_size = 12 * 1024 * 1024 * 1024;
影响范围: 生产环境专用数据库服务器建议设为物理内存的 50%~70%(有其他大内存组件时取低值)。设太大数据页换出 OS 缓冲、OOM 风险增大;设太小缓存命中率低、磁盘 I/O 高。观察指标:SHOW STATUS LIKE 'Innodb_buffer_pool_read%'; 中 Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests 应低于 1%。
innodb_buffer_pool_instances
| 属性 | 值 |
|---|---|
| 默认值(实测) | 1 |
| 取值范围 | 1 ~ 64 |
| 动态 | 是(8.0 起随 buffer_pool_size 在线调整) |
说明: 缓冲池切分的实例数,多实例减少内部锁竞争(高并发读写同一缓冲池时的 mutex 争用)。
使用示例:
[mysqld]
innodb_buffer_pool_size = 16G
innodb_buffer_pool_instances = 8
影响范围: buffer_pool_size ≥ 1GB 时建议设 28(经验:每 12GB 一个实例)。中低并发场景保持默认即可,影响不明显。
innodb_redo_log_capacity(8.0.30+ 新参数)
| 属性 | 值 |
|---|---|
| 默认值(实测) | 104857600(100MB) |
| 取值范围 | 8589934592(8MB)~ 128GB(实际受 innodb_redo_log_archive_dirs 等限制) |
| 动态 | 是 |
说明: redo log(重做日志)总容量,控制崩溃恢复所需日志量与 checkpoint 频率。8.0.30 起取代旧参数 innodb_log_file_size × innodb_log_files_in_group(8.4 中旧参数已移除)。
使用示例:
SET PERSIST innodb_redo_log_capacity = 2 * 1024 * 1024 * 1024; -- 2GB
影响范围: 写入密集场景太小会导致频繁 checkpoint 刷脏页(I/O 抖动、性能下跌);太大则崩溃恢复时间变长。经验值:容纳 1 小时写入量,或从 1~2GB 起步观察。监控:SHOW STATUS LIKE 'Innodb_redo_log_current_lsn'; 与 checkpoint 差值。
tmp_table_size / max_heap_table_size
| 属性 | 值 |
|---|---|
| 默认值(实测) | 16777216(16MB)/ 16777216(16MB) |
| 取值范围 | 1024 ~ 18446744073709547520 |
| 动态 | 是 |
说明: 内存临时表大小上限(两者取较小值生效)。GROUP BY / ORDER BY / DISTINCT 等操作产生的中间结果先放内存临时表,超过上限转为磁盘临时表(InnoDB 引擎),性能下降一个数量级。
使用示例:
SET PERSIST tmp_table_size = 64 * 1024 * 1024;
SET PERSIST max_heap_table_size = 64 * 1024 * 1024;
影响范围: 这两个参数是会话级消耗(每个会话的每张临时表都占用),大并发下盲目调大有内存风险。判断是否溢出磁盘:SHOW STATUS LIKE 'Created_tmp_disk_tables'; 占比高再针对性调优或优化 SQL。
sort_buffer_size / join_buffer_size / read_buffer_size
| 属性 | 值 |
|---|---|
| 默认值(实测) | 262144(256KB)/ 262144(256KB)/ 131072(128KB) |
| 取值范围 | 32768 ~ OS 上限 |
| 动态 | 是 |
说明: 会话级排序缓冲(ORDER BY 无索引时)、无索引 JOIN 缓冲、顺序扫描读缓冲。
使用示例:
[mysqld]
sort_buffer_size = 1M
join_buffer_size = 1M
影响范围: ⚠️ 这些是每连接每操作分配的,大并发 × 大缓冲 = 内存爆炸。保持默认或小幅调整(≤4MB),靠索引优化解决排序/JOIN 性能,不要靠调大缓冲。8.0.28 起 sort_buffer 在超过 64KB 时改为分块申请,调大收益进一步降低。
key_buffer_size(MyISAM 专用)
| 属性 | 值 |
|---|---|
| 默认值(实测) | 8388608(8MB) |
| 取值范围 | 0 ~ OS 上限 |
| 动态 | 是 |
说明: MyISAM 表的索引缓存。MySQL 8 默认引擎已是 InnoDB,系统表也已 InnoDB 化。
影响范围: 除非业务大量使用 MyISAM 表(不建议),保持默认即可。设很大纯属浪费内存。
table_open_cache / thread_cache_size
| 属性 | 值 |
|---|---|
| 默认值(实测) | 4000 / 9 |
| 取值范围 | 1 |
| 动态 | 是 |
说明: table_open_cache 是所有会话可同时打开的表句柄数;thread_cache_size 缓存的线程句柄数,避免每连接新建线程的开销。
影响示例:
SET PERSIST thread_cache_size = 64;
影响范围: 表很多且并发打开表报 Cannot open any more tables 时调大 table_open_cache(注意同步 OS 的 open_files_limit)。短连接多的场景调大 thread_cache_size 降低线程创建开销;Threads_created / Connections 比值高时调大。
三、字符集与排序规则
character_set_server / collation_server
| 属性 | 值 |
|---|---|
| 默认值(实测) | utf8mb4 / utf8mb4_0900_ai_ci |
| 取值范围 | utf8mb4、latin1、binary 等 / 对应 collation 列表 |
| 动态 | 是 |
说明: 服务端默认字符集与排序规则。MySQL 8.0 起默认 utf8mb4(完整 UTF-8,支持 emoji 等 4 字节字符),排序规则默认 utf8mb4_0900_ai_ci(accent 不敏感、大小写不敏感)。
使用示例:
[mysqld]
character_set_server = utf8mb4
collation_server = utf8mb4_0900_ai_ci
影响范围: 影响新建库/表/列的默认字符集(已建对象不追溯)。如果业务需要区分大小写(如用户名唯一约束),建表时显式指定 utf8mb4_0900_as_cs 或 utf8mb4_bin。从 5.7 迁移的库注意 collation 混用导致 JOIN 时 Illegal mix of collations 错误。
四、日志参数
log_error
| 属性 | 值 |
|---|---|
| 默认值(实测) | /var/log/mysql/error.log |
| 取值范围 | 文件路径或 stderr |
| 动态 | 否(需重启) |
说明: 错误日志路径,记录启动/关闭、严重错误、告警信息。排障第一入口。
使用示例:
[mysqld]
log_error = /var/log/mysql/error.log
log_error_verbosity = 2 -- 1=错误 2=错误+告警 3=错误+告警+信息(默认2)
影响范围: 磁盘满会导致 MySQL 挂起(写日志阻塞),需要日志轮转(logrotate)与磁盘监控配套。
log_bin / binlog_expire_logs_seconds / sync_binlog
| 属性 | 值 |
|---|---|
| 默认值(实测) | ON(8.0 起默认开启)/ 2592000(30 天)/ 1 |
| 动态 | log_bin 否;expire 与 sync_binlog 是 |
说明: 二进制日志(binlog)记录所有变更操作,用于复制与基于时间点恢复(PITR)。MySQL 8.0 起默认开启。binlog_expire_logs_seconds 控制自动清理天数(默认 30 天);sync_binlog 控制刷盘策略。
使用示例:
[mysqld]
log_bin = mysql-bin
binlog_format = ROW # 8.0+ 默认且推荐
binlog_expire_logs_seconds = 604800 # 7 天
sync_binlog = 1
影响范围:
- 开启 binlog 占用磁盘(写入量与业务更新量成正比),必须配套 expire 时间与磁盘监控,否则磁盘写满导致服务挂起
sync_binlog=1:每次事务提交都 fsync,最安全(主从都不丢)但 I/O 开销最大;=0交给 OS,最快但崩溃可能丢日志;=100折中。金融类业务保持 1- 与
innodb_flush_log_at_trx_commit组合构成"双 1"配置(见下)
slow_query_log / long_query_time
| 属性 | 值 |
|---|---|
| 默认值(实测) | OFF / 10.000000 秒 |
| 取值范围 | ON/OFF / 0 ~ 31536000 秒 |
| 动态 | 是 |
说明: 慢查询日志开关与阈值。执行时间超过 long_query_time 的 SQL 记入慢日志,是 SQL 优化的核心数据源。
使用示例:
SET PERSIST slow_query_log = ON;
SET PERSIST long_query_time = 1; -- 超过 1 秒即记录
SET PERSIST log_queries_not_using_indexes = ON; -- 未走索引的 SQL 也记录
影响范围: 开启有轻微性能开销(通常可忽略),生产环境建议常开(阈值 0.5~1 秒)。配合 mysqldumpslow 或 pt-query-digest 分析 TOP N 慢 SQL。log_queries_not_using_indexes 在全表扫描频繁的库会产生大量日志,按需开启。
五、InnoDB 核心参数
innodb_flush_log_at_trx_commit
| 属性 | 值 |
|---|---|
| 默认值(实测) | 1 |
| 取值范围 | 0 / 1 / 2 |
| 动态 | 是 |
说明: redo log 刷盘策略,直接决定崩溃时的数据安全性:
| 值 | 行为 | 崩溃丢失风险 |
|---|---|---|
| 1 | 每次事务提交 fsync 到磁盘 | 不丢(ACID 完整) |
| 2 | 提交时写到 OS 缓存,每秒 fsync | OS 崩溃丢 1 秒 |
| 0 | 每秒写 + 每秒 fsync | MySQL 崩溃丢 1 秒 |
使用示例:
SET PERSIST innodb_flush_log_at_trx_commit = 1; -- 生产默认
SET PERSIST innodb_flush_log_at_trx_commit = 2; -- 可容忍秒级丢失的非核心业务
影响范围: 与 sync_binlog 组合的"双 1"(都=1)是最安全配置,也是默认值;对 I/O 敏感场景可改"双 0/双 100"换性能。改 0/2 后宕机最多丢 1 秒事务,需要业务方确认可接受。
innodb_flush_method
| 属性 | 值 |
|---|---|
| 默认值(实测) | O_DIRECT(Linux) |
| 取值范围 | fsync / O_DSYNC / littlesync / nosync / O_DIRECT / O_DIRECT_NO_FSYNC / unbuffered |
| 动态 | 否(8.0 起部分支持动态,保守按重启处理) |
说明: InnoDB 刷数据/日志文件的方式。O_DIRECT 绕过 OS 级缓存直写磁盘,避免 InnoDB 缓冲池与 OS Page Cache 双重缓存。
影响范围: Linux 生产环境保持 O_DIRECT(8.0 默认已是),减少内存浪费与刷盘放大。配合 RAID 卡带 BBU 或 NVMe SSD 效果最佳。
innodb_io_capacity / innodb_io_capacity_max
| 属性 | 值 |
|---|---|
| 默认值(实测) | 10000 / 20000 |
| 取值范围 | 100~18446744073709551615 / 2000~~ |
| 动态 | 是 |
说明: 后台任务(刷脏页、change buffer 合并)的 IOPS 参考。MySQL 根据该值调节后台刷脏速度。
使用示例:
SET PERSIST innodb_io_capacity = 2000; -- SATA SSD
SET PERSIST innodb_io_capacity_max = 4000;
影响范围: 设太低 → 脏页积压,redo 空间压力大时触发激进修(用户线程被拉去刷盘,RT 飙升);设太高 → 磁盘被后台刷盘打满影响前台。经验:HDD 200400,SATA SSD 2000,NVMe 40008000(8.4 默认 10000 已较大众化)。
innodb_file_per_table
| 属性 | 值 |
|---|---|
| 默认值(实测) | ON |
| 动态 | 否(新表按设置处理,存量表不追溯) |
说明: 每张 InnoDB 表使用独立 .ibd 文件(位于 datadir/库名/表名.ibd),关闭则放入共享系统表空间。
影响范围: 保持 ON(默认)。独立表空间支持 DROP TABLE/TRUNCATE 直接回收磁盘空间(共享表空间删除表不释放空间),且便于按表监控大小。已实测:迁移数据目录后 ls /opt/data/mysql/test_db/t1.ibd 即独立表空间文件。
transaction_isolation
| 属性 | 值 |
|---|---|
| 默认值(实测) | REPEATABLE-READ |
| 取值范围 | READ-UNCOMMITTED / READ-COMMITTED / REPEATABLE-READ / SERIALIZABLE |
| 动态 | 是(会话级 + 全局级) |
说明: 默认事务隔离级别。MySQL 默认 RR,配合间隙锁(Next-Key Lock)防止幻读;PostgreSQL/Oracle 默认 RC。
使用示例:
SET GLOBAL transaction_isolation = 'READ-COMMITTED';
SET SESSION transaction_isolation = 'READ-COMMITTED'; -- 仅当前会话
影响范围: RR 下范围更新锁粒度大,高并发写入容易死锁;互联网业务常改用 RC(锁冲突少,但存在不可重复读)。改动只影响新事务,需评估业务对一致性语义的依赖(如对账类逻辑依赖 RR 快照读)。
skip_name_resolve
| 属性 | 值 |
|---|---|
| 默认值(实测) | OFF |
| 动态 | 否(需重启) |
说明: 是否跳过连接时的 DNS 反向解析(客户端 IP → 主机名)。
使用示例:
[mysqld]
skip_name_resolve = ON # 或 skip-name-resolve
影响范围: 开启后连接不再等 DNS 解析(DNS 故障时能避免连接挂起超时),用户授权表必须用 IP('user'@'192.168.1.%'),不能再用主机名('user'@'db01.example.com')。内网生产环境建议开启。
六、安全与 SQL 模式
sql_mode
| 属性 | 值(8.0/8.4 默认,实测) | |
|---|---|---|
| ONLY_FULL_GROUP_BY | 拒绝非确定性的 GROUP BY 查询 | 保证结果确定性 |
| STRICT_TRANS_TABLES | 严格模式:非法数据直接报错 | 替代旧 NO_ENGINE_SUBSTITUTION 场景下的静默截断 |
| NO_ZERO_IN_DATE / NO_ZERO_DATE | 禁止 2026-00-01 这类零日期 | 数据质量 |
| ERROR_FOR_DIVISION_BY_ZERO | 除零报错而非 NULL | 数据质量 |
| NO_ENGINE_SUBSTITUTION | 建表指定的引擎不可用时直接报错 | 避免悄悄降级 |
说明: SQL 行为模式集合。8.0 默认开启严格模式,杜绝了 5.6 时代"超长截断、零日期静默插入"等脏数据来源。
使用示例:
SELECT @@sql_mode; -- 查看当前模式
SET PERSIST sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION'; -- 按需调整
影响范围: 从旧版本迁移的应用可能依赖宽松行为(如 GROUP BY 随意选列),严格模式下会报错。不要为了绕过报错全局关掉 ONLY_FULL_GROUP_BY,应修复 SQL。
密码策略(validate_password 组件)
说明: MySQL 8 中 validate_password 从插件改为组件(component),8.4 默认已安装(validate_password),无需手动 INSTALL PLUGIN。
使用示例:
-- 查看策略(8.4 默认 MEDIUM:长度≥8,含大小写/数字/特殊字符各1)
SELECT * FROM mysql.component WHERE component_urn LIKE '%validate_password%';
SHOW VARIABLES LIKE 'validate_password%';
-- 调整长度要求
SET PERSIST validate_password.length = 12;
影响范围: 影响 CREATE USER/ALTER USER 的密码校验,弱密码直接报 ERROR 1819。生产环境建议保持 MEDIUM 以上。
local_infile
| 属性 | 值 |
|---|---|
| 默认值(实测) | OFF |
| 动态 | 是 |
说明: 是否允许客户端执行 LOAD DATA LOCAL INFILE(从客户端机器读文件上传到服务端)。
影响范围: 该能力可被恶意服务端利用读取客户端文件(中间人场景),保持默认 OFF;确需批量导入时临时开启或改用服务端文件 LOAD DATA INFILE(受 secure_file_priv 限制)。
七、生产配置模板(16GB 内存、NVMe SSD、OLTP 通用场景)
[mysqld]
# ---- 基础 ----
port = 3306
bind_address = *
datadir = /opt/data/mysql
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid
skip_name_resolve = ON
default_storage_engine = InnoDB
character_set_server = utf8mb4
collation_server = utf8mb4_0900_ai_ci
# ---- 连接 ----
max_connections = 1000
max_connect_errors = 1000
wait_timeout = 600
interactive_timeout = 600
max_allowed_packet = 256M
thread_cache_size = 64
table_open_cache = 8000
open_files_limit = 65535
# ---- InnoDB 内存 ----
innodb_buffer_pool_size = 10G # 物理内存 60%~70%
innodb_buffer_pool_instances = 8
innodb_redo_log_capacity = 2G
tmp_table_size = 64M
max_heap_table_size = 64M
# ---- InnoDB 可靠性与 I/O ----
innodb_flush_method = O_DIRECT
innodb_flush_log_at_trx_commit = 1 # 双 1
sync_binlog = 1
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
transaction_isolation = REPEATABLE-READ
# ---- 日志 ----
log_error = /var/log/mysql/error.log
log_error_verbosity = 2
log_bin = mysql-bin
binlog_format = ROW
binlog_expire_logs_seconds = 604800 # 7 天
slow_query_log = ON
long_query_time = 1
log_queries_not_using_indexes = ON
# ---- 安全 ----
local_infile = OFF
validate_password.length = 12
💡 使用说明:模板按"修改配置文件 + 重启"方式落地;动态参数可先用
SET PERSIST灰度验证再固化到配置文件。落地后观察 1~3 天SHOW GLOBAL STATUS与错误日志,确认无内存告警、连接拒绝、刷盘打满后再全量。
常见问题
问题 1:修改参数后不生效
原因: 静态参数(port、datadir、log_bin、skip_name_resolve 等)只读,必须重启;或 mysqld-auto.cnf 中 PERSIST 的旧值优先级高于 my.cnf。
解决:
sudo systemctl restart mysql # 静态参数重启
-- 检查持久化文件是否覆盖了配置文件
SELECT * FROM performance_schema.persisted_variables;
-- 清除某参数的持久化值(恢复由 my.cnf 决定)
RESET PERSIST max_connections;
问题 2:SET PERSIST 报错 Variable is a read only variable
原因: 该参数是静态参数(需重启),不属于 SET GLOBAL/PERSIST 可修改范围。
解决: 写入配置文件 [mysqld] 段后重启服务。
问题 3:调大 max_connections 后出现 OOM 或连接反而更慢
原因: 每连接内存消耗(排序/JOIN/临时表缓冲)× 连接数超过物理内存,触发 swap 或 OOM killer。
解决: 回调 max_connections;同时检查 sort_buffer_size/join_buffer_size/tmp_table_size 是否被调得过大;应用侧引入连接池(每实例 20~50 连接通常足够)。
问题 4:磁盘被 binlog 写满
原因: 8.0 起默认开启 binlog 且默认保留 30 天(binlog_expire_logs_seconds=2592000),写入量大的实例日志累积超预期。
解决:
SET PERSIST binlog_expire_logs_seconds = 604800; -- 缩短保留期
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY; -- 手动清理(谨慎)
同时检查是否需要该实例做 PITR/复制,清理前确认从库已消费相应日志。
问题 5:忘记参数改成了什么,想回滚
解决:
-- 对比 my.cnf 与运行时差异
SELECT * FROM performance_schema.persisted_variables;
-- 全部清除持久化参数(恢复 my.cnf 控制)
RESET PERSIST;
参考链接
- Server System Variables(官方,全部参数权威文档)
- InnoDB System Variables
- SET PERSIST 语法
- Nonpersistent and Persistent System Variables(动态/静态参数清单)
- Binlog 官方文档
本文档由 www.quzuo.net 平台开发