記一次線上mysql死鎖分析(一)

記錄一次比較詭異的mysql死鎖日志。系統(tǒng)運行幾個月來笤昨,就在前幾天發(fā)生了一次死鎖,而且就只發(fā)生了一次死鎖握恳,整個排查過程耗時將近一天咐吼,最后感謝我們的DBA大神和老大一起分析找到原因炭臭。

診斷死鎖

借助于我們dapeng開源的分布式日志查詢系統(tǒng)(EFF)及日志告警系統(tǒng),我們得益于及時發(fā)現了業(yè)務中的死鎖日志。(想了解dapeng分布式日志查詢系統(tǒng)請點擊)

08-02 08:46:24 787 dapeng-eventbus--scheduler-0 ERROR [] - 
eventbus: 定時輪詢線程內出現了異常格嘁,已捕獲 msg:Deadlock found when trying to get lock; try restarting transaction
com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_161]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_161]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_161]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_161]
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:400) ~[mysql-connector-java-5.1.36.jar:5.1.36]
        at com.mysql.jdbc.Util.getInstance(Util.java:383) ~[mysql-connector-java-5.1.36.jar:5.1.36]
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987) ~[mysql-connector-java-5.1.36.jar:5.1.36]
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3847) ~[mysql-connector-java-5.1.36.jar:5.1.36]
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3783) ~[mysql-connector-java-5.1.36.jar:5.1.36]
       // 省略部分...
        at com.today.eventbus.scheduler.ScalaSql$.executeUpdateWithGenerateKey(ScalaSql.scala:104) ~[event-bus_2.12-2.0.4.jar:2.0.4]
        at com.today.eventbus.scheduler.ScalaSql$.executeUpdate(ScalaSql.scala:57) ~[event-bus_2.12-2.0.4.jar:2.0.4]
        at com.today.eventbus.scheduler.MsgPublishTask.$anonfun$doPublishMessagesAsync$1(MsgPublishTask.scala:154) ~[event-bus_2.12-2.0.4.jar:2.0.4]
        at com.today.eventbus.scheduler.MsgPublishTask.$anonfun$doPublishMessagesAsync$1$adapted(MsgPublishTask.scala:144) ~[event-bus_2.12-2.0.4.jar:2.0.4]
        at com.today.eventbus.scheduler.ScalaSql$.withTransaction(ScalaSql.scala:26) ~[event-bus_2.12-2.0.4.jar:2.0.4]
        at com.today.eventbus.scheduler.MsgPublishTask.doPublishMessagesAsync(MsgPublishTask.scala:144) ~[event-bus_2.12-2.0.4.jar:2.0.4]
        at com.today.eventbus.scheduler.MsgPublishTask.$anonfun$startScheduled$2(MsgPublishTask.scala:95) ~[event-bus_2.12-2.0.4.jar:2.0.4]
        //省略部分...

當我們找到業(yè)務中的ERROR日志后,發(fā)現只有如下簡單的一句發(fā)現死鎖的日志吼野,無法進行死鎖定定位聘鳞,我們需要診斷分析當時出現死鎖的上下文信息以及相關的執(zhí)行語句。這時候就需要查看mysql死鎖日志了妻怎。

首先壳炎,需要打開mysql死鎖日志開關,我們線上是已經打開的逼侦。打開方式

set global innodb_print_all_deadlocks=on

然后我們去mysql錯誤日志中撈這次的死鎖日志

2018-08-02T08:46:24.758848+08:00 871635 [Note] InnoDB:
*** (1) TRANSACTION:

TRANSACTION 206663716, ACTIVE 0 sec fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1136, 10 row lock(s), undo log entries 5
MySQL thread id 872226, OS thread handle 140243727415040, query id 461709452 192.168.10.126 today_user updating
DELETE FROM dp_common_event WHERE id in (268241,268242,268243,268810,268811)
2018-08-02T08:46:24.758879+08:00 871635 [Note] InnoDB: *** (1) WAITING FOR THIS LOCK TO BE GRANTED:

