[TOC]
## 一、主從同步的實現原理

首先,備庫B跟主庫A之間維持了一個長連接。
一個事務日志同步的過程:
1. 在備庫B通過change master命令,設置主庫A的IP、端口、用戶名、密碼,以及要從哪個位置開始請求binlog,這個位置包含文件名和日志偏移量
2. 在備庫B上執行start slave命令,這時備庫會啟動io_thread、sql_thread。io_thread負責與主庫建立連接
3. 主庫A校驗完用戶名、密碼后,開始按照備庫B傳過來的位置,從本地讀取binlog,發給B
4. 備庫B拿到binlog后,寫到本地文件,稱為中轉日志(relay log)
5. sql_thread讀取中轉日志,解析出日志里的命令,并執行。
## 一、binlog格式
說起主從同步,binlog是其中的重要依據。mysql binlog有三種格式:row、statement、mixed。
> binlog 的不同模式有什么區別呢?
#### Statement:每一條會修改數據的sql都會記錄在binlog中。
**優點**:不需要記錄每一行的變化,減少了binlog日志量,節約了IO,提高性能。(相比row能節約多少性能與日志量,這個取決于應用的SQL情況,正常同一條記錄修改或者插入row格式所產生的日志量還小于Statement產生的日志量,但是考慮到如果帶條件的update操作,以及整表刪除,alter表等操作,ROW格式會產生大量日志,因此在考慮是否使用ROW格式日志時應該根據應用的實際情況,其所產生的日志量會增加多少,以及帶來的IO性能問題。)
**缺點**:由于記錄的只是執行語句,為了這些語句能在slave上正確運行,因此還必須記錄每條語句在執行的時候的一些相關信息,以保證所有語句能在slave得到和在master端執行時候相同的結果。另外mysql 的復制,像一些特定函數功能,slave可與master上要保持一致會有很多相關問題(如sleep()函數, last\_insert\_id(),以及user-defined functions(udf)會出現問題).
#### Row:不記錄sql語句上下文相關信息,僅保存哪條記錄被修改。
**優點**:?binlog中可以不記錄執行的sql語句的上下文相關的信息,僅需要記錄那一條記錄被修改成什么了。所以rowlevel的日志內容會非常清楚的記錄下每一行數據修改的細節。而且不會出現某些特定情況下的存儲過程,或function,以及trigger的調用和觸發無法被正確復制的問題
**缺點**:所有的執行的語句當記錄到日志中的時候,都將以每行記錄的修改來記錄,這樣可能會產生大量的日志內容,比如一條update語句,修改多條記錄,則binlog中每一條修改都會有記錄,這樣造成binlog日志量會很大,特別是當執行alter table之類的語句的時候,由于表結構修改,每條記錄都發生改變,那么該表每一條記錄都會記錄到日志中。
#### Mixedlevel:?是以上兩種level的混合使用
一般的語句修改使用statment格式保存binlog,如一些函數,statement無法完成主從復制的操作,則采用row格式保存binlog。
MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日志形式,也就是在Statement和Row之間選擇一種.新版本的MySQL中隊row level模式也被做了優化,并不是所有的修改都會以row level來記錄,像遇到表結構變更的時候就會以statement模式來記錄。至于update或者delete等修改數據的語句,還是會記錄所有行的變更。
## 二、主從結構(Master-Slave)
Mysql集群里面有兩種結構:主從結構、雙主結構。
### 如何避免主備切換中導致的雙寫問題?
主備切換過程中,備庫應設置為**只讀狀態**。
### 把備庫設置成只讀了,還能和主庫保持同步更新嗎?
> 用于同步更新的線程,擁有超級權限。 readonly設置對超級(super)權限用戶無效。
## 三、雙主結構(Master-Master)
binlog確保了在備庫執行相同的binlog,可以得到與主庫相同的狀態。
因此,可以認為正常情況下主備數據是一致的。即文章一開始的圖中。M-S結構A、B兩個節點的內容是一致的,實際生產上使用比較多的是雙M結構——節點A和B之間總是互為主備關系。
### 循環復制
MySQL在binlog中記錄了這個命令第一次執行時所在實例的server id。因此,可以用下面的邏輯解決兩個節點間的循環復制的問題:
規定兩個庫的server id必須不同,如果相同,則它們之間不能設定為主備關系
一個備庫接到binlog并在重放的過程中,生成與原binlog的server id相同的新的binlog
每個庫在收到從自己的主庫發過來的日志后,先判斷server id,如果跟自己的相同,表示這個日志是自己生成的,就直接丟棄這個日志。
參考文章:
- [【阿里最新數據庫面試題】MySQL主從一致性](https://blog.csdn.net/qq_33589510/article/details/117607508)
- [Mysql Binlog三種格式詳細介紹](https://www.cnblogs.com/baizhanshi/p/10512399.html)
- 前言
- 第一部分 計算機網絡與操作系統
- 大量的 TIME_WAIT 狀態 TCP 連接,對業務有什么影響?怎么處理?
- 性能占用
- 第二部分 Java基礎
- 2-1 JVM
- JVM整體結構
- 方法區
- JVM的生命周期
- 堆對象結構
- 垃圾回收
- 調優案例
- 類加載機制
- 執行引擎
- 類文件結構
- 2-2 多線程
- 線程狀態
- 鎖與阻塞
- 悲觀鎖與樂觀鎖
- 阻塞隊列
- ConcurrentHashMap
- 線程池
- 線程框架
- 徹底搞懂AQS
- 2-3 Spring框架基礎
- Spring注解
- Spring IoC 和 AOP 的理解
- Spring工作原理
- 2-4 集合框架
- 死磕HashMap
- 第三部分 高級編程
- Socket與NIO
- 緩沖區
- Bybuffer
- BIO、NIO、AIO
- Netty的工作原理
- Netty高性能原因
- Rabbitmq
- mq消息可靠性是怎么保障的?
- 認證授權
- 第四部分 數據存儲
- 第1章 mysql篇
- MySQL主從一致性
- Mysql的數據組織方式
- Mysql性能優化
- 數據庫中的樂觀鎖與悲觀鎖
- 深度分頁
- 從一條SQL語句看Mysql的工作流程
- 第2章 Redis
- Redis緩存
- redis key過期策略
- 數據持久化
- 基于Redis分布式鎖的實現
- Redis高可用
- 第3章 Elasticsearch
- 全文查詢為什么快
- battle with mysql
- 第五部分 數據結構與算法
- 常見算法題
- 基于數組實現的一個隊列
- 第六部分 真實面試案例
- 初級開發面試材料
- 答案部分
- 現場編碼
- 第七部分 面試官角度
- 第八部分 計算機基礎
- 第九部分 微服務
- OpenFeign工作原理