在談到mysql主從同步前,我們先來了解下普通文件的數據同步。
普通文件的數據同步
1.NFS網絡文件共享可以同步存儲數據
2.samba共享--windows平臺
3.定時任務或守護進程結合rsync,scp
4.inotify+rsync實時同步
5.ftp數據同步
6.svn
......
mysql同步
mysql有其自帶的同步功能,mysql同步不是磁盤上文件直接同步。
mysql支持單向、雙向、鏈式級聯、事實、異步複製。在複製過程中,一臺服務器充當主服務器Master,而一個或者多個其他服務器充當爲從服務器Slave。
複製可以是單向:M==>S,也可以是雙向;M<==>M,當然也可以多從多M環狀同步等。
如果設置了鏈式級聯複製,那麼,從服務器本身除了充當從服務器外,也會同時充當其下面從服務器的主服務器
鏈式級聯複製:A-->B-->C-->D的複製形式
在當前的生產工作中,大多數應用的mysql主從同步都是異步的複製方式,即不是嚴格實時的數據同步。
生產環境授權
主庫用戶:grant select, insert, update,delete on 'xx'.* to '用戶'@'網段' identified by '用戶密碼';
從庫:grant select on 'xx'.* to '用戶'@'網段' identified by '用戶密碼';
可以結合read-only參數共同做
如何實現上述授權方案,最簡單的辦法是在主庫配置binlog-ignore-db=mysql
當配置好主從同步後,所有數據庫內容更新必須在主服務器上進行,避免用戶對主服務器的數據庫內容的更新與對從服務器上數據更新不一致而導致衝突
如何確保用戶在主服務器上更新呢?
1.防止從庫寫數據方法
採取忽略授權表方式的同步,然後對從服務器上的用戶僅授權select讀權限。不同步mysql庫
2.防止從庫寫數據方法
除了select授權外,在slave服務器啓動選項增加參數或者在my.cnf配置文件中加read-only保證從庫只讀,兩者同時操作效果更佳
應用場景
1.主從服務器互爲備份
2.主從服務器讀寫分離分擔網站壓力
3.根據服務器拆分業務獨立分擔壓力
在企業生產環境中,通常採取讀寫分離策略,即主庫負責寫操作,從庫負責讀操作。一般從庫有多臺,主庫可以採用高可用手段實現故障自動切換,如採用heartbeat+drbd。如果網站讀的壓力比較大,還可以利用負載均衡,分擔從庫服務器讀的壓力。
mysql讀寫分離方法
1.通過程序實現讀寫分離(性能、效率最佳),如php,java程序
2.通過軟件實現,如mysql-proxy amoeba等一些代理軟件也可以實現讀寫分離,但最常用最好用的還是程序實現讀寫分離。
mysql主從複製原理
mysql主從複製是一個異步的複製過程(一般情況下感覺是實時同步),數據從master複製到slave。這個過程是由三個線程參與完成的,兩個線程(SQL線程和IO線程)在slave端,另一個線程(IO線程)在master端。slave端的IO線程負責與master端的線程打交道
要實現mysql的主從複製,首先必須打開master端的Binlog(mysql-bin.xxx)功能,否則無法實現主從複製。因爲整個複製過程實際上是slave從master端獲取binlog日誌,然後在slave自身上以相同順序執行獲取的binlog日誌中記錄的操作。
當用戶寫入數據到主庫中,主庫將這些sql語句(數據庫的更改語句)放到binlog中,從庫開啓複製後通過IO線程和主庫IO線程打交道,提供用戶名密碼,log文件及位置信息給主庫,主庫驗證通過後讀取binlog信息(根據從庫IO縣線程需求)返回給從庫IO,位置信息保存在master-info中,sql放到relay-log(中繼日誌)中,從庫通過sql線程按照順序執行sql,從庫IO線程繼續讀取 master-info信息,然後與主庫IO交互。
mysql主從複製實踐
1.定義服務器角色
主庫(mysql master):ip 192.168.132.10 端口:3306
從庫(mysql slave): ip 192.168.132.20 端口: 3306
2.數據庫環境準備
實踐環境以兩臺虛擬機爲實踐對象,進行單向主從複製。
虛擬機均安裝mysql 5.1.72版本且數據庫已啓動
3.主庫上執行操作
設置server-id值並且開啓binlog參數
vim /etc/my.cnf
開啓log-bin
[mysqld]
server-id = 1
# Uncomment the following if you want to log updates
log-bin=mysql-bin
由於虛擬機mysql安裝路徑爲/usr/local/mysql,數據路徑爲/usr/local/mysql/data,即日誌文件在該路徑下。
server-id不能一樣
提示:
1. server-id與log-bin必須放在mysqld模塊裏
2. server-id的值使用服務器ip地址的最後8位如10目的是避免不同機器或實例重複(不適合多實例)
3. 現在配置文件中查找相關參數,不存在時再添加,參數不要重複
4. 修改配置文件中需要重啓數據庫
檢查是否生效:
[root@backupserver data]# mysql -uroot -p'123456' -e "show variables like 'log_bin';"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
4.建立用於從庫複製的賬號
登陸主庫mysql
grant replication slave on *.* to rep@'192.168.132.%' identified by 'rep99';
刷新權限flush privileges;
檢查用戶
select user,host from mysql.user;
+------+---------------+
| user | host |
+------+---------------+
| root | % |
| root | 127.0.0.1 |
| rep | 192.168.132.% |
| root | localhost |
+------+---------------+
4 rows in set (0.00 sec)
5.對數據庫鎖表只讀(當前窗口不要關掉)
因爲要備份數據庫,鎖表後能保證數據導出時一致
flush tables with read lock;
當前狀態,即當前binlog日誌文件名和二進制binlog日誌偏移量,後續從庫同步時需要用到。
show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 1336 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
6.導出數據庫備份
打開新的窗口,導出數據庫數據,如果數據很大(100G+),並且允許停機,可以停庫直接打包數據文件遷移
mysqldump -uroot -p'123456' -A -B|gzip>/home/tuwei/new.sql.gz
-A表示備份所有庫 -B表示增加use DB和drop等(導庫時會直接覆蓋原有的)
7. 解鎖主庫
解鎖主庫,恢復可寫
mysql> unlock table;
Query OK, 0 rows affected (0.00 sec)
8. 從庫執行操作
設置server-id值並關閉binlog參數
這裏將從庫server-id值設爲2,log-bin註釋掉,注意要在mysqld模塊裏設置
有兩種情況需要打開binlog:
1. 級聯同步A->B->C中間的B就要開啓
2. 從庫做數據庫備份,數據庫備份需要全備及binlog
設置完後重啓數據庫
9. 導入數據庫到從庫
將主庫上備份的數據庫文件傳送到從庫上進行導入,可以利用scp,sftp等命令進行傳送。
解壓數據庫文件
gzip -d new.sql.gz
導入數據庫
mysql -uroot -p'123456' <new.sql
10. 配置從庫同步參數
可以不用登陸數據庫裏面進行操作,快速執行change master語句(適合腳本里操作)
cat |mysql -uroot -p'123456' <<EOF
> CHANGE MASTER TO
> MASTER_HOST='192.168.132.10',
> MASTER_PORT=3306,
> MASTER_USER='rep',
> MASTER_PASSWORD='rep99',
> MASTER_LOG_FILE='mysql-bin.000001',
> MASTER_LOG_POS=1336;
> EOF
11. 啓動從庫同步開關
slave start;
然後查看從庫狀態
show slave status\G;
查看關鍵的三點
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
表示同步完成