起因:在工作中常常要用到mysql,平常只是對數據庫crud,并沒有認真的了解過她,sql語句也只是會一些最基本的,和常用的,一些不常用的都要去網上百度,即決定學習一下mysql,來了解她,雖然開發(fā)很多都是黑盒,但追本溯源總是我們想要的。
1.什么是數據庫高可用
1.1.什么是高可用集群
N+1:N就是集群,1就是高可用,高可用的核心就是冗余,集群是保證服務最低使用標準的
1.2.高可用集群的衡量標準
一般是通過系統(tǒng)的可靠性和可維護性來衡量的MTTF:平均無故障時間,這是衡量可靠性的MTTR:衡量系統(tǒng)的可維護性的HA=MTTF/(MTTF+MTTR)*100%
SLA:99.999%:表示一年年故障時間/宕機時間不超過6分鐘
1.3.實現高可用的三種方式
主從方式(非對稱)
這種?方式的組織形式通常都是通過兩個節(jié)點和一個或多個服務器?,其中一臺作為主節(jié)點
(active),另一臺作為備份節(jié)點(standy),備份節(jié)點應該隨時都在檢測主節(jié)點的健康狀況,當主節(jié)點發(fā)?生故障,服務會自動切換到備份節(jié)點保障服務正常運行
對稱方式
兩個節(jié)點,都運行著不同的服務且相互備份,相互檢測對方的健康,當任意一個節(jié)點發(fā)?生故障,這 個節(jié)點上的服務就會自動切換到另一節(jié)點
多機?方式
包含多個節(jié)點多個服務,每個節(jié)點都要備份運?行不同的服務,出現問題自動遷移
1.4MySQL數據的高可用實現
1.4.1.主從方式(非對稱)
資源:兩臺同版本的MySQL數據庫
主從實現的內部運行原理和機制
First Step:主數據庫服務器?會把數據的修改記錄記錄進binlog?日志,binlog?一定要打開
Second Step:從庫的I/O進?行行讀取主庫的binlog內容后存?入?自?己的Relay Log中繼?日志中,這個I/O線程會和主庫建?立?一個普通的客戶端連接,然后主庫啟動?一個?二進制轉儲線程,I/O線程通過轉儲線程讀取binlog更更新事件,同步完畢后I/O進?入sleep,有新的更更新會再喚醒
Relay Log和Binlog的格式是一樣的,可以?用mysqlbinlog讀取,也可show
mysql> show relaylog events in 'relay-log.000001';
目前數據庫有兩種復制方式
binlog日志點position
GTID?方式也要依賴binlog
第三步:從服務器?的SQL進程會從Relay Log中讀取事件并在從庫中重放
從服務器?執(zhí)行重放操作時是可以在配置里聲明是否寫?入服務?的binlog日志中

