一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

mysql之show engine innodb status解讀

 瓜瓜2uuq7332fe 2019-12-12
注:以下內(nèi)容為根據(jù)《高性能mysql第三版》和《mysql技術(shù)內(nèi)幕innodb存儲(chǔ)引擎》的innodb status部分的個(gè)人理解,如果有錯(cuò)誤,還望指正?。?/span>
  innodb存儲(chǔ)引擎在show engine innodb status(老版本對(duì)應(yīng)的是show innodb status)輸出中,顯示除了大量的內(nèi)部信息,它輸出就是一個(gè)單獨(dú)的字符串,沒有行和列,內(nèi)容分為很多小段,每一段對(duì)應(yīng)innodb存儲(chǔ)引擎不同部分的信息,其中有一些信息對(duì)于innodb開發(fā)者來說非常有用,但是,許多信息,如果你嘗試去理解,并且應(yīng)用到高性能innodb調(diào)優(yōu)的時(shí)候,你會(huì)發(fā)現(xiàn)它們非常有趣,甚至是非常有必要的。
    輸出內(nèi)容中包含了一些平均值的統(tǒng)計(jì)信息,這些平均值是自上次輸出結(jié)果生成以來的統(tǒng)計(jì)數(shù),因此,如果你正在檢查這些值,那就要確保已經(jīng)等待了至少30s的時(shí)間,使兩次采樣之間的積累足夠長(zhǎng)的統(tǒng)計(jì)時(shí)間并多次采樣,檢查計(jì)數(shù)器變化從而弄清其行為,并不是所有的輸出都會(huì)在一個(gè)時(shí)間點(diǎn)上生成,因而也不是所有的顯示出來的平均值會(huì)在同一時(shí)間間隔里重新再計(jì)算。而且,innodb有一個(gè)內(nèi)部復(fù)位間隔,而它是不可預(yù)知的,各個(gè)版本也不一樣。
