17.高性能MySQL --- MySQL 分支與變種

原文鏈接:https://book.douban.com/subject/3766465/

 

1.系統參數
	mysql 通過 show variables sql 命令暴露了許多系統變量。或者通過命令行 mysqladmin variables。
  這些變量反映了一系列配置信息,如服務器的默認存儲引擎,可用時區等。

2.show status
	show status 命令會顯示每個服務器變量的名字和值。和上面講的服務器參數不一樣,狀態變量是隻讀的。可以在mysql
  客戶端裏運行show status 或者在命令行裏運行mysqladmin extended-status 來查看這些變量。如果用sql命令,可以
  使用 like 或者 where 來限制。可以用 like 對變量名做標準模式匹配。命令將返回一個表,但不能對它進行排序,與另外
  一個表進行聯合操作。在mysql 5.1 中,可以直接從 information_schema.global_status 和 information_schema.session_status 
  表中查詢值。
  	show global status; //全局變量
  	show status; //會話變量

  	有上百個變量。大部分要麼是計數器,要麼是包含某些狀態指標的當前值。每次mysql做一些事情都會導致計數器的增長,比如開始初始化一個全表
  掃描(Select_scan)。度量值,例如打開的到服務器的連接數(Threads_connected),可能增長或者減少。有時候幾個變量貌似指向相同的事情,如
  Connections(嘗試連接到服務器的連接數量)和Threads_connected。變量是關聯的,但類似的名字並不總是隱含某種關係。
    變量採用無符號整形存儲。它們在32位編譯系統上是4個字節,而在64位環境上用8個字節,並且當達到最大後重新從0開始。如果你增量的監測這些
  變量,可能需要觀察並修正這個繞回處理。你也需要意識到如果服務器已經運行了很長一段時間,可能會有比預期更小的值,這是因爲這些變量值已經被
  重置爲0.
    如果想對服務器的工作負載有一個大體的瞭解,可以將相關的一組變量放在一起查看和對比---例如,一起查看所有的 Select_* 變量,或所有的
  Handler_* 變量。如果使用 innotop,在 Comand Summary 模式下查看更簡單,也可以通過 mysqladmin extended -r -i60 | grep Handler_ 的
  命令完成。

3.線程和連接統計
	這些變量用來追蹤 嘗試的連接,退出的連接,網絡流量和線程統計。
	Connections, Max_used_connections, THreads_connected
	Aborted_clients, Aborted_connects
	Bytes_received, Bytes_sent
	Slow_launch_threads, Threads_cached, Threads_created, Threads_running

	如果 Aborted_connects 不爲0,可能意味着網絡有問題或某人嘗試連接但失敗(可能用戶制定了錯誤的密碼,無效的數據庫,或者某個監控系統正在打開tcp
  的3306端口來檢測服務器是否存活)。如果這個值太高,可能有嚴重的副作用:導致mysql阻塞一個主機。

4.二進制日誌狀態
	Binlog_cache_use 和 Binlog_cache_disk_use 狀態變量顯示了在二進制日誌緩存中有多少事務被存儲過,以及多少事務因超過二進制日誌緩存而必須存儲
  到一個臨時文件中。mysql5.5 中還包含了 Binlog_stmt_cache_use 和 Binlog_stmt_cache_disk_use ,顯示了非事務語句相應的度量值。所謂的 '二進制
  日誌緩存命中率' 往往對配置二進制日誌緩存的大小沒有多少參考意義。

5.命令計數器
	Com_* 變量統計了每種類型的sql或 C API 命令發起過的次數。例如,Com_select 統計了 select 語句的數量,Com_change_db 統計了一個連接的默認數據庫
  被通過 use 語句或者 C API 調用的更改次數。Questions 變量統計總查詢量和服務器收到的命令數。然後,它並不完全等於所有的 Com_* 變量的總和,這與查詢
  緩存命中,關閉和退出的連接,以及其他因素可能有關。
    Com_admin_commands 狀態變量可能非常大。它不僅技術管理命令,並且還包括對mysql實例的ping請求。這些請求通過 C API 發起,並且一般來自客戶端代碼。
  例如, $db->ping();
  	這些 Ping 是垃圾查詢。它們往往不會對服務器產生許多負載,但仍然是個浪費,因爲網絡迴路時間會增加應用的響應時間。我們曾看到ORM系統在每次查詢之前 ping
  服務器,ping 服務器然後再查詢是一個'跳躍之前看一下'設計模式的典型例子,它會產生競爭條件。也看到過每次查詢之前更改默認的數據庫抽象函數庫,這也會產生大量
  的Com_change_db命令。最好消除這2個做法。

6.臨時文件和表
	可以通過下面的命令查看mysql創建臨時表和文件的計數:
	show global status like 'created_tmp%';
	這顯示了關於隱式臨時表和文件的統計---執行查詢時內部創建的。

