1. 程式人生 > >mysql資料庫巡檢

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`

執行