> 技术文档 > MySQL长事务:潜伏的数据库杀手!如何识别与消灭它?

MySQL长事务:潜伏的数据库杀手!如何识别与消灭它?


你的数据库是否突然变慢甚至冻结?罪魁祸首可能正是那些被忽视的长事务 本文将揭示MySQL长事务的致命危害,并提供全套解决方案,让你的数据库重获新生!

一、什么是长事务?一个定时炸弹💣

想象你在超市结账:

  • 正常事务:扫码-付款-离开(30秒)
  • 长事务:挑选商品时接电话聊半小时,后面队伍全堵死!

MySQL中的长事务

指那些开启后长时间未提交或回滚的事务,通常超过5秒即可视为长事务

长事务的典型特征

MySQL长事务:潜伏的数据库杀手!如何识别与消灭它?

二、长事务的五大罪状

1. 锁等待雪崩

#mermaid-svg-c44da5sVHd19aRL6 {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-c44da5sVHd19aRL6 .error-icon{fill:#552222;}#mermaid-svg-c44da5sVHd19aRL6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-c44da5sVHd19aRL6 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-c44da5sVHd19aRL6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-c44da5sVHd19aRL6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-c44da5sVHd19aRL6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-c44da5sVHd19aRL6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-c44da5sVHd19aRL6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-c44da5sVHd19aRL6 .marker.cross{stroke:#333333;}#mermaid-svg-c44da5sVHd19aRL6 svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-c44da5sVHd19aRL6 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-c44da5sVHd19aRL6 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-c44da5sVHd19aRL6 .actor-line{stroke:grey;}#mermaid-svg-c44da5sVHd19aRL6 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-c44da5sVHd19aRL6 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-c44da5sVHd19aRL6 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-c44da5sVHd19aRL6 .sequenceNumber{fill:white;}#mermaid-svg-c44da5sVHd19aRL6 #sequencenumber{fill:#333;}#mermaid-svg-c44da5sVHd19aRL6 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-c44da5sVHd19aRL6 .messageText{fill:#333;stroke:#333;}#mermaid-svg-c44da5sVHd19aRL6 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-c44da5sVHd19aRL6 .labelText,#mermaid-svg-c44da5sVHd19aRL6 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-c44da5sVHd19aRL6 .loopText,#mermaid-svg-c44da5sVHd19aRL6 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-c44da5sVHd19aRL6 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-c44da5sVHd19aRL6 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-c44da5sVHd19aRL6 .noteText,#mermaid-svg-c44da5sVHd19aRL6 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-c44da5sVHd19aRL6 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-c44da5sVHd19aRL6 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-c44da5sVHd19aRL6 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-c44da5sVHd19aRL6 .actorPopupMenu{position:absolute;}#mermaid-svg-c44da5sVHd19aRL6 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-c44da5sVHd19aRL6 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-c44da5sVHd19aRL6 .actor-man circle,#mermaid-svg-c44da5sVHd19aRL6 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-c44da5sVHd19aRL6 :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}事务A(长事务)行1事务B事务C事务D事务A所有事务客户端持有X锁请求锁(等待)请求锁(等待)请求锁(等待)30秒后...超时错误事务A(长事务)行1事务B事务C事务D事务A所有事务客户端

影响:整个系统连锁冻结

2. 回滚段膨胀

Undo Log增长曲线

