資料庫實戰(一)資料庫主從複製
一、資料複製原理
Master將改變記錄到二進位制日誌(binary log)中,Slave將Master的二進位制日誌檔案拷貝到它的中繼日誌(relay log),Slave重做中繼日誌(relay log)中的事件。那麼,Master的變化,Slave也會變化,這樣就是所謂的MYSQL的複製,即MYSQL replication。
值得注意的是,通過上面的機制,可以保證Master和Slave的資料庫資料一致,但是時間上肯定有延遲,即Slave的資料是滯後的。
二、主從複製方式
1、同步複製
同步複製,即master的變化,必須等待slave-1,slave-2,…,slave-n完成後才能返回。這樣,顯然不可取,也不是MYSQL複製的預設設定。比如,在WEB前端頁面上,使用者增加了條記錄,需要等待很長時間。
2、非同步複製
非同步複製,master只需要完成自己的資料庫操作即可。至於slaves是否收到二進位制日誌,是否完成操作,不用關心。MYSQL的預設設定。
3、半同步複製
半同步複製,master只保證slaves中的一個操作成功,就返回,其他slave不管。這個功能,是由google為MYSQL引入的。
三、主從複製分析
-
問題1:master的寫操作,slave被動的進行一樣的操作,保持資料一致性,那麼slave是否可以主動的進行寫操作?
答:假設slave可以主動的進行寫操作,slave又無法通知master,這樣就導致了master和slave資料不一致了。因此slave不應該進行寫操作,至少是slave上涉及到複製的資料庫不可以寫。實際上,這裡已經揭示了讀寫分離的概念。 -
問題2:主從複製中,可以有N個slave,slave的作用?
答:一方面,進行資料備份,防止單點故障,保證高可用性。另一方面,分擔負載,提高查詢效能。 -
問題3:主從複製中有master,slave1,slave2,…等等這麼多MYSQL資料庫,那比如一個JAVA WEB應用到底應該連線哪個資料庫?
答:一般,insert/delete/update這些更新資料庫的操作,用master進行操作,select用slave進行操作。或者,找一個元件用它來完成MYSQL的代理,實現SQL語句的路由。這就是所謂的MYSQL READ WRITE SPLITE,MYSQL的讀寫分離。 -
問題4:當master的二進位制日誌每產生一個事件,都需要發往slave,如果我們有N個slave,那是發N次,還是隻發一次?
答:如果只發一次,發給了slave-1,那slave-2,slave-3,…它們怎麼辦?顯然,應該發N次。實際上,在MYSQL master內部,維護N個執行緒,每一個執行緒負責將二進位制日誌檔案發往對應的slave。master既要負責寫操作,還的維護N個執行緒,負擔會很重。可以這樣,slave-1是master的從,slave-1又是slave-2,slave-3,…的主,同時slave-1不再負責select。 slave-1將master的複製執行緒的負擔,轉移到自己的身上。這就是所謂的多級複製的概念。
四、mysql主從複製配置
1、安裝mysql
需要注意修改my.cnf的檔案許可權就Ok,命令:chmod 644 my.cnf。
2、配置master主伺服器
在Master MySQL上建立一個使用者‘repl’,並允許其他Slave伺服器可以通過遠端訪問Master,通過該使用者 讀取二進位制日誌,實現資料同步。
- //建立新使用者
- mysql>create user repl;
- //repl使用者必須具有REPLICATION SLAVE許可權.說明一下192.168.0.%,是指明repl使用者所在伺服器,當然你也可以指定固定Ip。
- mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.0.%' IDENTIFIED BY 'mysql';
- server-id=1 //給資料庫服務的唯一標識,一般為大家設定伺服器Ip的末尾號
- log-bin=master-bin
- log-bin-index=master-bin.index
3、配置slave伺服器
找到MySQL安裝資料夾修改my.ini檔案,在[mysqld]下面增加下面幾行程式碼,重啟MySQL服務。
- [mysqld]
- server-id=2
- relay-log-index=slave-relay-bin.index
- relay-log=slave-relay-bin
連結master伺服器
- change master to master_host='192.168.0.104', //Master 伺服器Ip
- master_port=3306,
- master_user='repl',
- master_password='mysql',
- master_log_file='master-bin.000001',//Master伺服器產生的日誌
- master_log_pos=0;