7.句柄操作
	句柄API是mysql和存儲引擎之間的接口,Handler_* 變量用於統計句柄的操作,例如mysql請求一個存儲引擎從索引中讀取下一行的次數。可以通過下面的語句查看
  這些變量:show global status like 'Handler%';

8.MyISAM 鍵緩衝
	Key_* 變量包含度量值和關於MyISAM鍵緩衝的計數。可以通過下面命令:
	show global status like 'Key_%';
	
9.文件描述符
	如果你主要使用MyISAM存儲引擎,那麼 Open_* 變量揭示了 mysql 每隔多久會打開每個表的 .frm, .MYI, .MYD 文件。InnoDB 保持所有的數據在表空間文件中,
  因此如果你主要使用 InnoDB,那麼這些變量並不精確。
    show global status like 'Open_%';

10.查詢緩存
	通過查詢 Qcache_* 狀態變量可以檢查查詢緩存:
	show global status like 'Qcache_%';

11.SELECT 類型	
	Select_* 變量是特定類型的 select 查詢的計數器。它們能幫助你瞭解使用各種查詢計劃的 select 查詢比率。不幸的是,並沒有關於其他查詢類型的狀態變量,
  例如 update 和 replace;然而,可以看一下 Handler_* 狀態變量大致瞭解非 select 查詢的相對數量。
  show global status like 'Select_%';
  	以我們的判斷,Select_* 狀態變量可以按花費遞增的順序如下排序:
  	1.Select_range
  		在第一個表上掃描一個索引區間的聯接數目。
  	2.Select_scan
  		掃描整個第一張表的聯接數目。如果第一個表中的每行都參與聯接,這樣計數並沒有問題;如果你並不想要所有的行但又沒有索引以查找到所需要的行,就比較糟糕了。
  	3.Select_full_range_join
  		使用在表n中的一個值來從表n+1 中通過參考索引的區間內獲取行所做的聯接數。這個值或多或少比 Select_scan 開銷多些,具體取決於查詢。
  	4.Select_range_check
  		在表n+1 中重新評估表n中的每一行的索引是否開銷最小所做的聯接數。這一般意味着在表n+1中對該聯接而言並沒有有用的索引。這個查詢有非常高的額外開銷。
  	5.Select_full_join
  		交叉聯接或並沒有條件匹配表中行的聯接的數目。檢測的行數是每個表中行數的乘積。這通常是個壞事。
  	最後2個變量一般並不會快速的增長,如果快速增長,則可能表明一個'糟糕'的查詢引入了系統中。

12.排序
	當mysql不能使用一個索引來獲取預先排序的行時,必須使用文件排序,這會增加 Sort_* 狀態變量。除 Sort_merge_passes外,你可以只是增加mysql 會用來排序的
  索引以改變這些值。Sort_merge_passed 依賴 sort_buffer_size 服務器變量(不要與myisam_sort_buffer_size服務器變量混淆)。mysql使用排序緩存來容納排序的
  行塊。當完成排序後,它將這些排序後的行合併到結果集中,增加 Sort_merge_passes,並且用下一個待排序的行塊填充緩存。然後,使用這個變量來指導排序緩存的大小並
  不是個好辦法。
    show global status like 'Sort_%';
    當mysql從文件排序的結果中讀取已經排好序的行並返回給客戶端時,Sort_scan 和 Sort_range 變量會增長。不同點在於:前者是當查詢計劃導致 Select_scan 增加時
  增加,而後者是當 Select_range 增加時增加。二者的實現和開銷完全一樣;僅僅指示了導致排序的查詢計劃類型。

13.表鎖
	Table_lock_immediate 和 Table_locks_waited 變量可以告訴你又多少鎖被立即授權,有多少鎖需要等待。但請注意,它們只是展示了服務器級別鎖的統計,並不是存儲引擎
  級別的鎖統計。

14.InnoDB 相關
	Innodb_* 變量展示了 show engine innodb status 中包含的一些數據。這些變量按名字分組:Innodb_buffer_pool_*,Innodb_log_* 等等。
	這些變量存在於mysql5.5 或更新的版本中,它們有重要的副作用:它們會創建一個全局鎖,然後在釋放該鎖之前遍歷整個Innodb緩衝池。同時,另外一些線程也會遇到該鎖而阻塞,
  直到它被釋放。這歪曲了一些狀態值,比如 Threads_running,因此,它們看起來比平時更高(可能高許多,取決於系統的負載有忙)。當運行 show engine innodb status 或通過
  information_schema 表訪問這些統計時,有相同的副作用。
    因此,這些操作在這些版本的mysql中會更加昂貴---檢查服務器狀態太頻繁可能會顯著的增加負載。使用 show status like 也無濟於事,因爲它要獲取所有的狀態然後再進行過濾。

