背景:
晚上,公司業務群里發信息說,有玩家在游戲里面贈送別人禮物后,贈送記錄在20多分鍾以后才出現,延時太高。
問題:
公司數據庫使用mysql,配置了主從。配置的是,游戲程序寫數據到主庫,讀數據到從庫。
數據庫服務器主:A
數據庫服務器從:B
1.首先查看了A主上面的贈送記錄的庫,發現都是正常的。然后查看B從上面贈送記錄的庫,發現有幾個表沒有通過過來。
2.在B從上面查看,從數據庫是否正常: show slave status\G;發現如下問題:
根據上面圈出來的參數發現:主從存在延遲,主庫執行到了mysql-bin-000077,而從庫才執行到mysql-bin-000070,也可以從執行的位置,上面兩個_POS看出來有延遲,根據Seconds_Behind_Master發現,大約有365360的延遲。
由上面分析可以發現,從庫B雖然已經從主庫拉取了所有的binlog,但是執行卻沒有完成。
show processlist;發現Slave_SQL線程處於:Reading event from the relay log.
經查找發現:由於主庫可以並發執行,而從庫只有一個slave_sql線程來進行執行,所以當事務多的時候,從庫來不及處理就會出現以上情況。
查找是哪些資源到了瓶頸:
top發現,loadavg平均在1.7左右,內存,cpu都沒有異常。cpu行中的wa%卻有些偏高。'狀態列'有一個程序處於D狀態,即不可終端的睡眠。狀態D,一般是由於wait IO造成的所謂“非中斷睡眠”。
用iostat, $iostat -x 1 10 發現IO utils%一直出於70%-99%之間,發現是系統IO達到了瓶頸。
用iotop查看是哪些進程在頻繁的進行IO操作,發現是mysqld和jdb2/dm-2-8
進行相關的優化:
由於主數據庫上面也有IO瓶頸,同樣是上面兩個進程。
進入mysql查看show processlist,發現有1500多個任務,大部分處於sleep狀態。(發現了之前公司業務發的,有些玩家登錄不上游戲的原因,( ╯□╰ )),mysql配置中,max_connection最大連接數設置的才只有2000,所以很容易到達,然后滿了后玩家就進不來了。
對於sleep任務太多的處理:(1)程序里每次連接數據庫后,記得關閉數據庫。(2)或者,在mysql配置文件中,設置mysql超時時間wait_timout,默認是八小時,設置低一點。