#mermaid-svg-qZarY7WLoj7OyaCV {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-qZarY7WLoj7OyaCV .error-icon{fill:#552222;}#mermaid-svg-qZarY7WLoj7OyaCV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qZarY7WLoj7OyaCV .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-qZarY7WLoj7OyaCV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qZarY7WLoj7OyaCV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qZarY7WLoj7OyaCV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qZarY7WLoj7OyaCV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qZarY7WLoj7OyaCV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qZarY7WLoj7OyaCV .marker.cross{stroke:#333333;}#mermaid-svg-qZarY7WLoj7OyaCV svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qZarY7WLoj7OyaCV .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-qZarY7WLoj7OyaCV .cluster-label text{fill:#333;}#mermaid-svg-qZarY7WLoj7OyaCV .cluster-label span{color:#333;}#mermaid-svg-qZarY7WLoj7OyaCV .label text,#mermaid-svg-qZarY7WLoj7OyaCV span{fill:#333;color:#333;}#mermaid-svg-qZarY7WLoj7OyaCV .node rect,#mermaid-svg-qZarY7WLoj7OyaCV .node circle,#mermaid-svg-qZarY7WLoj7OyaCV .node ellipse,#mermaid-svg-qZarY7WLoj7OyaCV .node polygon,#mermaid-svg-qZarY7WLoj7OyaCV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qZarY7WLoj7OyaCV .node .label{text-align:center;}#mermaid-svg-qZarY7WLoj7OyaCV .node.clickable{cursor:pointer;}#mermaid-svg-qZarY7WLoj7OyaCV .arrowheadPath{fill:#333333;}#mermaid-svg-qZarY7WLoj7OyaCV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qZarY7WLoj7OyaCV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qZarY7WLoj7OyaCV .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-qZarY7WLoj7OyaCV .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-qZarY7WLoj7OyaCV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qZarY7WLoj7OyaCV .cluster text{fill:#333;}#mermaid-svg-qZarY7WLoj7OyaCV .cluster span{color:#333;}#mermaid-svg-qZarY7WLoj7OyaCV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qZarY7WLoj7OyaCV :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}事务开始Undo Log 1MB10秒后 100MB1分钟后 1GB磁盘空间耗尽

3. MVCC版本链失控

#mermaid-svg-HHl08REsSApbwQoq {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-HHl08REsSApbwQoq .error-icon{fill:#552222;}#mermaid-svg-HHl08REsSApbwQoq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HHl08REsSApbwQoq .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-HHl08REsSApbwQoq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HHl08REsSApbwQoq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HHl08REsSApbwQoq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HHl08REsSApbwQoq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HHl08REsSApbwQoq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HHl08REsSApbwQoq .marker.cross{stroke:#333333;}#mermaid-svg-HHl08REsSApbwQoq svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HHl08REsSApbwQoq .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-HHl08REsSApbwQoq .cluster-label text{fill:#333;}#mermaid-svg-HHl08REsSApbwQoq .cluster-label span{color:#333;}#mermaid-svg-HHl08REsSApbwQoq .label text,#mermaid-svg-HHl08REsSApbwQoq span{fill:#333;color:#333;}#mermaid-svg-HHl08REsSApbwQoq .node rect,#mermaid-svg-HHl08REsSApbwQoq .node circle,#mermaid-svg-HHl08REsSApbwQoq .node ellipse,#mermaid-svg-HHl08REsSApbwQoq .node polygon,#mermaid-svg-HHl08REsSApbwQoq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HHl08REsSApbwQoq .node .label{text-align:center;}#mermaid-svg-HHl08REsSApbwQoq .node.clickable{cursor:pointer;}#mermaid-svg-HHl08REsSApbwQoq .arrowheadPath{fill:#333333;}#mermaid-svg-HHl08REsSApbwQoq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-HHl08REsSApbwQoq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-HHl08REsSApbwQoq .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-HHl08REsSApbwQoq .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-HHl08REsSApbwQoq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-HHl08REsSApbwQoq .cluster text{fill:#333;}#mermaid-svg-HHl08REsSApbwQoq .cluster span{color:#333;}#mermaid-svg-HHl08REsSApbwQoq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-HHl08REsSApbwQoq :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}数据行版本100版本101版本102...版本200

后果:简单查询需要遍历上百个版本

4. 内存资源耗尽

Buffer Pool污染
MySQL长事务:潜伏的数据库杀手!如何识别与消灭它?

导致正常查询被迫访问磁盘

5. 主从复制延迟