15.插件相關
	mysql5.1和更新的版本中支持可插拔的存儲引擎,並在服務器內部對這些存儲引擎提供了註冊它們自己的狀態和配置變量的機制。如果你在使用一個可插拔的存儲引擎,也許會看到許多插件
  特有的變量。類似的變量總是以插件名開頭。

16.show engine innodb status
	show engine innodb status
	show innodb status //老版本
	不像其他大部分show命令,它的輸出就是單獨的一個字符串,沒有行和列。它會分爲很多段,每一段對應了InnoDB存儲引擎不同部分的信息。
	輸出內容包含了一些平均值的統計信息,例如fsync()每秒調用次數。這些平均值是自上次輸出結果生成以來的統計數。因此,如果你正在檢查這些值,那麼就要確保已經等待了30s左右的
  時間,使2次採樣之間積累起足夠長的統計時間並多次採樣,檢查計數器變化而弄清其行爲。並不是所有的輸出都會在一個時間點生成,因而不是所有顯示出來的平均值會在同一時間間隔重新
  計算一遍。而且,innodb有一個內部復位間隔,而它是不可預知的,各個版本也不同。你應該檢查一下輸出,看看哪些平均值在這個時間段生成,因爲每次採樣的時間間隔不總是相同的。

    1.頭部信息
