加入收藏 | 设为首页 | 会员中心 | 我要投稿 航空爱好网 (https://www.ikongjun.com/)- 混合云存储、媒体智能、AI行业应用、应用程序集成、办公协同!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

站长必避的3个MySQL设计陷阱:半年一崩的根源

发布时间:2026-11-06 11:30:17 所属栏目:MySql教程 来源:DaWei
导读:文章配图,仅供参考  去年七月份,我蹲在IDC机房里听硬盘阵列咔哒咔哒响,像心跳快停了似的——那是我们主站MySQL从凌晨三点开始报502的第八次。监控面板红得发烫,但错误日志就一句:“Lost connection to MySQL server dur

文章配图,仅供参考

  去年七月份,我蹲在IDC机房里听硬盘阵列咔哒咔哒响,像心跳快停了似的——那是我们主站MySQL从凌晨三点开始报502的第八次。监控面板红得发烫,但错误日志就一句:“Lost connection to MySQL server during query”。我原以为是网络抖动,结果运维小张把交换机端口换了一遍,连光模块都擦了三遍,它还是每隔四十七分钟崩一次。


  那天下午我把主库dump下来重装——不是迁移,就是原地卸载再装同版本。结果恢复完刚上线二十来分钟,后台订单表INSERT突然卡住,前端用户下单按钮点了三秒没反应。客服老王在钉钉群里发截图,说“用户反馈支付页转圈,客服话术还没编好”。我就站在他工位后面看屏幕,他手指悬在键盘上,没敲出一个字。反正谁也想不到,问题出在建表语句里那行`ENGINE=MyISAM DEFAULT CHARSET=utf8`——整站七个核心表,六个还在用MyISAM,其中三个带全文索引(可MyISAM全文索引不支持中文分词,但我们根本没调用过那个功能)。


  更怪的是,每次崩前五分钟,`show processlist`里总会多出三到五条状态为`Locked`的慢查询,但SQL本身特别简单,就`SELECT id FROM user_log WHERE status=1 ORDER BY create_time DESC LIMIT 10`这种。查了索引,`status`字段有单列索引,`create_time`也有,可就是没复合索引。我让小张加了个`(status,create_time)`,当天夜里没崩;第二天中午又崩了,因为另一个脚本在`user_log`表上跑了`ALTER TABLE ADD COLUMN remark TEXT`——MyISAM执行这种DDL是锁整表的,而我们定时任务恰好每小时跑一遍清理逻辑,一撞上就死锁十秒起步。


  对,就这事儿——半年里八次502,六次发生在周四下午,两次在周日凌晨。我数过,第七次崩的时候,DBA老李正蹲在隔壁帮电商客户调InnoDB buffer pool,回消息说“你先用read_only顶一下”,结果我刚`SET GLOBAL read_only=ON`,所有写请求立刻返回“ERROR 1290 (HY000)”,因为MyISAM压根不认这个变量。(空调出风口滴了两滴水在我后颈上,凉得我一激灵)


  最绝的是备份恢复那次。我们按常规用mysqldump --single-transaction导出,恢复到测试库时发现:timestamp字段全变成0000-00-00 00:00:00。不是NULL,是零值。问老李,他说MyISAM不支持事务快照,`--single-transaction`对它完全无效——dump过程中只要有人更新某行,就可能导出时间戳被覆盖过的脏数据。可我们所有备份脚本里都写着这参数,五年没改过。我盯着恢复后那片刺眼的零值,突然想起去年备案被驳回时,管局留言写的那句:“未说明数据库事务一致性保障机制”。(其实我们根本没事务)


  我原以为换存储引擎只是个技术选型问题,结果它卡在每个缝里:客服回复要等锁释放、搜索插件更新不了索引、连阿里云RDS的自动备份日志里都飘着“[Warning] MyISAM table ‘xxx’ has no primary key”的提示……可没人点开看。昨天又崩了一次,这次我干脆没动数据库,就在Nginx层做了个缓存兜底——页面能打开,订单却悄悄丢了两百单。老王递给我一杯咖啡,热的,说:“用户说付款成功了,但我后台没记录。”


  有谁碰到过这个吗?

(编辑:航空爱好网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!