咱們的Mysql服務運行一段時間後,不知什麼緣由就變慢了,怎麼查找緣由呢?
在數據庫性能評測中,有幾項指標很重要,用它來評估數據庫的能力,不是他們能起着多麼關鍵的做用,而是他們可以較爲明確的表明數據庫在某些方面的能力。html
IOPS:Input/Output operation Per Second, 每秒處理的IO請求次數。
咱們知道I/O就是磁盤的讀寫能力,好比每秒讀 300M,寫 200M,這個即數據的吞吐量(I/O能力的另外一個關鍵指標),可是 IOPS
指的可不是讀寫的數據吞吐量,IOPS 指的是每秒可以處理的 I/O 請求次數
。mysql
若是想I/O 系統響應夠快,那麼 IOPS 越高越好,由於IOPS 和硬件有關,因此,要提升IOPS,就目前來看基本只能拼硬件,傳統方案是使用多塊磁盤經過 RAID 條帶後,使 I/O 讀寫能力得到提高,咱們也可使用固態硬盤SSD來提高IOPS,不過固態硬盤成本可能比較大。sql
QPS:Query Per Second,每秒請求(查詢)次數。
這個參數很是重要,能夠直觀的反映系統的性能,這就像IOPS衡量磁盤每秒鐘能接收多少次請求。數據庫
咱們能夠在MySQL命令行模式下執行 status
命令,返回的最後一行輸出信息中就包含 QPS 指標。緩存
TPS:Transaction Per Second,每秒事務數。
TPS參數MySQL原生沒有提供,若是須要咱們本身算,能夠利用計算的公式:安全
TPS = (Com_commit + Com_rollback) / Seconds
這個公式有兩個狀態變量,分別表明提交次數和回滾次數,Seconds 就是咱們定義的時間間隔。服務器
TPCC-MySQL 由Percona基於TPCC規範開發的一套MySQL基準測試程序,咱們使用這套工具來測試前面的三個重要指標。網絡
具體的安裝,能夠看這這兩篇博文 mysql壓力測試工具tpcc-mysql安裝測試使用,mysql性能測試-tpcc,TPCC更能模擬線上業務。併發
若是數據庫參數配置合理,則能夠大大的提升運行效率,即最大化利用系統資源。app
可使用該命令查看MySQL的默認配置:
show global variables
show global variables like '%max_connections%'
max_connections:指定 MySQL 服務端最大併發鏈接數
,值得範圍從 1~10 萬,默認值爲151.
這個參數很是重要,由於它決定了同時最多能有多少個會話鏈接到 MySQL 服務。設定該參數時,根據數據庫服務器的配置和性能,通常將參數值設置在 500~2000 都沒太大的問題。
max_connect_errors:指定容許鏈接不成功的最大嘗試次數
,值得範圍從 1~2^64 之間,在 5.6.6 版本默認值是 100。
必定不要忽視這個參數,若是嘗試鏈接的錯誤數量超過該參數指定值,則服務器就再也不容許新的鏈接,沒錯,就是拒絕鏈接,儘管 MySQL 仍在提供服務,但沒法建立新的鏈接了。可使用 FLUSH HOSTS
,使狀態清零或從新啓動數據庫服務,不過這個代價過高了,通常不會這麼幹,因此,這個參數的默認值過小,這裏建議將之設置爲 10 萬以上的量級
。
這兩個參數都與鏈接會話的自動超時斷開有關,前者用於指定關閉交互鏈接前等待的時間,後者用於指定關閉非交互鏈接前的等待時間,單位均是秒,默認值均爲 28800,即 8 個小時。
skip-name-resolve:能夠將其簡單的理解爲禁用 DNS 解析,注意啊,這個是服務端的行爲,鏈接時不檢查客戶端主機名,而只使用IP。若是制定了該參數,那麼在建立用戶及授予權限時,HOST 列必須是IP而不能是主機名。建議啓用該參數,對於加快網絡鏈接有必定的幫助,等因而跳過了主機名的解析。
back_log:指定 MySQL 鏈接請求隊列中存放的最大鏈接請求數量
,在 5.6.6
版本之前
,默認是 50 個,最大值不超過 65535。在 5.6.6
版本之後
,默認值爲 -1,表示由MySQL自動調節,所謂自行調節其實也有規則,即 50+(max_connections/5)。
該參數主要應對短期內有大量的鏈接請求,MySQL 主線程沒法及時爲每個鏈接請求分配(或建立)鏈接的線程,怎麼辦呢,它也不能直接拒絕,因而就將一部分請求放到等待隊列中待處理
,這個等待隊列的長度就是 back_log 的參數值,若等待隊列也被放滿了,那麼後續的鏈接請求才會被拒絕。
sync_binlog:指定同步二進制日誌文件的平率,默認爲0.
若是要性能,則指定該參數爲0,爲了安全起見則指定該參數值爲 1.
expire_logs_day:指定設置二進制日誌文件的生命週期,超出則將自動被刪除
,參數值以天爲單位,值得範圍從0~99,默認值是0,建議將該參數設置爲 7~14 之間,保存一到兩週就足夠了。
max_binlog_size: 指定二進制日誌的大小,值得範圍從 4KB~1GB,默認爲 1GB。
thread_cache_size:指定MySQL爲快速重用而緩存的線程數量。值得範圍從 0~16384,默認值爲0.
通常當客戶端中斷鏈接後,爲了後續再有鏈接建立時,可以快速建立成功,MySQL 會將客戶端中斷的鏈接放入緩存區,而不是立刻中斷釋放資源。這樣當有新的客戶端請求鏈接時,就能夠快速建立成功。所以,本參數最好保持必定的數量,建議設置在 300~500
之間都可.另外,線程緩存的命中率也是一項比較重要的監控指標,計算規則爲(1-Threads_created/Connections)* 100%,咱們能夠經過該指標來優化和調整thread_cache_size參數。
sql_cache意思是說,將查詢結果放入查詢緩存中。
sql_no_cache意思是查詢的時候不緩存查詢結果。
sql_buffer_result意思是說,在查詢語句中,將查詢結果緩存到臨時表中。
這三者正好配套使用。sql_buffer_result將盡快釋放表鎖,這樣其餘sql就可以儘快執行。
使用 FLUSH QUERY CACHE 命令,你能夠整理查詢緩存,以更好的利用它的內存。這個命令不會從緩存中移除任何查詢。FLUSH TABLES 會轉儲清除查詢緩存。
RESET QUERY CACHE 使命從查詢緩存中移除全部的查詢結果。
那麼mysql究竟是怎麼決定到底要不要把查詢結果放到查詢緩存中呢?
是根據query_cache_type
這個變量來決定的。
這個變量有三個取值:0,1,2,分別表明了off、on、demand。
mysql默認爲開啓 on
意思是說,若是是0,那麼query cache
是關閉的。
若是是1,那麼查詢老是先到查詢緩存中查找,即便使用了sql_no_cache仍然查詢緩存,由於sql_no_cache只是不緩存查詢結果,而不是不使用查詢結果。
select count(*) from innodb; 1 row in set (1.91 sec) select sql_no_cache count(*) from innodb; 1 row in set (0.25 sec)
若是是2,DEMAND。
在my.ini中增長一行
query_cache_type=2
重啓mysql服務
select count(*) from innodb; 1 row in set (1.56 sec) select count(*) from innodb; 1 row in set (0.28 sec)
沒有使用sql_cache,好像仍然使用了查詢緩存
select sql_cache count(*) from innodb; 1 row in set (0.28 sec)
使用sql_cache查詢時間也同樣,由於sql_cache只是將查詢結果放入緩存,沒有使用sql_cache查詢也會先到查詢緩存中查找數據
結論:只要query_cache_type沒有關閉,sql查詢老是會使用查詢緩存,若是緩存沒有命中則開始查詢的執行計劃到表中查詢數據。
query cache優缺點
優勢很明顯,對於一些頻繁select query,mysql直接從cache中返回相應的結果集,而不用再從表table中取出,減小了IO開銷。
即便query cache的收益很明顯,可是也不能忽略它所帶來的一些缺點:
合理利用query cache
query cache有利有弊,合理的使用query cache可使其發揮優點,而且有效的避開其劣勢。
更多有關query cache詳情文章,請看這裏的原文:mysql query cache優化
query_cache_size:指定用於緩存查詢結果集的內存區大小,該參數值應爲 1024 的整數倍。
這個參數不能太大,也不能過小,查詢緩存至少會須要 40KB 的空間分配給其自身結構,過小時緩存結果集就沒有意義,熱點數據保存不了多少,並且老是很快就被刷新出去;但也不能太大,不然可能過多佔用內存資源,影響整機性能,再說太大也沒有意義,由於即使數據不被刷新,但只要源數據發生變動,緩存中的數據也就自動失效了,這種狀況下分配多大都沒有意義
。我的建議設置不要超過 256MB
。
query_cache_limit:用來控制查詢緩存,可以緩存的單條 SQL 語句生成的最大結果集,默認是 1MB,超出的就不要進入查詢緩存。這個大小對於不少場景都夠了,縮小能夠考慮,加大就不用了。
sort_buffer_size:指定單個會話可以使用的排序區的大小,默認值爲 256KB,建議設置爲 1~4MB
之間。
read_buffer_size:指定隨機讀取時的數據緩存區大小,默認是 256KB,最大可以支持4GB,適當加大本參數,對於提高全表掃描的效率會有幫助。
innodb_buffer_pool_size:指定InnoDB引擎專用的緩存區大小,用來緩存表對象的數據及索引信息,默認值爲 128MB,最大可以支持(2^64 -1)B.
若是你有不少事務的更新,插入或刪除很操做,經過修改innodb_buffer_pool 大小這個參數會大量的節省了磁盤I / O
。
innodb_buffer_pool_size 是個全局參數,其所分配的緩存區將供全部被訪問到的InnoDb表對象使用,若MySQL數據庫中的表對象以 InnoDb 爲主,那麼本參數的值就越大越好,官方文檔中建議,能夠將該參數設置爲服務器物理內存的70%~80%
。
innodb_buffer_instances:指定 InnoDB 緩存池分爲多少個區域來使用,值得範圍從 1~64,默認值爲-1,表示由 InnoDB 自行調整。
只有當innodb_buffer_pool_size參數值大於1GB時,本參數纔有效,那麼本參數怎麼設置呢?我的感受能夠參照 InnoDB 緩存池的大小,以 GB 爲單位,每GB指定一個instances
。例如當innodb_buffer_pool_size設置爲16GB時,則指定 innodb_buffer_instances 設置爲 16 便可。
測試服務器有 16GB的物理內存,假定其峯值最大的鏈接數爲 500 個,表對象使用InnoDB 存儲引擎,咱們的內存參數如何配置呢?
具體配置以下:
(1)、首先,爲操做系統預留 20% 的內存,約爲 3GB。
(2)、與線程相關的幾個關鍵參數設置以下:
sort_buffer_size=2m read_buffer_size=2m read_rnd_buffer_size=2m join_buffer_size=2m
預計鏈接數達到峯值時,線程預計最大將有可能佔用 500 *(2+2+2+2)= 4GB
內存(理論最大值)。
(3)、剩下的空間 16-3-4=9GB,就能夠所有都分配給InnoDB 的緩存池,設定相關的參數以下:
innodb_buffer_pool_size=9g innodb_thread_concurrency=8 innodb_flush_method=O_DIRECT innodb_log_buffer_size=16m innodb_flush_log_at_trx_commit=2
想要了解MySQL服務當前在作什麼,有個很是重要而且極爲經常使用的命令:
SHOW [FULL] PROCESSLIST
SHOW PROCESSLIST
命令將每個鏈接的線程,做爲一條獨立的記錄輸出。
還有類似的語句,
SHOW PROFILES 和 SHOW PROFILE能夠獲取會話執行語句過程當中,資源的使用狀況。
關於SQL的執行性能:
SHOW STATUS # 能夠查詢掃描的行的數據 EXPLAIN # 單條語句信息 SHOW PROFILES # show PROCESSLIST; SHOW STATUS show global variables like '%max_connections%' show global variables like '%back_log%' show global variables like '%thread_cache_size%'