《MySQL——外部检测与内部统计 判断 主库是否出现问题》
目錄
- select1判斷
- 查表判斷
- 更新判斷
- 外部檢測弊端
- 內(nèi)部統(tǒng)計
一主一備的雙M架構(gòu)里,主備切換只需要把客戶端流量切換到備庫。
在一主多從的架構(gòu)里,主備切換要把客戶端流量切換到備庫,也需要把從庫接到新主庫上。
切換有兩種場景:1、主動切換 2、被動切換。
被動切換是由于主庫出問題了,下面是幾種判斷主庫出問題的方法:
select1判斷
select 1 成功返回,說明這個庫的進程孩子啊,但是不能說明主庫沒問題。
如果在執(zhí)行語句超過了設(shè)置的innodb_thread_concurrency,此時select 1語句是成功的,但是CPU不能滿足線程查詢要求了,新的查詢要求進來只會阻塞。
查表判斷
在系統(tǒng)庫(mysql庫)里創(chuàng)建一個表,命名為health_check,里面只放一行數(shù)據(jù),然后定期執(zhí)行語句:
select * from mysql.headlth_check;使用這個方法,可以檢測出由于并發(fā)線程過多導致的數(shù)據(jù)庫不可用的情況。
但是這個方法也會有一個問題:空間滿了,失效
更新事務要寫binlog,一旦binlog所在的磁盤空間占用率達到100%,那么所有的更新語句和事務提交commit語句就會堵住。但是系統(tǒng)此時是可以正常讀數(shù)據(jù)的。
更新判斷
放一個timestamp字段,用來表示最后一次執(zhí)行檢測的時間:
update mysql.health_check set t_modified = now();這種節(jié)點可用性檢測應該包含主庫和備庫。
備庫檢測也要寫binlog, 一般只能主庫寫,備庫不能寫。這里是為了檢測備庫,所以才能寫,但是binlog是雙M結(jié)構(gòu),所以會互相同步這一個檢測sql,那么有可能會造成主從數(shù)據(jù)不一致(t_modified內(nèi)容不同)
如果主庫A和備庫B都用相同的更新命令,就可能出現(xiàn)行沖突,從而導致主備同步停止。
我們可以在表上存入多行數(shù)據(jù),用A,B的server_id做主鍵:
create table 'health_check' ('id' int(11) not null,'t_modified' timestamp not null default current_timestamp,PRIMARY KEY ('id') ) engine = InnoDB;檢測命令如下:
insert into mysql.health_check(id,t_modified) values(@@server_id, now()) on duplicate key update t_modified=now();MySQL規(guī)定了主庫和備庫的server_id必須不同,就可以保證主、備庫各自的檢測命令不會發(fā)生沖突
這種方法仍然存在問題:判定慢
所有的檢測邏輯都需要一個超時時間N。即執(zhí)行一條update語句,超過N秒后還不返回就認為系統(tǒng)不可用。
如果一個日志盤的IO利用率已經(jīng)是100%的場景,此時系統(tǒng)響應非常慢,已經(jīng)需要做主備切換了。
我們檢測使用的update命令由于需要的資源比較少,很可能在拿到IO資源的時候就可以提交成功,并且在超時時間N秒未到達之前就返回給檢測系統(tǒng)。所以update命令沒有超時,然后得到系統(tǒng)正常的錯誤結(jié)論。
外部檢測弊端
上面的三種方法都是基于外部檢測的。外部檢測天然有個問題,就是隨機性。
外部檢測都需要定時輪詢,所以系統(tǒng)可能已經(jīng)出現(xiàn)問題了,但是卻要等到下一個檢測語句執(zhí)行的時候才能發(fā)現(xiàn)問題。運氣不好,第一次輪詢還不能發(fā)現(xiàn)。
內(nèi)部統(tǒng)計
MySQL5.6版本后提供了performance_schema庫,在file_summary_by_event_name表里統(tǒng)計每次IO請求的時間。
該行數(shù)據(jù)統(tǒng)計的是redo log的寫入時間。
COUNT_STAR是所有IO總次數(shù)。
前綴SUM、MIN、AVG、MAX,指統(tǒng)計項的總和、最小值、平均值、最大值。
SUM_NUMBER_OF_BYTES_READ 統(tǒng)計總共從redo log里讀了多少字節(jié)
需要注意的是,每進行一次統(tǒng)計,是由性能損耗的,所以建議只打開自己需要的項進行統(tǒng)計。
如打開 redo log 的時間監(jiān)控:
mysql> update setup_instruments set ENABLED='YES', Timed='YES' where name like '%wait/io/file/innodb/innodb_log_file%';然后通過MAX_TIMER值來判斷數(shù)據(jù)庫是否出現(xiàn)問題。可以設(shè)定閾值,單次IO請求時間超過200ms屬于異常,然后使用類似于下面的語句檢測:
mysql> select event_name,MAX_TIMER_WAIT FROM performance_schema.file_summary_by_event_name where event_name in ('wait/io/file/innodb/innodb_log_file','wait/io/file/sql/binlog') and MAX_TIMER_WAIT>200*1000000000;發(fā)生異常后,取得需要數(shù)據(jù)后再:
mysql> truncate table performance_schema.file_summary_by_event_name;把之前的統(tǒng)計信息清空。
總結(jié)
以上是生活随笔為你收集整理的《MySQL——外部检测与内部统计 判断 主库是否出现问题》的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “渤渚水浴凫”下一句是什么
- 下一篇: 《MySQL——恢复数据-误删行、表、库