找个mysql客户端,执行show engine innodb status获得以下结果:css

详细信息以下:html
**************************************node
=====================================
2016-09-20 16:39:40 0x7f8040116700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 26 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 6928 srv_active, 0 srv_shutdown, 1725110 srv_idle
srv_master_thread log flush and writes: 1732038
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 11501
OS WAIT ARRAY INFO: signal count 14653
RW-shared spins 0, rounds 28035, OS waits 9399
RW-excl spins 0, rounds 153048, OS waits 986
RW-sx spins 2611, rounds 47408, OS waits 573
Spin rounds per wait: 28035.00 RW-shared, 153048.00 RW-excl, 18.16 RW-sx
------------------------
LATEST DETECTED DEADLOCK
------------------------
2016-09-20 16:24:30 0x7f801efe6700
*** (1) TRANSACTION:
TRANSACTION 3348053, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 10713, OS thread handle 140188808488704, query id 4311670 10.118.63.64 root update
INSERT INTO tt_rps_flight_mainline_info_init (
plan_send_batch_dt,
require_id,
line_id,
line_code,
conveyance_type,
src_zone_code,
depart_batch_code,
dest_zone_code,
plan_distribute_batch_dt,
plan_distribute_batch_code,
load_weight,
load_qty,
load_vol,
create_tm
)
VALUES ('2016-09-09','10000047160909',10000047,'010X020R1600',2,'010X','010X1400','020X','2016-09-09','020X2000',800.0,298,7.0,'2016-09-20') ON DUPLICATE KEY UPDATE
require_id ='10000047160909'
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1668 page no 4 n bits 96 index require_id of table `omcssit`.`tt_rps_flight_mainline_info_init` trx id 3348053 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 12 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 14; hex 3130303030303438313630393137; asc 10000048160917;;
1: len 4; hex 80000031; asc 1;;mysql
*** (2) TRANSACTION:
TRANSACTION 3348048, ACTIVE 0 sec updating or deleting
mysql tables in use 1, locked 1
7 lock struct(s), heap size 1136, 7 row lock(s), undo log entries 1
MySQL thread id 10710, OS thread handle 140188252530432, query id 4311629 10.118.63.64 root update
INSERT INTO tt_rps_flight_mainline_info_init (
plan_send_batch_dt,
require_id,
line_id,
line_code,
conveyance_type,
src_zone_code,
depart_batch_code,
dest_zone_code,
plan_distribute_batch_dt,
plan_distribute_batch_code,
load_weight,
load_qty,
load_vol,
create_tm
)
VALUES ('2016-09-23','10000047160923',10000047,'010X020R1600',2,'010X','010X1400','020X','2016-09-23','020X2000',800.0,298,7.0,'2016-09-20') ON DUPLICATE KEY UPDATE
require_id ='10000047160923'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 1668 page no 4 n bits 96 index require_id of table `omcssit`.`tt_rps_flight_mainline_info_init` trx id 3348048 lock_mode X locks gap before rec
Record lock, heap no 12 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 14; hex 3130303030303438313630393137; asc 10000048160917;;
1: len 4; hex 80000031; asc 1;;linux
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1668 page no 4 n bits 96 index require_id of table `omcssit`.`tt_rps_flight_mainline_info_init` trx id 3348048 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 12 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 14; hex 3130303030303438313630393137; asc 10000048160917;;
1: len 4; hex 80000031; asc 1;;算法
*** WE ROLL BACK TRANSACTION (1)
------------
TRANSACTIONS
------------
Trx id counter 3348415
Purge done for trx's n:o < 3348405 undo n:o < 0 state: running but idle
History list length 1152
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421667018339760, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018330640, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018327904, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018335200, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018320608, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018319696, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018322432, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018329728, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018321520, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018324256, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018323344, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018345232, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018334288, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018346144, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018343408, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018342496, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018340672, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018337024, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018333376, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018326080, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018337936, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018336112, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018331552, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018338848, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018326992, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018325168, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018332464, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421667018328816, 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
9681 OS file reads, 106275 OS file writes, 66325 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 0.88 writes/s, 0.00 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 218, seg size 220, 1 merges
merged operations:
insert 26, delete mark 0, delete 0
discarded operations:
insert 0, delete mark 0, delete 0
Hash table size 553193, node heap has 4 buffer(s)
Hash table size 553193, node heap has 38 buffer(s)
Hash table size 553193, node heap has 4 buffer(s)
Hash table size 553193, node heap has 38 buffer(s)
Hash table size 553193, node heap has 5 buffer(s)
Hash table size 553193, node heap has 15 buffer(s)
Hash table size 553193, node heap has 18 buffer(s)
Hash table size 553193, node heap has 14 buffer(s)
0.00 hash searches/s, 0.00 non-hash searches/s
---
LOG
---
Log sequence number 11294369115
Log flushed up to 11294369115
Pages flushed up to 11294369115
Last checkpoint at 11294369106
0 pending log flushes, 0 pending chkp writes
35039 log i/o's done, 0.00 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 2198863872
Dictionary memory allocated 4350175
Buffer pool size 131056
Free buffers 117742
Database pages 13178
Old database pages 4702
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 11, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 9524, created 3654, written 56445
0.00 reads/s, 0.00 creates/s, 0.88 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 13178, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
----------------------
INDIVIDUAL BUFFER POOL INFO
----------------------
---BUFFER POOL 0
Buffer pool size 16382
Free buffers 14669
Database pages 1693
Old database pages 604
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 1283, created 410, written 9934
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: 1693, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
---BUFFER POOL 1
Buffer pool size 16382
Free buffers 14875
Database pages 1487
Old database pages 528
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 1061, created 426, written 2942
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 1487, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
---BUFFER POOL 2
Buffer pool size 16382
Free buffers 14830
Database pages 1537
Old database pages 548
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 3, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 988, created 549, written 2304
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: 1537, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
---BUFFER POOL 3
Buffer pool size 16382
Free buffers 14661
Database pages 1705
Old database pages 610
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 2, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 1228, created 477, written 7440
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 1705, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
---BUFFER POOL 4
Buffer pool size 16382
Free buffers 14615
Database pages 1751
Old database pages 626
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 1310, created 441, written 7277
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 1751, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
---BUFFER POOL 5
Buffer pool size 16382
Free buffers 14653
Database pages 1716
Old database pages 613
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 1240, created 476, written 16534
0.00 reads/s, 0.00 creates/s, 0.88 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 1716, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
---BUFFER POOL 6
Buffer pool size 16382
Free buffers 14754
Database pages 1609
Old database pages 573
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 6, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 1158, created 451, written 5331
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: 1609, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
---BUFFER POOL 7
Buffer pool size 16382
Free buffers 14685
Database pages 1680
Old database pages 600
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 1256, created 424, written 4683
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: 1680, 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=51314, Main thread ID=140188844484352, state: sleeping
Number of rows inserted 353558, updated 150693, deleted 10356, read 720801965
4.23 inserts/s, 0.00 updates/s, 0.00 deletes/s, 42.69 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================sql
**************************************数据库
innodb存储引擎在show engine innodb status(老版本对应的是show innodb status)输出中,显示除了大量的内部信息,它输出就是一个单独的字符串,没有行和列,内容分为不少小段,每一段对应innodb存储引擎不一样部分的信息,其中有一些信息对于innodb开发者来讲很是有用,可是,许多信息,若是你尝试去理解,而且应用到高性能innodb调优的时候,你会发现它们很是有趣,甚至是很是有必要的。数组
输出内容中包含了一些平均值的统计信息,这些平均值是自上次输出结果生成以来的统计数,所以,若是你正在检查这些值,那就要确保已经等待了至少30s的时间,使两次采样之间的积累足够长的统计时间并屡次采样,检查计数器变化从而弄清其行为,并非全部的输出都会在一个时间点上生成,于是也不是全部的显示出来的平均值会在同一时间间隔里从新再计算。并且,innodb有一个内部复位间隔,而它是不可预知的,各个版本也不同。
这些输出信息足够提供给手工计算出大多数你想要的统计信息,有一款监控工具innotop能够帮你计算出增量差值和平均值。下面,在你的mysql命令行敲下show engine innodb status;看着输出跟着下面的步骤一步一步理解输出信息是什么含义:
注意:如下使用mysql5.5.24版本作解读,mysql5.6.x和5.7.x输出内容有些地方有调整。
1.第一段是头部信息,它仅仅声明了输出的开始,其内容包括当前的日期和时间,以及自上次输出以来通过的时长。
=====================================
160129 12:07:26 INNODB MONITOR OUTPUT
#第二行是当前日期和时间
=====================================
Per second averages calculated from the last 24 seconds
#第四行显示的是计算出这一平均值的时间间隔,即自上次输出以来的时间,或者是距上次内部复位的时长
2.从
innodb1.0.x开始,可使用命令show engine innodb status;来查看master thread的状态信息:
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 30977173 1_second, 30975685 sleeps, 3090359 10_second, 166112 background, 165988 flush
#这行显示主循环进行了30977173 1_second次,每秒挂起的操做进行了30975685 sleeps次(说明负载不是很大),10秒一次的活动进行了3090359 10_second次,1秒循环和10秒循环比值符合1:10,backgroup loop进行了166112 background次,flush loop进行了165988 flush次,若是在一台很大压力的mysql上,可能看到每秒运行次数和挂起次数比例小于1不少,这是由于innodb对内部进行了一些优化,当压力大时间隔时间并不老是等待1秒,所以,不能认为每秒循环和挂起的值老是相等,在某些状况下,能够经过二者之间的差值来比较反映当前数据库的负载压力。
srv_master_thread log flush and writes: 31160103
3.若是有高并发的工做负载,你就要关注下接下来的段(SEMAPHORES信号量),它包含了两种数据:事件计数器以及可选的当前等待线程的列表,若是有性能上的瓶颈,可使用这些信息来找出瓶颈,不幸的是,想知道怎么使用这些信息仍是有一点复杂,下面先给出一些解释:
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 68581015, signal count 218437328
--Thread 140653057947392 has waited at btr0pcur.c line 437 for 0.00 seconds the semaphore:
S-lock on RW-latch at 0x7ff536c7d3c0 created in file buf0buf.c line 916
a writer (thread id 140653057947392) has reserved it in mode exclusive
number of readers 0, waiters flag 1, lock_word: 0
Last time read locked in file row0sel.c line 3097
Last time write locked in file /usr/local/src/soft/mysql-5.5.24/storage/innobase/buf/buf0buf.c line 3151
--Thread 140653677291264 has waited at btr0pcur.c line 437 for 0.00 seconds the semaphore:
S-lock on RW-latch at 0x7ff53945b240 created in file buf0buf.c line 916
a writer (thread id 140653677291264) has reserved it in mode exclusive
number of readers 0, waiters flag 1, lock_word: 0
Last time read locked in file row0sel.c line 3097
Last time write locked in file /usr/local/src/soft/mysql-5.5.24/storage/innobase/buf/buf0buf.c line 3151
Mutex spin waits 1157217380, rounds 1783981614, OS waits 10610359
RW-shared spins 103830012, rounds 1982690277, OS waits 52051891
RW-excl spins 43730722, rounds 602114981, OS waits 3495769
Spin rounds per wait: 1.54 mutex, 19.10 RW-shared, 13.77 RW-excl
内容比较多,下面分段依次解释:
3.1.
OS WAIT ARRAY INFO: reservation count 68581015, signal count 218437328
#这行给出了关于操做系统等待数组的信息,它是一个插槽数组,innodb在数组里为信号量保留了一些插槽,操做系统用这些信号量给线程发送信号,使线程能够继续运行,以完成它们等着作的事情,这一行还显示出innodb使用了多少次操做系统的等待:保留统计(reservation count)显示了innodb分配插槽的频度,而信号
计数(signal count)衡量的是线程经过数组获得信号的频度,操做系统的等待相对于空转等待(spin wait)要昂贵些。
3.2.
--Thread 140653057947392 has waited at btr0pcur.c line 437 for 0.00 seconds the semaphore:
S-lock on RW-latch at 0x7ff536c7d3c0 created in file buf0buf.c line 916
a writer (thread id 140653057947392) has reserved it in mode exclusive
number of readers 0, waiters flag 1, lock_word: 0
Last time read locked in file row0sel.c line 3097
Last time write locked in file /usr/local/src/soft/mysql-5.5.24/storage/innobase/buf/buf0buf.c line 3151
--Thread 140653677291264 has waited at btr0pcur.c line 437 for 0.00 seconds the semaphore:
S-lock on RW-latch at 0x7ff53945b240 created in file buf0buf.c line 916
a writer (thread id 140653677291264) has reserved it in mode exclusive
number of readers 0, waiters flag 1, lock_word: 0
Last time read locked in file row0sel.c line 3097
Last time write locked in file /usr/local/src/soft/mysql-5.5.24/storage/innobase/buf/buf0buf.c line 3151
这部分显示的是当前正在等待互斥量的innodb线程,在这里能够看到有两个线程正在等待,每个都是以--Thread <数字> has waited...开始,这一段内容在正常状况下应该是空的(即查看的时候没有这部份内容),除非服务器运行着高并发的工做负载,促使innodb采起让操做系统等待的措施,除非你对innodb源码熟悉,不然这里看到的最有用的信息就是发生线程等待的代码文件名 /usr/local/src/soft/mysql-5.5.24/storage/innobase/buf/buf0buf.c line 3151。
在innodb内部哪里才是热点?举例来讲,若是看到许多线程都在一个名为buf0buf.c的文件上等待,那就意味着你的系统里存在着
缓冲池竞争,这个输出信息还显示了这些线程等待了多少时间,其中waiters flag显示了有多少个等待着正在等待同一个互斥量。 若是waiters flag为0那就表示没有线程在等待同一个互斥量(此时在waiters flag 0后面可能能够看到wait is ending,表示这个互斥量已经被释放了,但操做系统尚未把线程调度过来运行)。
你可能想知道innodb真正等待的是什么,innodb使用了互斥量和信号量来保护代码的临界区,如:限定每次只能有一个线程进入临界区,或者是当有活动的读时,就限制写入等。在innodb代码里有不少临界区,在合适的条件下,它们均可能出如今那里,经常能见到的一种情形是:获取缓冲池分页的访问权的时候。
3.3.
在等待线程以后的部分信息以下,这部分显示了更多的事件计数器,在每个情形中,都能看到innodb依靠操做系统等待的频度:
Mutex spin waits 1157217380, rounds 1783981614, OS waits 10610359
#这行显示的是跟互斥量相关的几个计数器
RW-shared spins 103830012, rounds 1982690277, OS waits 52051891
#这行显示读写的共享锁的计数器
RW-excl spins 43730722, rounds 602114981, OS waits 3495769
#这行显示读写的排他锁的计数器
Spin rounds per wait: 1.54 mutex, 19.10 RW-shared, 13.77 RW-excl
innodb有着一个多阶段等待的策略,首先,它会试着对锁进行空转等待,若是经历了一个预设的空转等待周期(设置innodb_sync_spin_loops配置变量命令)以后尚未成功,那就会退到更昂贵更复杂的等待数组中。
空转等待的成本相对较低,可是它们要不停地检查一个资源可否被锁定,这种方式会消耗CPU周期,可是,这没有听起来那么糟糕,由于当处理器在等待IO时,通常都有一些空闲的CPU周期可用,即便是没有空闲的CPU周期,空等也要比其余方式更加廉价一些。然而,当另一个线程能作一些事情的时候,空转等待也还会把CPU独占着。
空转等待的替代方案就是让操做系统作上下文切换,这样,当一个线程在等待时,另一个线程就能够被运行,而后,经过等待数组里的信号量发出信号,唤醒那个沉睡的线程,经过信号量来发送信号是比较有效的,可是上下文切换就很昂贵,这很快就会聚沙成塔,每秒钟几千次的切换会引起大量的系统开销。
你能够经过修改innodb_sync_spin_loops的值,试着在空转等待与操做系统等待之间达成平衡,不要担忧空转等待,除非你在一秒里看到几十万个空转等待。此时,你能够考虑performance_schema库或者show engine innodb mutex;查看下相关信息。
4.下面这一段外键错误的信息通常不会出现,除非你服务器上发生了外键错误,有时问题在于事务在插入,更新或删除一条记录时要寻找父表或子表,还有时候是当innodb尝试增长或删除一个外键或者修改一个已经存在的外键时,发现表之间类型不匹配,这部分输出对于调试与innodb不明确的外键错误发生的准确缘由很是有帮助,下面搞一个示例来看看:
4.1 建立父表:
mysql> create table parent(parent_id int not null,primary key(parent_id)) engine=innodb;
4.2 建立子表:
mysql> create table child(child_id int not null,key child_id(child_id),constraint i_child foreign key(child_id) references parent(parent_id)) engine=innodb;
4.3 插入数据:
mysql> insert into parent(parent_id) values(1);
mysql> insert into child(child_id) values(1);
4.5 有两种基本的外键错误:
第一种:以某种可能违反外键约束关系的方法增长,更新,删除数据,将致使第一类错误,如,在父表中删除行时发生以下错误:
mysql> delete from parent;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`xiaoboluo`.`child`, CONSTRAINT `i_child` FOREIGN KEY (`child_id`) REFERENCES `parent` (`parent_id`))
错误信息至关明了,对全部由增长,删除,更新不匹配的行致使的错误都会看到类似的信息,下面是show engine innodb status的输出:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
160128 1:17:06 Transaction:
#这行显示了最近一次外键错误的日期和时间
TRANSACTION D203D6, ACTIVE 0 sec updating or deleting
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
MySQL thread id 20027, OS thread handle 0x7f0a4c0f8700, query id 1813996 localhost root updating
delete from parent
Foreign key constraint fails for table `xiaoboluo`.`child`:
,
#上面部分显示了关于破坏外键约束的事务详情。后边部分显示了发现错误时innodb正尝试修改的准确数据,输出中有许可能是转换成可打印格式的行数据。
CONSTRAINT `i_child` FOREIGN KEY (`child_id`) REFERENCES `parent` (`parent_id`)
Trying to delete or update in parent table, in index `PRIMARY` tuple:
DATA TUPLE: 3 fields;
0: len 4; hex 80000001; asc ;;
1: len 6; hex 000000d203d6; asc ;;
2: len 7; hex 1e000001ca0110; asc ;;
But in child table `xiaoboluo`.`child`, in index `child_id`, there is a record:
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 80000001; asc ;;
1: len 6; hex 000013a99b3e; asc >;;
4.6 第二种:尝试修改父表的表结构时发生的错误,这种错误就没有那么清楚了,这可能会让调试更困难:
mysql> alter table parent modify parent_id int unsigned not null;
ERROR 1025 (HY000): Error on rename of './xiaoboluo/#sql-b695_4e3b' to './xiaoboluo/parent' (errno: 150)
查看show engine innodb status输出信息:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
160128 1:32:33 Error in foreign key constraint of table xiaoboluo/child:
there is no index in referenced table which would contain
the columns as the first columns, or the data types in the
referenced table do not match the ones in table. Constraint:
,
CONSTRAINT "i_child" FOREIGN KEY ("child_id") REFERENCES "parent" ("parent_id")
The index in the foreign key in table is "child_id"
for correct foreign key definition.
InnoDB: Renaming table `xiaoboluo`.<result 2 when explaining filename '#sql-b695_4e3b'> to `xiaoboluo`.`parent` failed!
上面的错误是数据类型不匹配,外键列必须有彻底相同的数据类型,包括任何的修饰符(如这里父表多加了一个unsigned,这也是问题所在),当看到1025错误并不理解为何时,最好查看下innodb status。在每次看到有新错误时,外键错误信息都会被重写,percona toolkit中的pt-fk-error-logger工具能够用表保存这些信息以供后续分析。
5.与外键错误同样,这部分只有当服务器产生死锁时才会出现,死锁信息一样在每次有新的死锁错误时被重写,percona toolkit中的pt-deadlock-logger工具能够用表保存这些信息以供后续分析
死锁在等待关系图里是一个循环,就是一个锁定了行的数据结构又在等待别的锁,这个循环能够任意地大,innodb会当即检测到死锁,由于每当有事务等待行锁的时候,它都会去检查等待关系图里是否有循环,死锁的状况可能会比较复杂,可是,这一部分只显示了最近的两个死锁的状况,它们在各自的事务里执行的最后一条语句,以及它们在等待关系图里造成环锁的信息。在这个循环里你看不到其余事务,也可能看不到在事务里早先真正得到了锁的语句,尽管如此,一般仍是能够经过查看这些输出结果来肯定究竟是什么引发了死锁。
在innodb里实际上有两种死锁,第一种就是经常碰到的那种,它在等待关系图里是一个真正的循环,另一种就是在一个等待关系图里,因代价昂贵而没法检测它是否是包含了循环,若是innodb要在关系图里检查超过100W个锁,或者在检查过程当中,innodb要重作200个以上的事务,那它会放弃,并宣布这里有一个死锁,这些数值都是硬编码在innodb代码里的常量,没法配置(若是你NB能够修改代码而后从新编译)。第二种死锁报错你能够在输出里看到一条信息:TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH
innodb不只会打印出事务和事务持有和等待的锁,并且还有记录自己,不幸的是,它至于可能超过为输出结果预留的长度(只能打印1M的内容且只能保留最近一次的死锁信息),若是你没法看到完整的输出,此时能够在任意库下建立innodb_monitor或innodb_lock_monitor表,这样innodb status信息会完整且每15s一次被记录到错误日志中。如:create table innodb_monitor(a int)engine=innodb;,不须要记录到错误日志中时就删掉这个表便可。缓存
5.1 下面也搞一个示例来看看:
5.1.1 建表:
mysql> create table test_deadlock(id int unsigned not null primary key auto_increment,test int unsigned not null);
Query OK, 0 rows affected (0.02 sec)
5.1.2 插入测试数据:
mysql> insert into test_deadlock(test) values(1),(2),(3),(4),(5);
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
打开两个会话终端:
5.1.3 会话1执行下面的SQL:
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test_deadlock where id=1 for update;
+----+------+
| id | test |
+----+------+
| 1 | 1 |
+----+------+
1 row in set (0.00 sec)
5.1.4 接着会话2执行下面的SQL:
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test_deadlock where id=2 for update;
+----+------+
| id | test |
+----+------+
| 2 | 2 |
+----+------+
1 row in set (0.00 sec)
5.1.5 回到会话1执行下面的SQL,会发生等待:
mysql> select * from test_deadlock where id=2 for update;
5.1.6 回到会话2执行下面的SQL,产生死锁,会话2被回滚:
mysql> select * from test_deadlock where id=1 for update;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
5.2 查看innodb status信息:
------------------------
LATEST DETECTED DEADLOCK
------------------------
160128 1:51:53
#这里显示了最近一次发生死锁的日期和时间
*** (1) TRANSACTION:
TRANSACTION D20847, ACTIVE 141 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 376, 2 row lock(s)
MySQL thread id 20027, OS thread handle 0x7f0a4c0f8700, query id 1818124 localhost root statistics
select * from test_deadlock where id=2 for update
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20847 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 00000002; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab011d; asc ;;
3: len 4; hex 00000002; asc ;;
*** (2) TRANSACTION:
TRANSACTION D20853, ACTIVE 119 sec starting index read
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1248, 2 row lock(s)
MySQL thread id 20081, OS thread handle 0x7f0a0f020700, query id 1818204 localhost root statistics
select * from test_deadlock where id=1 for update
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20853 lock_mode X locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 00000002; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab011d; asc ;;
3: len 4; hex 00000002; asc ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20853 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 00000001; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab0110; asc ;;
3: len 4; hex 00000001; asc ;;
*** WE ROLL BACK TRANSACTION (2)
这部份内容比较多,下面分段逐一进行解释:
5.2.1 下面这部分显示的是死锁的第一个事务的信息:
*** (1) TRANSACTION:
TRANSACTION D20847, ACTIVE 141 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 376, 2 row lock(s)
MySQL thread id 20027, OS thread handle 0x7f0a4c0f8700, query id 1818124 localhost root statistics
select * from test_deadlock where id=2 for update
TRANSACTION D20847, ACTIVE 141 sec starting index read:
这行表示事务D20847,ACTIVE 141 sec表示事务处于活跃状态141s,starting index read表示正在使用索引读取数据行
mysql tables in use 1, locked 1
#这行表示事务D20847正在使用1个表,且涉及锁的表有1个
LOCK WAIT 3 lock struct(s), heap size 376, 2 row lock(s)
#这行表示在等待3把锁,占用内存376字节,涉及2行记录,若是事务已经锁定了几行数据,这里将会有一行信息显示出锁定结构的数目(注意,这跟行锁是两回事)和堆大小,堆的大小指的是为了持有这些行锁而占用的内存大小,Innodb是用一种特殊的位图表来实现行锁的,从理论上讲,它可将每个锁定的行表示为一个比特,经测试显示,每一个锁一般不超过4比特
MySQL thread id 20027, OS thread handle 0x7f0a4c0f8700, query id 1818124 localhost root statistics
#这行表示该事务的线程ID信息,操做系统句柄信息,链接来源、用户
select * from test_deadlock where id=2 for update
#这行表示事务涉及的SQL
5.2.2 下面这一部分显示的是当死锁发生时,第一个事务正在等待的锁等信息:
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
#这行信息表示第一个事务正在等待锁被授予
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20847 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 00000002; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab011d; asc ;;
3: len 4; hex 00000002; asc ;;
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20847 lock_mode X locks rec but not gap waiting
#这行信息表示等待的锁是一个record lock,空间id是441,页编号为3,大概位置在页的72位处,锁发生在表xiaoboluo.test_deadlock的主键上,是一个X锁,可是不是gap lock。 waiting表示正在等待锁
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
#这行表示record lock的heap no 位置
#这部分剩下的内容只对调试才有用。
0: len 4; hex 00000002; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab011d; asc ;;
3: len 4; hex 00000002; asc ;;
5.2.3 下面这部分是事务二的状态:
*** (2) TRANSACTION:
TRANSACTION D20853, ACTIVE 119 sec starting index read
#事务2处于活跃状态119s
mysql tables in use 1, locked 1
#正在使用1个表,涉及锁的表有1个
3 lock struct(s), heap size 1248, 2 row lock(s)
#涉及3把锁,2行记录
MySQL thread id 20081, OS thread handle 0x7f0a0f020700, query id 1818204 localhost root statistics
select * from test_deadlock where id=1 for update
#第二个事务的SQL
5.2.4 下面这部分是事务二的持有锁信息:
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20853 lock_mode X locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 00000002; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab011d; asc ;;
3: len 4; hex 00000002; asc ;;
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20853 lock_mode X locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
#从这两行持有锁信息计息后面几行调试信息上看,就是事务1正在等待的锁。
5.2.5 下面这部分是事务二正在等待的锁,从下面的信息上看,等待的是同一个表,同一个索引,同一个page上的record lock X锁,可是heap no位置不一样,即不一样的行上的锁:
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 441 page no 3 n bits 72 index `PRIMARY` of table `xiaoboluo`.`test_deadlock` trx id D20853 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 00000001; asc ;;
1: len 6; hex 000000d20808; asc ;;
2: len 7; hex ad000001ab0110; asc ;;
3: len 4; hex 00000001; asc ;;
*** WE ROLL BACK TRANSACTION (2) #这个表示事务2被回滚,由于两个事务的回滚开销同样,因此选择了后提交的事务进行回滚,若是两个事务回滚的开销不一样(undo 数量不一样),那么就回滚开销最小的那个事务。
当一个事务持有了其余事务须要的锁,同时又想得到其余事务持有的锁时,等待关系图上就会产生循环,Innodb不会显示全部持有和等待的锁,可是,它显示了足够的信息来帮你肯定,查询操做正在使用哪些索引,这对于你肯定可否避免死锁有极大的价值。
若是能使两个查询对同一个索引朝同一个方向进行扫描,就能下降死锁的数目,由于,查询在同一个顺序上请求锁的时候不会建立循环,有时候,这是很容易作到的,如:要在一个事务里更新许多条记录,就能够在应用程序的内存里把它们按照主键进行排序,而后,再用一样的顺序更新到数据库里,这样就不会有死锁发生,可是在另外一些时候,这个方法也是行不通的(若是有两个进程使用了不一样的索引区间操做同一张表的时候)。
6. 下面这部分包含了一些关于innodb事务的总结信息,紧随其后的是当前活跃事务列表,如:
------------
TRANSACTIONS
------------
Trx id counter 4E0132AD
Purge done for trx's n:o < 4E01090B undo n:o < 0
History list length 1853
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 4E0131D3, not started
MySQL thread id 26208218, OS thread handle 0x7fec7c582700, query id 5274800318 10.207.162.69 gdsser
---TRANSACTION 4E01323F, not started
MySQL thread id 26208217, OS thread handle 0x7fec7c1b3700, query id 5274800938 10.207.162.69 gdsser
....................
---TRANSACTION 4E0132AC, ACTIVE 0 sec preparing
2 lock struct(s), heap size 376, 1 row lock(s), undo log entries 1
MySQL thread id 26208200, OS thread handle 0x7fec567e0700, query id 5274801557 10.207.162.69 gdsser
commit
---TRANSACTION 4E0110E7, ACTIVE 188 sec
mysql tables in use 1, locked 0
MySQL thread id 26208154, OS thread handle 0x7fec7c235700, query id 5274800671 10.143.90.228 root Sending data
SELECT /*!40001 SQL_NO_CACHE */ * FROM `m_flowskillpoint`
Trx read view will not see trx with id >= 4E0110E8, sees < 4E0108EE
---TRANSACTION 4E0108EF, ACTIVE 233 sec fetching rows
mysql tables in use 1, locked 0
MySQL thread id 26208131, OS thread handle 0x7fec578e3700, query id 5274801341 10.143.90.228 root Sending data
SELECT /*!40001 SQL_NO_CACHE */ * FROM `m_flowsilver`
Trx read view will not see trx with id >= 4E0108F0, sees < 4E0108EC
---TRANSACTION 4E0108EE, ACTIVE 233 sec fetching rows
mysql tables in use 1, locked 0
MySQL thread id 26208132, OS thread handle 0x7fec7c78a700, query id 5274797797 10.143.90.228 root Sending data
SELECT /*!40001 SQL_NO_CACHE */ * FROM `m_flowmail`
Trx read view will not see trx with id >= 4E0108EF, sees < 4E0108EC
这部份内容比较多,下面分段逐一进行解释:
6.1.
Trx id counter 4E0132AD
#这行表示当前事务ID,这是一个系统变量,每建立一个新事务都会增长
Purge done for trx's n:o < 4E01090B undo n:o < 0
#这是innodb清除旧MVCC行时所用的事务ID,将这个值和当前事务ID进行比较,就能够知道有多少老版本的数据未被清除。这个数字多大才能够安全的取值没有硬性和速成的规定,若是数据没作过任何更新,那么一个巨大的数字也不意味着有未清除的数据,由于实际上全部事务在数据库里查看的都是同一个版本的数据(此时只是事务ID在增长,而数据没有变动),另外一方面,若是有不少行被更新,那每一行就会有一个或多个版本留在内存里,减小此类开销的最好办法就是确保事务已完成就当即提交,不要让它长时间地处于打开状态,由于一个打开的事务即便不作任何操做,也会影响到innodb清理旧版本的行数据。 undo n:o < 0这个是innodb清理进程正在使用的撤销日志编号,为0 0时说明清理进程处于空闲状态。
History list length 1853
#历史记录的长度,即位于innodb数据文件的撤销空间里的页面的数目,若是事务执行了更新并提交,这个数字就会增长,而当清理进程移除旧版本数据时,它就会减小,清理进程也会更新Purge done for.....这行中的数值。
6.2.
头部信息以后就是一个事务列表,当前版本的mysql还不支持嵌套事务,所以,在某个时间点上,每一个客户端链接可以拥有的事务数量是有一个上限的,并且每个事务只能属于单一链接(即一个事务只能使用单个线程执行,不能使用多个线程)。在输出信息里,每个事务至少占有两行内容,如:
---TRANSACTION 4E0131D3, not started
#每一个事务的第一行以事务的ID和状态开始,not started表示这个事务已经提交而且没有再发起影响事务的语句,可能恰好空闲
MySQL thread id 26208218, OS thread handle 0x7fec7c582700, query id 5274800318 10.207.162.69 gdsser
#而后每一个事务的第二行是一些线程等信息,MySQL thread id <数字>部分和是hi用show full processlist;命令看到的id列相同。紧随其后的是一个内部查询id和一些链接信息,这些信息一样与show full processlist中的输出相同。
---TRANSACTION 4E01323F, not started
MySQL thread id 26208217, OS thread handle 0x7fec7c1b3700, query id 5274800938 10.207.162.69 gdsser
6.3.
上面是not started状态的事务信息,下面来看看为ACTIVE状态的事务信息:
---TRANSACTION 4E0110E7, ACTIVE 188 sec
#这行显示次事务处于活跃状态已经188s,可能的全部状态有not started,active,prepared和committed in memory,一旦事务日志落盘了就会变成not started状态。在时间后面会显示出当前事务正在作什么(在这里为空没有显示出来),在源代码中有超过30个字符串常量能够显示在时间后面,如:fetching,preparing,rows,adding foreign keys等等
mysql tables in use 1, locked 0
#该事务用到的表数和涉及表锁的表数,Innodb通常不会锁定表,但对有些语句会锁定,若是mysql服务器在高于innodb层之上将表锁定,这里也是可以显示出来的,若是事务已经锁定了几行数据,这里将会有一行信息显示出锁定结构的数目(注意,这跟行锁是两回事)和和堆大小,如:2 lock struct(s), heap size 376, 1 row lock(s), undo log entries 1,堆的大小指的是为了持有这些行锁而占用的内存大小,Innodb是用一种特殊的位图表来实现行锁的,从理论上讲,它可将每个锁定的行表示为一个比特,经测试显示,每一个锁一般不超过4比特。
MySQL thread id 26208154, OS thread handle 0x7fec7c235700, query id 5274800671 10.143.90.228 root Sending data
#与show processlist输出结果大部分相同
SELECT /*!40001 SQL_NO_CACHE */ * FROM `m_flowskillpoint`
#若是事务正在运行一个查询,那么这里就会显示事务涉及的SQL,注意:有些版本可能只显示其中一小段,而不是完整的SQL
Trx read view will not see trx with id >= 4E0110E8, sees < 4E0108EE
#这行显示了事务的读视图,它代表了由于版本关系而产生的对于事务可见和不可见两种类型的事务ID的范围,在这里,两个数字之间有一个事务的间隙,这个间隙里的事务多是不可见的,innodb在执行查询时,对于那些事务ID正好在这个间隙的行,还会检查其可见性。
注:若是事务正在等待一个锁,那么在查询SQL文本后面将能够看到这个锁的信息,在上文的死锁例子里,这样的信息看到过不少了,不幸的是,输出信息并无说出这个锁正被其余哪一个事务持有,不过能够经过information_schema库下的innodb_trx,innodb_lock_waits,innodb_locks三个表来查明这一点。若是输出信息里有不少个事务,innodb可能会限制要打印出来的事务数目,以避免输出信息增加得太大,这时就会看到...truncated...提示。
7.FILE I/O部分显示的是I/O辅助线程的状态,还有性能计数器的状态,以下:
--------
FILE I/O
--------
I/O thread 0 state: waiting for i/o request (insert buffer thread)
#insert buffer thread
I/O thread 1 state: waiting for i/o request (log thread)
#log thread
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (read thread)
I/O thread 4 state: waiting for i/o request (read thread)
I/O thread 5 state: doing file i/o (read thread) ev set
#以上为默认的4个read thread
I/O thread 6 state: waiting for i/o request (write thread)
I/O thread 7 state: waiting for i/o request (write thread)
I/O thread 8 state: waiting for i/o request (write thread)
I/O thread 9 state: waiting for i/o request (write thread)
#以上为默认的4个write thread
Pending normal aio reads: 128 [0, 0, 0, 128] , aio writes: 0 [0, 0, 0, 0] ,
#读线程和写线程挂起操做的数目等,aio的意思是异步I/O
ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
#insert buffer thread挂起的fsync()操做数目等
Pending flushes (fsync) log: 0; buffer pool: 0
#log thread挂起的fsync()操做数目等
146246831 OS file reads, 760501349 OS file writes, 247143684 OS fsyncs
#这行显示了读,写和fsync()调用执行的数目,在你的机器环境负载下这些绝对值可能会有所不一样,所以更重要的是监控它们过去一段时间内是如何改变的。
1 pending preads, 0 pending pwrites
#这行显示了当前被挂起的读和写操做数
145.49 reads/s, 783677 avg bytes/read, 28.75 writes/s, 10.67 fsyncs/s
#这行显示了在头部显示的时间(指的是第1部分的时间)段内的每秒平均值。
注:三行挂起读写线程、缓冲池线程、日志线程的统计信息的值是检测I/O受限的应用的一个好方法,若是这些I/O大部分有挂起操做,那么负载可能I/O受限。在linux系统下使用参数:innodb_read_io_threads和innodb_write_io_threads两个变量来配置读写线程的数量,默认为各4个线程。
insert buffer thread:负责插入缓冲合并,如:记录被从插入缓冲合并到表空间中
log thread:负责异步刷事务日志
read thread:执行预读操做以尝试预先读取innodb预感须要的数据
write thread:刷新脏页缓冲
8.这部分显示了insert buffer和adaptive hash index两个部分的结构的状态
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 12, free list len 27559, seg size 27572, 18074934 merges
#这行显示了关于size(size 12表明了已经合并记录页的数量)、free list(表明了插入缓冲中空闲列表长度)和seg size大小(seg size 27572显示了当前insert buffer的长度,大小为27572*16K=440M左右)的信息。18074934 merges表明合并插入的次数
merged operations:
#这个标签
下的一行信息insert,delete mark,delete分别表示merge操做合并了多少个insert buffer,delete buffer,purge buffer
insert 81340470, delete mark 8893610, delete 818579
discarded operations:
#这个标签下的一行信息表示当change buffer发生merge时表已经被删除了,就不须要再将记录合并到辅助索引中了
insert 0, delete mark 0, delete 0
Hash table size 87709057, node heap has 10228 buffer(s)
#这行显示了自使用哈希索引的状态,其中,Hash table size 87709057表示AHI的大小,node heap has 10228 buffer(s)表示AHI的使用状况
1741.05 hash searches/s, 539.48 non-hash searches/s
#这行显示了在头部第1部分说起的时间内Innodb每秒完成了多少哈希索引操做,1741.05 hash searches/s表示每秒使用AHI搜索的状况,539.48 non-hash searches/s表示每秒没有使用AHI搜索的状况(由于哈希索引只能用于等值查询,而范围查询,模糊查询是不能使用哈希索引的。),经过hash searches: non-hash searches的比例大概能够了解使用哈希索引后的效率,哈希索引查找与非哈希索引查找的比例仅供参考,自适应哈希索引没法配置,可是能够经过innodb_adaptive_hash_index=ON|OFF参数来选择是否须要这个特性。
innodb从1.0.x开始引入change buffer,能够视为insert buffer的升级,从这个版本开始,innodb能够对DML操做(insert,delete,update)都进行缓冲,他们分别是insert buffer,delete buffer,purge buffer,固然和以前insert buffer同样,change buffer适用对象仍然是非惟一索引的辅助索引,由于没有update buffer,因此对一条记录进行update的操做能够分为两个过程:
A:将记录标记为删除
B:真正将记录删除
所以,
delete buffer对应update 操做的第一个过程,即将记录标记为删除,purge buffer对应update的第二个过程,即将记录真正地删除
9.这部分显示了关于innodb事务日志(重作日志)子系统的统计:
---
LOG
---
Log sequence number 1351392990515
#这行显示了当前最新数据产生的日志序列号
Log flushed up to 1351392989504
#这行显示了日志已经刷新到哪一个位置了(已经落盘到事务日志中的日志序列号)
Last checkpoint at 1351373900020
#这行显示了上一次检查点的位置(一个检查点表示一个数据和日志文件都处于一致状态的时刻,而且能用于恢复数据),若是上一次检查点落后与上一行太多,而且差别接近于事务日志文件的大小,Innodb会触发“疯狂刷”,这对性能而言很是糟糕。
0 pending log writes, 0 pending chkp writes
#这行显示了当前挂起的日志读写操做,能够将这行的值与第7部分FILE I/O对应的值作比较,以了解你的I/O有多少是因为日志系统引发的。
286879989 log i/o's done, 15.92 log i/o's/second
#这行显示了日志操做的统计和每秒日志I/O数,能够将这行的值与第7部分FILE I/O对应的值作比较,以了解你的I/O有多少是因为日志系统引发的。
9.这部分显示了关于innodb缓冲池及其如何使用内存的统计:
9.1.
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 45357793280; in additional pool allocated 0
#这行显示了由innodb分配的总内存,以及其中多少是额外内存池分配,额外内存池仅分配了其中很小一部份内存,由内部内存分配器分配,如今的innodb版本通常使用操做系统的内存分配器,但老版本使用本身的,这是因为在那个时代有些操做系统并未提供一个很是好的内存分配实现。
Dictionary memory allocated 12681573
Buffer pool size 2705015
#从这行开始的下面4行显示缓冲池度量值,以页为单位,度量值有总的缓冲池大小,空闲页数,分配用来存储数据库页的页数,以及脏数据库页数。这行显示了缓冲池总共有多少个页,即即2705015*16K,共有43G的缓冲池
Free buffers 5
#这行显示了缓冲池空闲页数
Database pages 2694782
#这行显示了分配用来存储数据库页的页数,即,表示LRU列表中页的数量,包含young sublist和old sublist
Old database pages 994651
#这行显示了LRU中的old sublist部分页的数量
Modified db pages 10610
#这行显示脏数据库页数
Pending reads 128
#这行显示了挂起读的数量
Pending writes: LRU 0, flush list 0, single page 0
#这行显示了挂起写的数量
#注意,这里挂起的读和写操做并不与FILE I/O部分的值匹配,由于Innodb可能合并许多的逻辑读写操做到一个物理I/O操做中,LRU表明最近使用到的被挂起数量,它是经过冲刷缓冲中不常用的页来释放空间以供给常用的页的一种方法,冲刷列表flush list存放着检查点处理须要冲刷的旧页被挂起的数量,单页single page被挂起的数量(single page写是独立的页面写,不会被合并)。
Pages made young 3014373561, not young 0
#这行显示了LRU列表中页移动到LRU首部的次数,由于该服务器在运行阶段改变没有达到innodb_old_blocks_time阀值的值,所以not young为0
6960.42 youngs/s, 0.00 non-youngs/s
#表示每秒
young和non-youngs这两类操做的次数
Pages read 2946570833, created 43450158, written 574214278
#这行显示了innodb被读取,建立,写入了多少页,读/写页的值是指的从磁盘读到缓冲池的数据,或者从缓冲池写到磁盘中的数据,建立页指的是innodb在缓冲池中分配但没有从数据文件中读取内容的页,由于它并不关心内容是什么(如,它们可能属于一个已经被删除的表)
6960.54 reads/s, 4.42 creates/s, 9.33 writes/s
#这行显示了对应上面一行的每秒read,create,write的页数
Buffer pool hit rate 955 / 1000, young-making rate 45 / 1000 not 0 / 1000
#这行显示了缓冲池的命中率,它用来衡量innodb在缓冲池中查找到所需页的比例,它度量自上次Innodb状态输出后到本次输出这段时间内的命中率,所以,若是服务器自那之后一直很安静,你将会看到No buffer pool page gets since the last printout。它对于度量缓存池的大小并无用处。
Pages read ahead 6928.54/s, evicted without access 8.21/s, Random read ahead 0.00/s
#这行显示了页面预读,随机预读的每秒页数
LRU len: 2694782, unzip_LRU len: 0
#innodb1.0.x开始支持压缩页的功能,将原来16K的页压缩为1K,2K,4K,8K,而因为页的大小发生了变化,LRU列表也有了些改变,对于非16K的页,是经过unzip_LRU列表进行管理的,能够看到unzip_LRU len为0表示没有使用压缩页.
I/O sum[60790]:cur[30], unzip sum[0]:cur[0]
对于压缩页的表,每一个表的压缩比例可能不一样,可能存在有的表页大小为8K,有的表页大小为2K的状况,unzip_LRUs 怎样从缓存池中分配内存的呢?
首先,在unzip_LRU列表中对不一样压缩页大小的页进行分别管理,其次,经过伙伴算法进行内存的分配,例如:须要从缓存池中申请页为4K的大小,其过程以下:
a:检查4K的unzip_LRU列表,检查是否有可用的空闲页
b:如有,则直接使用
c:若没有,检查8K的unzip_LRU列表
d:若可以获得空闲页,将页分红2个4K的页,存放到4K的unzip_LRU列表
e:若不能获得空闲页,从LRU列表中申请一个16K的页,将页分红1个8K,2个4K的页,分别存放到各自大小对应的unzip_LRU列表中。
注:可能出现Free buffers和Database pages之和不等于Buffer pool size,由于缓冲池中的页肯会被分配给自适应哈希索引,lock信息,insert buffer等,而这部分页不须要LRU算法进行维护,所以不在LRU列表中。
9.2.若是innodb buffer pool使用参数innodb
_buffer_pool_instances=num设置了大于1个缓冲池实例,那么就会按照这个参数把innodb_buffer_pool_size=xxx平分为num份。每份的信息显示相似以下,这部分的内容和9.1小节内容相似,就再也不多说。
----------------------
INDIVIDUAL BUFFER POOL INFO
----------------------
---BUFFER POOL 0
Buffer pool size 541003
Free buffers 1
Database pages 538965
Old database pages 198933
Modified db pages 2190
Pending reads 128
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 603372180, not young 0
1441.81 youngs/s, 0.00 non-youngs/s
Pages read 589705199, created 8703138, written 116954697
1441.61 reads/s, 0.75 creates/s, 1.83 writes/s
Buffer pool hit rate 955 / 1000, young-making rate 45 / 1000 not 0 / 1000
Pages read ahead 1436.98/s, evicted without access 0.87/s, Random read ahead 0.00/s
LRU len: 538965, unzip_LRU len: 0
I/O sum[12158]:cur[6], unzip sum[0]:cur[0]
---BUFFER POOL 1
Buffer pool size 541003
Free buffers 1
Database pages 538959
Old database pages 198931
Modified db pages 2025
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 602366394, not young 0
1481.35 youngs/s, 0.00 non-youngs/s
Pages read 588738997, created 8708171, written 113209540
1480.56 reads/s, 0.83 creates/s, 1.92 writes/s
Buffer pool hit rate 958 / 1000, young-making rate 42 / 1000 not 0 / 1000
Pages read ahead 1473.73/s, evicted without access 1.96/s, Random read ahead 0.00/s
LRU len: 538959, unzip_LRU len: 0
I/O sum[12158]:cur[6], unzip sum[0]:cur[0]
10.这部分显示了其余各项的innodb统计:
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
#这行显示了innodb内核内有多少个线程,队列中有多少个线程,队列中的查询是innodb为限制并发执行的线程数量而不运行进入内核的线程。查询在进入队列以前会休眠等待。
5 read views open inside InnoDB
#这行显示了有多少打开的innodb读视图,读视图是包含事务开始点的数据库内容的MVCC快照,你能够看看某特定事务在第6部分TRANSACTIONS是否有读视图
Main thread process no. 4368, id 140653691242240, state: sleeping
#这行显示了内核的主线程状态
Number of rows inserted 3429012215, updated 153529675, deleted 112310240, read 3739562987410
#这行显示了多少行被插入,更新和删除,读取
428.52 inserts/s, 7.21 updates/s, 0.46 deletes/s, 1047933.92 reads/s
#这行显示了对应上面一行的每秒平均值,若是想查看innodb有多少工做量在进行,那么这两行是很好的参考值
----------------------------
END OF INNODB MONITOR OUTPUT
#要注意了,若是看不到这行输出,多是有大量事务或者是有一个大的死锁截断了输出信息
============================
注:内核的主线程状态可能的状态值有以下一些:
A:doing background drop tables
B:doing insert buffer merge
C:flushing buffer pool pages
D:making checkpoint
E:purging
F:reserving kernel mutex
G:sleeping
H:suspending
I:waiting for buffer pool flush to end
J:waiting for server activity