MySQL 安装、连接与核心配置
本文以 MySQL 8.0/8.4 与 InnoDB 为主。面试不要求背完参数默认值,但要知道参数属于哪个作用域、影响性能还是可靠性,以及修改后是否需要重启。
版本怎么选
- 新项目优先选择仍在官方支持周期内的 LTS 或云厂商稳定版本。
- 从 5.7 升级到 8.x 前,检查字符集、保留字、SQL mode、认证插件、数据字典和驱动兼容性。
- 不要用“切回旧镜像”回滚数据库升级;升级可能已经改变数据字典和磁盘格式。
MySQL 5.7、8.0 与 8.4 LTS 的能力差异、版本门槛、移除项和完整升级流程见 MySQL 8 新特性与 5.7 升级指南。
查看版本与关键环境:
select version();
show variables like 'version%';
show variables like 'default_storage_engine';
show variables like 'sql_mode';
show variables like 'time_zone';配置文件与参数作用域
常见配置文件是 Linux 的 /etc/my.cnf、/etc/mysql/my.cnf,Windows 常见 my.ini。实际加载顺序应使用下面的命令确认:
mysqld --verbose --help系统变量可能是:
GLOBAL:影响后续新连接,通常不改变已有会话。SESSION:只影响当前连接。- 只读变量:只能通过配置文件或启动参数修改。
- 动态变量:运行中可修改;MySQL 8 支持
SET PERSIST持久化部分变量。
show global variables like 'max_connections';
show session variables like 'transaction_isolation';
set session transaction_isolation = 'READ-COMMITTED';
set persist max_connections = 500;生产修改前必须确认当前连接峰值、内存预算和回滚方式。max_connections 调大并不等于吞吐提升,每个活跃连接还会消耗线程栈、排序区、Join Buffer 和临时表内存。
核心参数按问题分类
| 目标 | 常见参数 | 判断重点 |
|---|---|---|
| 缓存数据页 | innodb_buffer_pool_size | 专用数据库通常给主要内存,但必须给连接、OS、备份和其他结构留空间 |
| 控制连接 | max_connections、wait_timeout | 结合连接池上限和活跃连接,不靠无限放大 |
| 控制包大小 | max_allowed_packet | 大 SQL、大字段、复制事件是否超限 |
| 事务隔离 | transaction_isolation | 一致性要求与锁冲突成本 |
| 日志持久性 | innodb_flush_log_at_trx_commit、sync_binlog | 性能与宕机丢数据窗口的权衡 |
| 慢 SQL | slow_query_log、long_query_time | 日志容量、采样周期、Rows_examined |
| 临时表 | tmp_table_size、max_heap_table_size | 内存临时表转磁盘的比例与并发内存风险 |
| 字符集 | character_set_server、collation_server | 推荐完整 Unicode,客户端与服务端保持一致 |
| 时区 | time_zone、system_time_zone | 应用、JDBC、数据库、业务语义统一 |
连接建立发生了什么
sequenceDiagram
participant C as 客户端
participant M as MySQL Server
C->>M: TCP 或 Unix Socket 握手
M-->>C: 版本、连接 ID、认证挑战
C->>M: 用户、来源、认证响应、能力集
M->>M: 匹配 user@host 并校验权限
M-->>C: 建立会话并初始化会话变量排查连接问题时按顺序检查:
- 进程是否监听目标地址和端口。
- DNS、路由、防火墙和安全组是否放行。
- MySQL 用户的
user@host是否匹配来源。 - 驱动和认证插件是否兼容。
- TLS、字符集、时区和连接参数是否正确。
- 是否达到连接数上限,连接池是否泄漏。
show status like 'Threads_connected';
show status like 'Threads_running';
show processlist;内存为什么不能只看 Buffer Pool
可粗略理解为:
总内存 ≈ 全局内存 + 活跃连接数 × 单连接可能内存 + OS 与其他进程全局内存包括 Buffer Pool、Redo Buffer、Performance Schema 等;单连接内存可能包括排序、Join、读缓冲和临时表。按所有参数最大值直接相乘会高估,但只看 Buffer Pool 会低估。生产要用峰值活跃连接和真实 workload 压测。
SQL mode
sql_mode 会改变非法日期、截断、分组等行为。升级或迁移时尤其重要:
select @@global.sql_mode, @@session.sql_mode;不要为了让错误 SQL 能运行就直接清空严格模式。应该修复不确定的分组、超长值、非法日期和隐式转换,并用测试验证。
面试追问
为什么 max_connections 不能无限调大
连接会消耗内存和线程调度资源,数据库瓶颈通常是 CPU、IO 或锁竞争。连接过多会把可控的排队变成数据库内部争抢,最终延迟雪崩。应该限制应用连接池、设置超时、监控活跃连接并做容量压测。
SET GLOBAL 后为什么当前连接没变化
许多会话变量在连接建立时从全局值复制,修改全局值只影响后续连接;当前连接需要 SET SESSION 或重连。还要区分动态、只读和持久化变量。
数据库时区怎么设计
先区分绝对时间点和本地日历时间。绝对时间点建议统一存储并明确转换规则;应用、JDBC 和数据库会话时区要显式配置。timestamp 会按会话时区转换,datetime 保存给定字段值,两者不能只按字节大小选择。