1.4.2.配置主從服務步驟
#######1.4.2.1.Binlog的日志點方式配置主從同步
配置主從服務器?參數
在Master服務器?上創(chuàng)建?用于復制并授權的數據庫賬號
備份Master數據庫并初始化Slave服務器?數據
啟動復制鏈路路
Master服務器?配置
chown -R mysql:mysql /usr/local/binlog/
#配置?文件
server_id=163
log_bin=/usr/local/binlog/mysql-bin
Slave服務?配置
server_id=196
log_bin=/usr/local/binlog/mysql-bin
relay_log=/usr/local/relaylog/relay-bin
#當slave宕機后,如果relay log損壞了,導致?一部分中繼?日志沒有處理理,則放棄所有未完成的, 重新獲取執(zhí)?行行,保證完整性
relay_log_recovery=1
#讓從庫數據只讀,super?用戶,super_read_only=on
read_only=on
#從庫的復制鏈路路服務不會隨數據庫重啟而重啟,需要手動啟動
skip_slave_start=on
#確保數據一致性,通過innoDB的崩潰恢復機制來保護哦
master_info_repository=TABLE
relay_log_info_repository=TABLE
#select * from mysql.slave_master_info;
#select * from mysql.slave_relay_log_info;
主庫授權
mysql> use msyql;
mysql> grant replication slave on *.* to 'syncuser'@'192.168.0.103' identified by '123456';
mysql> flush privileges;
set global validate_password_policy=LOW;
set global validate_password_length=6;
初始化數據
mysqldump -uroot -p123456 --master-data=2 --single-transaction --routines -
-triggers --events --databases mydb > mydb.sql
創(chuàng)建復制鏈路
mysql>
CHANGE MASTER TO
MASTER_HOST='192.168.0.102',
MASTER_PORT=3306,
MASTER_USER='syncuser',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=8122;
mysql> start slave;
mysql> show slave status \G;
從庫的binlog是否寫入?
默認情況下是不寫入的:因為寫入binlog會消耗I/O,所以性能會下降,如果需要在從庫上恢復數據就到Relay Log里進行導出處理
直接在從庫上操作更更行語句句則會寫入binlog
如果就是需要寫入?在從庫的my.cnf : log_slave_updates=on #開啟同步并寫入binlog
開啟同步并寫入binlog應?用于從到從的情況
#Master配置?文件#不不同步哪些數據庫
binlog-ignore-db=mysql binlog-ignore-db=test
binlog-ignore-db=information_schema #同步哪些庫
binlog-do-db=game
binlog-do-db=mydb
#Slave配置?文件#復制哪些數據庫
replicate-do-db=mydb replicate-do-db=game
#不不復制哪些數據庫
replicate-ignore-db=mysql
replicate-ignore-db=test
--replicate-wild-ignore-table=foo%.bar% 不不復制使?用表名稱以開頭foo且表名稱以開頭的表的更更新bar
作業(yè):
?replicate-ignore-table=mydb.ad_user?
只同步其中三個表?
mysqldump只導出3張表,復制的配置只復制三張表
1.4.2.1. GTID的方式來進行主從復制
不同點
主從服務器?的參數有不同的地?方
#在上面的基礎上,需要給主從服務器?都加上
gtid_mode=on
enforce_gtid_consistency=on #開啟強制GTID的一致性確保事務
GTID下復制鏈路的啟動
mysql>
CHANGE MASTER TO
MASTER_HOST='192.168.0.102',
MASTER_PORT=3306,
MASTER_USER='syncuser',
MASTER_PASSWORD='123456',
MASTER_AUTO_POSITION=1;
啟動GTID后以下數據庫操作不可用
create table tableName. select
在一個事務中創(chuàng)建臨時表
在一個transaction中更更新innoDB表和myisam表
2.數據主從復制方式的容災處理
2.1.MySQL支持的復制格式
2.1.1.基于語句句的復制(statement)
優(yōu)點:記錄少,只記錄執(zhí)行語句句,易懂
缺點:insert into table1(create_time) values(now()),這個now就不是當時的時間了
2.1.2.基于行復制(row)
優(yōu)點:幾乎沒有基于行復制無法處理的場景
缺點:數據量量太大了
2.1.3.混合類型的復制(MIXED)
mixed格式默認采?用statement,?比如?用到UUID(),ROW_COUNT()
2.2.主從切換
作業(yè):自己把主從更更換一下
從庫的binlog目前是沒有寫入的
需要給old主庫授權new主庫的權限
在old主庫上創(chuàng)建復制鏈路路
從庫還需要把read_only關閉
2.3.MySQL主從復制模式
異步復制:MySQL默認就是異步復制,性能最好,但主從復制的數據不一致性概率最?大
同步復制:當客戶端發(fā)過來一個請求后,只有當所有的從庫都寫到Relay Log中,才回復給前端事務完成,性能最差,但一致性很強
半同步復制:至少一個從庫完成Relay Log寫?入后就返回事務完成給前端
主從上都要安裝
mysql> install plugin rpl_semi_sync_master soname='semisync_master.so'
rpl_semi_sync_master_enabled
rpl_semi_sync_master_timeout #單位是毫秒,如果主庫等待從庫回復超過這個時間就自動切換為異步
問題?
做過主從復制,主從一般都是實時的同步的?
update tableName set score=99;
從庫是不是也會被直接更新掉?
一般情況下,我的從庫對數據的實時性要求都不是非常高如果我們有一個從庫更更新可以延時10分鐘
如果運氣好,在你拿到10分鐘前的數據和你更新之間這個表沒有操作,是不不是完美解決? 設置?一個從庫,將延遲時間設置成我們能處理理和反應的周期長度即可
mysql> stop slave;
mysql> change master to master_delay=600; #單位是秒, SQL_Delay: 600
mysql> start slave;
不要以為每天把功能完成了就行了,這種思想是要不得的,互勉~!