RECORD LOCKS space id 812 page no 3 n bits 80 index PRIMARY of table `order_db`.`dp_common_event` trx id 206663716 lock_mode X waiting
Record lock, heap no 10 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 8; hex 8000000000041a0c; asc         ;;
 1: len 6; hex 00000c517014; asc    Qp ;;
 2: len 7; hex b5000006a20110; asc        ;;
 3: len 30; hex 636f6d2e746f6461792e6170692e6f726465722e7363616c612e6576656e; asc com.today.api.order.scala.even; (total 52 bytes);
 4: len 30; hex 636f6d2e746f6461792e6170692e6f726465722e7363616c612e6576656e; asc com.today.api.order.scala.even; (total 371 bytes);
 5: len 4; hex 5b625460; asc [bT`;;

2018-08-02T08:46:24.759242+08:00 871635 [Note] InnoDB: *** (2) TRANSACTION:

TRANSACTION 206663700, ACTIVE 0 sec inserting, thread declared inside InnoDB 5000
mysql tables in use 1, locked 1
10 lock struct(s), heap size 1136, 6 row lock(s), undo log entries 6
MySQL thread id 871635, OS thread handle 140243167844096, query id 461709463 192.168.10.126 today_user update
INSERT INTO  dp_common_event set id=268244, event_type='com.today.api.order.scala.events.StoreOrderEndEventNew', event_binary=x'636F6D2E746F6461792E6170692E6F726465722E7363616C612E6576656E74732E53746F72654F72646572456E644576656E744E65770016A8DF2015181C16F8E9111814313136303035303135333331373037353336373615061504180731322E35303030180731322E353030304806302E30303030F806302E30303030080E01311808313136303035303016E699A80436D0EBCC819F59280018001680DCCC819F59150216D0F7C8819F5915021680DCCC819F5915DEB1931E00192C16EEFC1E18143131363030353031353333313730373533363736180832303531383430301502180CE7899BE88289E58DA4E7B289160018003806302E303030301502180731302E30303030180015002806302E3030303016000016F0FC1E181431313630303530313533333137303735333637361808323034373138303415041812E9A699E88F87E6B2B9E88F9CE58C85383067160018003806302E3030303015021806322E35303030180015002806302E30303030160000190800'
2018-08-02T08:46:24.759270+08:00 871635 [Note] InnoDB: *** (2) HOLDS THE LOCK(S):

RECORD LOCKS space id 812 page no 3 n bits 80 index PRIMARY of table `order_db`.`dp_common_event` trx id 206663700 lock_mode X locks rec but not gap
Record lock, heap no 10 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 8; hex 8000000000041a0c; asc         ;;
 1: len 6; hex 00000c517014; asc    Qp ;;
 2: len 7; hex b5000006a20110; asc        ;;
 3: len 30; hex 636f6d2e746f6461792e6170692e6f726465722e7363616c612e6576656e; asc com.today.api.order.scala.even; (total 52 bytes);
 4: len 30; hex 636f6d2e746f6461792e6170692e6f726465722e7363616c612e6576656e; asc com.today.api.order.scala.even; (total 371 bytes);
 5: len 4; hex 5b625460; asc [bT`;;

2018-08-02T08:46:24.759691+08:00 871635 [Note] InnoDB: *** (2) WAITING FOR THIS LOCK TO BE GRANTED:

RECORD LOCKS space id 812 page no 3 n bits 80 index PRIMARY of table `order_db`.`dp_common_event` trx id 206663700 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 6 PHYSICAL RECORD: n_fields 6; compact format; info bits 32
 0: len 8; hex 8000000000041a0a; asc         ;;
 1: len 6; hex 00000c517024; asc    Qp$;;
 2: len 7; hex 40000001ac0a84; asc @      ;;
 3: len 30; hex 636f6d2e746f6461792e6170692e6f726465722e7363616c612e6576656e; asc com.today.api.order.scala.even; (total 54 bytes);
 4: len 30; hex 636f6d2e746f6461792e6170692e6f726465722e7363616c612e6576656e; asc com.today.api.order.scala.even; (total 476 bytes);
 5: len 4; hex 5b625460; asc [bT`;;

2018-08-02T08:46:24.760094+08:00 871635 [Note] InnoDB: *** WE ROLL BACK TRANSACTION (1)

解讀死鎖日志

死鎖日志里面記錄了兩個事務匿辩,事務1事務2榛丢,其中事務1最終被回滾了

  • 事務1

持有的鎖
事務1鎖住了5個對象铲球,持有10把鎖。執(zhí)行的sql語句為

DELETE FROM dp_common_event WHERE id in (268241,268242,268243,268810,268811)

等待的鎖
等待order_db.dp_common_event的主鍵的排他鎖(X鎖)

  • 事務2

持有的鎖
事務2鎖住了10個對象晰赞,持有6把鎖稼病,sql語句如下

INSERT INTO  dp_common_event set id=268244, event_type='com.today.api.order.scala.events.StoreOrderEndEventNew', event_binary=x'二進制數據(略)'

等待的鎖
lock_mode X locks gap before rec insert intention waiting
意思為事務2正在向表dp_common_event插入一行數據,在獲取意向插入鎖之前需要先獲取到當前表的一個排他鎖(LOCK_X)选侨。

查看發(fā)生死鎖時間上下文業(yè)務日志

//省略
08-02 08:46:24 684 dapeng-container-biz-pool-79 DEBUG [ac1e0002a068ab95] - SQL Preparing: INSERT INTO  dp_common_event set id=?, event_type=?, event_binary=? args: WrappedArray(JdbcValue(268812), JdbcValue(com.today.api.order.scala.events.CreateOrderEventNew), JdbcValue([B@255b9459))
08-02 08:46:24 688 dapeng-container-biz-pool-79 DEBUG [ac1e0002a068ab95] - SQL result: 1
// 省略中間業(yè)務代碼
08-02 08:46:24 758 dapeng-container-biz-pool-79 DEBUG [ac1e0002a068ab95] - SQL Preparing: INSERT INTO  dp_common_event set id=?, event_type=?, event_binary=? args: WrappedArray(JdbcValue(268244), JdbcValue(com.today.api.order.scala.events.StoreOrderEndEventNew), JdbcValue([B@3f796e10))
08-02 08:46:24 762 dapeng-container-biz-pool-79 DEBUG [ac1e0002a068ab95] - SQL result: 1

在一個事務中(根據死鎖日志,此事務為事務2)然走,我們先后向dp_common_event表插入了兩次數據援制,然后就在這時候發(fā)生了死鎖。

//第一條數據
 INSERT INTO  dp_common_event set id= 268812, event_type='com.today.api.order.scala.events.CreateOrderEventNew', event_binary= [B@255b9459);
//第二條數據
 INSERT INTO  dp_common_event set id= 268244, event_type='com.today.api.order.scala.events.StoreOrderEndEventNew', event_binary=[B@3f796e10)

與此同時芍瑞,事務1(發(fā)生死鎖后被回滾的一方)的操作如下:

DELETE FROM dp_common_event WHERE id in (268241,268242,268243,268810,268811)

查看表結構

CREATE TABLE `dp_common_event` (
  `id` bigint(20) NOT NULL COMMENT '事件id晨仑,全局唯一, 可用于冪等操作',
  `event_type` varchar(255) DEFAULT NULL COMMENT '事件類型',
  `event_binary` blob COMMENT '事件內容',
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  PRIMARY KEY (`id`),
  KEY `idx_dp_common_event` (`updated_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

可以看到,該表id字段為主鍵拆檬,update_at是普通索引洪己。

分析

時間線分析

通過比對,我們整理出事務1和事務2執(zhí)行的先后順序竟贯,如下圖:

時間線.png
t1 時刻

事務2dp_common_event表插入一條數據答捕,插入的數據id為268812,插入完成后屑那,此時事務2會持有鎖,鎖住的是一行記錄拱镐。lock_mode X locks rec but not gap代表鎖住的是一個索引,不是一個范圍齐莲。

t2 時刻

事務1開啟事務,并刪除 dp_common_event一部分數據痢站,使用的條件是in的形式,刪除的數據為(268241,268242,268243,268810,268811)选酗。
我們在本地模擬插入上述5條數據阵难,并使用desc分析這條刪除語句。

desc delete from dp_common_event where id in (268241,268242,268243,268810,268811);

結果如下圖:

desc.png
  • key欄為空,說明mysql并沒有走主鍵索引芒填,這是為什么呢呜叫?

原來,當mysql走索引查詢的數據占全表30%以上時殿衰,mysql就不會選擇走索引朱庆。由于dp_common_event表的數據量很少,使用 in 的模式并沒有走索引闷祥。因此這里沒有加行鎖娱颊。這里加的鎖就是Gap鎖。需要鎖住的是一個范圍凯砍。

本例中,gap鎖從左至右依次鎖住 268241 到 268811之間的每一條記錄,以及268811以上的所有的記錄箱硕。由于事務2中鎖住的記錄id268812,該條記錄的鎖被事務2悟衩。因此gap鎖當鎖到268812這條記錄時剧罩,會進行等待。等待巨鹿如下座泳。lock_mode X locks rec but not gap代表的意思是等待的是一條記錄而不是一個范圍惠昔。

t3 時刻

事務2繼續(xù)向下執(zhí)行幕与,插入第二條數據,id為268244镇防,由于268244這條記錄已經在事務1中被`gap鎖鎖啦鸣。因此,這時候事務2反過來要去等待事務1的gap鎖,而上一步事務1再等待事務2的記錄鎖来氧。這就造成了循環(huán)等待赏陵,出現死鎖。于是事務1回滾饲漾,事務2提交了。

t3時刻mysql錯誤日志日下

RECORD LOCKS space id 812 page no 3 n bits 80 index PRIMARY of table `order_db`.`dp_common_event` trx id 206663716 lock_mode X waiting
Record lock, heap no 10 PHYSICAL RECORD: n_fields 6; compact format; info bits 0

如何避免死鎖

首先,上述例子中缕溉,如果事務2的兩條插入語句的id是順序遞增的,那么再第二條語句插入時考传,它的id值不會被事務1的gap鎖鎖住,這樣也不會造成死鎖证鸥。

其次,如果事務2中每次往dp_common_event中只插入一條數據僚楞,也不會造成死鎖。

第三枉层,如果事務1中使用的時精確單條刪泉褐,以多條語句單獨刪的形式,那么就不會鎖住范圍鸟蜡,而是精確的鎖住每一行膜赃,這樣也不回出現死鎖。

總結揉忘,由于每次插入的id是通過一個分布式取號服務獲取的跳座,該取號服務會有兩個節(jié)點,兩個節(jié)點的id會有一個區(qū)間的差距泣矛,比如a節(jié)點目前取號的起始值為268241疲眷,那么b節(jié)點的起始值為268810。因此您朽,每次插入時不能嚴格保證id的絕對遞增狂丝。

因此,我們決定在刪除操作時哗总,精確到一行一行進行刪除几颜。

案例2

由于某次需要刪除線上的臟數據時,與生產的業(yè)務相沖出現了死鎖,如下日志顯示魂奥。

08-05 18:55:56 582 dapeng-container-biz-pool-1 ERROR [ac190004bcca51e5] - 
Deadlock found when trying to get lock; try restarting transaction
com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: 
Deadlock found when trying to get lock; try restarting transaction
         // 省略部分
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:400) ~[mysql-connector-java-5.1.36.jar:5.1.36]
        at com.mysql.jdbc.Util.getInstance(Util.java:383) ~[mysql-connector-java-5.1.36.jar:5.1.36]
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987) ~[mysql-connector-java-5.1.36.jar:5.1.36]
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3847) ~[mysql-connector-java-5.1.36.jar:5.1.36]
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3783) ~[mysql-connector-java-5.1.36.jar:5.1.36]
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2447) ~[mysql-connector-java-5.1.36.jar:5.1.36]
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2594) ~[mysql-connector-java-5.1.36.jar:5.1.36]
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2545) ~[mysql-connector-java-5.1.36.jar:5.1.36]
         //省略部分
        at wangzx.scala_commons.sql.RichDataSource.$anonfun$generateKey$1(RichDataSource.scala:30) ~[scala-sql_2.12-2.0.6.jar:2.0.6]
        at wangzx.scala_commons.sql.RichDataSource.withConnection(RichDataSource.scala:12) ~[scala-sql_2.12-2.0.6.jar:2.0.6]
        at wangzx.scala_commons.sql.RichDataSource.generateKey(RichDataSource.scala:30) ~[scala-sql_2.12-2.0.6.jar:2.0.6]
        at com.today.service.order_new.sql.OrderSql$.createOrderDetail(OrderSql.scala:80) ~[order_service_2.12-0.2.0-SNAPSHOT.jar:0.2.0-SNAPSHOT]
        at com.today.service.order_new.action.CreateOrderAction.$anonfun$action$1(CreateOrderAction.scala:53) [order_service_2.12-0.2.0-SNAPSHOT.jar:0.2.0-SNAPSHOT]
        at com.today.service.order_new.action.CreateOrderAction.$anonfun$action$1$adapted(CreateOrderAction.scala:53) [order_service_2.12-0.2.0-SNAPSHOT.jar:0.2.0-SNAPSHOT]
        at scala.collection.immutable.List.foreach(List.scala:389) ~[scala-library.jar:na]
        at com.today.service.order_new.action.CreateOrderAction.action(CreateOrderAction.scala:53) [order_service_2.12-0.2.0-SNAPSHOT.jar:0.2.0-SNAPSHOT]
        at com.today.service.order_new.action.CreateOrderAction.action(CreateOrderAction.scala:24) [order_service_2.12-0.2.0-SNAPSHOT.jar:0.2.0-SNAPSHOT]
        at com.today.service.commons.Action.execute(Action.scala:15) [service-commons_2.12-1.5-SNAPSHOT.jar:1.5-SNAPSHOT]
        at com.today.service.commons.Action.execute$(Action.scala:10) [service-commons_2.12-1.5-SNAPSHOT.jar:1.5-SNAPSHOT]
        at com.today.service.order_new.action.CreateOrderAction.execute(CreateOrderAction.scala:24) [order_service_2.12-0.2.0-SNAPSHOT.jar:0.2.0-SNAPSHOT]
        at com.today.service.order_new.OrderService2Impl.createOrder(OrderService2Impl.scala:45) [order_service_2.12-0.2.0-SNAPSHOT.jar:0.2.0-SNAPSHOT]

死鎖日志

*** (1) TRANSACTION:

TRANSACTION 216689660, ACTIVE 27 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 4 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2
MySQL thread id 995341, OS thread handle 140243168642816, query id 539333372 192.168.10.131 today_user update
INSERT INTO `order_detail` SET
            id = 379373,
            order_no = '11600202533466529666',
            detail_seq = 1,
            sku_no='20507572',
            sku_name='海氏海諾創(chuàng)可貼',
            sku_version=0,
            barcode='',
            coupon_id=0,
            sku_count=1,
            sku_selling_price=7.0,
            discount_amount = 0.0,
            remark = '',
            created_at = now(),
            created_by = 1,
            updated_at = now(),
            updated_by=1
         ,promotion_id = 0
2018-08-05T18:55:56.524630+08:00 995779 [Note] InnoDB: *** (1) WAITING FOR THIS LOCK TO BE GRANTED:

RECORD LOCKS space id 1045 page no 6219 n bits 440 index idx_order_detail of table `order_db`.`order_detail` trx id 216689660 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
 0: len 20; hex 3131363030353031353333303531333137333333; asc 11600501533051317333;;
 1: len 8; hex 8000000000032b87; asc       + ;;

2018-08-05T18:55:56.524779+08:00 995779 [Note] InnoDB: *** (2) TRANSACTION:

TRANSACTION 216688923, ACTIVE 49 sec fetching rows, thread declared inside InnoDB 1251
mysql tables in use 2, locked 2
1653 lock struct(s), heap size 172240, 160498 row lock(s), undo log entries 43
MySQL thread id 995779, OS thread handle 140243732473600, query id 539339615 localhost root Sending data
delete from orders where order_no in (
select a.order_no from (
select order_no from orders where  finish_time between '2018-07-01 00:00:00' and '2018-07-31 00:00:00' and store_id  in ('11866600','11888700','10008000','11866601','10009000','11703083','10003502','11608093','10004102','10010100', 
'11699800','11888900') ) as a
)
2018-08-05T18:55:56.524820+08:00 995779 [Note] InnoDB: *** (2) HOLDS THE LOCK(S):

RECORD LOCKS space id 1045 page no 6219 n bits 440 index idx_order_detail of table `order_db`.`order_detail` trx id 216688923 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

Record lock, heap no 2 PHYSICAL RECORD: n_fields 2; compact format; info bits 32
 0: len 20; hex 3131363030353031353333303531333137333333; asc 11600501533051317333;;
 1: len 8; hex 8000000000032b87; asc       + ;;

2018-08-05T18:55:56.524993+08:00 995779 [Note] InnoDB: *** (2) WAITING FOR THIS LOCK TO BE GRANTED:

RECORD LOCKS space id 817 page no 2397 n bits 184 index PRIMARY of table `order_db`.`orders` trx id 216688923 lock mode S waiting
Record lock, heap no 106 PHYSICAL RECORD: n_fields 26; compact format; info bits 0
 0: len 8; hex 8000000000032336; asc       #6;;
 1: len 6; hex 00000cea6bfc; asc     k ;;
 2: len 7; hex aa000001430110; asc     C  ;;
 3: len 20; hex 3131363030323032353333343636353239363636; asc 11600202533466529666;;
 4: len 2; hex 8001; asc   ;;
 5: len 4; hex 80000001; asc     ;;
 6: len 5; hex 8000070000; asc      ;;
 7: len 5; hex 8000070000; asc      ;;
 8: len 8; hex 8000000000000002; asc         ;;
 9: len 4; hex 80b1014a; asc    J;;
 10: len 8; hex 8000000000000000; asc         ;;
 11: len 5; hex 8000000000; asc      ;;
 12: len 5; hex 8000000000; asc      ;;
 13: len 5; hex 8000000000; asc      ;;
 14: len 2; hex 8000; asc   ;;
 15: SQL NULL;
 16: SQL NULL;
 17: len 5; hex 99a08b2dde; asc    - ;;
 18: len 0; hex ; asc ;;
 19: len 0; hex ; asc ;;
 20: SQL NULL;
 21: len 4; hex 81e24944; asc   ID;;
 22: len 5; hex 99a08b2ddd; asc    - ;;
 23: len 4; hex 80000001; asc     ;;
 24: len 4; hex 5b66d7a1; asc [f  ;;
 25: len 4; hex 80000001; asc     ;;

2018-08-05T18:55:56.525617+08:00 995779 [Note] InnoDB: *** WE ROLL BACK TRANSACTION (1)

分析死鎖日志

主要是事務1 insert操作時在插入order_detail表時菠剩,需要獲取插入意向鎖之前,需要獲取一個gap x鎖耻煤。

事務2在刪除數據時具壮,需要獲取一個 S鎖准颓,共享鎖。orders表的棺妓。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末攘已,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子怜跑,更是在濱河造成了極大的恐慌样勃,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件性芬,死亡現場離奇詭異峡眶,居然都是意外死亡,警方通過查閱死者的電腦和手機植锉,發(fā)現死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門辫樱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人俊庇,你說我怎么就攤上這事狮暑。” “怎么了辉饱?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵搬男,是天一觀的道長。 經常有香客問我彭沼,道長缔逛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任溜腐,我火速辦了婚禮译株,結果婚禮上,老公的妹妹穿的比我還像新娘挺益。我一直安慰自己歉糜,他們只是感情好,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布望众。 她就那樣靜靜地躺著匪补,像睡著了一般。 火紅的嫁衣襯著肌膚如雪烂翰。 梳的紋絲不亂的頭發(fā)上夯缺,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天,我揣著相機與錄音甘耿,去河邊找鬼踊兜。 笑死,一個胖子當著我的面吹牛佳恬,可吹牛的內容都是我干的捏境。 我是一名探鬼主播于游,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼垫言!你這毒婦竟也來了贰剥?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤筷频,失蹤者是張志新(化名)和其女友劉穎蚌成,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體凛捏,經...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡担忧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了坯癣。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涵妥。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖坡锡,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情窒所,我是刑警寧澤鹉勒,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站吵取,受9級特大地震影響禽额,放射性物質發(fā)生泄漏。R本人自食惡果不足惜皮官,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一脯倒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捺氢,春花似錦藻丢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至馍佑,卻和暖如春斋否,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拭荤。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工茵臭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人舅世。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓旦委,卻偏偏與公主長得像奇徒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子社证,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內容