mysql資料庫巡檢
本文首發於個人的公眾號:Java技術大雜燴,歡迎關注共同學習,有Spring , Mybatis, Redis, JDK 等原始碼分析的文章
前言
shell 中執行 mysql 命令
各項巡檢命令
shell 指令碼實現
前言
在系統執行的過程中,DBA需要經常的對資料庫進行一些檢查,如資料庫磁碟的佔用量,快取的命中率,記憶體的分配等;由於有個客戶需要對系統的資料庫進行檢查,所以進行了一些學習,在此記錄下;由於不可能讓使用者手動的輸入這些繁瑣的命令,所以寫了個 shell 指令碼。
shell 指令碼中連線資料庫執行mysql 命令
在 shell 指令碼中,去連結資料庫,並執行相關的命令的步驟如下:
1. 首先使用 touch 命令建立個檔案, 使用 chmod 賦給這個檔案執行許可權
2. 在檔案中輸入如下shell:
#!/bin/bash host="127.0.0.1" #資料庫IP port="3306" #資料庫埠 userName="root" #使用者名稱 password="root" #密碼 dbname="dbname" #資料庫 名稱 dbset="--default-character-set=utf8 -A" # 字符集 cmd="show variables like '%datadir%';" /home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${cmd}")
如果要一次執行多個命令,則直接寫多條命令就可以了,但是記得要換行,如下所示:
cmd2="show variables like '%datadir%';
show tables;
show databases;"
/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${cmd}")
各項巡檢命令
mysql 的資料檔案存放的位置
有時候需要知道mysql資料檔案的存放位置,此時,可以使用 datadir 變數檢視,命令如下:
a: 進入到MySQL的bin目錄下,執行 ./mysql -h127.0.0.1 -uroot -proot 登陸mysql:
b: 然後執行 show variables like '%datadir%'; 或者 elect @@datadir; 命令檢視資料檔案的存放路徑:
shell指令碼如下:
#!/bin/bash
host="127.0.0.1" #資料庫IP
port="3306" #資料庫埠
userName="root" #使用者名稱
password="root" #密碼
dbname="dbname" #資料庫 名稱
dbset="--default-character-set=utf8 -A" # 字符集
datadir="show variables like '%datadir%';"
datadir_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${datadir}")
echo "mysql 資料檔案存放位置:" `echo ${datadir_val} | cut -d' ' -f4`
其中,“cut -d' ' -f4” 意思是獲取到字串按照空格(‘ ’)進行分割,然後取第 4 個;
檢視MySQL中執行次數最多的前 10 條SQL
在MySQL中,要統計執行次數最大的SQL ,需要開啟慢查詢,通過慢查詢日誌進行統計,
檢視是否開啟慢查詢日誌命令:
show variables like '%slow_query%';
其中,slow_query_log 表示是否開啟慢查詢,OFF表示未開啟,ON 表示開啟。slow_query_log_file表示慢查詢日誌的路徑。
開啟慢查詢日誌
set global slow_query_log=ON;
慢查詢是指SQL的執行時間超過一定的秒數之後才算是慢查詢,這個時間預設是10秒,可以通過 long_query_time 變數檢視,如下:
show variables like '%long_query_time%';
在測試的時候,可以把這個時間設定短一些,可以設定為1秒,0.1秒或者0.01秒都可以,通過如下命令設定:
set global long_query_time=秒數
當設定成功後,再次執行show variables like '%long_query_time%';命令來檢視發現還是10秒,這時需要重新退出的,在進行登入,再檢視就好了。
當開啟慢查詢日誌後,就可以通過慢查詢日誌來分析執行次數最多的SQL了。
使用MySQL提供的 mysqldumpslow 工具來進行分析慢查詢日誌。mysqldumpslow 工具的主要功能是統計不同慢SQL的:
執行次數(count)
執行最長時間(time)
等待鎖的時間(lock)
傳送給客戶端的總行數(rows)
進入到mysql的bin目錄下,執行 mysqldumpslow -help 來檢視引數,如下:
-s:表示按照哪種方式進行排序,c, t, l, r, 分別表示按照執行次數,執行時間,等待鎖時間和返回的記錄數來排序,at, al, ar 分別按照平均執行時間,平均等待鎖時間和平均傳送行數進行排序。
-r:是前面排序的逆序
-t:top n 的意思,即返回排序後前面 n 條的資料
-g:正則匹配
現在可以通過該工具來統計執行次數最多的前 10 條SQL了,命令如下:
# -s c -t 10 表示按照執行次數排序,之後,取前10條
./mysqldumpslow -s c -t 10 /home/datas/mysql/data/R6-slow.log;
檢視資料庫快取的命中率
首先看下是否開啟了查詢快取:
show variables like '%query_cache%';
其中 query_cache_type 為 ON 表示開啟查詢快取,OFF表示關閉快取
query_cache_size 允許設定的值最小為40K,對於最大值則可以幾乎認為無限制,但是,該值並不是越大, 查詢快取的命中率就越高,需要根據情況來定。
開啟了查詢快取之後,接下來來看下快取的相關選項說明:
執行檢視命令:
show global status like 'QCache%';
Qcache_free_blocks:目前還處於空閒狀態的 Query Cache 中記憶體 Block 數目
Qcache_free_memory:目前還處於空閒狀態的 Query Cache 記憶體總量
Qcache_hits:Query Cache 命中次數
Qcache_inserts:向 Query Cache 中插入新的 Query Cache 的次數,也就是沒有命中的次數
Qcache_lowmem_prunes:當 Query Cache 記憶體容量不夠,需要從中刪除老的 Query Cache 以給新的 Cache 物件使用的次數
Qcache_not_cached:沒有被 Cache 的 SQL 數,包括無法被 Cache 的 SQL 以及由於 query_cache_type 設定的不會被 Cache 的 SQL
Qcache_queries_in_cache:目前在 Query Cache 中的 SQL 數量
Qcache_total_blocks:Query Cache 中總的 Block 數量
此時可以根據這些值進行計算快取的命中率和快取的記憶體使用率
公式:
查詢快取命中率 ≈ (Qcache_hits – Qcache_inserts) / Qcache_hits * 100%
查詢快取記憶體使用率 ≈ (query_cache_size – Qcache_free_memory) / query_cache_size * 100%
shell指令碼計算快取命中率:
#!/bin/bash
host="127.0.0.1" #資料庫IP
port="3306" #資料庫埠
userName="root" #使用者名稱
password="root" #密碼
dbname="dbname" #資料庫 名稱
dbset="--default-character-set=utf8 -A" # 字符集
cache_hits="show global status like 'QCache_hits';"
hits=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${cache_hits}")
hits_val=`echo ${hits} | cut -d' ' -f4`
echo "快取命中次數:" ${hits_val}
cache_not_hits="show global status like 'Qcache_inserts';"
not_hits=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${cache_not_hits}")
not_hits_val=`echo ${not_hits} | cut -d' ' -f4`
echo "快取未命中次數:" ${not_hits_val}
cache_hits_rate_1=$(($hits_val - $not_hits_val))
cache_hits_rate_2=`echo | awk "{print $cache_hits_rate_1/$hits_val * 100}"`
echo "快取命中率:" ${cache_hits_rate_2} "%"
執行該指令碼,如下所示:
查詢等待事件的TOP 10
查詢等待事件相關的需要通過 performance_schema 來進行統計,MySQL的 performance schema 主要用於監控MySQL server在一個較低級別的執行過程中的資源消耗、資源等待等,關於 performance_schema 的介紹,可以參考 performance_schema全方位介紹,介紹得比較詳細。
統計 top 10 的等待事件 SQL 如下:
select event_name, count_star, sum_timer_wait from performance_schema.events_waits_summary_by_user_by_event_name where count_star > 0 order by sum_timer_wait desc limit 10;
shell指令碼執行
#!/bin/bash
host="127.0.0.1" #資料庫IP
port="3306" #資料庫埠
userName="root" #使用者名稱
password="root" #密碼
dbname="dbname" #資料庫 名稱
dbset="--default-character-set=utf8 -A" # 字符集
top_event_10="select event_name, count_star, sum_timer_wait from performance_schema.events_waits_summary_global_by_event_name where count_star > 0 order by sum_timer_wait desc limit 10;"
echo "等待事件 TOP 10:"
/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${top_event_10}"
mysql的記憶體配置情況,
可以通過檢視相關的變數來檢視mysql記憶體 分配:
show variables like 'innodb_buffer_pool_size'; //InnoDB 資料和索引快取
show variables like 'innodb_log_buffer_size'; // InnoDB 日誌緩衝區
show variables like 'binlog_cache_size'; // 二進位制日誌緩衝區
show variables like 'thread_cache_size'; // 連線執行緒快取
show variables like 'query_cache_size'; // 查詢快取
show variables like 'table_open_cache'; // 表快取
show variables like 'table_definition_cache'; // 表定義資訊快取
show variables like 'max_connections'; // 最大執行緒數
show variables like 'thread_stack'; // 執行緒棧資訊使用記憶體
show variables like 'sort_buffer_size'; // 排序使用記憶體
show variables like 'join_buffer_size'; // Join操作使用記憶體
show variables like 'read_buffer_size'; // 順序讀取資料緩衝區使用記憶體
show variables like 'read_rnd_buffer_size'; // 隨機讀取資料緩衝區使用記憶體
show variables like 'tmp_table_size'; // 臨時表使用記憶體
除了使用 show variables 的方式。還可以使用 select @@xxx的方式:
shell 指令碼:
#!/bin/bash
host="127.0.0.1" #資料庫IP
port="3306" #資料庫埠
userName="root" #使用者名稱
password="root" #密碼
dbname="dbname" #資料庫 名稱
dbset="--default-character-set=utf8 -A" # 字符集
echo "================= 記憶體配置情況 ==============================="
mem_dis_1="show variables like 'innodb_buffer_pool_size';"
mem_dis_1_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_1}")
mem_dis_1_val_1=`echo ${mem_dis_1_val} | cut -d' ' -f4`
mem_dis_1_val_2=`echo | awk "{print $mem_dis_1_val_1/1024/1024}"`
echo "InnoDB 資料和索引快取:" $mem_dis_1_val_1
mem_dis_2="show variables like 'innodb_log_buffer_size';"
mem_dis_2_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_2}")
mem_dis_2_val_1=`echo ${mem_dis_2_val} | cut -d' ' -f4`
mem_dis_2_val_2=`echo | awk "{print $mem_dis_2_val_1/1024/1024}"`
echo "InnoDB 日誌緩衝區:" $mem_dis_2_val_1
mem_dis_3="show variables like 'binlog_cache_size';"
mem_dis_3_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_3}")
mem_dis_3_val_1=`echo ${mem_dis_3_val} | cut -d' ' -f4`
mem_dis_3_val_2=`echo | awk "{print $mem_dis_3_val_1/1024/1024}"`
echo "二進位制日誌緩衝區:" $mem_dis_3_val_1
mem_dis_4="show variables like 'thread_cache_size';"
mem_dis_4_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_4}")
echo "連線執行緒快取:" `echo $mem_dis_4_val | cut -d' ' -f4`
mem_dis_5="show variables like 'query_cache_size';"
mem_dis_5_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_5}")
echo "查詢快取:" `echo ${mem_dis_5_val} | cut -d' ' -f4`
mem_dis_6="show variables like 'table_open_cache';"
mem_dis_6_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_6}")
echo "表快取:" `echo ${mem_dis_6_val} | cut -d' ' -f4`
mem_dis_7="show variables like 'table_definition_cache';"
mem_dis_7_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_7}")
echo "表定義快取:" `echo ${mem_dis_7_val} | cut -d' ' -f4`
mem_dis_8="show variables like 'max_connections';"
mem_dis_8_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_8}")
echo "最大執行緒數:" `echo ${mem_dis_8_val} | cut -d' ' -f4`
mem_dis_9="show variables like 'thread_stack';"
mem_dis_9_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_9}")
echo "執行緒棧資訊使用記憶體:" `echo ${mem_dis_9_val} | cut -d' ' -f4`
mem_dis_10="show variables like 'sort_buffer_size';"
mem_dis_10_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_10}")
echo "排序使用記憶體:" `echo ${mem_dis_10_val} | cut -d' ' -f4`
mem_dis_11="show variables like 'join_buffer_size';"
mem_dis_11_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_11}")
echo "Join操作使用記憶體:" `echo ${mem_dis_11_val} | cut -d' ' -f4`
mem_dis_12="show variables like 'read_buffer_size';"
mem_dis_12_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_12}")
echo "順序讀取資料緩衝區使用記憶體:" `echo ${mem_dis_12_val} | cut -d' ' -f4`
mem_dis_13="show variables like 'read_rnd_buffer_size';"
mem_dis_13_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_13}")
echo "隨機讀取資料緩衝區使用記憶體:" `echo ${mem_dis_13_val} | cut -d' ' -f4`
mem_dis_14="show variables like 'tmp_table_size';"
mem_dis_14_val=$(/home/mysql/bin/mysql -h${host} -u${userName} -p${password} ${dbname} -P${port} -e "${mem_dis_14}")
echo "臨時表使用記憶體:" `echo ${mem_dis_14_val} | cut -d' ' -f4`
執行