#mermaid-svg-IuodMyUJcPPdsDsT {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-IuodMyUJcPPdsDsT .error-icon{fill:#552222;}#mermaid-svg-IuodMyUJcPPdsDsT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IuodMyUJcPPdsDsT .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-IuodMyUJcPPdsDsT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IuodMyUJcPPdsDsT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IuodMyUJcPPdsDsT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IuodMyUJcPPdsDsT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IuodMyUJcPPdsDsT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IuodMyUJcPPdsDsT .marker.cross{stroke:#333333;}#mermaid-svg-IuodMyUJcPPdsDsT svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IuodMyUJcPPdsDsT .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-IuodMyUJcPPdsDsT .cluster-label text{fill:#333;}#mermaid-svg-IuodMyUJcPPdsDsT .cluster-label span{color:#333;}#mermaid-svg-IuodMyUJcPPdsDsT .label text,#mermaid-svg-IuodMyUJcPPdsDsT span{fill:#333;color:#333;}#mermaid-svg-IuodMyUJcPPdsDsT .node rect,#mermaid-svg-IuodMyUJcPPdsDsT .node circle,#mermaid-svg-IuodMyUJcPPdsDsT .node ellipse,#mermaid-svg-IuodMyUJcPPdsDsT .node polygon,#mermaid-svg-IuodMyUJcPPdsDsT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-IuodMyUJcPPdsDsT .node .label{text-align:center;}#mermaid-svg-IuodMyUJcPPdsDsT .node.clickable{cursor:pointer;}#mermaid-svg-IuodMyUJcPPdsDsT .arrowheadPath{fill:#333333;}#mermaid-svg-IuodMyUJcPPdsDsT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-IuodMyUJcPPdsDsT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-IuodMyUJcPPdsDsT .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-IuodMyUJcPPdsDsT .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-IuodMyUJcPPdsDsT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-IuodMyUJcPPdsDsT .cluster text{fill:#333;}#mermaid-svg-IuodMyUJcPPdsDsT .cluster span{color:#333;}#mermaid-svg-IuodMyUJcPPdsDsT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-IuodMyUJcPPdsDsT :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}Binlog流阻塞主库从库长事务未提交复制延迟增加数据不一致

三、长事务问题原理深度剖析

InnoDB事务生命周期

#mermaid-svg-9Sut7ZcBVXHk9pay {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-9Sut7ZcBVXHk9pay .error-icon{fill:#552222;}#mermaid-svg-9Sut7ZcBVXHk9pay .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9Sut7ZcBVXHk9pay .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-9Sut7ZcBVXHk9pay .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9Sut7ZcBVXHk9pay .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9Sut7ZcBVXHk9pay .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9Sut7ZcBVXHk9pay .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9Sut7ZcBVXHk9pay .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9Sut7ZcBVXHk9pay .marker.cross{stroke:#333333;}#mermaid-svg-9Sut7ZcBVXHk9pay svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9Sut7ZcBVXHk9pay .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-9Sut7ZcBVXHk9pay text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-9Sut7ZcBVXHk9pay .actor-line{stroke:grey;}#mermaid-svg-9Sut7ZcBVXHk9pay .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-9Sut7ZcBVXHk9pay .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-9Sut7ZcBVXHk9pay #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-9Sut7ZcBVXHk9pay .sequenceNumber{fill:white;}#mermaid-svg-9Sut7ZcBVXHk9pay #sequencenumber{fill:#333;}#mermaid-svg-9Sut7ZcBVXHk9pay #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-9Sut7ZcBVXHk9pay .messageText{fill:#333;stroke:#333;}#mermaid-svg-9Sut7ZcBVXHk9pay .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-9Sut7ZcBVXHk9pay .labelText,#mermaid-svg-9Sut7ZcBVXHk9pay .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-9Sut7ZcBVXHk9pay .loopText,#mermaid-svg-9Sut7ZcBVXHk9pay .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-9Sut7ZcBVXHk9pay .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-9Sut7ZcBVXHk9pay .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-9Sut7ZcBVXHk9pay .noteText,#mermaid-svg-9Sut7ZcBVXHk9pay .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-9Sut7ZcBVXHk9pay .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-9Sut7ZcBVXHk9pay .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-9Sut7ZcBVXHk9pay .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-9Sut7ZcBVXHk9pay .actorPopupMenu{position:absolute;}#mermaid-svg-9Sut7ZcBVXHk9pay .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-9Sut7ZcBVXHk9pay .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-9Sut7ZcBVXHk9pay .actor-man circle,#mermaid-svg-9Sut7ZcBVXHk9pay line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-9Sut7ZcBVXHk9pay :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}事务Undo LogBuffer PoolRedo Log锁系统MVCC磁盘空间记录修改前值修改数据记录操作持有锁创建版本链loop[长事务期间]持续增长占用增加事务Undo LogBuffer PoolRedo Log锁系统MVCC磁盘空间

