1. 程式人生 > 其它 >55.Mysql的巡檢

55.Mysql的巡檢

技術分享 | MySQL 巡檢

王向 愛可生開源社群 愛可生開源社群

ActiontechOSS

愛可生開源社群,提供穩定的MySQL企業級開源工具及服務,每年1024開源一款優良元件,並持續運營維護。

2021-05-28 16:30

作者:王向

愛可生 DBA 團隊成員,負責公司 DMP 產品的運維和客戶 MySQL 問題的處理。擅長資料庫故障處理。對資料庫技術和 python 有著濃厚的興趣。本文來源:原創投稿*愛可生開源社群出品,原創內容未經授權不得隨意使用,轉載請聯絡小編並註明來源。
MySQL巡檢
  • 作業系統層面

    • cpu

    • 記憶體

    • I/O

    • 磁碟

    • 系統基礎資訊

    • 作業系統日誌

  • MySQL

    • 重點引數

    • MySQL的狀態

    • 庫表情況

    • MySQL主從檢測

    • 高可用層面

    • 中介軟體的巡檢

作業系統層面

巡檢嘛沒啥特別的,就直奔主題把。

cpu
sar -u 10 3 

記憶體

 sar -r 10 3

I/O

sar -b 10 3

磁碟

df -h

系統基礎資訊

當然,檢視是否使用numa和swap,或是否頻繁互動資訊等。還有其他的監控專案,這裡就不一一贅述了。

作業系統日誌

除此之外,還需要關注日誌類資訊,例如:
tail 200 /var/log/messages
dmesg | tail 200

MySQL

MySQL重點引數的檢查,及主從健康狀態的巡檢。

點引數
引數 參考值
innodb_buffer_pool_size 系統的50%-75%
binlog_format ROW
sync_binlog 1
innodb_flush_log_at_trx_commit 1
read_only 從庫ON,主庫OFF
super_read_only 從庫ON,主庫OFF
log_slave_updates 1
innodb_io_capacity sata/sas硬碟這個值在200
sas raid10: 2000
ssd硬碟:8000
fusion-io(快閃記憶體卡):25,000-50,000
max_connections  

MySQL的狀態

\s
show full processlist;
show engine innodb status\G
show slave hosts;

wait事件

show global status like 'Innodb_buffer_pool_wait_free';
show global status like 'Innodb_log_waits';

#表鎖
show global status like 'Table_locks_waited';
show global status like 'Table_locks_immediate';

#行鎖
show global status like 'Innodb_row_lock_current_waits';當前等待鎖的行鎖數量
show global status like 'Innodb_row_lock_time';請求行鎖總耗時
show global status like 'Innodb_row_lock_time_avg';請求行鎖平均耗時
show global status like 'Innodb_row_lock_time_max';請求行鎖最久耗時
show global status like 'Innodb_row_lock_waits';行鎖發生次數

#還可以定時收集INFORMATION_SCHEMA裡面的資訊:

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS; 
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS; // MySQL 8.0 中已經不再使用,建議觀測 sys 庫
#臨時表/臨時檔案
show global status like 'Created_tmp_disk_tables';
show global status like 'Created_tmp_files';

#開啟表/檔案數
show global status like 'Open_files';
show global status like 'Open_table_definitions';
show global status like 'Open_tables';

#併發連線數
show global status like 'Threads_running';
show global status like 'Threads_created';
show global status like 'Threads_cached';
show global status like 'Aborted_clients';
 
#客戶端沒有正確關閉連線導致客戶端終止而中斷的連線數
show global status like 'Aborted_connects';
Binlog
# 使用臨時二進位制日誌快取但超過 binlog_cache_size 值,需要使用臨時檔案儲存事務中的語句的事務數
binlog_cache_disk_use;

# 使用二進位制日誌快取的事務數
binlog_cache_use;

# 使用二進位制日誌語句快取但超過 binlog_stmt_cache_size 的值,需要使用臨時檔案儲存這些語句的非事務語句的數量
binlog_stmt_cache_disk_use;

# 使用二進位制日誌語句快取的非事務性語句的數量
binglog_cache_disk_use;

連結數

# 試圖連線到(不管成不成功)mysql伺服器的連結數
show global status like 'Connection'

臨時表

# 伺服器執行語句時,在硬碟上自動建立的臨時表的數量,是指在排序時,記憶體不夠用(tmp_table_size小於需要排序的結果集),所以需要建立基於磁碟的臨時表進行排序
show global status like 'Created_tmp_disk_tables'

# 伺服器執行語句時自動建立的記憶體中的臨時表的數量
show global status like 'Created_tmp_files';

索引

# 內部提交語句
show global status like 'Handler_commit'

# 內部 rollback語句數量
show global status like 'Handler_rollback'

# 索引第一條記錄被讀的次數,如果高,則它表明伺服器正執行大量全索引掃描
show global status like 'Handler_read_first';  