這些輸出信息足夠提供給手工計(jì)算出大多數(shù)你想要的統(tǒng)計(jì)信息,有一款監(jiān)控工具innotop可以幫你計(jì)算出增量差值和平均值。下面,在你的mysql命令行敲下show engine innodb status;看著輸出跟著下面的步驟一步一步理解輸出信息是什么含義:
注意:以下使用mysql5.5.24版本做解讀,mysql5.6.x和5.7.x輸出內(nèi)容有些地方有調(diào)整。
1.第一段是頭部信息,它僅僅聲明了輸出的開始,其內(nèi)容包括當(dāng)前的日期和時(shí)間,以及自上次輸出以來經(jīng)過的時(shí)長(zhǎng)。
=====================================
160129 12:07:26 INNODB MONITOR OUTPUT  #第二行是當(dāng)前日期和時(shí)間
=====================================
Per second averages calculated from the last 24 seconds #第四行顯示的是計(jì)算出這一平均值的時(shí)間間隔,即自上次輸出以來的時(shí)間,或者是距上次內(nèi)部復(fù)位的時(shí)長(zhǎng)
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)進(jìn)行了30977173 1_second次,每秒掛起的操作進(jìn)行了30975685 sleeps次(說明負(fù)載不是很大),10秒一次的活動(dòng)進(jìn)行了3090359 10_second次,1秒循環(huán)和10秒循環(huán)比值符合1:10,backgroup loop進(jìn)行了166112 background次,flush loop進(jìn)行了165988 flush次,如果在一臺(tái)很大壓力的mysql上,可能看到每秒運(yùn)行次數(shù)和掛起次數(shù)比例小于1很多,這是因?yàn)?span lang="EN-US">innodb對(duì)內(nèi)部進(jìn)行了一些優(yōu)化,當(dāng)壓力大時(shí)間隔時(shí)間并不總是等待1秒,因此,不能認(rèn)為每秒循環(huán)和掛起的值總是相等,在某些情況下,可以通過兩者之間的差值來比較反映當(dāng)前數(shù)據(jù)庫的負(fù)載壓力。
srv_master_thread log flush and writes: 31160103
3.如果有高并發(fā)的工作負(fù)載,你就要關(guān)注下接下來的段(SEMAPHORES信號(hào)量),它包含了兩種數(shù)據(jù):事件計(jì)數(shù)器以及可選的當(dāng)前等待線程的列表,如果有性能上的瓶頸,可以使用這些信息來找出瓶頸,不幸的是,想知道怎么使用這些信息還是有一點(diǎn)復(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ù)組的信息,它是一個(gè)插槽數(shù)組,innodb在數(shù)組里為信號(hào)量保留了一些插槽,操作系統(tǒng)用這些信號(hào)量給線程發(fā)送信號(hào),使線程可以繼續(xù)運(yùn)行,以完成它們等著做的事情,這一行還顯示出innodb使用了多少次操作系統(tǒng)的等待:保留統(tǒng)計(jì)(reservation count)顯示了innodb分配插槽的頻度,而信號(hào)計(jì)數(shù)(signal count)衡量的是線程通過數(shù)組得到信號(hào)的頻度,操作系統(tǒng)的等待相對(duì)于空轉(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
    這部分顯示的是當(dāng)前正在等待互斥量的innodb線程,在這里可以看到有兩個(gè)線程正在等待,每一個(gè)都是以--Thread <數(shù)字> has waited...開始,這一段內(nèi)容在正常情況下應(yīng)該是空的(即查看的時(shí)候沒有這部分內(nèi)容),除非服務(wù)器運(yùn)行著高并發(fā)的工作負(fù)載,促使innodb采取讓操作系統(tǒng)等待的措施,除非你對(duì)innodb源碼熟悉,否則這里看到的最有用的信息就是發(fā)生線程等待的代碼文件名 /usr/local/src/soft/mysql-5.5.24/storage/innobase/buf/buf0buf.c line 3151。
    在innodb內(nèi)部哪里才是熱點(diǎn)?舉例來說,如果看到許多線程都在一個(gè)名為buf0buf.c的文件上等待,那就意味著你的系統(tǒng)里存在著
緩沖池競(jìng)爭(zhēng),這個(gè)輸出信息還顯示了這些線程等待了多少時(shí)間,其中waiters flag顯示了有多少個(gè)等待著正在等待同一個(gè)互斥量。 如果waiters flag為0那就表示沒有線程在等待同一個(gè)互斥量(此時(shí)在waiters flag 0后面可能可以看到wait is ending,表示這個(gè)互斥量已經(jīng)被釋放了,但操作系統(tǒng)還沒有把線程調(diào)度過來運(yùn)行)。
    你可能想知道innodb真正等待的是什么,innodb使用了互斥量和信號(hào)量來保護(hù)代碼的臨界區(qū),如:限定每次只能有一個(gè)線程進(jìn)入臨界區(qū),或者是當(dāng)有活動(dòng)的讀時(shí),就限制寫入等。在innodb代碼里有很多臨界區(qū),在合適的條件下,它們都可能出現(xiàn)在那里,常常能見到的一種情形是:獲取緩沖池分頁的訪問權(quán)的時(shí)候。
3.3.
在等待線程之后的部分信息如下,這部分顯示了更多的事件計(jì)數(shù)器,在每一個(gè)情形中,都能看到innodb依靠操作系統(tǒng)等待的頻度:
Mutex spin waits 1157217380, rounds 1783981614, OS waits 10610359 #這行顯示的是跟互斥量相關(guān)的幾個(gè)計(jì)數(shù)器
RW-shared spins 103830012, rounds 1982690277, OS waits 52051891 #這行顯示讀寫的共享鎖的計(jì)數(shù)器
RW-excl spins 43730722, rounds 602114981, OS waits 3495769 #這行顯示讀寫的排他鎖的計(jì)數(shù)器
Spin rounds per wait: 1.54 mutex, 19.10 RW-shared, 13.77 RW-excl
    innodb有著一個(gè)多階段等待的策略,首先,它會(huì)試著對(duì)鎖進(jìn)行空轉(zhuǎn)等待,如果經(jīng)歷了一個(gè)預(yù)設(shè)的空轉(zhuǎn)等待周期(設(shè)置innodb_sync_spin_loops配置變量命令)之后還沒有成功,那就會(huì)退到更昂貴更復(fù)雜的等待數(shù)組中。
    空轉(zhuǎn)等待的成本相對(duì)較低,但是它們要不停地檢查一個(gè)資源能否被鎖定,這種方式會(huì)消耗CPU周期,但是,這沒有聽起來那么糟糕,因?yàn)楫?dāng)處理器在等待IO時(shí),一般都有一些空閑的CPU周期可用,即使是沒有空閑的CPU周期,空等也要比其他方式更加廉價(jià)一些。然而,當(dāng)另外一個(gè)線程能做一些事情的時(shí)候,空轉(zhuǎn)等待也還會(huì)把CPU獨(dú)占著。
    空轉(zhuǎn)等待的替代方案就是讓操作系統(tǒng)做上下文切換,這樣,當(dāng)一個(gè)線程在等待時(shí),另外一個(gè)線程就可以被運(yùn)行,然后,通過等待數(shù)組里的信號(hào)量發(fā)出信號(hào),喚醒那個(gè)沉睡的線程,通過信號(hào)量來發(fā)送信號(hào)是比較有效的,但是上下文切換就很昂貴,這很快就會(huì)積少成多,每秒鐘幾千次的切換會(huì)引發(fā)大量的系統(tǒng)開銷。
    你可以通過修改innodb_sync_spin_loops的值,試著在空轉(zhuǎn)等待與操作系統(tǒng)等待之間達(dá)成平衡,不要擔(dān)心空轉(zhuǎn)等待,除非你在一秒里看到幾十萬個(gè)空轉(zhuǎn)等待。此時(shí),你可以考慮performance_schema庫或者show engine innodb mutex;查看下相關(guān)信息。
