Skip to content

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 升级指南

查看版本与关键环境:

sql
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。实际加载顺序应使用下面的命令确认:

bash
mysqld --verbose --help

系统变量可能是:

  • GLOBAL:影响后续新连接,通常不改变已有会话。
  • SESSION:只影响当前连接。
  • 只读变量:只能通过配置文件或启动参数修改。
  • 动态变量:运行中可修改;MySQL 8 支持 SET PERSIST 持久化部分变量。
sql
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_connectionswait_timeout结合连接池上限和活跃连接,不靠无限放大
控制包大小max_allowed_packet大 SQL、大字段、复制事件是否超限
事务隔离transaction_isolation一致性要求与锁冲突成本
日志持久性innodb_flush_log_at_trx_commitsync_binlog性能与宕机丢数据窗口的权衡
慢 SQLslow_query_loglong_query_time日志容量、采样周期、Rows_examined
临时表tmp_table_sizemax_heap_table_size内存临时表转磁盘的比例与并发内存风险
字符集character_set_servercollation_server推荐完整 Unicode,客户端与服务端保持一致
时区time_zonesystem_time_zone应用、JDBC、数据库、业务语义统一

连接建立发生了什么

mermaid
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: 建立会话并初始化会话变量

排查连接问题时按顺序检查:

  1. 进程是否监听目标地址和端口。
  2. DNS、路由、防火墙和安全组是否放行。
  3. MySQL 用户的 user@host 是否匹配来源。
  4. 驱动和认证插件是否兼容。
  5. TLS、字符集、时区和连接参数是否正确。
  6. 是否达到连接数上限,连接池是否泄漏。
sql
show status like 'Threads_connected';
show status like 'Threads_running';
show processlist;

内存为什么不能只看 Buffer Pool

可粗略理解为:

text
总内存 ≈ 全局内存 + 活跃连接数 × 单连接可能内存 + OS 与其他进程

全局内存包括 Buffer Pool、Redo Buffer、Performance Schema 等;单连接内存可能包括排序、Join、读缓冲和临时表。按所有参数最大值直接相乘会高估,但只看 Buffer Pool 会低估。生产要用峰值活跃连接和真实 workload 压测。

SQL mode

sql_mode 会改变非法日期、截断、分组等行为。升级或迁移时尤其重要:

sql
select @@global.sql_mode, @@session.sql_mode;

不要为了让错误 SQL 能运行就直接清空严格模式。应该修复不确定的分组、超长值、非法日期和隐式转换,并用测试验证。

面试追问

为什么 max_connections 不能无限调大

连接会消耗内存和线程调度资源,数据库瓶颈通常是 CPU、IO 或锁竞争。连接过多会把可控的排队变成数据库内部争抢,最终延迟雪崩。应该限制应用连接池、设置超时、监控活跃连接并做容量压测。

SET GLOBAL 后为什么当前连接没变化

许多会话变量在连接建立时从全局值复制,修改全局值只影响后续连接;当前连接需要 SET SESSION 或重连。还要区分动态、只读和持久化变量。

数据库时区怎么设计

先区分绝对时间点和本地日历时间。绝对时间点建议统一存储并明确转换规则;应用、JDBC 和数据库会话时区要显式配置。timestamp 会按会话时区转换,datetime 保存给定字段值,两者不能只按字节大小选择。