=====================================
2019-09-01 16:07:29 7fda67186700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 3 seconds
	第一段是頭部信息,它僅僅聲明瞭輸出的開始,其內容包括當前的日期和時間,以及自上次輸出以來經過的時長。下來的第二行是當前日期和時間。第4行顯示的是計算出這一平均值的
  時間間隔,即自上次輸出以來的時間,或者是距離上次內部復位的時長。

	2.SEMAPHORES
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 17302
OS WAIT ARRAY INFO: signal count 30366
Mutex spin waits 1316797, rounds 1183725, OS waits 1645
RW-shared spins 26012, rounds 518136, OS waits 15432
RW-excl spins 297681, rounds 141195, OS waits 171
Spin rounds per wait: 0.90 mutex, 19.92 RW-shared, 0.47 RW-excl
	第4行給出了關於操作系統等待數組的信息,它是一個'插槽'數組.innodb在數組裏爲信號量保留了一些插槽,操作系統爲這些信號量給線程發送信號,使線程可以繼續運行,以完成
  它們等着做的事情。這一行還顯示了innodb 使用了多少次操作系統的等待。保留技術(reservation count)顯示了innodb分配插槽的頻度,而信號技術(signal count)衡量的是線程
  通過數組得到信號的頻度。操作系統的等待相對於空轉等待(spin wait)要更昂貴一些。
    第5~12行顯示的是當前正在等待互斥量的innodb線程。在這個例子中有2個線程正在等待,每一個都是以 '--Thread<數字> has waited...' 開始的。這一段應該是空的,除非服務器
  運行着高併發的工作負載,促使innodb採取讓操作系統等待的措施。除非你對innodb源碼很熟,否則這裏看到的最有用的信息是發生線程等待的代碼文件名。這就給了你一個提示:在innodb
  內部哪裏纔是熱點。舉例來說,如果看到許多線程都在一個名爲 buf0buf.ic 的文件上等待着,那就意味着你的系統裏存在緩衝池競爭。這個輸出信息還顯示了這些線程等待了多長時間,其中
  'waiters flags' 顯示了有多少個等待者正在等待同一個互斥量。
    文本'wait is ending' 意味着這個互斥鎖實際上已經被釋放了,但操作系統還沒把線程調度過來運行。
    你可能想知道innodb真正等待的是什麼。innodb 使用了互斥量和信號量來保護代碼的臨界區,例如,限定每次只能有一個線程進入臨界區,或者是當有活動的讀時,就限制寫入等。在innodb
  代碼裏有很多臨界區,在合適的條件下,它們都可能出現在那裏。常常能見到的一種情形就是獲取緩衝池分頁的訪問權。
    在等待線程的列表之後,第13行和第14行顯示了更多的事件計數器。在第13行顯示的是跟互斥量相關的幾個計數器,第14行用於顯示讀/寫共享和排它鎖的計數器。在每一種情形中,都能看到
  innodb 依靠操作系統等待的頻度。
    innodb有着一個多階等待策略。首先,它會嘗試着對鎖進行空等待。如果經過了一個預設的空轉等待週期(設置 innodb_sync_spin_loops 配置變量指令)之後還沒有成功,那就會退回到
  更昂貴更復雜的等待數組中。
    空轉等待的成本相對比較低,但是它們要不停的檢查一個資源是否被鎖定,這種方式會消耗cpu週期。但是,這沒那麼糟糕,因爲當處理器等待IO時,一般都會有一些空閒的cpu週期可用,
  即使沒有空閒的cpu週期,空等也要比其他方式更加廉價一些。然後,當另外一條線程能做一些事情時,空轉等待也還會獨佔處理器。
  	空轉等待的替代方案就是讓操作系統做上下文切換,這樣,當這個線程在等待時,另外一個線程就可以運行了,然後,通過等待數組裏的信號量發出信號,喚醒那個沉睡的線程。通過信號量
  來發送信號是比較有效率的,但是上下文切換就很昂貴,這很快就會積少成多:每秒鐘幾千次的切換會引發大量的系統開銷。
    你可以通過改變系統變量 innodb_sync_spin_loops 的值,試着在空轉等待與操作系統等待之間達成平衡。不要擔心空轉等待,除非你在每一秒裏面會看到許多空轉等待(大概是幾十萬
  這個水平)。這經常需要理解源代碼或諮詢專家才能解決。或者看一下,show engine innodb mutex。

    3.LATEST FOREIGN KEY ERROR
    	下一段即,latest foreign key error,一般不會出現,除非你的服務器上有外鍵錯誤。在源代碼裏面有許多地方會產生這樣的輸出,具體取決於錯誤的類型。有時問題在於
      事務在插入,更新或刪除一條記錄時要尋找到父行或子行。還有些時候是當innodb嘗試增加或刪除一個鍵,或修改一個已經存在的外鍵時,發現表之間類型不匹配。
        這部分輸出對於調試與innodb往往不明確的外鍵錯誤相對應的準確原因非常有幫助。

    4.LATEST DETECTED DEADLOCK
    	跟上面一樣,latest detected deadlock 部分也只有當服務器內部有死鎖時纔會出現。死鎖信息同樣在每次有新錯誤時都會重寫。Percona Toolkit 中的 
      pt-deadlock-logger 工具可以保存這些信息供後續分析。
      	死鎖在等待關係圖裏是一個循環,就是一個鎖定了行的數據結構又在等待別的鎖。這個循環可以任意的大。innodb 會立即檢測到死鎖,因爲每當有事務等待行鎖時,它都會去檢測
      等待關係圖裏是否有循環。死鎖的情況可能比較複雜,但是,這一部分只顯示了最近2個死鎖的情況,它們在各自的事務裏執行的最後一條語句,以及它們在圖裏形成循環鎖的信息。
      在這個循環裏你看不到其他事務,也看不到在事務裏早先可能真正獲得了鎖的語句。儘管如此,通常還是可以通過查看這些輸出來確定到底是什麼引起了死鎖。
        在innodb裏實際上有2種死鎖。
        1.就是常見的一種,它在等待關係圖裏是一個真正的循環。
        2.另外一個就是在等待關係圖裏,因爲代價昂貴而無法檢查它是不是包含了循環。如果innodb要在關係圖裏檢查超過100w個鎖,或者在檢查的過程中,innodb要重做200個以上的事務,
        它就會放棄,並宣佈這是一個死鎖。這些數值硬編碼在innodb裏面,無法配置(修改,重新編譯)。當innodb的檢查工作超過了這個極限後,它就會引發一個死鎖,這時候你就會看到
        一條信息 'too deep or long search in the lock table waits-for graph'.

        innodb 不僅會打印出事務和事務持有及等待的鎖,而且還有記錄本身。
        當事務持有了其他事務需要的鎖,同時又想獲得其他事務持有的鎖時,等待關係圖上就會產生循環了。innodb不會顯示所有持有和等待的鎖。但是,它顯示了足夠的信息幫你確定:
      查詢操作正在使用哪些索引。這對於你確定是否能避免死鎖有着極大的價值。
        如果能使2個查詢對同一個索引朝同一個方向進行掃描,就能降低死鎖的數目。因爲,查詢在同一順序上請求的鎖的時候不會創建循環。

    5.TRANSACTIONS
------------
TRANSACTIONS
------------
Trx id counter 22043759
Purge done for trx's n:o < 21888087 undo n:o < 0 state: running but idle
History list length 2918
LIST OF TRANSACTIONS FOR EACH SESSION:

		第4行:當前事務id,這是一個事務變量,每創建一個新事務都會增加
		第5行:這是InnoDB清楚舊 mvcc 行時所用的事務id.將這個值和當前事務id進行比較,可以知道有多少老版本的數據未被清楚。這個數字多大纔可以安全的取值沒有
		硬性規定和速成的規定。如果數據沒有做過任何更新,那麼一個巨大的數字也不意味着有未清楚的數據,因爲實際上所有事物在數據庫裏查看的都是同一個版本的數據。
		從另外一方面來說,如果有很多行被更新,那每一行就會有一個或者多個版本留在內存裏。減少此類開銷的最好辦法是確保事物一完成就立刻提交它,不要讓它長時間處於
		打開狀態。因爲一個打開的事務即使不做任何操作,也會影響到innodb清理舊版本的行數據。
		第6行:歷史記錄長度,即位於innodb數據文件的撤銷空間裏的頁面的數目。如果事務執行了更新並提交,這個數字就會增加;而當清理進程移除舊版本數據時,它就會遞減,
		清理進程也會更新第5行中的數值。
		第7行:鎖結構數目。每個鎖結構經常持有多個行鎖,所以,它跟被鎖定行的數目不一樣。

		頭部信息之後就是一個事務列表。當前版本的mysql還不支持嵌套事務,因此,在某個時間點,每個客戶端連接能擁有的事務數目是有一個上限的,而每個事務只能屬於單一連接。
	  在輸出的信息裏,每一個事務至少佔2行內容。