4.下面這一段外鍵錯(cuò)誤的信息一般不會(huì)出現(xiàn),除非你服務(wù)器上發(fā)生了外鍵錯(cuò)誤,有時(shí)問題在于事務(wù)在插入,更新或刪除一條記錄時(shí)要尋找父表或子表,還有時(shí)候是當(dāng)innodb嘗試增加或刪除一個(gè)外鍵或者修改一個(gè)已經(jīng)存在的外鍵時(shí),發(fā)現(xiàn)表之間類型不匹配,這部分輸出對(duì)于調(diào)試與innodb不明確的外鍵錯(cuò)誤發(fā)生的準(zhǔn)確原因非常有幫助,下面搞一個(gè)示例來看看:
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 有兩種基本的外鍵錯(cuò)誤:
第一種:以某種可能違反外鍵約束關(guān)系的方法增加,更新,刪除數(shù)據(jù),將導(dǎo)致第一類錯(cuò)誤,如,在父表中刪除行時(shí)發(fā)生如下錯(cuò)誤:
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`))
錯(cuò)誤信息相當(dāng)明了,對(duì)所有由增加,刪除,更新不匹配的行導(dǎo)致的錯(cuò)誤都會(huì)看到相似的信息,下面是show engine innodb status的輸出:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
160128  1:17:06 Transaction:  #這行顯示了最近一次外鍵錯(cuò)誤的日期和時(shí)間
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)錯(cuò)誤時(shí)innodb正嘗試修改的準(zhǔn)確數(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)時(shí)發(fā)生的錯(cuò)誤,這種錯(cuò)誤就沒有那么清楚了,這可能會(huì)讓調(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"
for correct foreign key definition.
InnoDB: Renaming table `xiaoboluo`.<result 2 when explaining filename '#sql-b695_4e3b'> to `xiaoboluo`.`parent` failed!
    上面的錯(cuò)誤是數(shù)據(jù)類型不匹配,外鍵列必須有完全相同的數(shù)據(jù)類型,包括任何的修飾符(如這里父表多加了一個(gè)unsigned,這也是問題所在),當(dāng)看到1025錯(cuò)誤并不理解為什么時(shí),最好查看下innodb status。在每次看到有新錯(cuò)誤時(shí),外鍵錯(cuò)誤信息都會(huì)被重寫,percona toolkit中的pt-fk-error-logger工具可以用表保存這些信息以供后續(xù)分析。
5.與外鍵錯(cuò)誤一樣,這部分只有當(dāng)服務(wù)器產(chǎn)生死鎖時(shí)才會(huì)出現(xiàn),死鎖信息同樣在每次有新的死鎖錯(cuò)誤時(shí)被重寫,percona toolkit中的pt-deadlock-logger工具可以用表保存這些信息以供后續(xù)分析
    死鎖在等待關(guān)系圖里是一個(gè)循環(huán),就是一個(gè)鎖定了行的數(shù)據(jù)結(jié)構(gòu)又在等待別的鎖,這個(gè)循環(huán)可以任意地大,innodb會(huì)立即檢測(cè)到死鎖,因?yàn)槊慨?dāng)有事務(wù)等待行鎖的時(shí)候,它都會(huì)去檢查等待關(guān)系圖里是否有循環(huán),死鎖的情況可能會(huì)比較復(fù)雜,但是,這一部分只顯示了最近的兩個(gè)死鎖的情況,它們?cè)诟髯缘氖聞?wù)里執(zhí)行的最后一條語句,以及它們?cè)诘却P(guān)系圖里形成環(huán)鎖的信息。在這個(gè)循環(huán)里你看不到其他事務(wù),也可能看不到在事務(wù)里早先真正獲得了鎖的語句,盡管如此,通常還是可以通過查看這些輸出結(jié)果來確定到底是什么引起了死鎖。
    在innodb里實(shí)際上有兩種死鎖,第一種就是常常碰到的那種,它在等待關(guān)系圖里是一個(gè)真正的循環(huán),另外一種就是在一個(gè)等待關(guān)系圖里,因代價(jià)昂貴而無法檢測(cè)它是不是包含了循環(huán),如果innodb要在關(guān)系圖里檢查超過100W個(gè)鎖,或者在檢查過程中,innodb要重做200個(gè)以上的事務(wù),那它會(huì)放棄,并宣布這里有一個(gè)死鎖,這些數(shù)值都是硬編碼在innodb代碼里的常量,無法配置(如果你NB可以修改代碼然后重新編譯)。第二種死鎖報(bào)錯(cuò)你可以在輸出里看到一條信息:TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH

    innodb不僅會(huì)打印出事務(wù)和事務(wù)持有和等待的鎖,而且還有記錄本身,不幸的是,它至于可能超過為輸出結(jié)果預(yù)留的長(zhǎng)度(只能打印1M的內(nèi)容且只能保留最近一次的死鎖信息),如果你無法看到完整的輸出,此時(shí)可以在任意庫下創(chuàng)建innodb_monitor或innodb_lock_monitor表,這樣innodb status信息會(huì)完整且每15s一次被記錄到錯(cuò)誤日志中。如:create table innodb_monitor(a int)engine=innodb;,不需要記錄到錯(cuò)誤日志中時(shí)就刪掉這個(gè)表即可。

5.1 下面也搞一個(gè)示例來看看:
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 插入測(cè)試數(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
打開兩個(gè)會(huì)話終端:
5.1.3 會(huì)話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 接著會(huì)話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 回到會(huì)話1執(zhí)行下面的SQL,會(huì)發(fā)生等待:
mysql> select * from test_deadlock where id=2 for update;
5.1.6 回到會(huì)話2執(zhí)行下面的SQL,產(chǎn)生死鎖,會(huì)話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ā)生死鎖的日期和時(shí)間
*** (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)容比較多,下面分段逐一進(jìn)行解釋:
5.2.1 下面這部分顯示的是死鎖的第一個(gè)事務(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個(gè)表,且涉及鎖的表有1個(gè)
LOCK WAIT 3 lock struct(s), heap size 376, 2 row lock(s) #這行表示在等待3把鎖,占用內(nèi)存376字節(jié),涉及2行記錄,如果事務(wù)已經(jīng)鎖定了幾行數(shù)據(jù),這里將會(huì)有一行信息顯示出鎖定結(jié)構(gòu)的數(shù)目(注意,這跟行鎖是兩回事)和堆大小,堆的大小指的是為了持有這些行鎖而占用的內(nèi)存大小,Innodb是用一種特殊的位圖表來實(shí)現(xiàn)行鎖的,從理論上講,它可將每一個(gè)鎖定的行表示為一個(gè)比特,經(jīng)測(cè)試顯示,每個(gè)鎖通常不超過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 下面這一部分顯示的是當(dāng)死鎖發(fā)生時(shí),第一個(gè)事務(wù)正在等待的鎖等信息:
*** (1) WAITING FOR THIS LOCK TO BE GRANTED: #這行信息表示第一個(gè)事務(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#這行信息表示等待的鎖是一個(gè)record lock,空間id是441,頁編號(hào)為3,大概位置在頁的72位處,鎖發(fā)生在表xiaoboluo.test_deadlock的主鍵上,是一個(gè)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)容只對(duì)調(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個(gè)表,涉及鎖的表有1個(gè)
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 #第二個(gè)事務(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 #從這兩行持有鎖信息計(jì)息后面幾行調(diào)試信息上看,就是事務(wù)1正在等待的鎖。
5.2.5 下面這部分是事務(wù)二正在等待的鎖,從下面的信息上看,等待的是同一個(gè)表,同一個(gè)索引,同一個(gè)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) #這個(gè)表示事務(wù)2被回滾,因?yàn)閮蓚€(gè)事務(wù)的回滾開銷一樣,所以選擇了后提交的事務(wù)進(jìn)行回滾,如果兩個(gè)事務(wù)回滾的開銷不同(undo 數(shù)量不同),那么就回滾開銷最小的那個(gè)事務(wù)。
    當(dāng)一個(gè)事務(wù)持有了其他事務(wù)需要的鎖,同時(shí)又想獲得其他事務(wù)持有的鎖時(shí),等待關(guān)系圖上就會(huì)產(chǎn)生循環(huán),Innodb不會(huì)顯示所有持有和等待的鎖,但是,它顯示了足夠的信息來幫你確定,查詢操作正在使用哪些索引,這對(duì)于你確定能否避免死鎖有極大的價(jià)值。
    如果能使兩個(gè)查詢對(duì)同一個(gè)索引朝同一個(gè)方向進(jìn)行掃描,就能降低死鎖的數(shù)目,因?yàn)?,查詢?cè)谕粋€(gè)順序上請(qǐng)求鎖的時(shí)候不會(huì)創(chuàng)建循環(huán),有時(shí)候,這是很容易做到的,如:要在一個(gè)事務(wù)里更新許多條記錄,就可以在應(yīng)用程序的內(nèi)存里把它們按照主鍵進(jìn)行排序,然后,再用同樣的順序更新到數(shù)據(jù)庫里,這樣就不會(huì)有死鎖發(fā)生,但是在另一些時(shí)候,這個(gè)方法也是行不通的(如果有兩個(gè)進(jìn)程使用了不同的索引區(qū)間操作同一張表的時(shí)候)。
6. 下面這部分包含了一些關(guān)于innodb事務(wù)的總結(jié)信息,緊隨其后的是當(dāng)前活躍事務(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)容比較多,下面分段逐一進(jìn)行解釋:
6.1.
Trx id counter 4E0132AD #這行表示當(dāng)前事務(wù)ID,這是一個(gè)系統(tǒng)變量,每創(chuàng)建一個(gè)新事務(wù)都會(huì)增加
Purge done for trx's n:o < 4E01090B undo n:o < 0 #這是innodb清除舊MVCC行時(shí)所用的事務(wù)ID,將這個(gè)值和當(dāng)前事務(wù)ID進(jìn)行比較,就可以知道有多少老版本的數(shù)據(jù)未被清除。這個(gè)數(shù)字多大才可以安全的取值沒有硬性和速成的規(guī)定,如果數(shù)據(jù)沒做過任何更新,那么一個(gè)巨大的數(shù)字也不意味著有未清除的數(shù)據(jù),因?yàn)閷?shí)際上所有事務(wù)在數(shù)據(jù)庫里查看的都是同一個(gè)版本的數(shù)據(jù)(此時(shí)只是事務(wù)ID在增加,而數(shù)據(jù)沒有變更),另一方面,如果有很多行被更新,那每一行就會(huì)有一個(gè)或多個(gè)版本留在內(nèi)存里,減少此類開銷的最好辦法就是確保事務(wù)已完成就立即提交,不要讓它長(zhǎng)時(shí)間地處于打開狀態(tài),因?yàn)橐粋€(gè)打開的事務(wù)即使不做任何操作,也會(huì)影響到innodb清理舊版本的行數(shù)據(jù)。 undo n:o < 0這個(gè)是innodb清理進(jìn)程正在使用的撤銷日志編號(hào),為0 0時(shí)說明清理進(jìn)程處于空閑狀態(tài)。
History list length 1853  #歷史記錄的長(zhǎng)度,即位于innodb數(shù)據(jù)文件的撤銷空間里的頁面的數(shù)目,如果事務(wù)執(zhí)行了更新并提交,這個(gè)數(shù)字就會(huì)增加,而當(dāng)清理進(jìn)程移除舊版本數(shù)據(jù)時(shí),它就會(huì)減少,清理進(jìn)程也會(huì)更新Purge done for.....這行中的數(shù)值。
6.2.
頭部信息之后就是一個(gè)事務(wù)列表,當(dāng)前版本的mysql還不支持嵌套事務(wù),因此,在某個(gè)時(shí)間點(diǎn)上,每個(gè)客戶端連接能夠擁有的事務(wù)數(shù)量是有一個(gè)上限的,而且每一個(gè)事務(wù)只能屬于單一連接(即一個(gè)事務(wù)只能使用單個(gè)線程執(zhí)行,不能使用多個(gè)線程)。在輸出信息里,每一個(gè)事務(wù)至少占有兩行內(nèi)容,如:
---TRANSACTION 4E0131D3, not started  #每個(gè)事務(wù)的第一行以事務(wù)的ID和狀態(tài)開始,not started表示這個(gè)事務(wù)已經(jīng)提交并且沒有再發(fā)起影響事務(wù)的語句,可能剛好空閑
MySQL thread id 26208218, OS thread handle 0x7fec7c582700, query id 5274800318 10.207.162.69 gdsser #然后每個(gè)事務(wù)的第二行是一些線程等信息,MySQL thread id <數(shù)字>部分和是hi用show full processlist;命令看到的id列相同。緊隨其后的是一個(gè)內(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ù)日志落盤了就會(huì)變成not started狀態(tài)。在時(shí)間后面會(huì)顯示出當(dāng)前事務(wù)正在做什么(在這里為空沒有顯示出來),在源代碼中有超過30個(gè)字符串常量可以顯示在時(shí)間后面,如:fetching,preparing,rows,adding foreign keys等等
mysql tables in use 1, locked 0 #該事務(wù)用到的表數(shù)和涉及表鎖的表數(shù),Innodb一般不會(huì)鎖定表,但對(duì)有些語句會(huì)鎖定,如果mysql服務(wù)器在高于innodb層之上將表鎖定,這里也是能夠顯示出來的,如果事務(wù)已經(jīng)鎖定了幾行數(shù)據(jù),這里將會(huì)有一行信息顯示出鎖定結(jié)構(gòu)的數(shù)目(注意,這跟行鎖是兩回事)和和堆大小,如:2 lock struct(s), heap size 376, 1 row lock(s), undo log entries 1,堆的大小指的是為了持有這些行鎖而占用的內(nèi)存大小,Innodb是用一種特殊的位圖表來實(shí)現(xiàn)行鎖的,從理論上講,它可將每一個(gè)鎖定的行表示為一個(gè)比特,經(jīng)測(cè)試顯示,每個(gè)鎖通常不超過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ù)正在運(yùn)行一個(gè)查詢,那么這里就會(huì)顯示事務(wù)涉及的SQL,注意:有些版本可能只顯示其中一小段,而不是完整的SQL
Trx read view will not see trx with id >= 4E0110E8, sees < 4E0108EE #這行顯示了事務(wù)的讀視圖,它表明了因?yàn)榘姹娟P(guān)系而產(chǎn)生的對(duì)于事務(wù)可見和不可見兩種類型的事務(wù)ID的范圍,在這里,兩個(gè)數(shù)字之間有一個(gè)事務(wù)的間隙,這個(gè)間隙里的事務(wù)可能是不可見的,innodb在執(zhí)行查詢時(shí),對(duì)于那些事務(wù)ID正好在這個(gè)間隙的行,還會(huì)檢查其可見性。
注:如果事務(wù)正在等待一個(gè)鎖,那么在查詢SQL文本后面將可以看到這個(gè)鎖的信息,在上文的死鎖例子里,這樣的信息看到過很多了,不幸的是,輸出信息并沒有說出這個(gè)鎖正被其他哪個(gè)事務(wù)持有,不過可以通過information_schema庫下的innodb_trx,innodb_lock_waits,innodb_locks三個(gè)表來查明這一點(diǎn)。如果輸出信息里有很多個(gè)事務(wù),innodb可能會(huì)限制要打印出來的事務(wù)數(shù)目,以免輸出信息增長(zhǎng)得太大,這時(shí)就會(huì)看到...truncated...提示。
7.FILE I/O部分顯示的是I/O輔助線程的狀態(tài),還有性能計(jì)數(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  #以上為默認(rèn)的4個(gè)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) #以上為默認(rèn)的4個(gè)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ù)目,在你的機(jī)器環(huán)境負(fù)載下這些絕對(duì)值可能會(huì)有所不同,因此更重要的是監(jiān)控它們過去一段時(shí)間內(nèi)是如何改變的。
1 pending preads, 0 pending pwrites  #這行顯示了當(dāng)前被掛起的讀和寫操作數(shù)
145.49 reads/s, 783677 avg bytes/read, 28.75 writes/s, 10.67 fsyncs/s  #這行顯示了在頭部顯示的時(shí)間(指的是第1部分的時(shí)間)段內(nèi)的每秒平均值。
注:三行掛起讀寫線程、緩沖池線程、日志線程的統(tǒng)計(jì)信息的值是檢測(cè)I/O受限的應(yīng)用的一個(gè)好方法,如果這些I/O大部分有掛起操作,那么負(fù)載可能I/O受限。在linux系統(tǒng)下使用參數(shù):innodb_read_io_threads和innodb_write_io_threads兩個(gè)變量來配置讀寫線程的數(shù)量,默認(rèn)為各4個(gè)線程。
insert buffer thread:負(fù)責(zé)插入緩沖合并,如:記錄被從插入緩沖合并到表空間中
log thread:負(fù)責(zé)異步刷事務(wù)日志
read thread:執(zhí)行預(yù)讀操作以嘗試預(yù)先讀取innodb預(yù)感需要的數(shù)據(jù)
write thread:刷新臟頁緩沖
8.這部分顯示了insert buffer和adaptive hash index兩個(gè)部分的結(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(代表了插入緩沖中空閑列表長(zhǎng)度)和seg size大?。?span lang="EN-US">seg size 27572顯示了當(dāng)前insert buffer的長(zhǎng)度,大小為27572*16K=440M左右)的信息。18074934 merges代表合并插入的次數(shù)
merged operations: #這個(gè)標(biāo)簽下的一行信息insert,delete mark,delete分別表示merge操作合并了多少個(gè)insert buffer,delete buffer,purge buffer
 insert 81340470, delete mark 8893610, delete 818579
discarded operations: #這個(gè)標(biāo)簽下的一行信息表示當(dāng)change buffer發(fā)生merge時(shí)表已經(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部分提及的時(shí)間內(nèi)Innodb每秒完成了多少哈希索引操作,1741.05 hash searches/s表示每秒使用AHI搜索的情況,539.48 non-hash searches/s表示每秒沒有使用AHI搜索的情況(因?yàn)楣K饕荒苡糜诘戎挡樵?,而范圍查詢,模糊查詢是不能使用哈希索引的?span lang="EN-US">),通過hash searches: non-hash searches的比例大概可以了解使用哈希索引后的效率,哈希索引查找與非哈希索引查找的比例僅供參考,自適應(yīng)哈希索引無法配置,但是可以通過innodb_adaptive_hash_index=ON|OFF參數(shù)來選擇是否需要這個(gè)特性。
注:

innodb從1.0.x開始引入change buffer,可以視為insert buffer的升級(jí),從這個(gè)版本開始,innodb可以對(duì)DML操作(insert,delete,update)都進(jìn)行緩沖,他們分別是insert buffer,delete buffer,purge buffer,當(dāng)然和之前insert buffer一樣,change buffer適用對(duì)象仍然是非唯一索引的輔助索引,因?yàn)闆]有update buffer,所以對(duì)一條記錄進(jìn)行update的操作可以分為兩個(gè)過程:

A:將記錄標(biāo)記為刪除

B:真正將記錄刪除

因此,delete buffer對(duì)應(yīng)update 操作的第一個(gè)過程,即將記錄標(biāo)記為刪除,purge buffer對(duì)應(yīng)update的第二個(gè)過程,即將記錄真正地刪除
9.這部分顯示了關(guān)于innodb事務(wù)日志(重做日志)子系統(tǒng)的統(tǒng)計(jì):
---
LOG
---
Log sequence number 1351392990515  #這行顯示了當(dāng)前最新數(shù)據(jù)產(chǎn)生的日志序列號(hào)
Log flushed up to   1351392989504 #這行顯示了日志已經(jīng)刷新到哪個(gè)位置了(已經(jīng)落盤到事務(wù)日志中的日志序列號(hào))
Last checkpoint at  1351373900020 #這行顯示了上一次檢查點(diǎn)的位置(一個(gè)檢查點(diǎn)表示一個(gè)數(shù)據(jù)和日志文件都處于一致狀態(tài)的時(shí)刻,并且能用于恢復(fù)數(shù)據(jù)),如果上一次檢查點(diǎn)落后與上一行太多,并且差異接近于事務(wù)日志文件的大小,Innodb會(huì)觸發(fā)“瘋狂刷”,這對(duì)性能而言非常糟糕。
0 pending log writes, 0 pending chkp writes  #這行顯示了當(dāng)前掛起的日志讀寫操作,可以將這行的值與第7部分FILE I/O對(duì)應(yīng)的值做比較,以了解你的I/O有多少是由于日志系統(tǒng)引起的。
286879989 log i/o's done, 15.92 log i/o's/second #這行顯示了日志操作的統(tǒng)計(jì)和每秒日志I/O數(shù),可以將這行的值與第7部分FILE I/O對(duì)應(yīng)的值做比較,以了解你的I/O有多少是由于日志系統(tǒng)引起的。
9.這部分顯示了關(guān)于innodb緩沖池及其如何使用內(nèi)存的統(tǒng)計(jì):
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)部?jī)?nèi)存分配器分配,現(xiàn)在的innodb版本一般使用操作系統(tǒng)的內(nèi)存分配器,但老版本使用自己的,這是由于在那個(gè)時(shí)代有些操作系統(tǒng)并未提供一個(gè)非常好的內(nèi)存分配實(shí)現(xiàn)。
Dictionary memory allocated 12681573
Buffer pool size   2705015  #從這行開始的下面4行顯示緩沖池度量值,以頁為單位,度量值有總的緩沖池大小,空閑頁數(shù),分配用來存儲(chǔ)數(shù)據(jù)庫頁的頁數(shù),以及臟數(shù)據(jù)庫頁數(shù)。這行顯示了緩沖池總共有多少個(gè)頁,即即2705015*16K,共有43G的緩沖池
Free buffers       5  #這行顯示了緩沖池空閑頁數(shù)
Database pages     2694782  #這行顯示了分配用來存儲(chǔ)數(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部分的值匹配,因?yàn)镮nnodb可能合并許多的邏輯讀寫操作到一個(gè)物理I/O操作中,LRU代表最近使用到的被掛起數(shù)量,它是通過沖刷緩沖中不經(jīng)常使用的頁來釋放空間以供給經(jīng)常使用的頁的一種方法,沖刷列表flush list存放著檢查點(diǎn)處理需要沖刷的舊頁被掛起的數(shù)量,單頁single page被掛起的數(shù)量(single page寫是獨(dú)立的頁面寫,不會(huì)被合并)。
Pages made young 3014373561, not young 0 #這行顯示了LRU列表中頁移動(dòng)到LRU首部的次數(shù),因?yàn)樵摲?wù)器在運(yùn)行階段改變沒有達(dá)到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)容的頁,因?yàn)樗⒉魂P(guān)心內(nèi)容是什么(如,它們可能屬于一個(gè)已經(jīng)被刪除的表)
6960.54 reads/s, 4.42 creates/s, 9.33 writes/s  #這行顯示了對(duì)應(yīng)上面一行的每秒read,create,write的頁數(shù)
Buffer pool hit rate 955 / 1000, young-making rate 45 / 1000 not 0 / 1000  #這行顯示了緩沖池的命中率,它用來衡量innodb在緩沖池中查找到所需頁的比例,它度量自上次Innodb狀態(tài)輸出后到本次輸出這段時(shí)間內(nèi)的命中率,因此,如果服務(wù)器自那以后一直很安靜,你將會(huì)看到No buffer pool page gets since the last printout。它對(duì)于度量緩存池的大小并沒有用處。
Pages read ahead 6928.54/s, evicted without access 8.21/s, Random read ahead 0.00/s #這行顯示了頁面預(yù)讀,隨機(jī)預(yù)讀的每秒頁數(shù)
LRU len: 2694782, unzip_LRU len: 0  #innodb1.0.x開始支持壓縮頁的功能,將原來16K的頁壓縮為1K,2K,4K,8K,而由于頁的大小發(fā)生了變化,LRU列表也有了些改變,對(duì)于非16K的頁,是通過unzip_LRU列表進(jìn)行管理的,可以看到unzip_LRU len為0表示沒有使用壓縮頁.
I/O sum[60790]:cur[30], unzip sum[0]:cur[0]

對(duì)于壓縮頁的表,每個(gè)表的壓縮比例可能不同,可能存在有的表頁大小為8K,有的表頁大小為2K的情況,unzip_LRUs 怎樣從緩存池中分配內(nèi)存的呢?

首先,在unzip_LRU列表中對(duì)不同壓縮頁大小的頁進(jìn)行分別管理,其次,通過伙伴算法進(jìn)行內(nèi)存的分配,例如:需要從緩存池中申請(qǐng)頁為4K的大小,其過程如下:

a:檢查4K的unzip_LRU列表,檢查是否有可用的空閑頁

b:若有,則直接使用

c:若沒有,檢查8K的unzip_LRU列表

d:若能夠得到空閑頁,將頁分成2個(gè)4K的頁,存放到4K的unzip_LRU列表

e:若不能得到空閑頁,從LRU列表中申請(qǐng)一個(gè)16K的頁,將頁分成1個(gè)8K,2個(gè)4K的頁,分別存放到各自大小對(duì)應(yīng)的unzip_LRU列表中。

注:可能出現(xiàn)Free buffers和Database pages之和不等于Buffer pool size,因?yàn)榫彌_池中的頁肯會(huì)被分配給自適應(yīng)哈希索引,lock信息,insert buffer等,而這部分頁不需要LRU算法進(jìn)行維護(hù),因此不在LRU列表中。

 

 

9.2.如果innodb buffer pool使用參數(shù)innodb

_buffer_pool_instances=num設(shè)置了大于1個(gè)緩沖池實(shí)例,那么就會(huì)按照這個(gè)參數(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.這部分顯示了其他各項(xiàng)的innodb統(tǒng)計(jì):

--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue  #這行顯示了innodb內(nèi)核內(nèi)有多少個(gè)線程,隊(duì)列中有多少個(gè)線程,隊(duì)列中的查詢是innodb為限制并發(fā)執(zhí)行的線程數(shù)量而不運(yùn)行進(jìn)入內(nèi)核的線程。查詢?cè)谶M(jìn)入隊(duì)列之前會(huì)休眠等待。
5 read views open inside InnoDB  #這行顯示了有多少打開的innodb讀視圖,讀視圖是包含事務(wù)開始點(diǎn)的數(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 #這行顯示了對(duì)應(yīng)上面一行的每秒平均值,如果想查看innodb有多少工作量在進(jìn)行,那么這兩行是很好的參考值
----------------------------
END OF INNODB MONITOR OUTPUT  #要注意了,如果看不到這行輸出,可能是有大量事務(wù)或者是有一個(gè)大的死鎖截?cái)嗔溯敵鲂畔?/strong>
============================

 

注:內(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

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    日韩熟妇人妻一区二区三区| 久久精视频免费视频观看| 成人精品欧美一级乱黄| 亚洲夫妻性生活免费视频| 欧美成人一区二区三区在线 | 欧美日韩国产福利在线观看| 日韩一区二区三区观看| 亚洲欧美日韩网友自拍| 九九久久精品久久久精品| 一区二区三区亚洲国产| 久久亚洲精品中文字幕| 免费观看成人免费视频| 五月激情综合在线视频| 久久99青青精品免费| 超碰在线免费公开中国黄片| 国产女同精品一区二区| 午夜福利大片亚洲一区| 日韩一区二区三区在线日| 五月婷婷缴情七月丁香| 午夜午夜精品一区二区| 日本不卡在线一区二区三区| 久久福利视频这里有精品| 一区二区日韩欧美精品| 国产免费一区二区不卡| 国产日韩综合一区在线观看| 99久久国产精品免费| 偷拍偷窥女厕一区二区视频| 粉嫩国产美女国产av| 久久久精品区二区三区| 日本人妻熟女一区二区三区| 日韩和欧美的一区二区三区| 国产精品午夜福利免费阅读| 日本加勒比不卡二三四区| 亚洲av首页免费在线观看| 亚洲欧美日本国产有色| 91亚洲国产成人久久| 精品日韩欧美一区久久| 老熟女露脸一二三四区| 日本女优一区二区三区免费| 国产一区二区在线免费| 日韩欧美一区二区亚洲|