innodb存儲引擎在show engine innodb status(老版本對應(yīng)的是show innodb status)輸出中,顯示除了大量的內(nèi)部信息,它輸出就是一個單獨的字符串追他,沒有行和列粥鞋,內(nèi)容分為很多小段踊东,每一段對應(yīng)innodb存儲引擎不同部分的信息产徊,其中有一些信息對于innodb開發(fā)者來說非常有用,但是井赌,許多信息谤逼,如果你嘗試去理解,并且應(yīng)用到高性能innodb調(diào)優(yōu)的時候仇穗,你會發(fā)現(xiàn)它們非常有趣流部,甚至是非常有必要的。
輸出內(nèi)容中包含了一些平均值的統(tǒng)計信息纹坐,這些平均值是自上次輸出結(jié)果生成以來的統(tǒng)計數(shù)枝冀,因此,如果你正在檢查這些值耘子,那就要確保已經(jīng)等待了至少30s的時間果漾,使兩次采樣之間的積累足夠長的統(tǒng)計時間并多次采樣,檢查計數(shù)器變化從而弄清其行為谷誓,并不是所有的輸出都會在一個時間點上生成绒障,因而也不是所有的顯示出來的平均值會在同一時間間隔里重新再計算。而且捍歪,innodb有一個內(nèi)部復(fù)位間隔户辱,而它是不可預(yù)知的鸵钝,各個版本也不一樣。
這些輸出信息足夠提供給手工計算出大多數(shù)你想要的統(tǒng)計信息焕妙,有一款監(jiān)控工具innotop可以幫你計算出增量差值和平均值蒋伦。下面弓摘,在你的mysql命令行敲下show engine innodb status;看著輸出跟著下面的步驟一步一步理解輸出信息是什么含義:
注意:以下使用mysql5.5.24版本做解讀焚鹊,mysql5.6.x和5.7.x輸出內(nèi)容有些地方有調(diào)整。
1.第一段是頭部信息韧献,它僅僅聲明了輸出的開始末患,其內(nèi)容包括當前的日期和時間,以及自上次輸出以來經(jīng)過的時長锤窑。
=====================================
160129 12:07:26 INNODB MONITOR OUTPUT #第二行是當前日期和時間
=====================================
Per second averages calculated from the last 24 seconds** #第四行顯示的是計算出這一平均值的時間間隔璧针,即自上次輸出以來的時間,或者是距上次內(nèi)部復(fù)位的時長**
2.從innodb1.0.x開始渊啰,可以使用命令show engine innodb status;來查看master thread的狀態(tài)信息:
BACKGROUND THREAD
srv_master_thread loops: 30977173 1_second, 30975685 sleeps, 3090359 10_second, 166112 background, 165988 flush #這行顯示主循環(huán)進行了30977173 1_second次探橱,每秒掛起的操作進行了30975685 sleeps次(說明負載不是很大),10秒一次的活動進行了3090359 10_second次绘证,1秒循環(huán)和10秒循環(huán)比值符合1:10隧膏,backgroup loop進行了166112 background次,flush loop進行了165988 flush次嚷那,如果在一臺很大壓力的mysql上胞枕,可能看到每秒運行次數(shù)和掛起次數(shù)比例小于1很多,這是因為innodb對內(nèi)部進行了一些優(yōu)化魏宽,當壓力大時間隔時間并不總是等待1秒腐泻,因此,不能認為每秒循環(huán)和掛起的值總是相等队询,在某些情況下派桩,可以通過兩者之間的差值來比較反映當前數(shù)據(jù)庫的負載壓力。
srv_master_thread log flush and writes: 31160103
3.如果有高并發(fā)的工作負載蚌斩,你就要關(guān)注下接下來的段(SEMAPHORES信號量),它包含了兩種數(shù)據(jù):事件計數(shù)器以及可選的當前等待線程的列表窄坦,如果有性能上的瓶頸,可以使用這些信息來找出瓶頸凳寺,不幸的是鸭津,想知道怎么使用這些信息還是有一點復(fù)雜,下面先給出一些解釋:
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
內(nèi)容比較多肠缨,下面分段依次解釋:
3.1.
OS WAIT ARRAY INFO: reservation count 68581015, signal count 218437328 **#這行給出了關(guān)于操作系統(tǒng)等待數(shù)組的信息逆趋,它是一個插槽數(shù)組,innodb在數(shù)組里為信號量保留了一些插槽晒奕,操作系統(tǒng)用這些信號量給線程發(fā)送信號闻书,使線程可以繼續(xù)運行名斟,以完成它們等著做的事情,這一行還顯示出innodb使用了多少次操作系統(tǒng)的等待:保留統(tǒng)計(reservation count)顯示了innodb分配插槽的頻度魄眉,而信號****計數(shù)(signal count)衡量的是線程通過數(shù)組得到信號的頻度砰盐,操作系統(tǒng)的等待相對于空轉(zhuǎn)等待(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 <數(shù)字> has waited...開始,這一段內(nèi)容在正常情況下應(yīng)該是空的(即查看的時候沒有這部分內(nèi)容)晃择,除非服務(wù)器運行著高并發(fā)的工作負載冀值,促使innodb采取讓操作系統(tǒng)等待的措施,除非你對innodb源碼熟悉宫屠,否則這里看到的最有用的信息就是發(fā)生線程等待的代碼文件名 /usr/local/src/soft/mysql-5.5.24/storage/innobase/buf/buf0buf.c line 3151列疗。**
在innodb內(nèi)部哪里才是熱點?舉例來說浪蹂,如果看到許多線程都在一個名為buf0buf.c的文件上等待抵栈,那就意味著你的系統(tǒng)里存在著
緩沖池競爭,這個輸出信息還顯示了這些線程等待了多少時間坤次,其中waiters flag顯示了有多少個等待著正在等待同一個互斥量古劲。 如果waiters flag為0那就表示沒有線程在等待同一個互斥量(此時在waiters flag 0后面可能可以看到wait is ending,表示這個互斥量已經(jīng)被釋放了浙踢,但操作系統(tǒng)還沒有把線程調(diào)度過來運行)绢慢。
你可能想知道innodb真正等待的是什么,innodb使用了互斥量和信號量來保護代碼的臨界區(qū)洛波,如:限定每次只能有一個線程進入臨界區(qū)胰舆,或者是當有活動的讀時,就限制寫入等蹬挤。在innodb代碼里有很多臨界區(qū)缚窿,在合適的條件下,它們都可能出現(xiàn)在那里焰扳,常常能見到的一種情形是:獲取緩沖池分頁的訪問權(quán)的時候倦零。
3.3.
在等待線程之后的部分信息如下,這部分顯示了更多的事件計數(shù)器吨悍,在每一個情形中扫茅,都能看到innodb依靠操作系統(tǒng)等待的頻度:
Mutex spin waits 1157217380, rounds 1783981614, OS waits 10610359** #這行顯示的是跟互斥量相關(guān)的幾個計數(shù)器**
RW-shared spins 103830012, rounds 1982690277, OS waits 52051891 #這行顯示讀寫的共享鎖的計數(shù)器
RW-excl spins 43730722, rounds 602114981, OS waits 3495769 #這行顯示讀寫的排他鎖的計數(shù)器
Spin rounds per wait: 1.54 mutex, 19.10 RW-shared, 13.77 RW-excl
innodb有著一個多階段等待的策略,首先育瓜,它會試著對鎖進行空轉(zhuǎn)等待葫隙,如果經(jīng)歷了一個預(yù)設(shè)的空轉(zhuǎn)等待周期(設(shè)置innodb_sync_spin_loops配置變量命令)之后還沒有成功,那就會退到更昂貴更復(fù)雜的等待數(shù)組中躏仇。
空轉(zhuǎn)等待的成本相對較低恋脚,但是它們要不停地檢查一個資源能否被鎖定腺办,這種方式會消耗CPU周期,但是糟描,這沒有聽起來那么糟糕怀喉,因為當處理器在等待IO時,一般都有一些空閑的CPU周期可用船响,即使是沒有空閑的CPU周期躬拢,空等也要比其他方式更加廉價一些。然而灿意,當另外一個線程能做一些事情的時候估灿,空轉(zhuǎn)等待也還會把CPU獨占著崇呵。
空轉(zhuǎn)等待的替代方案就是讓操作系統(tǒng)做上下文切換,這樣,當一個線程在等待時膝但,另外一個線程就可以被運行总寻,然后,通過等待數(shù)組里的信號量發(fā)出信號犹褒,喚醒那個沉睡的線程抵窒,通過信號量來發(fā)送信號是比較有效的,但是上下文切換就很昂貴叠骑,這很快就會積少成多李皇,每秒鐘幾千次的切換會引發(fā)大量的系統(tǒng)開銷。
你可以通過修改innodb_sync_spin_loops的值宙枷,試著在空轉(zhuǎn)等待與操作系統(tǒng)等待之間達成平衡掉房,不要擔心空轉(zhuǎn)等待,除非你在一秒里看到幾十萬個空轉(zhuǎn)等待慰丛。此時卓囚,你可以考慮performance_schema庫或者show engine innodb mutex;查看下相關(guān)信息。
4.下面這一段外鍵錯誤的信息一般不會出現(xiàn)诅病,除非你服務(wù)器上發(fā)生了外鍵錯誤哪亿,有時問題在于事務(wù)在插入,更新或刪除一條記錄時要尋找父表或子表贤笆,還有時候是當innodb嘗試增加或刪除一個外鍵或者修改一個已經(jīng)存在的外鍵時蝇棉,發(fā)現(xiàn)表之間類型不匹配,這部分輸出對于調(diào)試與innodb不明確的外鍵錯誤發(fā)生的準確原因非常有幫助芥永,下面搞一個示例來看看:
4.1 創(chuàng)建父表:
mysql> create table parent(parent_id int not null,primary key(parent_id)) engine=innodb;
4.2 創(chuàng)建子表:
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 插入數(shù)據(jù):
mysql> insert into parent(parent_id) values(1);
mysql> insert into child(child_id) values(1);
4.5 有兩種基本的外鍵錯誤:
第一種:以某種可能違反外鍵約束關(guān)系的方法增加篡殷,更新,刪除數(shù)據(jù)恤左,將導致第一類錯誤贴唇,如搀绣,在父表中刪除行時發(fā)生如下錯誤:
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
:
,** #上面部分顯示了關(guān)于破壞外鍵約束的事務(wù)詳情瓶您。后邊部分顯示了發(fā)現(xiàn)錯誤時innodb正嘗試修改的準確數(shù)據(jù)麻捻,輸出中有許多是轉(zhuǎn)換成可打印格式的行數(shù)據(jù)**。
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 第二種:嘗試修改父表的表結(jié)構(gòu)時發(fā)生的錯誤呀袱,這種錯誤就沒有那么清楚了贸毕,這可能會讓調(diào)試更困難:
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"
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
InnoDB: Renaming table xiaoboluo
.<result 2 when explaining filename '#sql-b695_4e3b'> to xiaoboluo
.parent
failed!
上面的錯誤是數(shù)據(jù)類型不匹配,外鍵列必須有完全相同的數(shù)據(jù)類型夜赵,包括任何的修飾符(如這里父表多加了一個unsigned明棍,這也是問題所在),當看到1025錯誤并不理解為什么時寇僧,最好查看下innodb status摊腋。在每次看到有新錯誤時,外鍵錯誤信息都會被重寫嘁傀,percona toolkit中的pt-fk-error-logger工具可以用表保存這些信息以供后續(xù)分析兴蒸。
5.與外鍵錯誤一樣,這部分只有當服務(wù)器產(chǎn)生死鎖時才會出現(xiàn)细办,死鎖信息同樣在每次有新的死鎖錯誤時被重寫橙凳,percona toolkit中的pt-deadlock-logger工具可以用表保存這些信息以供后續(xù)分析
死鎖在等待關(guān)系圖里是一個循環(huán),就是一個鎖定了行的數(shù)據(jù)結(jié)構(gòu)又在等待別的鎖笑撞,這個循環(huán)可以任意地大岛啸,innodb會立即檢測到死鎖,因為每當有事務(wù)等待行鎖的時候娃殖,它都會去檢查等待關(guān)系圖里是否有循環(huán)值戳,死鎖的情況可能會比較復(fù)雜,但是炉爆,這一部分只顯示了最近的兩個死鎖的情況堕虹,它們在各自的事務(wù)里執(zhí)行的最后一條語句,以及它們在等待關(guān)系圖里形成環(huán)鎖的信息芬首。在這個循環(huán)里你看不到其他事務(wù)赴捞,也可能看不到在事務(wù)里早先真正獲得了鎖的語句,盡管如此郁稍,通常還是可以通過查看這些輸出結(jié)果來確定到底是什么引起了死鎖赦政。
在innodb里實際上有兩種死鎖,第一種就是常常碰到的那種,它在等待關(guān)系圖里是一個真正的循環(huán)恢着,另外一種就是在一個等待關(guān)系圖里桐愉,因代價昂貴而無法檢測它是不是包含了循環(huán),如果innodb要在關(guān)系圖里檢查超過100W個鎖掰派,或者在檢查過程中从诲,innodb要重做200個以上的事務(wù),那它會放棄靡羡,并宣布這里有一個死鎖系洛,這些數(shù)值都是硬編碼在innodb代碼里的常量,無法配置(如果你NB可以修改代碼然后重新編譯)略步。第二種死鎖報錯你可以在輸出里看到一條信息:TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH
innodb不僅會打印出事務(wù)和事務(wù)持有和等待的鎖描扯,而且還有記錄本身,不幸的是趟薄,它至于可能超過為輸出結(jié)果預(yù)留的長度(只能打印1M的內(nèi)容且只能保留最近一次的死鎖信息)绽诚,如果你無法看到完整的輸出,此時可以在任意庫下創(chuàng)建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 插入測試數(shù)據(jù):
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執(zhí)行下面的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執(zhí)行下面的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執(zhí)行下面的SQL,會發(fā)生等待:
mysql> select * from test_deadlock where id=2 for update;
5.1.6 回到會話2執(zhí)行下面的SQL导绷,產(chǎn)生死鎖犀勒,會話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 #這里顯示了最近一次發(fā)生死鎖的日期和時間
*** (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)
這部分內(nèi)容比較多,下面分段逐一進行解釋:
5.2.1 下面這部分顯示的是死鎖的第一個事務(wù)的信息:
*** (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:這行表示事務(wù)D20847妥曲,ACTIVE 141 sec表示事務(wù)處于活躍狀態(tài)141s贾费,starting index read表示正在使用索引讀取數(shù)據(jù)行
mysql tables in use 1, locked 1#這行表示事務(wù)D20847正在使用1個表,且涉及鎖的表有1個
LOCK WAIT 3 lock struct(s), heap size 376, 2 row lock(s)** #這行表示在等待3把鎖檐盟,占用內(nèi)存376字節(jié)褂萧,涉及2行記錄,如果事務(wù)已經(jīng)鎖定了幾行數(shù)據(jù)葵萎,這里將會有一行信息顯示出鎖定結(jié)構(gòu)的數(shù)目(注意导犹,這跟行鎖是兩回事)和堆大小,堆的大小指的是為了持有這些行鎖而占用的內(nèi)存大小羡忘,Innodb是用一種特殊的位圖表來實現(xiàn)行鎖的谎痢,從理論上講,它可將每一個鎖定的行表示為一個比特卷雕,經(jīng)測試顯示节猿,每個鎖通常不超過4比特**
MySQL thread id 20027, OS thread handle 0x7f0a4c0f8700, query id 1818124 localhost root statistics** #這行表示該事務(wù)的線程ID信息,操作系統(tǒng)句柄信息漫雕,連接來源滨嘱、用戶**
select * from test_deadlock where id=2 for update#這行表示事務(wù)涉及的SQL
5.2.2 下面這一部分顯示的是當死鎖發(fā)生時峰鄙,第一個事務(wù)正在等待的鎖等信息:
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:** #這行信息表示第一個事務(wù)正在等待鎖被授予**
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位處,鎖發(fā)生在表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 位置
#這部分剩下的內(nèi)容只對調(diào)試才有用宪拥。
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 下面這部分是事務(wù)二的狀態(tài):
*** (2) TRANSACTION:
TRANSACTION D20853, ACTIVE 119 sec starting index read #事務(wù)2處于活躍狀態(tài)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** #第二個事務(wù)的SQL**
5.2.4 下面這部分是事務(wù)二的持有鎖信息:
*** (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 #從這兩行持有鎖信息計息后面幾行調(diào)試信息上看她君,就是事務(wù)1正在等待的鎖脚作。
5.2.5 下面這部分是事務(wù)二正在等待的鎖,從下面的信息上看缔刹,等待的是同一個表球涛,同一個索引,同一個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) #這個表示事務(wù)2被回滾,因為兩個事務(wù)的回滾開銷一樣鸟廓,所以選擇了后提交的事務(wù)進行回滾从祝,如果兩個事務(wù)回滾的開銷不同(undo 數(shù)量不同),那么就回滾開銷最小的那個事務(wù)引谜。
當一個事務(wù)持有了其他事務(wù)需要的鎖牍陌,同時又想獲得其他事務(wù)持有的鎖時,等待關(guān)系圖上就會產(chǎn)生循環(huán)员咽,Innodb不會顯示所有持有和等待的鎖毒涧,但是,它顯示了足夠的信息來幫你確定贝室,查詢操作正在使用哪些索引契讲,這對于你確定能否避免死鎖有極大的價值。
如果能使兩個查詢對同一個索引朝同一個方向進行掃描档玻,就能降低死鎖的數(shù)目怀泊,因為,查詢在同一個順序上請求鎖的時候不會創(chuàng)建循環(huán)误趴,有時候霹琼,這是很容易做到的,如:要在一個事務(wù)里更新許多條記錄,就可以在應(yīng)用程序的內(nèi)存里把它們按照主鍵進行排序枣申,然后售葡,再用同樣的順序更新到數(shù)據(jù)庫里,這樣就不會有死鎖發(fā)生忠藤,但是在另一些時候挟伙,這個方法也是行不通的(如果有兩個進程使用了不同的索引區(qū)間操作同一張表的時候)。
6. 下面這部分包含了一些關(guān)于innodb事務(wù)的總結(jié)信息模孩,緊隨其后的是當前活躍事務(wù)列表尖阔,如:
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
這部分內(nèi)容比較多,下面分段逐一進行解釋:
6.1.
Trx id counter 4E0132AD #這行表示當前事務(wù)ID榨咐,這是一個系統(tǒng)變量介却,每創(chuàng)建一個新事務(wù)都會增加
Purge done for trx's n:o < 4E01090B undo n:o < 0 #這是innodb清除舊MVCC行時所用的事務(wù)ID,將這個值和當前事務(wù)ID進行比較块茁,就可以知道有多少老版本的數(shù)據(jù)未被清除齿坷。這個數(shù)字多大才可以安全的取值沒有硬性和速成的規(guī)定,如果數(shù)據(jù)沒做過任何更新数焊,那么一個巨大的數(shù)字也不意味著有未清除的數(shù)據(jù)永淌,因為實際上所有事務(wù)在數(shù)據(jù)庫里查看的都是同一個版本的數(shù)據(jù)(此時只是事務(wù)ID在增加,而數(shù)據(jù)沒有變更)佩耳,另一方面遂蛀,如果有很多行被更新,那每一行就會有一個或多個版本留在內(nèi)存里蚕愤,減少此類開銷的最好辦法就是確保事務(wù)已完成就立即提交答恶,不要讓它長時間地處于打開狀態(tài),因為一個打開的事務(wù)即使不做任何操作萍诱,也會影響到innodb清理舊版本的行數(shù)據(jù)。 undo n:o < 0這個是innodb清理進程正在使用的撤銷日志編號污呼,為0 0時說明清理進程處于空閑狀態(tài)裕坊。
History list length 1853 ** #歷史記錄的長度,即位于innodb數(shù)據(jù)文件的撤銷空間里的頁面的數(shù)目燕酷,如果事務(wù)執(zhí)行了更新并提交籍凝,這個數(shù)字就會增加,而當清理進程移除舊版本數(shù)據(jù)時苗缩,它就會減少饵蒂,清理進程也會更新Purge done for.....這行中的數(shù)值。**
6.2.
頭部信息之后就是一個事務(wù)列表酱讶,當前版本的mysql還不支持嵌套事務(wù)退盯,因此,在某個時間點上,每個客戶端連接能夠擁有的事務(wù)數(shù)量是有一個上限的渊迁,而且每一個事務(wù)只能屬于單一連接(即一個事務(wù)只能使用單個線程執(zhí)行慰照,不能使用多個線程)。在輸出信息里琉朽,每一個事務(wù)至少占有兩行內(nèi)容毒租,如:
---TRANSACTION 4E0131D3, not started** #每個事務(wù)的第一行以事務(wù)的ID和狀態(tài)開始,not started表示這個事務(wù)已經(jīng)提交并且沒有再發(fā)起影響事務(wù)的語句箱叁,可能剛好空閑**
MySQL thread id 26208218, OS thread handle 0x7fec7c582700, query id 5274800318 10.207.162.69 gdsser** #然后每個事務(wù)的第二行是一些線程等信息墅垮,MySQL thread id <數(shù)字>部分和是hi用show full processlist;命令看到的id列相同。緊隨其后的是一個內(nèi)部查詢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狀態(tài)的事務(wù)信息,下面來看看為ACTIVE狀態(tài)的事務(wù)信息:
---TRANSACTION 4E0110E7, ACTIVE 188 sec #這行顯示次事務(wù)處于活躍狀態(tài)已經(jīng)188s孤个,可能的所有狀態(tài)有not started剃允,active,prepared和committed in memory齐鲤,一旦事務(wù)日志落盤了就會變成not started狀態(tài)斥废。在時間后面會顯示出當前事務(wù)正在做什么(在這里為空沒有顯示出來),在源代碼中有超過30個字符串常量可以顯示在時間后面给郊,如:fetching牡肉,preparing,rows淆九,adding foreign keys等等
mysql tables in use 1, locked 0** #該事務(wù)用到的表數(shù)和涉及表鎖的表數(shù)统锤,Innodb一般不會鎖定表,但對有些語句會鎖定炭庙,如果mysql服務(wù)器在高于innodb層之上將表鎖定饲窿,這里也是能夠顯示出來的,如果事務(wù)已經(jīng)鎖定了幾行數(shù)據(jù)焕蹄,這里將會有一行信息顯示出鎖定結(jié)構(gòu)的數(shù)目(注意逾雄,這跟行鎖是兩回事)和和堆大小,如:2 lock struct(s), heap size 376, 1 row lock(s), undo log entries 1腻脏,堆的大小指的是為了持有這些行鎖而占用的內(nèi)存大小鸦泳,Innodb是用一種特殊的位圖表來實現(xiàn)行鎖的,從理論上講永品,它可將每一個鎖定的行表示為一個比特做鹰,經(jīng)測試顯示,每個鎖通常不超過4比特鼎姐。**
MySQL thread id 26208154, OS thread handle 0x7fec7c235700, query id 5274800671 10.143.90.228 root Sending data** #與show processlist輸出結(jié)果大部分相同**
SELECT /*!40001 SQL_NO_CACHE */ * FROM m_flowskillpoint
#如果事務(wù)正在運行一個查詢钾麸,那么這里就會顯示事務(wù)涉及的SQL更振,注意:有些版本可能只顯示其中一小段,而不是完整的SQL
Trx read view will not see trx with id >= 4E0110E8, sees < 4E0108EE #這行顯示了事務(wù)的讀視圖喂走,它表明了因為版本關(guān)系而產(chǎn)生的對于事務(wù)可見和不可見兩種類型的事務(wù)ID的范圍殃饿,在這里,兩個數(shù)字之間有一個事務(wù)的間隙芋肠,這個間隙里的事務(wù)可能是不可見的乎芳,innodb在執(zhí)行查詢時,對于那些事務(wù)ID正好在這個間隙的行帖池,還會檢查其可見性奈惑。
注:如果事務(wù)正在等待一個鎖,那么在查詢SQL文本后面將可以看到這個鎖的信息睡汹,在上文的死鎖例子里肴甸,這樣的信息看到過很多了,不幸的是囚巴,輸出信息并沒有說出這個鎖正被其他哪個事務(wù)持有原在,不過可以通過information_schema庫下的innodb_trx,innodb_lock_waits彤叉,innodb_locks三個表來查明這一點庶柿。如果輸出信息里有很多個事務(wù),innodb可能會限制要打印出來的事務(wù)數(shù)目秽浇,以免輸出信息增長得太大浮庐,這時就會看到...truncated...提示。
7.FILE I/O部分顯示的是I/O輔助線程的狀態(tài)柬焕,還有性能計數(shù)器的狀態(tài)审残,如下:
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] , #讀線程和寫線程掛起操作的數(shù)目等,aio的意思是異步I/O
ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0 ** #insert buffer thread掛起的fsync()操作數(shù)目等**
Pending flushes (fsync) log: 0; buffer pool: 0 #log thread掛起的fsync()操作數(shù)目等
146246831 OS file reads, 760501349 OS file writes, 247143684 OS fsyncs #這行顯示了讀斑举,寫和fsync()調(diào)用執(zhí)行的數(shù)目搅轿,在你的機器環(huán)境負載下這些絕對值可能會有所不同,因此更重要的是監(jiān)控它們過去一段時間內(nèi)是如何改變的懂昂。
1 pending preads, 0 pending pwrites #這行顯示了當前被掛起的讀和寫操作數(shù)
145.49 reads/s, 783677 avg bytes/read, 28.75 writes/s, 10.67 fsyncs/s ** #這行顯示了在頭部顯示的時間(指的是第1部分的時間)段內(nèi)的每秒平均值介时。**
注:三行掛起讀寫線程、緩沖池線程凌彬、日志線程的統(tǒng)計信息的值是檢測I/O受限的應(yīng)用的一個好方法,如果這些I/O大部分有掛起操作循衰,那么負載可能I/O受限铲敛。在linux系統(tǒng)下使用參數(shù):innodb_read_io_threads和innodb_write_io_threads兩個變量來配置讀寫線程的數(shù)量,默認為各4個線程会钝。
insert buffer thread:負責插入緩沖合并伐蒋,如:記錄被從插入緩沖合并到表空間中
log thread:負責異步刷事務(wù)日志
read thread:執(zhí)行預(yù)讀操作以嘗試預(yù)先讀取innodb預(yù)感需要的數(shù)據(jù)
write thread:刷新臟頁緩沖
8.這部分顯示了insert buffer和adaptive hash index兩個部分的結(jié)構(gòu)的狀態(tài)
INSERT BUFFER AND ADAPTIVE HASH INDEX
Ibuf: size 12, free list len 27559, seg size 27572, 18074934 merges ** #這行顯示了關(guān)于size(size 12代表了已經(jīng)合并記錄頁的數(shù)量)工三、free list(代表了插入緩沖中空閑列表長度)和seg size大小(seg size 27572顯示了當前insert buffer的長度先鱼,大小為2757216K=440M左右)的信息俭正。18074934 merges代表合并插入的次數(shù)*
merged operations:** #這個標簽****下的一行信息insert,delete mark焙畔,delete分別表示merge操作合并了多少個insert buffer掸读,delete buffer,purge buffer**
insert 81340470, delete mark 8893610, delete 818579
discarded operations:** #這個標簽下的一行信息表示當change buffer發(fā)生merge時表已經(jīng)被刪除了宏多,就不需要再將記錄合并到輔助索引中了**
insert 0, delete mark 0, delete 0
Hash table size 87709057, node heap has 10228 buffer(s)** #這行顯示了自使用哈希索引的狀態(tài)儿惫,其中,Hash table size 87709057表示AHI的大小伸但,node heap has 10228 buffer(s)表示AHI的使用情況**
1741.05 hash searches/s, 539.48 non-hash searches/s** #這行顯示了在頭部第1部分提及的時間內(nèi)Innodb每秒完成了多少哈希索引操作肾请,1741.05 hash searches/s表示每秒使用AHI搜索的情況,539.48 non-hash searches/s表示每秒沒有使用AHI搜索的情況(因為哈希索引只能用于等值查詢更胖,而范圍查詢铛铁,模糊查詢是不能使用哈希索引的。)却妨,通過hash searches: non-hash searches的比例大概可以了解使用哈希索引后的效率饵逐,哈希索引查找與非哈希索引查找的比例僅供參考,自適應(yīng)哈希索引無法配置管呵,但是可以通過innodb_adaptive_hash_index=ON|OFF參數(shù)來選擇是否需要這個特性梳毙。**
注:
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對應(yīng)update 操作的第一個過程,即將記錄標記為刪除档叔,purge buffer對應(yīng)update的第二個過程桌粉,即將記錄真正地刪除
9.這部分顯示了關(guān)于innodb事務(wù)日志(重做日志)子系統(tǒng)的統(tǒng)計:
LOG
Log sequence number 1351392990515 ** #這行顯示了當前最新數(shù)據(jù)產(chǎn)生的日志序列號**
Log flushed up to 1351392989504 #這行顯示了日志已經(jīng)刷新到哪個位置了(已經(jīng)落盤到事務(wù)日志中的日志序列號)
Last checkpoint at 1351373900020 #這行顯示了上一次檢查點的位置(一個檢查點表示一個數(shù)據(jù)和日志文件都處于一致狀態(tài)的時刻,并且能用于恢復(fù)數(shù)據(jù))衙四,如果上一次檢查點落后與上一行太多铃肯,并且差異接近于事務(wù)日志文件的大小,Innodb會觸發(fā)“瘋狂刷”传蹈,這對性能而言非常糟糕押逼。
0 pending log writes, 0 pending chkp writes** #這行顯示了當前掛起的日志讀寫操作步藕,可以將這行的值與第7部分FILE I/O對應(yīng)的值做比較,以了解你的I/O有多少是由于日志系統(tǒng)引起的挑格。**
286879989 log i/o's done, 15.92 log i/o's/second #這行顯示了日志操作的統(tǒng)計和每秒日志I/O數(shù)咙冗,可以將這行的值與第7部分FILE I/O對應(yīng)的值做比較,以了解你的I/O有多少是由于日志系統(tǒng)引起的漂彤。
9.這部分顯示了關(guān)于innodb緩沖池及其如何使用內(nèi)存的統(tǒng)計:
9.1.
BUFFER POOL AND MEMORY
Total memory allocated 45357793280; in additional pool allocated 0** #這行顯示了由innodb分配的總內(nèi)存雾消,以及其中多少是額外內(nèi)存池分配,額外內(nèi)存池僅分配了其中很小一部分內(nèi)存显歧,由內(nèi)部內(nèi)存分配器分配仪或,現(xiàn)在的innodb版本一般使用操作系統(tǒng)的內(nèi)存分配器,但老版本使用自己的士骤,這是由于在那個時代有些操作系統(tǒng)并未提供一個非常好的內(nèi)存分配實現(xiàn)范删。**
Dictionary memory allocated 12681573
Buffer pool size 2705015 #從這行開始的下面4行顯示緩沖池度量值,以頁為單位拷肌,度量值有總的緩沖池大小到旦,空閑頁數(shù),分配用來存儲數(shù)據(jù)庫頁的頁數(shù)巨缘,以及臟數(shù)據(jù)庫頁數(shù)添忘。這行顯示了緩沖池總共有多少個頁,即即270501516K若锁,共有43G的緩沖池*
Free buffers 5 ** #這行顯示了緩沖池空閑頁數(shù)**
Database pages 2694782 ** #這行顯示了分配用來存儲數(shù)據(jù)庫頁的頁數(shù)搁骑,即,表示LRU列表中頁的數(shù)量,包含young sublist和old sublist**
Old database pages 994651 #這行顯示了LRU中的old sublist部分頁的數(shù)量
Modified db pages 10610** #這行顯示臟數(shù)據(jù)庫頁數(shù)**
Pending reads 128 #這行顯示了掛起讀的數(shù)量
Pending writes: LRU 0, flush list 0, single page 0** #這行顯示了掛起寫的數(shù)量**
#注意又固,這里掛起的讀和寫操作并不與FILE I/O部分的值匹配仲器,因為Innodb可能合并許多的邏輯讀寫操作到一個物理I/O操作中,LRU代表最近使用到的被掛起數(shù)量仰冠,它是通過沖刷緩沖中不經(jīng)常使用的頁來釋放空間以供給經(jīng)常使用的頁的一種方法乏冀,沖刷列表flush list存放著檢查點處理需要沖刷的舊頁被掛起的數(shù)量,單頁single page被掛起的數(shù)量(single page寫是獨立的頁面寫洋只,不會被合并)辆沦。
Pages made young 3014373561, not young 0 #這行顯示了LRU列表中頁移動到LRU首部的次數(shù),因為該服務(wù)器在運行階段改變沒有達到innodb_old_blocks_time閥值的值识虚,因此not young為0
6960.42 youngs/s, 0.00 non-youngs/s** #表示每秒****young和non-youngs這兩類操作的次數(shù)**
Pages read 2946570833, created 43450158, written 574214278** #這行顯示了innodb被讀取肢扯,創(chuàng)建,寫入了多少頁担锤,讀/寫頁的值是指的從磁盤讀到緩沖池的數(shù)據(jù)鹃彻,或者從緩沖池寫到磁盤中的數(shù)據(jù),創(chuàng)建頁指的是innodb在緩沖池中分配但沒有從數(shù)據(jù)文件中讀取內(nèi)容的頁妻献,因為它并不關(guān)心內(nèi)容是什么(如蛛株,它們可能屬于一個已經(jīng)被刪除的表)**
6960.54 reads/s, 4.42 creates/s, 9.33 writes/s ** #這行顯示了對應(yīng)上面一行的每秒read,create育拨,write的頁數(shù)**
Buffer pool hit rate 955 / 1000, young-making rate 45 / 1000 not 0 / 1000 #這行顯示了緩沖池的命中率谨履,它用來衡量innodb在緩沖池中查找到所需頁的比例,它度量自上次Innodb狀態(tài)輸出后到本次輸出這段時間內(nèi)的命中率熬丧,因此笋粟,如果服務(wù)器自那以后一直很安靜,你將會看到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** #這行顯示了頁面預(yù)讀,隨機預(yù)讀的每秒頁數(shù)**
LRU len: 2694782, unzip_LRU len: 0 ** #innodb1.0.x開始支持壓縮頁的功能闷畸,將原來16K的頁壓縮為1K尝盼,2K,4K佑菩,8K盾沫,而由于頁的大小發(fā)生了變化,LRU列表也有了些改變殿漠,對于非16K的頁赴精,是通過unzip_LRU列表進行管理的,可以看到unzip_LRU len為0表示沒有使用壓縮頁.**
I/O sum[60790]:cur[30], unzip sum[0]:cur[0]
對于壓縮頁的表绞幌,每個表的壓縮比例可能不同蕾哟,可能存在有的表頁大小為8K,有的表頁大小為2K的情況莲蜘,unzip_LRUs 怎樣從緩存池中分配內(nèi)存的呢谭确?
首先,在unzip_LRU列表中對不同壓縮頁大小的頁進行分別管理菇夸,其次琼富,通過伙伴算法進行內(nèi)存的分配,例如:需要從緩存池中申請頁為4K的大小庄新,其過程如下:
a:檢查4K的unzip_LRU列表鞠眉,檢查是否有可用的空閑頁
b:若有,則直接使用
c:若沒有择诈,檢查8K的unzip_LRU列表
d:若能夠得到空閑頁械蹋,將頁分成2個4K的頁,存放到4K的unzip_LRU列表
e:若不能得到空閑頁羞芍,從LRU列表中申請一個16K的頁哗戈,將頁分成1個8K,2個4K的頁荷科,分別存放到各自大小對應(yīng)的unzip_LRU列表中唯咬。
注:可能出現(xiàn)Free buffers和Database pages之和不等于Buffer pool size纱注,因為緩沖池中的頁肯會被分配給自適應(yīng)哈希索引,lock信息胆胰,insert buffer等狞贱,而這部分頁不需要LRU算法進行維護,因此不在LRU列表中蜀涨。
9.2.如果innodb buffer pool使用參數(shù)innodb
_buffer_pool_instances=num設(shè)置了大于1個緩沖池實例瞎嬉,那么就會按照這個參數(shù)把innodb_buffer_pool_size=xxx平分為num份。每份的信息顯示類似如下厚柳,這部分的內(nèi)容和9.1小節(jié)內(nèi)容類似氧枣,就不再多說。
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統(tǒng)計:
ROW OPERATIONS
0 queries inside InnoDB, 0 queries in queue ** #這行顯示了innodb內(nèi)核內(nèi)有多少個線程别垮,隊列中有多少個線程便监,隊列中的查詢是innodb為限制并發(fā)執(zhí)行的線程數(shù)量而不運行進入內(nèi)核的線程。查詢在進入隊列之前會休眠等待宰闰。**
5 read views open inside InnoDB ** #這行顯示了有多少打開的innodb讀視圖枚冗,讀視圖是包含事務(wù)開始點的數(shù)據(jù)庫內(nèi)容的MVCC快照贼邓,你可以看看某特定事務(wù)在第6部分TRANSACTIONS是否有讀視圖**
Main thread process no. 4368, id 140653691242240, state: sleeping ** #這行顯示了內(nèi)核的主線程狀態(tài)**
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 #這行顯示了對應(yīng)上面一行的每秒平均值,如果想查看innodb有多少工作量在進行葡盗,那么這兩行是很好的參考值
END OF INNODB MONITOR OUTPUT ** #要注意了螟左,如果看不到這行輸出,可能是有大量事務(wù)或者是有一個大的死鎖截斷了輸出信息**
============================
注:內(nèi)核的主線程狀態(tài)可能的狀態(tài)值有如下一些:
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