---TRANSACTION 22043755, not started, process no 5388, OS thread id 123123
MySQL thread id 101577, OS thread handle 0x7fda96144700, query id 7661049 192.168.0.38 apollo_user	
		第1行以該事務的id和開始狀態。這個事務是 'no started',意思是已經提交併且沒有再發起影響事務的語句;可能剛好空閒。然後是一些進程和線程信息。第2行顯示了
	  mysql 進程id,也和 show full processlist 中的id是一樣的。緊隨其後的是一個內部查詢號和一些連接信息。

---TRANSACTION 22043755, ACTIVE 4 sec, process no 1234, OS thread id 123123, thread declared inside innodb 442
mysql tables in use 1,locked 0
MySQL thread id 8079, query id 728899 localhost baron Sending data
select sql_calc_found_rows * from b limit 5
Trx read view will not see trx with id >= 08099888, sees < 0 8098281
		本例中的第1行顯示此事務已經活躍了4s。可能的狀態有'no started','active','prepared'和'committed in memory' (一旦被提交到磁盤上,狀態就會變爲 'no started')。
	  儘管這個示例沒有被提示,但是在其他條件下,你也許能看到關於事務當前正在做什麼的信息。在源代碼中有超過30個字符串常量可以顯示在這裏,例如'fetching rows',
	  'adding foreign keys' 等等。
	    第1行裏的文本'thread declared inside InnoDB 442' 的意思是該線程正在innodb內核裏做一些操作,並且還有442張'票'可以使用。換句話說,就是同樣的sql查詢可以重新
	  進入innodb內核442次。這個票是系統用來限制內核中線程併發操作的手段,以防止其在某些平臺上運行失常。即使線程的狀態是'inside InnoDB',它也不是在innodb裏面完成所有
	  的工作。查詢可能是在服務器一級做一些操作,而只是通過某個途徑跟innodb內核互動一下。你也可能看到事務的狀態是'sleeping before joining InnoDB queue'或者 
	  'waiting in InnoDB queue'。
	    接下來一行顯示了當前語句裏有多少表被使用和鎖定。innodb一般不會鎖定表,但對有些語句會鎖定。如果mysql服務器高於innodb層次之上將表鎖定,這裏也是能夠顯示出來的。
	  如果事務已經鎖定了幾行數據,這裏將會有一行信息顯示出鎖定結構的數目(再聲明一次,這跟行鎖是2回事)和堆的大小。
	    堆的大小指的是持有這些行鎖而佔用的內存大小.innodb是用一種特殊的位圖表來實現行鎖的,從理論上講,它可將每一個鎖定的行表示爲一個比特。我們的測試顯示,每一個鎖通常
	  不超過4比特。
	    如果一個事務正在運行一個查詢,那麼接下來就會顯示出查詢的文本。
	    第5行顯示了事務的讀視圖,它表明了因爲版本關係而產生的對於事務可見和不可見兩種類型的事務id的範圍。在本例中,有2個數字之間有一個4個事務的間隙,這4個事務可能是不可見
	  的。innodb 在執行查詢時,對於那些事務id正好在這個間隙的行,還會檢查其可見性。
	    如果事務正在等待一個鎖,那麼在查詢內容之後將可以看到這個鎖的信息。不幸的是,輸出信息並沒有說出這個鎖正在被哪個事務持有。
	    如果輸出信息裏有很多個事務,innodb可能會限制要打印出來的事務數目。

    6.FILE I/O
