mysql重启时连接中断的根本原因是暴力终止连接导致协议层硬断开;真正避免中断需架构级高可用或实例不杀连接的可控启停,配合客户端连接池主动验证与清理。

MySQL 重启时连接中断的根本原因
生产环境里 systemctl restart mysqld 或直接 kill -9 进程,本质是暴力终止所有活跃连接,客户端会立刻收到 Lost connection to MySQL server during query。这不是配置问题,是协议层的硬断开——MySQL 没机会通知客户端“我要下线了”。
真正能避免中断的,只有两种路径:让新连接自动切到备用实例(依赖架构),或让当前实例在不杀连接的前提下重载配置、释放资源、甚至切换主从角色。
用 mysqladmin shutdown + mysqld_safe 实现可控停启
相比 systemctl,手动控制启动流程能插入检查点,减少不可控窗口。但必须配合 --skip-networking 和连接 draining 逻辑。
- 先执行
mysqladmin -u root -p shutdown,它会等待当前事务提交完成再关闭监听端口,已建立的连接仍可继续执行完语句 - 启动前确认
/var/lib/mysql权限未被 systemd 重置(常见于 SELinux 启用环境) - 用
mysqld_safe --defaults-file=/etc/my.cnf &启动,比直接调mysqld多一层异常捕获和自动拉起能力 - 启动后立刻执行
SELECT VERSION(), @@uptime;验证是否真跑起来了,而不是卡在初始化阶段
配置热加载:哪些参数能 SET GLOBAL,哪些必须重启
不是所有配置都能在线改。改错会导致行为不一致,比如 innodb_buffer_pool_size 在 5.7+ 支持动态调整,但仅限增大;而 max_connections 可增可减,但减小后新连接会被拒绝,已有连接不受影响。
- 安全可热改:
slow_query_log、long_query_time、wait_timeout - 需谨慎热改:
innodb_buffer_pool_size(只允许增大,且每次最多增 1GB)、sort_buffer_size(只影响新连接) - 必须重启:
datadir、socket、port、default_authentication_plugin - 验证方式:改完立刻查
SELECT @@global.sort_buffer_size;,别只信配置文件
连接平滑过渡的关键:客户端侧要配合
服务端再稳,客户端不重连也白搭。很多应用用长连接池(如 HikariCP、Druid),它们默认不会感知 MySQL 进程重启,只会不断重试失败连接,直到超时。
- 设置连接池的
connection-test-query=SELECT 1和validation-timeout=3000,确保空闲连接被及时踢出 - 启用
failOverReadOnly=false(MySQL Connector/J)避免主从切换时误判只读 - 如果用了 ProxySQL 或 MaxScale,记得在重启前执行
PROXYSQL ADMIN> UPDATE mysql_servers SET status='OFFLINE_SOFT' WHERE hostgroup_id=1;,等连接自然耗尽 - 最简兜底:在应用部署脚本里加
sleep 5,给连接池留出清理时间,别一重启完就发流量
真正的平滑不在 MySQL 自身,而在整个链路对“连接生命周期”的共识。漏掉客户端那一环,服务端做得再优雅也没用。