长事务与短事务对比

特性 短事务(<1s) 长事务(>5s) 锁持有时间 极短 很长 Undo使用 少量 巨大 MVCC版本 0-1个 数十上百 内存占用 低 高 影响范围 局部 全局

四、如何检测长事务?四大侦查工具

1. 信息模式查询

SELECT * FROM information_schema.INNODB_TRX\\G

关键字段

  • trx_started:事务开始时间
  • trx_query:最后执行的SQL
  • trx_rows_locked:锁定行数

2. 性能模式监控

-- 开启监控UPDATE performance_schema.setup_instruments SET ENABLED = \'YES\' WHERE NAME LIKE \'%transaction%\';-- 查看长事务SELECT * FROM performance_schema.events_transactions_current WHERE TIMER_WAIT > 5000000000; -- 5秒

3. 慢事务日志

# my.cnf配置[mysqld]long_query_time = 5 -- 记录超过5秒的事务log_slow_transactions = ONslow_query_log = ON

4. 实时诊断工具

SHOW ENGINE INNODB STATUS\\G

在输出中查找

---TRANSACTION 123456, ACTIVE 25 sec -- 长事务!2 lock struct(s), 1354 lock(s), undo log entries 1200MySQL thread id 789, OS thread handle 0x7f8b1c0a6700

五、解决长事务的七种武器

1. 紧急终止(KILL命令)

-- 查找长事务IDSELECT trx_mysql_thread_id FROM information_schema.INNODB_TRX WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 30;-- 终止事务KILL 789;

2. 优化查询语句

长事务源头

-- 问题查询(全表扫描)SELECT * FROM orders WHERE YEAR(create_time) = 2023 AND status = \'completed\';

优化方案

-- 添加索引CREATE INDEX idx_create_status ON orders(create_time, status);-- 重写查询SELECT * FROM orders WHERE create_time BETWEEN \'2023-01-01\' AND \'2023-12-31\' AND status = \'completed\';

3. 事务拆分

#mermaid-svg-K5T7MW39KnvGS8eZ {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-K5T7MW39KnvGS8eZ .error-icon{fill:#552222;}#mermaid-svg-K5T7MW39KnvGS8eZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-K5T7MW39KnvGS8eZ .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-K5T7MW39KnvGS8eZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-K5T7MW39KnvGS8eZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-K5T7MW39KnvGS8eZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-K5T7MW39KnvGS8eZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-K5T7MW39KnvGS8eZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-K5T7MW39KnvGS8eZ .marker.cross{stroke:#333333;}#mermaid-svg-K5T7MW39KnvGS8eZ svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-K5T7MW39KnvGS8eZ .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-K5T7MW39KnvGS8eZ .cluster-label text{fill:#333;}#mermaid-svg-K5T7MW39KnvGS8eZ .cluster-label span{color:#333;}#mermaid-svg-K5T7MW39KnvGS8eZ .label text,#mermaid-svg-K5T7MW39KnvGS8eZ span{fill:#333;color:#333;}#mermaid-svg-K5T7MW39KnvGS8eZ .node rect,#mermaid-svg-K5T7MW39KnvGS8eZ .node circle,#mermaid-svg-K5T7MW39KnvGS8eZ .node ellipse,#mermaid-svg-K5T7MW39KnvGS8eZ .node polygon,#mermaid-svg-K5T7MW39KnvGS8eZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-K5T7MW39KnvGS8eZ .node .label{text-align:center;}#mermaid-svg-K5T7MW39KnvGS8eZ .node.clickable{cursor:pointer;}#mermaid-svg-K5T7MW39KnvGS8eZ .arrowheadPath{fill:#333333;}#mermaid-svg-K5T7MW39KnvGS8eZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-K5T7MW39KnvGS8eZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-K5T7MW39KnvGS8eZ .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-K5T7MW39KnvGS8eZ .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-K5T7MW39KnvGS8eZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-K5T7MW39KnvGS8eZ .cluster text{fill:#333;}#mermaid-svg-K5T7MW39KnvGS8eZ .cluster span{color:#333;}#mermaid-svg-K5T7MW39KnvGS8eZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-K5T7MW39KnvGS8eZ :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}大事务事务1事务2事务3