--------
FILE I/O
--------
I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (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: waiting for i/o request (read thread)
I/O thread 6 state: waiting for i/o request (write thread)
		第4~7行顯示了IO輔助線程的狀態。第8~10行顯示的是每個輔助線程的掛起操作的數目,以及日誌和緩衝池線程掛起的 fsync() 操作數目。簡寫'aio'的意思是
	  '異步IO'。第11行顯示了讀,寫和fsync()調用執行的數目。在你的負載下這些絕對值會有所不同,因此更重要的是監控它們過去一段時間內是如何改變的。第12行
	  顯示了頭部顯示的時間段內的每秒平均值。
	    在第8~9行顯示的是掛起值是檢查IO受限的應用的一個好辦法。如果這些IO大部分有掛起操作,那麼負載可能IO受限。
	    在windows下,可以通過 innodb_file_io_threads 配置變量來調整 IO 輔助線程數,因此可能會看到不止一個讀線程和寫線程。然後,在所有平臺下至少會
	  看到4個線程。
	    1.Insert buffer thread
	    	負責插入緩衝合併(例如,記錄從被插入緩衝合併到表空間中)
	    2.Log thread
	    	負責異步刷日誌
	    3.Read thread
	    	執行預讀操作以嘗試預先讀取innodb預感需要的數據
	    4.Write thread
	    	刷髒緩衝

    7.INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 2703, seg size 2705, 0 merges
merged operations:
 insert 0, delete mark 0, delete 0
discarded operations:
 insert 0, delete mark 0, delete 0
Hash table size 34673, node heap has 2 buffer(s)
Hash table size 34673, node heap has 0 buffer(s)
Hash table size 34673, node heap has 0 buffer(s)

    	第4行顯示了關於插入插入緩存大小,'free list'的長度和段大小的信息。文本 'for space 0' 像是指明瞭多個插入緩衝的可能性--每個表空間一個,
      但從未實現,並且這個文本在最新的mysql版本中被移除了。只有一個插入緩衝,因此第5行是多餘的。第6行顯示了有多少緩衝操作已經完成。合併與插入的
      比例很好的說明了緩衝使用效率如何。
        第7行顯示的是自適應哈希索引的狀態。第8行顯示了在頭部提及的時間內innodb完成了多少哈希索引操作。哈希索引查找與非哈希索引的查找的比例僅供
      參考。自適應索引無法配置。

    8.LOG
---
LOG
---
Log sequence number 6091114310
Log flushed up to   6091114310
Pages flushed up to 6091114310
Last checkpoint at  6091114301
0 pending log flushes, 0 pending chkp writes
46 log i/o's done, 0.00 log i/o's/second

      第4行顯示了當前日誌序號,第5行顯示了日誌已經刷到哪個位置。日誌序號就是寫到日誌文件中的字節數,因此可用來計算日誌緩衝中還有多少沒有寫入到
    日誌文件中。在這個例子中,它有 9615 字節(13000620880 - 13000611265)。第6行顯示了上一次檢測點(一個監測點表示一個數據和日誌文件都處於
    已知狀態的時刻,並且能用於恢復)。如果上一個監測點落後日誌序號太多,並且差異接近於該日誌文件的大小,innodb會觸發'瘋狂刷',這對性能有影響。
    第7~8行顯示了掛起的日誌操作和統計,你可以將其與FILE IO 部分的值相比較,以瞭解你的IO有多少是由日誌子系統引起,有多少是其他原因。

   9.BUFFER POLL AND MEMORY
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 137756672; in additional pool allocated 0
Total memory allocated by read views 88
Internal hash tables (constant factor + variable factor)
    Adaptive hash index 2217584 	(2213368 + 4216)
    Page hash           139112 (buffer pool 0 only)
    Dictionary cache    593780 	(554768 + 39012)
    File system         83536 	(82672 + 864)
    Lock system         333248 	(332872 + 376)
    Recovery system     0 	(0 + 0)
Dictionary memory allocated 39012
Buffer pool size        8191
Buffer pool size, bytes 134201344
Free buffers            8047
Database pages          144
Old database pages      0
Modified db pages       0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 144, created 0, written 0
		第4行顯示了innodb分配的總內存,以及其中多個是額外的內存池分配。額外內存池僅分配了其中(一般很小)一部分的內存,由內部內存分配器分配。
	  現代innodb版本一般使用操作系統的內存分配器,但是老版本用自己的。因爲之前有些操作系統並未提供一個非常好的實現。
	    第5~8行顯示了緩衝池度量值,以頁爲單位。度量值有總的緩衝池大小,空閒頁數,分配用來存儲數據頁的頁數,以及'髒'數據頁數。innodb 使用的是
	  緩衝池中的部分頁來對鎖,自適應哈希,以及其他系統結構做索引,因此池中的數據庫頁數永遠不等於總的池大小。
	    第9~10行顯示了掛起的讀和寫的數量(例如innodb需要爲緩衝池而做的總的邏輯讀和寫)。這些值並不與FILE IO 部分的值相匹配,因爲innodb可能合併
	  許多的邏輯 操作到一個物理IO操作中。LRU 代表'最近使用到的';它是通過沖刷緩衝中不經常使用的頁來釋放空間以供給經常使用的頁的一種辦法。沖刷
	  列表存放由檢查點處理需要衝刷的舊頁,並且單頁的寫是獨立的頁面寫,不會被合併。
	    輸出的第8行顯示緩衝池包含37491個髒頁,這是某些時刻(它們已經在內存中被修改但尚未寫到磁盤上)需要被刷到磁盤上。然後,第10行顯示當前沒有安排
	  沖刷。這不是一個問題,innodb會在需要的時候刷。如果在innodb的狀態輸出中到處可見大量掛起的IO操作,這往往表明服務器有嚴重問題。
	    第11行顯示了innodb被讀取,創建和寫入多少頁。讀/寫頁的值指的是從磁盤讀到緩衝池中的數據,或反過來說。創建頁的值是指innodb在緩衝池中分配但
	  沒有從數據文件中讀取內容的頁,因爲它並不關心內容是什麼。
	    第13行報告了緩衝池的命中率,它用來衡量innodb在緩衝池中查找所需頁的比例。它度量自上次innodb狀態輸出後的命中率,因此,如果服務器自那以後
	  一直很安靜,你會看到'no buffer pool page gets since the last printout'。它對度量緩衝池的大小並沒有用處。

   10.ROW OPERATIONS
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
1 read views open inside InnoDB
0 transactions active inside InnoDB
0 out of 1000 descriptors used
---OLDEST VIEW---
Normal read view
Read view low limit trx n:o D00
Read view up limit trx id D00
Read view low limit trx id D00
Read view individually stored trx ids:
-----------------
Main thread process no. 1612, id 140456879916800, state: waiting for server activity
Number of rows inserted 0, updated 0, deleted 0, read 0
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s

	第4行顯示了innodb內核內有多少線程。隊列中的查詢是innodb爲限制併發執行的線程量而不允許進入內核的線程。查詢同樣在進入隊列之前會休眠等待。
	第5行顯示了有多少打開的innodb讀視圖。讀視圖是包含事務開始點的數據庫內容的mvcc'快照'。你可以看看某特定事務是否在 transactions 部分有
  讀視圖。
    第6行顯示了內核的主線程狀態。可能的狀態值如下:
    1.doing background drop tables
    2.doing insert buffer merge
    3.flushing buffer pool pages
    4.flushing log
    5.making checkpoint
    6.purging
    7.reserving kernel mutex
    8.sleeping
    9.suspending
    10.waiting for buffer pool flush to end
    11.waiting for server activity
    大部分服務器上應該會經常看到 'sleeping' ,如果生成多個快照而一再查看到不同的狀態,例如'flushing buffer pool pages',則應該懷疑相關的活動
   有問題---例如,'瘋狂刷'問題,可能由某個沖刷算法差勁的innodb版本引起,或由糟糕的配置導致的,例如太小的事務日誌文件。
     第7~8行顯示了多少行被插入,更新,刪除和讀取,以及它們的每秒均值。如果你想查看innodb有多少工作正在進行,那麼它們是很好的參考值。
     show engine innodb status 輸出在第9~13行結束,如果看不到這個文本,那可能是有一個很大的死鎖截斷了輸出。


17.SHOW PROCESSLIST
	進程列表是當前連接到mysql的連接或現場的清單。show processlist 列出了這些線程,以及每個線程的狀態信息。
MariaDB [(none)]> show full processlist \G
*************************** 1. row ***************************
      Id: 2
    User: system user
    Host:
      db: NULL
 Command: Qeury
    Time: 3792
   State: Sending data
    Info: NULL
Progress: 0.000
*************************** 2. row ***************************
      Id: 5
    User: root
    Host: localhost
      db: NULL
 Command: Killed
    Time: 0
   State: end
    Info: show full processlist
Progress: 0.000
	
	也可以從 information_schema 中的表來獲取這個信息。上面例子中,第一個進程正在運行查詢併發送數據,而第二個進程已經被殺死,這可能是由於這需要非常長
  的一段時間來完成,於是某人深思熟慮後通過kill命令終結它。線程有可能在kill狀態停留一段時間,因爲kill命令有可能不立即執行完成,比如它可能需要一些時間
  來回滾事務。
    show full processlist (增加了full關鍵字)將顯示每個查詢的全文,否則最多顯示100個字符。

18.SHOW ENGINE INNODB MUTEX
	SHOW ENGINE INNODB MUTEX 返回innodb互斥體的詳細信息,主要對洞悉可擴展性和併發性問題有幫助。每個互斥體都保護着代碼中的一個臨界區。
	基於等待的數量,可以使用這個輸出幫助確定innodb那一塊是瓶頸。只要有互斥體,就會有潛在的競爭。該命令可能輸出非常多,需要一些腳本進行聚合分析。
	有3種策略可以消除互斥相關的瓶頸:儘量避開innodb的弱點,限制併發,或者在cpu密集型的空轉等待和資源密集型密集型的操作系統等待之前做平衡。

19.複製狀態
	在主庫上執行 show master status 可以顯示主庫的複製狀態和配置。
MariaDB [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000018 |      245 |              |                  |
+------------------+----------+--------------+------------------+

	輸出包含了主庫當前的二進制日誌位置。通過show binary logs 可以獲取二進制日誌列表。
MariaDB [(none)]> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       584 |
| mysql-bin.000002 |       245 |
| mysql-bin.000003 |       245 |
| mysql-bin.000004 |       245 |
| mysql-bin.000005 |       288 |
	

MariaDB [(none)]> show binlog events\G
*************************** 1. row ***************************
   Log_name: mysql-bin.000001
        Pos: 4
 Event_type: Format_desc
  Server_id: 10
End_log_pos: 245
       Info: Server ver: 5.5.60-MariaDB, Binlog ver: 4
*************************** 2. row ***************************
   Log_name: mysql-bin.000001
        Pos: 245
 Event_type: Query
  Server_id: 10
End_log_pos: 397
       Info: use `test`; create table a (
id int(11) not null auto_increment,
name varchar(11),
primary key(`id`))
	要查看這些二進制日誌中的事件,可以使用 show binlog events

	show slave status;
	Master_Log_File/Read_Master_Log_Pos
	io線程讀主庫二進制日誌的位置

	Relay_Log_File/Relay_Log_Pos
	sql線程執行中繼日誌的位置

	Relay_Master_Log_File/Exec_Master_Log_Pos	
	sql線程執行的映射到主庫二進制日誌的位置。這與 Relay_Log_File/Relay_Log_Pos 有着相同的邏輯位置,但是主庫的二進制日誌而非複製的中繼日誌。換句話說,
  如果你看一下日誌中的這2個位置,你會發現有相同的日誌事件。

20.INFORMATION_SCHEMA
	INFORMATION_SCHEMA 庫是一個sql標準中定義的系統視圖的集合。mysql實現了許多標準中的視圖,並且增加了一些其他的視圖。在mysql5.1中,其中許多的視圖與
  mysql的 show 命令對應,例如show full processlist 和 show status。然後,也有一些視圖沒有對應的show 命令。
    INFORMATION_SCHEMA 視圖的美在於能夠以標準的sql來進行查詢。這比show 命令更靈活,因爲show命令產生的結果不能聚合,聯接或者進行其他標準的sql操作。
  在系統視圖層擁有所有可獲得的數據使得寫感興趣和有用的查詢變得可行。
    MySQL Forge 是一個查詢和分析針對這些視圖的查詢的好地方。
    最大的缺點是視圖與相應的show命令相比,有時非常慢。它們一般會取所有的數據,存在臨時表中,然後使查詢可以獲取臨時表。當服務器上數據量大或者表多時,
  查詢INFORMATION_SCHEMA 表會導致非常高的負載,並且會導致服務器對其他用戶而言停轉或者不可響應,因此在一個高負載且數據量大的生產服務器上使用時要小心。
  查詢時會有危險的表主要是那些包含下列元素的表:TABLES,COLUMNS,REFERNTIAL_CONSTRAINTS,KEY_COLUMN_USAGE.對這些表的查詢會導致mysql向存儲引擎請求
  獲取類似服務器上表的索引統計等數據,而這些在innodb裏是非常繁重的。
    這些視圖不可更新。儘管你可以從中檢索服務器設置,但不能更新影響服務器的配置,因此,仍然需要對配置使用 show 和 set 命令。

21.InnoDB 表
	innodb 插件創建了許多 INFORMATION_SCHEMA 表。
	
	1.INNODB_CMP 和 INNODB_CMP_RESET
		這些表顯示了innodb中以新文件格式 Barracuda 壓縮的數據的相關信息。第二個表顯示的信息和第一個表相同,但具有重置所包含數據的副作用,好像使用 FLUSH
	  命令那樣。

	2.INNODB_CMPMEM 和 INNODB_CMPMEM_RESET
		這些表顯示了用於innodb壓縮數據的緩衝池中頁的信息。第二個表是個重置表。

	3.INNODB_TRX 和 INNODB_LOCKS
		這些表顯示了事務,擁有和等待鎖的事務。它們對於診斷鎖等待問題和長時間運行的事務非常重要。

	除了這些表,mysql5.5還增加了 INNODB_LOCK_WAITS,它可以幫助更容易的診斷更多類型的鎖等待問題。

22.Performance Schema
	Performance Schema 是mysql增強儀表的心的彙總處。默認情況下,Performance Schema 是禁用的,你必須打開並且使其在一個想要手機的特定的儀表點(消費者)啓用。
	在mysql5.5 中,Performance Schema 包含了指示條件變量,互斥體,讀/寫鎖和文件IO實例的表。還有指示實例上的等待信息的表,而這些經常是你在查詢時首先感興趣的,
  以及與其實例表的聯接。

總結:
	mysql暴露服務器內部信息的首要方式是 show 命令,但這在改變。在mysql5.1中引入的可插拔的 INFORMATION_SCHEMA 表允許innodb插件增加一些非常有意義的儀表.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章