MySQL运维与设计五大致命坑(13年实战避坑指南)
|
三个月前,我蹲在IDC三号机房的冷凝水管底下接漏——不是修,是拿个乐扣盒接着,水滴声跟心跳一个节奏。隔壁组老陈叼着没点着的烟,说他们新上线的“读写分离架构”跑通了。我抬头看他工牌反光里自己的脸,心想这玩意儿连binlog半同步都还没开,就敢叫通了? 第一坑:ALTER TABLE ONLINE=1,你真信它在线?上周五凌晨两点十七分,一个加NOT NULL + DEFAULT的语句卡在copy to tmp table阶段三百七十二秒,主从延迟跳到两小时四十三分。主库load飙到27,从库IO线程挂了两次。我原以为是pt-online-schema-change的bug,结果抓包一看,那个DEFAULT值被MySQL解析成表达式触发了全表扫描。不是引擎问题,是语法糖在背后捅刀子。这个我敢打包票。 当时桌上摊着三份外卖,其中一份麻婆豆腐凉透了,浮着层红油,筷子斜插在里头。旁边小杨正用手机录屏复现步骤,突然抬头问:“主键用UUIDv4的话,二级索引B+树分裂是不是更疯?”我没理他。他接着拍——咔哒一声,手机壳掉了一角,在水泥地上弹了两下,滚进机柜缝里去了。 第二坑:JSON字段存业务逻辑。上个月财务系统导出对账单,开发说“反正前端自己parse”,运维说“反正空间够”。结果某天一个商户名字段塞进去了base64图片(真事),MySQL报错Message too long,但错误码还是1300。没人看error log,只盯着slow query log刷屏。等发现时,binlog里已经混进一堆乱码EVENT,GTID连续性断了三次。现在他们还在用mysqlbinlog --base64-output=DECODE-ROWS硬解……解出来是十六进制和换行符打架的诗。 那天窗外一直在下雨,不是暴雨,是那种粘腻的、不歇气的江南梅雨。监控屏右下角显示机房湿度81%,空调外机在楼顶嗡嗡震,声音闷得像有人用拳头敲铁皮桶。老张进来倒水,顺手把湿外套挂在门后挂钩上,滴水在“禁止吸烟”标牌下积了一小滩。他问我:“你猜DBA跟DB运维谁该背这个锅?”我没答。他笑了笑,走了。 第三坑:字符集和排序规则混搭。utf8mb4_unicode_ci跟utf8mb4_0900_as_cs放同一张表?别笑。有次JOIN两张表,字段都是VARCHAR(255),一个是_ci一个是_as_cs,WHERE条件里一个等于号,执行计划直接放弃使用索引,改走嵌套循环。explain输出的type列写着ALL,rows列是个带小数点的数字——你数到第三位就心梗。我们没动表结构,就改了SET NAMES那一行,结果凌晨四点线上退款失败率翻了三倍。我说不准这是Bug还是设计,但我知道,MySQL 8.0文档第4.11节写的是“推荐统一”,不是“必须兼容”。 第四坑:基于时间戳的乐观锁,update set version=version+1 where id=? and updated_at=?。听着干净。实际呢?NTP服务抖动十八秒,两个节点看到的updated_at差了六秒;应用层没做幂等重试;update影响行数返回0,日志埋点只记“业务失败”,没记“版本冲突”。等查到时,用户已投诉二十七单,财务多出十八笔“疑似重复支付”流水。我们最后是翻general_log比对事务时间戳才串起来的链路。那天下班地铁里我听见旁边俩人聊股票复盘,其中一个说“止损点设早了”,我盯着手机里刚pull下来的slow_log截图,想笑,没笑出来。 第五坑:用max_connections撑并发。去年Q4大促前,DBA和SRE为这个参数吵了四次会。一边说“再扩三百连接池稳过峰值”,另一边举证连接泄漏、TIME_WAIT堆积、操作系统文件描述符耗尽。最后折中设成2048。结果那天凌晨0:18,show processlist里三百一十二个Sleep状态,平均空闲时长四百零三秒。而真正干活的连接只有八十九个。优胜劣汰?不存在的。劣质连接躺在那里呼吸,还占着线程缓存、内存分配器slot、甚至SSL session cache。这不是压测,是养蛊。 我原以为只要keepalive timeout调低就能救,结果抓包发现客户端根本没发FIN。是Spring Boot的HikariCP配置了connection-test-query但忘了设test-on-borrow=true。一个boolean缺位,害我们半夜手动KILL掉了七百多个僵尸连接。老陈后来在食堂端着餐盘坐我对面,夹起一块豆腐,说:“其实你该试试pg_stat_activity视图。”我没接话。他低头嚼,酱汁滴在工装裤上,像颗褐色的痣。
文章配图,仅供参考 说到pg……上周我去给个兄弟单位做灾备评估,对方DBA递给我一份MySQL高可用方案,里面写着“VIP漂移期间允许30秒无响应”。我喝了一口咖啡——纸杯边沿有个小小的缺口,硌着下嘴唇。我说:“你们切主之前,先看看当前主库有没有正在执行的DDL。”他愣了一下,翻PPT,第十九页写着“已规避DDL风险”。我没拆穿。桌上的投影仪灯泡在散热,嗡嗡声越来越响。这些坑没一个新。但每个都还在重复塌方。不是知识没传下去,是有人非要亲手踩一遍才肯信混凝土里没钢筋。我现在改版网站时不碰数据库架构文档了,直接约DBA喝咖啡,聊五分钟就懂他心里的阈值在哪。比如他提到“锁等待超时”时眨眼频率变快,我就知道上次死锁他亲手kill过master thread;他摸耳机线——左耳那根——说明对备份策略没底。这些比explain输出靠谱多了。 对了,刚才那盒没吃完的麻婆豆腐,我让保洁阿姨顺手扔了。她戴着蓝胶手套,掀盖看了眼,说:“辣油分层了,不能留。”我点头。她转身时,后颈衣领翘起一点,露出半截蓝色纹身,像是什么缩写的首字母。我没看清。 接下来我要干的事很简单:把所有alter语句塞进自动化审批流,加三道卡点——是否有DEFAULT、是否涉及TEXT/JSON、执行窗口是否在非业务高峰。别的先不动。至于能不能防住所有人?我说不准。但我今天下午三点,要盯着第一轮灰度脚本跑完,亲自看log。那台机器的hostname叫db-prod-web03,它机柜编号A21,风扇转速现在是2940rpm。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


MySQL运维设计实战:36小时崩盘到高可用蜕变
mysql设计概念多表查询和事务制作实例分析

