MySQL延遲問題和數據刷盤策略

1、MySQL複製流程
官方文檔流程圖以下:
MySQL延遲問題和數據刷盤策略mysql

一、絕對的延時,相對的同步sql

二、純寫操做,線上標準配置下,從庫壓力大於主庫,最起碼從庫有relaylog的寫入。數據庫

2、MySQL延遲問題分析服務器

一、主庫DML請求頻繁併發

緣由:主庫併發寫入數據,而從庫爲單線程應用日誌,很容易形成relaylog堆積,產生延遲。async

解決思路:作sharding,打散寫請求。考慮升級到MySQL 5.7+,開啓基於邏輯時鐘的並行複製。ide

二、主庫執行大事務函數

緣由:相似主庫花費很長時間更新了一張大表,在主從庫配置相近的狀況下,從庫也須要花幾乎一樣的時間更新這張大表,此時從庫延遲開始堆積,後續的events沒法更新。高併發

解決思路:拆分大事務,及時提交。性能

三、主庫對大表執行DDL語句

緣由:DDL未開始執行,被阻塞,檢查到位點不變;DDL正在執行,單線程應用致使延遲增長,位點不變。

解決思路:找到被阻塞DDL或是寫操做的查詢,幹掉該查詢,讓DDL正常在從庫上執行;業務低峯期執行,儘可能使用支持Online DDL的高版本MySQL。

四、主從實例配置不一致

緣由:硬件上:主庫實例服務器使用SSD,而從庫實例服務器使用普通SAS盤、cpu主頻不一致等;配置上:如RAID卡寫策略不一致,OS內核參數設置不一致,MySQL落盤策略(innodb_flush_log_at_trx_commit和sync_binlog等)不一致等

解決思路:儘可能統一DB機器的配置(包括硬件及選項參數);甚至對於某些OLAP業務,從庫實例硬件配置高於主庫等。

五、從庫自身壓力過大

緣由:從庫執行大量select請求,或業務大部分select請求被路由到從庫實例上,甚至大量OLAP業務,或者從庫正在備份等,此時可能形成cpu負載太高,io利用率太高等,致使SQL Thread應用過慢。

解決思路:創建更多從庫,打散讀請求,下降現有從庫實例的壓力。

也能夠調整innodb_flush_log_at_trx_commit=0和sync_binlog=0刷盤參數來緩解IO壓力來下降主從延遲。

3、大促期間CPU太高問題

現象:

高併發致使CPU負載太高,處理請求時間拉長,逐步積壓,最終致使服務不可用;大量的慢SQL致使CPU負載太高。

解決思路:

基本上是禁止或是慎重考慮數據庫主從切換,這個解決不了根本問題,須要研發配合根治SQL問題,也能夠服務降級,容器的話能夠動態擴容CPU;和業務協商啓動pt-kill查殺只讀慢SQL;查看是否能夠經過增長通常索引或是聯合索引來解決慢SQL問題,但此時要考慮DDL對數據庫影響。

4、InnoDB刷盤策略

MySQL的innodb_flush_method這個參數控制着innodb數據文件及redo log的打開、刷寫模式,對於這個參數,文檔上是這樣描述的:
有三個值:fdatasync(默認),O_DSYNC,O_DIRECT
默認是fdatasync,調用fsync()去刷數據文件與redo log的buffer
爲O_DSYNC時,innodb會使用O_SYNC方式打開和刷寫redo log,使用fsync()刷寫數據文件
爲O_DIRECT時,innodb使用O_DIRECT打開數據文件,使用fsync()刷寫數據文件跟redo log
首先文件的寫操做包括三步:open,write,flush
上面最常提到的fsync(int fd)函數,該函數做用是flush時將與fd文件描述符所指文件有關的buffer刷寫到磁盤,而且flush完元數據信息(好比修改日期、建立日期等)纔算flush成功。
使用O_DSYNC方式打開redo文件表示當write日誌時,數據都write到磁盤,而且元數據也須要更新,才返回成功。
O_DIRECT則表示咱們的write操做是從MySQL innodb buffer裏直接向磁盤上寫。

這三種模式寫數據方式具體以下:

fdatasync模式:寫數據時,write這一步並不須要真正寫到磁盤纔算完成(可能寫入到操做系統buffer中就會返回完成),真正完成是flush操做,buffer交給操做系統去flush,而且文件的元數據信息也都須要更新到磁盤。
O_DSYNC模式:寫日誌操做是在write這步完成,而數據文件的寫入是在flush這步經過fsync完成
O_DIRECT模式:數據文件的寫入操做是直接從mysql innodb buffer到磁盤的,並不用經過操做系統的緩衝,而真正的完成也是在flush這步,日誌仍是要通過OS緩衝。

MySQL延遲問題和數據刷盤策略

MySQL延遲問題和數據刷盤策略
一、在類unix操做系統中,文件的打開方式爲O_DIRECT會最小化緩衝對io的影響,該文件的io是直接在用戶空間的buffer上操做的,而且io操做是同步的,所以不論是read()系統調用仍是write()系統調用,數據都保證是從磁盤上讀取的;因此IO方面壓力最小,對於CPU處理壓力上也最小,對物理內存的佔用也最小;可是因爲沒有操做系統緩衝的做用,對於數據寫入磁盤的速度會下降明顯(表現爲寫入響應時間的拉長),但不會明顯形成總體SQL請求量的下降(這有賴於足夠大的innodb_buffer_pool_size)。

二、O_DSYNC方式表示以同步io的方式打開文件,任何寫操做都將阻塞到數據寫入物理磁盤後才返回。這就形成CPU等待加長,SQL請求吞吐能力下降,insert時間拉長。

三、fsync(int filedes)函數只對由文件描述符filedes指定的單一文件起做用,而且等待寫磁盤操做結束,而後返回。fdatasync(int filedes)函數相似於fsync,但它隻影響文件的數據部分。而除數據外,fsync還會同步更新文件的元信息到磁盤。

O_DSYNC對CPU的壓力最大,datasync次之,O_DIRECT最小;總體SQL語句處理性能和響應時間看,O_DSYNC較差;O_DIRECT在SQL吞吐能力上較好(僅次於datasync模式),但響應時間倒是最長的。

默認datasync模式,總體表現較好,由於充分利用了操做系統buffer和innodb_buffer_pool的處理性能,但帶來的負面效果是free內存下降過快,最後致使頁交換頻繁,磁盤IO壓力大,這會嚴重影響大併發量數據寫入的穩定性。

相關文章
相關標籤/搜索