示例

-- 原始长事务START TRANSACTION;UPDATE ... -- 1万行INSERT ... -- 5千行COMMIT;-- 拆分后START TRANSACTION;UPDATE ... LIMIT 1000; -- 分批处理COMMIT;START TRANSACTION;UPDATE ... LIMIT 1000;COMMIT;

4. 设置超时参数

-- 会话级超时SET SESSION max_execution_time = 5000; -- 5秒-- 全局超时SET GLOBAL innodb_rollback_on_timeout = ON;SET GLOBAL innodb_lock_wait_timeout = 30; -- 锁等待超时30秒

5. 应用层重试机制

# Python伪代码示例def execute_transaction(): attempts = 0 while attempts < 3: try: with db.transaction(): # 业务操作 db.execute(\"UPDATE ...\") db.execute(\"INSERT ...\") return True except LockTimeoutError: attempts += 1 sleep(1) return False

6. 版本链清理

-- 定期清理旧版本SET GLOBAL innodb_purge_threads = 4; -- 增加清理线程SET GLOBAL innodb_max_purge_lag = 100000; -- 控制清理延迟

7. 架构优化

#mermaid-svg-3GJJHFhP4uLMseWv {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3GJJHFhP4uLMseWv .error-icon{fill:#552222;}#mermaid-svg-3GJJHFhP4uLMseWv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3GJJHFhP4uLMseWv .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-3GJJHFhP4uLMseWv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3GJJHFhP4uLMseWv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3GJJHFhP4uLMseWv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3GJJHFhP4uLMseWv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3GJJHFhP4uLMseWv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3GJJHFhP4uLMseWv .marker.cross{stroke:#333333;}#mermaid-svg-3GJJHFhP4uLMseWv svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3GJJHFhP4uLMseWv .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3GJJHFhP4uLMseWv .cluster-label text{fill:#333;}#mermaid-svg-3GJJHFhP4uLMseWv .cluster-label span{color:#333;}#mermaid-svg-3GJJHFhP4uLMseWv .label text,#mermaid-svg-3GJJHFhP4uLMseWv span{fill:#333;color:#333;}#mermaid-svg-3GJJHFhP4uLMseWv .node rect,#mermaid-svg-3GJJHFhP4uLMseWv .node circle,#mermaid-svg-3GJJHFhP4uLMseWv .node ellipse,#mermaid-svg-3GJJHFhP4uLMseWv .node polygon,#mermaid-svg-3GJJHFhP4uLMseWv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3GJJHFhP4uLMseWv .node .label{text-align:center;}#mermaid-svg-3GJJHFhP4uLMseWv .node.clickable{cursor:pointer;}#mermaid-svg-3GJJHFhP4uLMseWv .arrowheadPath{fill:#333333;}#mermaid-svg-3GJJHFhP4uLMseWv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3GJJHFhP4uLMseWv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3GJJHFhP4uLMseWv .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-3GJJHFhP4uLMseWv .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-3GJJHFhP4uLMseWv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3GJJHFhP4uLMseWv .cluster text{fill:#333;}#mermaid-svg-3GJJHFhP4uLMseWv .cluster span{color:#333;}#mermaid-svg-3GJJHFhP4uLMseWv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3GJJHFhP4uLMseWv :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}应用读写分离主库-写从库-读分库分表订单库用户库

