MySQL 各類場景的故障恢復概要(持續更新)

一、CPU打高

數據庫CPU打高消耗過大一般來說主要有兩點原因:

  • 慢SQL
      慢sql導致,比如說全表掃描、掃描數據量太大,排序操作,鎖爭用等。
    使用explain,profile進行優化
  • QPS高
      大量併發導致資源緊張。

OS
  首先通過top查看系統CPU使用率情況,是否是MySQL導致。如果是雲上RDS可忽略,直接查看RDS實例CPU使用率即可

MySQL
查看QPS

show global status like 'Question%';

查看活躍會話

select * from information_schema.processlist where command!='Sleep';

查看邏輯讀

show global status like 'innodb_buffer_pool_read_requests';

查看臨時表情況

show status like 'Create_tmp%';

查看鎖爭用

SHOW STATUS LIKE ‘Innodb_row_lock%’;

引擎各種狀態查看

show engine innodb status\G

分析慢日誌

mysqldumpslow -s c slow.log>/tmp/slow_report.txt

  根據以上狀態值分析CPU打高原因,針對具體問題具體分析。如:優化SQL,控制併發等。

二、IOPS打高

OS
  iostat 和pt-ioprofile查看IO性能,如果是雲上RDS可忽略,直接查看RDS實例IOPS即可。

MySQL

查看活躍會話

select * from information_schema.processlist where command!='Sleep';

查看數據庫讀寫壓力

SELECT file_name AS file,
    count_read,
    sum_number_of_bytes_read AS total_read,
    count_write,
    sum_number_of_bytes_write AS total_written,
    (sum_number_of_bytes_read + sum_number_of_bytes_write) AS total
 FROM performance_schema.file_summary_by_instance
ORDER BY sum_number_of_bytes_read+ sum_number_of_bytes_write DESC;

查看物理讀

show global status like 'Innodb_buffer_pool_reads';

  分析並優化相應SQL。

三、活躍連接數打高

  通過監控查看活躍連接數以及其他數據庫資源問題,確定是由於大量活躍連接導致數據庫資源打滿還是資源打滿導致活躍連接堆積。

MySQL

查看當前活躍會話

select * from information_schema.processlist where command!='Sleep';

  如果是大量高效SQL併發導致的問題,需要從業務上定位;如果是低效SQL導致資源緊張,則需要根據活躍會話以及慢日誌進行優化,臨時解決可以通過kill會話處理。

四、磁盤打高/滿


OS

查看磁盤空間

df -TH

查看innode用量

df -iH

MySQL

查看binlog佔用空間

show master logs;

查看錶大小

SELECT table_schema as `Database`, table_name AS `Table`, round(((data_length + index_length) / 1024 / 1024 / 1024), 2) `Size in GB` FROM information_schema.TABLES where table_schema = 'test' ORDER BY (data_length + index_length) DESC ;

查看臨時表空間大小

select * from INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO;

碎片查看

SELECT CONCAT(table_schema, '.', table_name)                    AS  TABLE_NAME
      ,engine                                                   AS  TABLE_ENGINE 
      ,table_type                                               AS  TABLE_TYPE
      ,table_rows                                               AS  TABLE_ROWS
      ,CONCAT(ROUND(data_length  / ( 1024 * 1024), 2), 'M')     AS  TB_DATA_SIZE 
      ,CONCAT(ROUND(index_length / ( 1024 * 1024), 2), 'M')     AS  TB_IDX_SIZE 
      ,CONCAT(ROUND((data_length + index_length ) 
            / ( 1024 * 1024 ), 2), 'M')                         AS  TOTAL_SIZE
      ,CASE WHEN  data_length =0 THEN 0
            ELSE  ROUND(index_length / data_length, 2) END      AS  TB_INDX_RATE
    ,CONCAT(ROUND( data_free / 1024 / 1024,2), 'MB')            AS  TB_DATA_FREE 
    ,CASE WHEN (data_length + index_length) = 0 THEN 0
             ELSE ROUND(data_free/(data_length + index_length),2) 
     END                                                        AS  TB_FRAG_RATE
