mysql主备模型_MySQL主从复制 - 基于二进制日志(理论篇)
mysql日志類型
1????二進制日志
2????事務日志
3????一般查詢日志
4????中繼日志
5????慢查詢日志
二進制日志
二進制日志通常記錄的是可能潛在引起數據庫發生改變的操作,每一個操作我們稱為一個event。
二進制日志記錄一個event的時候,通常還會記錄timestamp,position(偏移量offset),server-id,event本身。
二進制日志的數據存儲形式,形如mysql-bin.xxxxxx這種,二進制日志除了mysql-bin.xxxxxx之外,還有mysql-bin.index(二進制日志索引文件)
二進制日志滾動條件:容量達到定義的最大上限,flush logs ,服務器重啟
二進制日志刪除:一般不建議用rm直接刪除,建議用mysql的PURGE命令清除
語法:PURGE {MASTER | BINARY} LOGS TO ‘log_name‘ ? ?# 刪除指定的日志PURGE {MASTER | BINARY} LOGS BEFORE ‘date‘ ?# 刪除日期之前的日志,BEFORE變量的date自變量可以為‘YYYY-MM-DD hh:mm:ss‘格式如:(MASTER 和BINARY 在這里都是等效的)PURGE MASTER LOGS TO ‘test-bin.000001‘;PURGE MASTER LOGS BEFORE ‘2011-01-0100:00:00‘;
二進制日志格式:statement(mysql官方不推薦)
row(mysql 5.6以后推薦)
mixed
二進制日志查看:
查看當前mysql使用的二進制文件及處在哪個position上:SHOW MASTER STATUS;
查看當前mysql上使用的二進制文件列表:SHOW BINARY LOGS;
查看某個二進制日志文件的具體內容:SHOW BINARY EVENTS IN ‘mysql-bin.1234567‘;
二進制日志用途:
二進制日志可以即時點還原,因為二進制日志中記錄的是潛在引起數據庫發生改變的操作。要注意的是,通過二進制日志恢復的數據可能跟原始數據不一樣,在多顆cpu并行工作的情況下,會同時執行多個事務,如果mysql的隔離級別較低,事務之間可能交叉執行(互相影響),當前能夠被使用的二進制日志只有一個,寫入二進制日志的方式是串行寫入,而事務是并行執行的,事務執行的次序和記錄在二進制日志中的次序可能不一致。
mysql隔離級別:(由低到高)
READ-UNCOMMITTED
READ-COMMITTED
REPEATABLE-READ(缺省隔離級別)
SERIALIZABLE
如果你的mysql隔離級別是REPEATABLE-READ,二進制日志格式是statement,在某些場景下絕對會出現通過二進制日志恢復的數據和原始數據不一致的情況。
如果你的mysql隔離級別是READ-COMMITED,二進制日志格式推薦row。
主從復制原理
主從復制模式
mysql支持一主多從
同步:?確保event發送到所有的slave
半同步: ?只要本地event寫入本地的二進制日志文件中即可,但是不確保event一定發送到slave,它是不管的
異步:?確保event發送到其中一個slave
注:mysql 5.5 之前是不支持半同步的(google貢獻的mysql半同步補丁)
多級復制
一個從可以是某個主的從,也可以是某個從的從。
中繼日志(relay log)不能發送給其它節點
復制的作用:
實現備份
高可用
異地容災
分攤負載(scale out)
Mysql一主多從、讀寫分離架構
分析:這種架構隨著mysql從服務器的增加會消耗mysql主服務器的性能(cpu、IO、內存),因為從服務器直接接受二進制日志中的event。有幾個從服務器接受主服務器發送的event,相應地mysql主服務器就要啟幾個線程,這些mysql線程各自獨立地從二進制日志中讀取數據,讀完后發送給對應的mysql從服務器,所以下面引入新架構。
Mysql一主多從、讀寫分離、多級復制架構
分析:"主的從,從的主" mysql server實際上它只是起把二進制日志的event從主服務器發送到從服務器的中間件而已,實在沒有必要把數據持久化存儲下來,浪費IO。但是從中繼日志中讀取的event不在本地執行寫入數據文件是不會記錄到二進制日志文件中的,沒有二進制日志就不能發送event給從服務器了。
解決思路:
mysql有種存儲引擎叫black hole,功能類似于linux的/dev/null,"主的從,從的主" mysql 數據庫使用black hole存儲引擎,這樣從中繼日志中讀取的event在本地執行完后,數據并沒有保存下來。
主從架構中,如果不使用mysql-proxy,如何到主服務器寫,到從服務器讀?
就lamp架構來說,可以在前端程序中指定到哪個主服務器寫,到哪個從服務器讀;如果有多個從服務器,還可以在程序中使用rr輪詢調度訪問,增加了前端程序的復雜度。
mysql實際上是支持雙主模型的,
雙主模型可以減輕讀操作,但是無法減輕寫操作,所有在第一個節點的寫操作,第二個節點也同樣要執行一遍,不然就出現數據不一致了。
一般來說,在生產環境中絕對不建議使用雙主模型
雙主模型原理實現預測
雙主模型很容易出問題,舉個例子:
keystone數據庫的user表:
字段: id ?name ?default_project_id
id ?name default_project_id
1 ? ? user1 ? ? 111
2 ? ? user2 ? ? 222
server1: update user set name=‘yao‘ where default_project_id=‘111‘;
server2: update user set default_project_id=‘123‘ where name=‘user1‘
最后怎么合并呢,就會出現數據不一致了,雙主模型存在這種 mysql邏輯問題
Mysql集群規模擴大
當一個服務器承受的壓力過大的時候,兩種方式提升它的性能:
scale on:縱向擴展,增加單臺服務器的性能
scale out: 橫向擴展,增加服務器分攤負載
當規模越來越大的時候,我們的主服務器怎么都無法承擔寫操作的時候,怎么辦?
數據庫服務器之所以壓力大,那是因為庫里面有很多張表,每個表可能都需要讀寫操作;雙主也無法減輕寫操作,需要垂直拆分(分庫),就是將一個大的數據庫拆分成n個小的數據庫,把那些查詢(聯合查詢)或操作的時候相關聯的表放在一起,每一個小的數據庫放在一個物理服務器上;
當需要對某張表操作的時候,我們只需要聯系這張表所在的數據庫,但是垂直拆分治標不治本,數據庫的數據也是有熱區的,比如說我們有50G的數據,其中有2G的數據最繁忙,而這2G的數據都在同一張表上,這時候就需要水平拆分(分表)了,分表的目的就是把熱區數據分開。
注:拆分是根據業務來拆的,不了解業務是不行的。
一般來說,能不拆盡量不拆,一旦出現問題,trouble shooting起來將變得很困難。
實現讀寫分離的開源軟件
mysql-proxy(mysql官方)
amoeba(阿里巴巴貢獻,java編寫)
cobar(在amoeba基礎上開發,java編寫,這實際上是一個數據拆分后實現路由的軟件)
原文:http://iceyao.blog.51cto.com/9426658/1571865
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的mysql主备模型_MySQL主从复制 - 基于二进制日志(理论篇)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java dom4j 去除空行_如何从X
- 下一篇: java logic_Java Logi