六、预防长事务的最佳实践

事务设计黄金法则

#mermaid-svg-U083tR7hM5a6BYTY {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-U083tR7hM5a6BYTY .error-icon{fill:#552222;}#mermaid-svg-U083tR7hM5a6BYTY .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-U083tR7hM5a6BYTY .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-U083tR7hM5a6BYTY .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-U083tR7hM5a6BYTY .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-U083tR7hM5a6BYTY .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-U083tR7hM5a6BYTY .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-U083tR7hM5a6BYTY .marker{fill:#333333;stroke:#333333;}#mermaid-svg-U083tR7hM5a6BYTY .marker.cross{stroke:#333333;}#mermaid-svg-U083tR7hM5a6BYTY svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-U083tR7hM5a6BYTY .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-U083tR7hM5a6BYTY .cluster-label text{fill:#333;}#mermaid-svg-U083tR7hM5a6BYTY .cluster-label span{color:#333;}#mermaid-svg-U083tR7hM5a6BYTY .label text,#mermaid-svg-U083tR7hM5a6BYTY span{fill:#333;color:#333;}#mermaid-svg-U083tR7hM5a6BYTY .node rect,#mermaid-svg-U083tR7hM5a6BYTY .node circle,#mermaid-svg-U083tR7hM5a6BYTY .node ellipse,#mermaid-svg-U083tR7hM5a6BYTY .node polygon,#mermaid-svg-U083tR7hM5a6BYTY .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-U083tR7hM5a6BYTY .node .label{text-align:center;}#mermaid-svg-U083tR7hM5a6BYTY .node.clickable{cursor:pointer;}#mermaid-svg-U083tR7hM5a6BYTY .arrowheadPath{fill:#333333;}#mermaid-svg-U083tR7hM5a6BYTY .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-U083tR7hM5a6BYTY .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-U083tR7hM5a6BYTY .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-U083tR7hM5a6BYTY .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-U083tR7hM5a6BYTY .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-U083tR7hM5a6BYTY .cluster text{fill:#333;}#mermaid-svg-U083tR7hM5a6BYTY .cluster span{color:#333;}#mermaid-svg-U083tR7hM5a6BYTY div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-U083tR7hM5a6BYTY :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}开始事务操作耗时>5秒?拆分事务执行操作完成?立即提交

