您现在的位置是:娱乐 >>正文
SQL数据库可疑
娱乐35517人已围观
简介凌晨两点,运维群里弹出一条告警:某核心业务库的CPU飙到97%,持续了十五分钟没回落。我登上跳板机,连进数据库,第一眼看到的是`SHOW PROCESSLIST`里堆着几十个状态为“Sending d ...
凌晨两点,据库运维群里弹出一条告警:某核心业务库的可疑CPU飙到97%,持续了十五分钟没回落。据库我登上跳板机,可疑连进数据库,据库第一眼看到的可疑是`SHOW PROCESSLIST`里堆着几十个状态为“Sending data”的查询,全是据库同一张订单表的全表扫描。这张表不大,可疑两千万行,据库但每个查询都带着`LIKE '%关键词%'`——典型的可疑模糊匹配没走索引。
可疑的据库地方不在SQL本身,而在于这些查询来自一个三天前刚上线的可疑报表模块。开发说“测试环境跑得好好的据库”。测试环境那张表只有八万行,可疑全表扫描当然快。据库生产环境数据量翻了二百多倍,执行计划从`ALL`变成了`ALL`,但代价完全不同。这种“测试环境骗局”在数据库领域反复上演,几乎成了某种行业惯例。
再往下查,发现更蹊跷的事。这些查询的`TIME`字段显示已经运行了超过4000秒,但`INFO`里的SQL文本被截断了。我拉长`group_concat_max_len`重新看,才注意到每个查询后面都跟着一个隐式的`ORDER BY`,排序字段没有索引。MySQL的排序缓冲区不够用,只能走磁盘临时表。磁盘临时表一多,`tmp_table_size`被撑爆,服务器开始频繁刷脏页。CPU高只是表象,真正的瓶颈在IO。
但问题到这里还没完。我注意到这些查询的发起账号是`report_user`,而这个账号的权限配置里居然有`SELECT`整个库的权限。更离谱的是,连接来源IP段指向一个已经下线的旧报表服务器。也就是说,有人把旧服务器的连接配置直接复制到了新模块里,连账号都没换。旧服务器早就该退役了,但它的IP还在DNS缓存里活着。
这让我想起去年另一个案例。某电商平台的库存扣减逻辑,在代码里写的是`UPDATE stock SET count = count - 1 WHERE id = ? AND count > 0`,看起来没问题。但数据库隔离级别是`REPEATABLE READ`,高并发下多个事务同时读到`count = 1`,然后依次执行更新。InnoDB的行锁在`REPEATABLE READ`下会锁住索引记录,但这里的`id`是主键,锁是加上了,可`count > 0`这个条件在更新时并不重新校验。结果就是库存扣成负数,财务对账时发现少了三百多件货。这个案例后来被写进了很多面试题,但真正在生产环境里踩过坑的人,看到`REPEATABLE READ`这个词还是会心里一紧。
回到眼前的告警。我临时把`report_user`的查询超时时间从默认的0改成30秒,然后kill掉那些跑了超过一分钟的会话。CPU在五分钟内降到正常水平。但这不是根治。根治的办法要么给`LIKE`字段加全文索引,要么把报表查询挪到只读从库,要么直接重构那个模块——把实时查询改成预计算。开发选了最省事的方案:加索引。但`LIKE '%关键词%'`加B-tree索引没用,得用全文索引或者倒排索引。他们最后用了Elasticsearch,把报表查询整个搬走了。
数据库可疑,往往不是数据库本身的问题。它更像一面镜子,照出的是应用层的设计缺陷、运维层的配置疏忽、开发层的测试盲区。每次看到慢查询日志里那些“意料之外”的SQL,我都会想起一句话:数据库不会说谎,它只是忠实地执行你让它执行的东西。至于你让它执行的东西对不对,那是另一回事。
Tags:
上一篇:漏洞浏览器
下一篇:彩票组号经典旋转矩阵
相关文章
phpcms obd大数据采集
娱乐phpcms做OBD大数据采集?这事听着像拿菜刀砍电线,火花带闪电。但真有人这么干,而且跑通了。 去年给一家做车队管理的客户做技术选型,他们手里有三百台重卡,每台都装了OBD盒子,每秒回传转速、油耗、 ...
【娱乐】
阅读更多人民币网
娱乐人民币的汇率今天又涨了。早上九点半,外汇交易中心的大屏幕跳出一串数字,离岸人民币对美元报6.82,比昨天收盘高了200多个基点。朋友圈里做外贸的老刘发了一条状态:再涨下去,这单生意要白干了。配图是一张 ...
【娱乐】
阅读更多成功销售必读的24本书
娱乐销售这行当,门槛低得跟马路牙子似的,可天花板高得能戳破云层。我见过太多人抱着“口才好就能卖货”的幻觉冲进来,结果被现实扇得鼻青脸肿。真正能持续签单的家伙,书架上没几本烂书,全是能啃出骨头的硬货。下面这 ...
【娱乐】
阅读更多