FROM information_schema.TABLES  
ORDER BY data_free DESC;
#重建表空間
optimize table tablename;

  根據實際情況進行處理。

五、複製故障

5.1 複製延遲

MySQL
網絡延遲:減小副本集節點之間的網絡延遲。
磁盤吞吐量:保證磁盤吞吐。
查看show slave status;
在這裏插入圖片描述

通過以上指標判斷主從狀態以及複製延遲,如果出現較大延遲,可以從以下幾個方面考慮:

  • 大事物延遲,避免大事務
  • 大表DDL延遲,可能存在MDL鎖阻塞,kill掉阻塞源
  • 長期未提交的事物延遲,杜絕長事務
  • 表上沒有主鍵或者唯一鍵,可以通過slave_rows_search_algorithms變量一定程度優化,建議所有業務表均建立主鍵
  • Innodb層鎖造成延遲,分析鎖關係,做出相應處理

5.2 複製中斷

根據複製中斷做出相應調整,如果難以修復,建議重建從庫

##傳統複製##
#停止複製
mysql>stop slave;
#設定跳過一個事務
mysql>SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1
#重新開啓複製
mysql>start slave;
#這樣就正常了,但是,當然還是要把數據修改上去
mysql>update tables set ... where;
##GTID##
#停止複製
mysql>stop slave;
#然後執行設置一個事務GTID來跳過,就是要跳過這個事務的意思
mysql>SET gtid_next = '2a4aaa93-98e4-11ea-b9b2-00163e0c8a51:1-8';
#注入空事務
mysql>BEGIN;COMMIT;
#把GTID設置回自動模式
mysql>SET gtid_next = 'AUTOMATIC';
#重新開啓複製
mysql>START SLAVE;
#當然跳過了,並不代表這個數據就不修改了,還是要你手動去修改一下,這樣就一切迴歸正常了
mysql>update tables set ...;

#停止複製
mysql>stop slave;
#直接設置上面的GTID值+1
mysql>SET @@GLOBAL.GTID_PURGED='2a4aaa93-98e4-11ea-b9b2-00163e0c8a51:1-8';
#重新開啓複製
mysql>START SLAVE;
#當然跳過了,並不代表這個數據就不修改了,還是要你手動去修改一下,這樣就一切迴歸正常了
mysql>update tables set ...;

##傳統模式##
#停止複製
mysql>stop slave;
#設定跳過一個事務
mysql>SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1
#重新開啓複製
mysql>start slave;
#這樣就正常了,但是,當然還是要把數據修改上去
mysql>update tables set ... where ;

六、數據丟失

6.1 DML誤操作

使用binlog2sql/myflash/腳本方式通過binlog做數據閃回恢復

6.2 DDL誤操作

建立延遲從庫,基於全備+增備+binlog

七、其他場景

7.1 OOM排查

SELECT event_name,current_alloc FROM sys.memory_global_by_current_bytes WHERE event_name LIKE 'memory%innodb%';

7.2 數據庫無法啓動

通過錯誤日誌排查,具體問題具體分析。

7.3 數據庫壞頁

正常來講,innodb_force_recovery=1即可,然後邏輯導出。

innodb_force_recovery=1,即使發現了損壞頁面也繼續讓服務器繼續運行,這個選項對於備份或者轉存當前數據尤爲有用
innodb_force_recovery=2,阻止恢復主線程的運行,如果清除操作會導致服務器掛掉
innodb_force_recovery=3,恢復後不回滾事務
innodb_force_recovery=4,如果插入到緩衝區的合併操作會導致系統崩潰,將不會被執行
innodb_force_recovery=5,啓動數據庫時,忽略撤消日誌
innodb_force_recovery=6,啓動數據庫時,忽略與恢復相關的前滾日誌
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章