开发规范

  1. 事务范围最小化

    // 错误示例void processOrder() { startTransaction(); // 过早开始 // 复杂计算... updateInventory(); commit();}// 正确示例void processOrder() { // 复杂计算... startTransaction(); updateInventory(); // 仅包装DB操作 commit();}
  2. 设置超时监控

    -- 部署Prometheus监控mysql_global_status_innodb_row_lock_time_avgmysql_global_status_innodb_num_open_transactions
  3. 自动告警系统

    /* 创建长事务告警 */CREATE EVENT check_long_transactionsON SCHEDULE EVERY 1 MINUTEDOBEGIN IF (SELECT COUNT(*) FROM information_schema.INNODB_TRX WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 30) > 0 THEN -- 触发告警 CALL send_alert(\'Long transactions detected!\'); END IF;END;

七、真实案例分析:电商平台故障复盘

故障场景

  • 时间:大促期间
  • 现象:数据库冻结,订单失败率飙升
  • 紧急响应:15分钟无法恢复

排查过程

#mermaid-svg-I7EmMTyuqWkyepGU {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-I7EmMTyuqWkyepGU .error-icon{fill:#552222;}#mermaid-svg-I7EmMTyuqWkyepGU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-I7EmMTyuqWkyepGU .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-I7EmMTyuqWkyepGU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-I7EmMTyuqWkyepGU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-I7EmMTyuqWkyepGU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-I7EmMTyuqWkyepGU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-I7EmMTyuqWkyepGU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-I7EmMTyuqWkyepGU .marker.cross{stroke:#333333;}#mermaid-svg-I7EmMTyuqWkyepGU svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-I7EmMTyuqWkyepGU .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-I7EmMTyuqWkyepGU .cluster-label text{fill:#333;}#mermaid-svg-I7EmMTyuqWkyepGU .cluster-label span{color:#333;}#mermaid-svg-I7EmMTyuqWkyepGU .label text,#mermaid-svg-I7EmMTyuqWkyepGU span{fill:#333;color:#333;}#mermaid-svg-I7EmMTyuqWkyepGU .node rect,#mermaid-svg-I7EmMTyuqWkyepGU .node circle,#mermaid-svg-I7EmMTyuqWkyepGU .node ellipse,#mermaid-svg-I7EmMTyuqWkyepGU .node polygon,#mermaid-svg-I7EmMTyuqWkyepGU .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-I7EmMTyuqWkyepGU .node .label{text-align:center;}#mermaid-svg-I7EmMTyuqWkyepGU .node.clickable{cursor:pointer;}#mermaid-svg-I7EmMTyuqWkyepGU .arrowheadPath{fill:#333333;}#mermaid-svg-I7EmMTyuqWkyepGU .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-I7EmMTyuqWkyepGU .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-I7EmMTyuqWkyepGU .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-I7EmMTyuqWkyepGU .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-I7EmMTyuqWkyepGU .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-I7EmMTyuqWkyepGU .cluster text{fill:#333;}#mermaid-svg-I7EmMTyuqWkyepGU .cluster span{color:#333;}#mermaid-svg-I7EmMTyuqWkyepGU div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-I7EmMTyuqWkyepGU :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}用户报障检查数据库发现大量锁等待定位源头事务分析事务SQL发现未提交统计查询

问题根源

-- 罪魁祸首START TRANSACTION;SELECT COUNT(*) FROM orders; -- 2亿行表,耗时5分钟-- 忘记提交!

优化方案

  1. 紧急措施

    KILL 54321; -- 终止长事务
  2. 长期方案

    -- 添加汇总表CREATE TABLE order_count ( date DATE PRIMARY KEY, count INT);-- 定时更新INSERT INTO order_count SELECT CURRENT_DATE(), COUNT(*) FROM orders ON DUPLICATE KEY UPDATE count = VALUES(count);-- 查询优化SELECT count FROM order_count WHERE date = CURRENT_DATE();

优化效果

指标 优化前 优化后 提升 查询时间 300秒 0.01秒 30000倍 锁持有时间 300秒 0.1秒 3000倍 影响范围 整个数据库 无 100%

八、总结:长事务治理全景图

治理策略矩阵

阶段 预防措施 检测方法 治理手段 设计阶段 事务拆分原则 代码审查 架构优化 开发阶段 超时设置 单元测试 查询优化 测试阶段 压力测试 慢日志分析 SQL重写 生产阶段 自动告警 实时监控 事务终止

关键参数配置

# my.cnf 推荐配置[mysqld]# 事务超时innodb_lock_wait_timeout = 30max_execution_time = 5000# 长事务监控long_query_time = 5slow_query_log = 1# Undo优化innodb_undo_log_truncate = ONinnodb_max_undo_log_size = 1G

核心原则
🔄 事务越短越好 - 理想事务应在毫秒级完成
⚠️ 监控胜于救火 - 建立实时告警系统
🛡️ 预防重于治疗 - 从设计阶段规避风险

最后行动:立即执行以下命令检查你的数据库:

SELECT trx_id, TIMEDIFF(NOW(), trx_started) AS duration, trx_queryFROM information_schema.INNODB_TRXWHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 5;

讨论话题:你在工作中遇到过最严重的长事务问题是什么?是如何解决的?欢迎在评论区分享你的战斗故事!