MySQL安装与配置
大家好,我是一名拥有10年以上经验的DBA老兵。
做这个系列,源于一个朴素的愿望:把踩过的坑、总结的经验系统化输出,希望能帮到刚入行或想进阶的兄弟们。
让我们开始今天的第3天内容。
背景引入
💡 说白了:装MySQL谁不会?但装完能用和装完好用,差了十万八千里。
很多同学装完MySQL就直接用了,配置文件一个参数都不改。等线上跑起来,才发现——连接数不够、内存没吃满、慢查询没开……
今天的目标:搞清楚MySQL怎么装、怎么配,面试必问的核心参数!
核心概念
一、MySQL安装方式
三种主流方式,按场景选择:
| 安装方式 | 适用场景 | 特点 |
|---|---|---|
| RPM/YUM | 个人学习、快速搭建 | 安装简单,路径规范 |
| 二进制包 | 需要自定义路径 | 解压后初始化即可用,路径灵活 |
| 源码编译 | 大厂和小厂生产环境 | 可定制功能,生成RPM/Docker镜像统一部署 |
💡 说白了:大厂有内核开发团队,源码编译后打包成RPM/Docker镜像统一部署;小厂生产环境也常用源码编译,确保定制化;个人学习直接拿社区RPM装就行。
-- 查看MySQL版本信息
SELECT VERSION();
\status 或 \s (缩写)
二、配置文件在哪?
MySQL 启动时会按顺序读取配置文件,优先级从高到低:
| 文件路径 | 说明 |
|---|---|
/etc/my.cnf |
系统级配置(个人学习够用) |
/etc/mysql/my.cnf |
系统级配置(部分系统) |
~/.my.cnf |
用户级配置 |
💡 生产环境不会用系统级配置,不便于多实例部署。通常会为每个实例单独指定配置文件,如
my_3306.cnf,它会 include 统一的模板,再把需要自定义的参数写在本文件内。
三、核心参数配置
这是面试最爱问的部分,也是生产环境最容易踩坑的地方。
3.1 内存相关
# InnoDB缓冲池,一般设为物理内存的60%-80%
# ⚠️ 上来不要配太大!先配物理内存的50%,根据压测结果再调整
innodb_buffer_pool_size = 8G
# 每个连接的缓冲区
# ⚠️ 不要上来就调大,保持默认或小幅调整,根据压测结果再调
sort_buffer_size = 2M
join_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 2M
面试必问:
innodb_buffer_pool_size怎么配?- 连接相关的缓冲区参数能不能调大?
📝 面试解答:
Q: innodb_buffer_pool_size 怎么配?
核心原则:先保守,再根据压测结果调整。
- 上来先配物理内存的50%左右,不要一步到位配太大
- 例如使用 sysbench、mysqlslap 等工具(后续系列会详细介绍),或结合业务场景进行压测
- 查看
Buffer_pool_read命中率:SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';- 命中率高、内存还有余量,再逐步调大;命中率低,先加大 buffer pool
- 8G内存的服务器,先配4G,压测没问题再调到5G-6G
- 不要配满!要给操作系统和其他进程留空间
- MySQL 5.6.3+ 支持在线修改:
SET GLOBAL innodb_buffer_pool_size = 5368709120;
Q: 连接相关的缓冲区参数能不能调大?
不建议上来就调大!
sort_buffer_size、join_buffer_size这些参数每个连接都会分配- 假设 sort_buffer_size = 8M,1000个连接就是 8GB 内存
- 推荐保持默认或小幅调整(1M-4M),先压测,再调整
- 真正的优化方向是减少排序和连接操作,而不是加大缓冲区
3.2 连接相关
# 最大连接数
max_connections = 1000
# 连接空闲超时(秒)
wait_timeout = 1800
# 交互式连接超时(秒)
interactive_timeout = 1800
# 线程缓存
thread_cache_size = 64
面试必问:
max_connections设多少合适?wait_timeout和interactive_timeout有什么区别?
📝 面试解答:
Q: max_connections 设多少合适?
不是越大越好!
- 每个连接占用内存(约1MB+),1000个连接就1GB+
- 推荐做法:先设1000,配合连接池使用
- 如果达到上限,报
Too many connections,先查是不是连接泄漏- 别上来就设5000、10000,OOM了哭都来不及
Q: wait_timeout 和 interactive_timeout 有什么区别?
wait_timeout:非交互式连接的空闲超时(JDBC、连接池走的这个)interactive_timeout:交互式连接的空闲超时(命令行mysql客户端走的这个)- 生产环境两个都要改,建议都设1800(30分钟)
- 只改一个的话,另一个不生效!这是常见坑
3.3 日志相关
# 慢查询日志
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /var/log/mysql/slow.log
# 错误日志
log_error = /var/log/mysql/error.log
# Binlog
log_bin = mysql-bin
binlog_format = ROW
expire_logs_days = 7
# ⚠️ MySQL 8.0+ 建议改用 binlog_expire_logs_seconds,精确到秒
# binlog_expire_logs_seconds = 604800 # 7天 = 7*24*3600
面试必问:
- 慢查询日志怎么开?阈值设多少?
📝 面试解答:
Q: 慢查询日志怎么开?阈值设多少?
slow_query_log = 1开启慢查询日志long_query_time建议设 1秒,不要设太大- 1秒以上的SQL就需要关注了,真正快的不需要那么多
- 生产环境必须开,不开慢查询就是瞎子摸象
四、配置生效的方式
| 方式 | 命令 | 是否重启 | 是否持久 | 适用场景 |
|---|---|---|---|---|
| 修改my.cnf | 编辑配置文件 | 需要重启 | ✅ 持久 | 生产环境推荐 |
| SET PERSIST | SET PERSIST key = value; |
不需要 | ✅ 持久(写入mysqld-auto.cnf) | 个人学习方便,生产不推荐 |
| SET GLOBAL | SET GLOBAL key = value; |
不需要 | ❌ 重启失效 | 临时验证 |
| SET SESSION | SET SESSION key = value; |
不需要 | ❌ 仅当前会话 | 会话级调试 |
💡 说白了:临时验证用 SET GLOBAL,正式上线改 my.cnf。
SET PERSIST 是 MySQL 8.0+ 新增的,修改后会持久化到
mysqld-auto.cnf,重启不丢失。个人学习很方便,但生产环境个人建议不推荐——配置散落在 my.cnf 和 mysqld-auto.cnf 两个地方,管理复杂度高,排查问题容易踩坑。当然也有人接受用它统一通过 mysqld-auto.cnf 管理,看你团队规范。
-- 动态修改参数(临时)
SET GLOBAL wait_timeout = 1800;
-- 查看修改后的值
SHOW GLOBAL VARIABLES LIKE 'wait_timeout';
-- 8.0+ 持久化修改
SET PERSIST wait_timeout = 1800;
💡 AI辅助配置:让AI根据服务器配置生成my.cnf,直接问:
"我的服务器是XX核XXG内存,用于MySQL 8.0生产环境,帮我生成一份最简配置文件"💡 AI辅助排查:MySQL启动报错?直接问AI:
"MySQL启动失败,报错XXX,可能是什么原因?"💡 个人Skill建议:在你的Skill里加一个配置文件检查,检查项包括:
- innodb_buffer_pool_size ≤ 物理内存×80%
- max_connections 合理值(500-2000)
- slow_query_log = 1
- binlog_format = ROW
实战案例
场景一:生产环境最简配置
一份够用的 my.cnf 模板:
[mysqld]
# 基础配置
user = mysql
port = 3306
basedir = /usr/local/mysql
datadir = /data/mysql/data
socket = /tmp/mysql.sock
# 字符集
character_set_server = utf8mb4
# 连接
max_connections = 1000
wait_timeout = 1800
interactive_timeout = 1800
thread_cache_size = 64
# InnoDB
innodb_buffer_pool_size = 8G
# innodb_flush_log_at_trx_commit 取值说明:
# 1 = 每次提交都刷盘(双一标准),最安全但性能最低,主库推荐
# 2 = 每秒刷盘到OS缓存,崩溃可能丢1秒数据,从库或半同步可接受
# 0 = 每秒刷盘但不写日志文件,几乎不用
innodb_flush_log_at_trx_commit = 1
innodb_flush_method = O_DIRECT
# 日志
slow_query_log = 1
long_query_time = 1
log_error = /var/log/mysql/error.log
log_bin = mysql-bin
binlog_format = ROW
expire_logs_days = 7
场景二:查看当前配置
-- 查看所有配置参数
SHOW GLOBAL VARIABLES;
-- 查看特定参数
SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW GLOBAL VARIABLES LIKE 'max_connections';
-- 查看运行时状态
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';
避坑指南
⚠️ 真实踩过的坑:
只改 wait_timeout 不改 interactive_timeout
- 两个参数要一起改,否则交互式连接不受超时控制
- 建议都设1800秒
innodb_buffer_pool_size 上来就配太大
- 别一步到位!先配50%,根据压测结果逐步调大
- 配满物理内存会导致OOM,MySQL直接被杀
- 留20%-40%给操作系统和其他进程
慢查询日志不开
- 生产环境必须开,不开就是瞎子摸象
long_query_time别设太大,1秒起步
binlog_format 用 STATEMENT
- 主从复制可能数据不一致
- 推荐用 ROW,虽然日志大一点,但数据一致有保障
思考题
🤔 互动时间:
innodb_flush_log_at_trx_commit设为0、1、2有什么区别?生产环境怎么配?- 为什么
sort_buffer_size不建议调太大?
总结
🎯 面试考点
- MySQL三种安装方式及适用场景
- 核心参数配置:innodb_buffer_pool_size、max_connections、wait_timeout
- wait_timeout 和 interactive_timeout 的区别
- 慢查询日志必须开,阈值建议1秒
- 配置修改四种方式:my.cnf/SET PERSIST/SET GLOBAL/SET SESSION
💡 AI实战建议:让自己的AI助手记住my.cnf配置检查清单,每次写配置文件时自动检查这4项
下期预告:MySQL常用命令 —— 你每天都在用的那些命令
【合集】:每天一个MySQL知识点,百日打怪升级
有问题欢迎评论区交流,明天见!