#死锁分析与解决 ##事务并发执行node
##事务持锁 MySQL数据库是以行加锁的方式,避免不一样事务,对同一行数据库进行同时修改的。首先来看事务一,对张三这条记录的Account字段进行修改,须要持有张三这条数据库的行锁。而后事务二也同时并发执行,事务二首先修改李四这条数据库记录的Corp字段,持有李四这条数据库的行锁。
此时两个事务各持有一个行锁,可是接下来事务一要持有事务二的行锁,事务二要持有事务一的行锁。这样就造成了事务一与事务二相互等待,致使两个事务都没法继续执行下去。数据库
##死锁 死锁:指两个或者两个以上的事务,在执行过程当中,因争夺锁资源而形成的一种互相等待的现象。并发
死锁必须是两个或者两个以上的事务,单个事务不可能发生死锁。死锁是由于争夺锁资源,致使相互持有锁资源,致使相互等待。须要外部干涉的现象。dom
##死锁产生的必要条件ide
##MySQL中的锁 排它锁咱们用X来表示,共享锁咱们用S来表示。所谓排它锁,就是和任何的锁相互冲突,若是一个事务添加了排它锁,无论其余事务添加任何的锁,都必需要等待这个事务。所谓共享锁是指,多个事务能够共享一把锁,多个锁能够兼容,也就是说,事务一获取共享锁的状况下,事务二仍是要加共享锁,则能够直接获取无需等待。若是事务二须要添加一个排它锁,则必需要等待。 oop
##加锁方式性能
SELECT * FROM table LOCK IN SHARE MODE
SELECT * FROM table FOR UPDATE
##哪些SQL须要持有锁 在MySQL数据库中,全部的SELECT读版本控制
Innodb
实现了多版本控制(MVCC),支持不加锁快照读。SELECT * FROM table WHERE...
须要持锁的SQL语句code
SELECT * FROM table LOCK IN SHARE MODE
SELECT * FROM table FOR UPDATE
UPDATE FROM table SET ...
INSERT INTO...
DELETE FROM table...
增删改的加锁与内部的隔离级别息息相关,咱们是不容许出现幻读的现象,有可能会加一些间隙锁,避免出现幻读的现象。##SQL加锁分析 UPDATE user SET account=0 WHERE id = 1
语句,直接在行记录进行加排他锁,因为快照读的缘由此时SELECT操做是不会被阻塞的,若是是SELECT FOR UPDATE或者是SELECT IN SHARE MODE,都是会被阻塞的。orm
SELECT userName FROM user WHERE id=1 IN SHARE MODE
对行记录添加的是共享锁,此时,若是其余事务要执行SELECT IN SHARE MODE的话,对同一行记录仍是能够进行执行的。若是外部其余事务要执行SELECT FOR UPDATE的话,则必定会被阻塞。
##分析死锁的经常使用办法 MySQL数据库会自动分析死锁,并强制回滚代价最小的事务,不须要开发人员去关心。死锁的解除MySQL会自动帮助咱们去作。可是咱们须要在死锁解除之后,分析死锁产生的SQL语句,避免死锁再次产生。以下方法捕获死锁的SQL语句。
MySQL命令:
show engine innodb status
执行完毕之后,会有一大段内容出现其中,标红部分是关于死锁的,列出了发生死锁时两个等待的SQL语句,而后列出了系统强制回滚的是哪一个事务,知道了这些SQL语句,能够分析SQL语句的加锁方式,来调整SQL语句的顺序,改变SQL语句保证按顺序获取锁资源,这样就能够有效的避免死锁的产生。
#附件 ##本身在MySQL数据库当中,执行
show engine innodb status
获得的结果
| InnoDB | | ===================================== 2016-10-08 22:04:17 0x7f61915e0700 INNODB MONITOR OUTPUT ===================================== Per second averages calculated from the last 45 seconds ----------------- BACKGROUND THREAD ----------------- srv_master_thread loops: 41 srv_active, 0 srv_shutdown, 12620 srv_idle srv_master_thread log flush and writes: 12661 ---------- SEMAPHORES ---------- OS WAIT ARRAY INFO: reservation count 73 OS WAIT ARRAY INFO: signal count 57 RW-shared spins 0, rounds 93, OS waits 45 RW-excl spins 0, rounds 0, OS waits 0 RW-sx spins 0, rounds 0, OS waits 0 Spin rounds per wait: 93.00 RW-shared, 0.00 RW-excl, 0.00 RW-sx ------------ TRANSACTIONS ------------ Trx id counter 12583 Purge done for trx's n:o < 12583 undo n:o < 0 state: running but idle History list length 174 LIST OF TRANSACTIONS FOR EACH SESSION: ---TRANSACTION 421532535461264, not started 0 lock struct(s), heap size 1136, 0 row lock(s) ---TRANSACTION 421532535460352, not started 0 lock struct(s), heap size 1136, 0 row lock(s) ---TRANSACTION 421532535459440, not started 0 lock struct(s), heap size 1136, 0 row lock(s) ---TRANSACTION 421532535458528, not started 0 lock struct(s), heap size 1136, 0 row lock(s) ---TRANSACTION 421532535457616, not started 0 lock struct(s), heap size 1136, 0 row lock(s) -------- FILE I/O -------- I/O thread 0 state: waiting for completed aio requests (insert buffer thread) I/O thread 1 state: waiting for completed aio requests (log thread) I/O thread 2 state: waiting for completed aio requests (read thread) I/O thread 3 state: waiting for completed aio requests (read thread) I/O thread 4 state: waiting for completed aio requests (read thread) I/O thread 5 state: waiting for completed aio requests (read thread) I/O thread 6 state: waiting for completed aio requests (write thread) I/O thread 7 state: waiting for completed aio requests (write thread) I/O thread 8 state: waiting for completed aio requests (write thread) I/O thread 9 state: waiting for completed aio requests (write thread) Pending normal aio reads: [0, 0, 0, 0] , aio writes: [0, 0, 0, 0] , ibuf aio reads:, log i/o's:, sync i/o's: Pending flushes (fsync) log: 0; buffer pool: 0 373 OS file reads, 290 OS file writes, 181 OS fsyncs 0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s ------------------------------------- INSERT BUFFER AND ADAPTIVE HASH INDEX ------------------------------------- Ibuf: size 1, free list len 0, seg size 2, 0 merges merged operations: insert 0, delete mark 0, delete 0 discarded operations: insert 0, delete mark 0, delete 0 Hash table size 34673, node heap has 0 buffer(s) Hash table size 34673, node heap has 0 buffer(s) Hash table size 34673, node heap has 0 buffer(s) Hash table size 34673, node heap has 0 buffer(s) Hash table size 34673, node heap has 0 buffer(s) Hash table size 34673, node heap has 0 buffer(s) Hash table size 34673, node heap has 0 buffer(s) Hash table size 34673, node heap has 0 buffer(s) 0.00 hash searches/s, 0.00 non-hash searches/s --- LOG --- Log sequence number 3162168 Log flushed up to 3162168 Pages flushed up to 3162168 Last checkpoint at 3162159 0 pending log flushes, 0 pending chkp writes 118 log i/o's done, 0.00 log i/o's/second ---------------------- BUFFER POOL AND MEMORY ---------------------- Total large memory allocated 137428992 Dictionary memory allocated 317905 Buffer pool size 8191 Free buffers 7813 Database pages 378 Old database pages 0 Modified db pages 0 Pending reads 0 Pending writes: LRU 0, flush list 0, single page 0 Pages made young 0, not young 0 0.00 youngs/s, 0.00 non-youngs/s Pages read 343, created 35, written 143 0.00 reads/s, 0.00 creates/s, 0.00 writes/s No buffer pool page gets since the last printout Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s LRU len: 378, unzip_LRU len: 0 I/O sum[0]:cur[0], unzip sum[0]:cur[0] -------------- ROW OPERATIONS -------------- 0 queries inside InnoDB, 0 queries in queue 0 read views open inside InnoDB Process ID=2247, Main thread ID=140057180620544, state: sleeping Number of rows inserted 175, updated 14, deleted 3, read 356 0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s ---------------------------- END OF INNODB MONITOR OUTPUT ============================