# 根據索引讀一行的請求數,如果較高,說明查詢和表的索引正確
show global status like 'Handler_read_key'

# 查詢讀索引最後一個索引鍵請求數
show global status like 'Handler_read_last';

# 按照索引順序讀下一行的請求數
show global status like 'Handler_read_next'

# 按照索引順序讀前一行的請求數
show global status like 'Handler_read_prev';

# 根據固定位置讀一行的請求數,如果值較高,說明可能使用了大量需要mysql掃整個表的查詢或沒有正確使用索引
show global status like 'Handler_read_rnd'

# 在資料檔案中讀下一行的請求數,如果你正進行大量的表掃,該值會較高
show global status like 'Handler_read_rnd_next'

# 被快取的.frm檔案數量
show global status like 'Open_table_definitions'

# 已經開啟的表的數量,如果較大,table_open_cache值可能太小
show global status like 'Opened_tables';

# 當前開啟的表的數量
show global status like 'Open_tables';

# 已經發送給伺服器的查詢個數
show global status like 'Queries';

# 沒有使用索引的聯接的數量,如果該值不為0,你應該仔細檢查表的所有
show global status like 'Select_full_join';

# 對第一個表進行完全掃的聯接的數量
show global status like 'Select_scan';

# 查詢時間超過long_query_time秒的查詢個數
show global status like 'Slow_queries';

# 排序演算法已經執行的合併的數量,如果值較大,增加sort_buffer_size大小
show global status like 'Sort_merge_passes';

執行緒

# 執行緒快取內的執行緒數量
show global status like 'Threads_cached';

# 當前開啟的連線數量
show global status like 'Threads_connected';

# 建立用來處理連線的執行緒數
show global status like 'Threads_created';

# 啟用的(非睡眠狀態)執行緒數
show global status like 'Threads_running';

庫表情況

自增id使用情況

SELECT
 table_schema,
 table_name,
 ENGINE,
 Auto_increment 
FROM
 information_schema.TABLES 
WHERE
 TABLE_SCHEMA NOT IN (
  "INFORMATION_SCHEMA",
  "PERFORMANCE_SCHEMA",
 "MYSQL",
 "SYS"limit 30;

錶行數資料大小統計

SELECT
 table_schema "Database name",
 sum( table_rows ) "No. of rows",
 sum( data_length ) / 1024 / 1024 "Size data (MB)",
 sum( index_length )/ 1024 / 1024 "Size index (MB)" 
FROM
 information_schema.TABLES 
GROUP BY
 table_schema;

錶行數 TOP 30

SELECT 
    TABLE_SCHEMA,
    TABLE_NAME,
    TABLE_ROWS
FROM 
    `information_schema`.`tables` 
WHERE
    TABLE_SCHEMA not in('information_schema','sys','mysql','performance_schema')
ORDER BY table_rows DESC LIMIT 30;

儲存引擎不是innodb的表

SELECT
 TABLE_SCHEMA,
 TABLE_NAME,
ENGINE 
FROM
 INFORMATION_SCHEMA.TABLES 
WHERE
 ENGINE != 'innodb' 
 AND TABLE_SCHEMA NOT IN ( "INFORMATION_SCHEMA""PERFORMANCE_SCHEMA""MYSQL""SYS" );

表資料和碎片 TOP 30

select 
    TABLE_SCHEMA,
    TABLE_NAME,
    TABLE_ROWS,
    DATA_LENGTH,
    INDEX_LENGTH,
    DATA_FREE
from 
    information_schema.tables 
where 
    DATA_FREE is not null 
ORDER BY DATA_FREE DESC LIMIT 30;

無主鍵的表

SELECT
 t1.table_schema,
 t1.table_name,
 t1.table_type 
FROM
 information_schema.TABLES t1
 LEFT OUTER JOIN information_schema.TABLE_CONSTRAINTS t2 ON t1.table_schema = t2.TABLE_SCHEMA 
 AND t1.table_name = t2.TABLE_NAME 
 AND t2.CONSTRAINT_NAME IN ( 'PRIMARY' ) 
WHERE
 t2.table_name IS NULL 
 AND t1.TABLE_SCHEMA NOT IN ( 'information_schema''performance_schema''test''mysql''sys' ) 
 AND t1.table_type = "BASE TABLE";

MySQL主從檢測

#主從狀態
show slave status\G

#主從是否延遲
Master_Log_File == Relay_Master_Log_File 
&& Read_Master_Log_Pos == Exec_Master_Log_Pos

高可用層面

MHA && keepalived

觀察日誌看是否有頻繁主從切換,如果有的話就分析一下是什麼原因導致頻繁切換?

間件的巡檢

mycat && proxysql

這些中介軟體的巡檢,首先參考系統巡檢,再看一下中介軟體本身的日誌類和狀態類資訊,網路延遲或丟包的檢查,也是必須要做工作。