概述
mysql從3.23版本開始提供複製功能,複製是將主庫的DDL和DML操作通過二進制日誌傳遞到複製服務器(從庫)上,然後從庫對這些日誌重新執行(重做),從而使得主庫和從庫保持數據一致。
mysql複製的優點:
如果主庫出現問題,可以快速切換到從庫提供服務
可以在從庫執行查詢操作,降低主庫的訪問壓力。
可以在從庫進行備份,以免備份期間影響主庫的服務。
注意:由於mysql實現的異步複製,所以主庫和從庫數據之間存在一定的差異,在從庫執行查詢操作需要考慮這些數據的差異,一般只有更新不頻繁和對實時性要求不高的數據可以通過從庫插敘,實行要求高的仍要從主庫查詢。
複製原理
mysql的複製原理大致如下。
(1)首先,mysql主庫在事務提交時會把數據庫變更作爲事件Events記錄在二進制文件binlog中;mysql主庫上的sys_binlog控制binlog日誌刷新到磁盤。
(2)主庫推送二進制文件binlog中的事件到從庫的中繼日誌relay log,之後從庫根據中繼日誌重做數據庫變更操作。通過邏輯複製,以此來達到數據一致。
Mysql通過3個線程來完成主從庫之間的數據複製:其中BinLog Dump線程跑在主庫上,I/O線程和SQl線程跑在從庫上。當從庫啓動複製(start slave)時,首先創建I/O線程連接主庫,主庫隨後創建Binlog Dump線程讀取數據庫事件併發給I/O線程,I/O線程獲取到數據庫事件更新到從庫的中繼日誌Realy log中去,之後從庫上的SQl線程讀取中繼日誌relay log 中更新的數據庫事件並應用。
複製中的各類文件
除了 二進制文件binlog 、中繼日誌relay-log外,爲了保證從庫crash重啓後,從庫的io線程和sql線程仍能夠知道從哪裏複製,從庫上默認還創建兩個日誌文件master.info和relay-log.info用來保存複製進度。
三種複製方式
二進制binlog的格式有三種:
statement:基於sql的binlog,每條修改數據的sql都會保存到binlog裏。
row:基於行級別,記錄每一行數據的變化,也就是將每一行數據的變化都記錄到binlog裏,記錄非常詳細。
mixed:混合statement和row模式。
複製的常見三種架構:
一主多從
多級複製
雙主複製
一、搭建主從複製
1、修改 主 配置文件(my.cnf) [mysqld]下增加
[mysqld]
server-id=1 #配置server-id 唯一
log-bin=log-bin ###bin log 文件名字
binlog_format=mixed ###binlog的格式
2、保存配置 並重啓數據庫。重啓完成連接數據庫,使用 show master status 命令查看主庫的狀態。
MariaDB [(none)]> show master status;
+----------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+----------------+----------+--------------+------------------+
| log-bin.000001 | 245 | | |
+----------------+----------+--------------+------------------+
3、修改 從 配置文件(my.cnf), [mysqld]下增加
[mysqld]
server-id=2 ##配置server id 唯一
relay-log=relay-log ###中繼日誌 文件名
binlog_format=mixed ###binlog的格式
4、保存配置 重啓數據
5、主機授權從機複製,主 機器 上操作
mysql> grant replication slave on *.* to ‘slave’@‘192.168.1.2’ identified by '123456';
Query OK, 0 rows affected (0.02 sec)
##解釋下 賦予 replication slave 權限給 slave 用戶 ,*.* 代表所有庫的所有表, 123456 是登錄密碼
6、從機 配置監聽主機
## 確保 停止salve
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
#開始配置
#master_host 配置你監聽的主機地址
#master_port 你監聽主機的端口
#master_user 用戶名,就是我們剛剛在主機授權時的用戶名
#master_password 授權的用戶密碼
#master_log_file 是你主機二進制文件,可以在主機中使用show mater status 查看
#master_log_pos 開始複製的位置。 show mater status 查看
mysql>
mysql> change master to
-> master_host='192.168.1.1',
-> master_port=3307,
-> master_user='slave',
-> master_password='123456',
-> master_log_file='log-bin.000001',
-> master_log_pos=245;
Query OK, 0 rows affected (0.06 sec)
#開啓slave
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
#配置完成 查看 slave 狀態
#可以看到 Slave_IO_State: Waiting for master to send event slave狀態是等待主機發送事件
#我們只要觀察Slave_IO_Running: Yes
# Slave_SQL_Running: Yes
#這兩個線程都是yes
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: localhost
Master_User: slave
Master_Port: 3307
Connect_Retry: 60
Master_Log_File: log-bin.000001
Read_Master_Log_Pos: 245
Relay_Log_File: relay-log.000001
Relay_Log_Pos: 258
Relay_Master_Log_File: log-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 254
Relay_Log_Space: 419
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 107
1 row in set (0.00 sec)
ERROR:
No query specified
mysql>
至此從機 已配置完成。
二、雙主熱備實現
1、slave 從機 開啓binlog,[mysqld]下增加
log-bin=log-bin ###bin-log日誌的名稱
binlog_format=mixed ###binlog的格式
log_slave_updates=1
----------------------------------
log_slave_updates =1 是代表通過主機同步過來的數據操作也寫入到bin-log 中,這樣就能保證 從庫的bin-log和主庫的bin-log是一致的。編輯完成後,保存退出。
2、保存配置 並重啓數據庫。重啓完成連接數據庫,使用 show master status 命令查看主庫的狀態。
MariaDB [(none)]> show master status;
+----------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+----------------+----------+--------------+------------------+
| log-bin.000001 | 245 | | |
+----------------+----------+--------------+------------------+
2、從機授權主機 複製
mysql> grant replication slave on *.* to ‘salve’@'192.168.1.1' identified by '123456';
3、主機 開啓 relay_log ,修改主機配置文件,[mysqld]下增加
relay_log=msyql-relay-log
log_slave_updates=1
4、配置 主機 開始 監聽 從機
mysql> change master to
-> master_host='192.168.1.2',
-> master_port=3306,
-> master_user='slave',
-> master_password='123456',
-> master_log_file='log-bin.000001',
-> master_log_pos=245;
Query OK, 0 rows affected (0.06 sec)
##開啓複製
三、其他參數配置
log-bin = mysql-bin #開啓mysql的binlog日誌功能
sync_binlog = 1 #master 配置。控制數據庫的binlog刷到磁盤上去 , 0 不控制,性能最好,1每次事物提交都會刷到日誌文件中,性能最差,最安全
binlog_format = mixed #binlog日誌格式,mysql默認採用statement,建議使用mixed
expire_logs_days = 7 #binlog過期清理時間
max_binlog_size = 100m #binlog每個日誌文件大小
binlog_cache_size = 4m #binlog緩存大小
max_binlog_cache_size= 512m #最大binlog緩存大
binlog-ignore-db=mysql #不生成日誌文件的數據庫,多個忽略數據庫可以用逗號拼接,或者 複製這句話,寫多行
binlog_do_db = test1,test2 #日誌記錄那些數據庫
binlog_ignore_db = mysql,performance_schema,information_schema #日誌記錄忽略那些數據庫的
auto-increment-offset = 1 # 自增值的偏移量
auto-increment-increment = 1 # 自增值的自增量
slave-skip-errors = all #跳過從庫錯誤
replicate_do_db = test1,test2 #是在slave上配置,指定slave要複製哪個庫
replicate-ignore-db=mysql,performance_schema,information_schema #是在slave上配置,指定slave要忽略哪個庫
replicate-wild-ignore-table=mysql.% # slave上配置。從庫複製跳過的表
relay_log_recovery = 1 #slave上配置。從庫建議開啓,有利於數據一致性
log_slave_updates = 1 #如果從庫還會用做主庫,建議開啓
2、relay log的相關參數說明
通過語句:show variables like '%relay%',查看先骨幹的relay的所有相關參數
mysql> show variables like '%relay%';
+-----------------------+----------------+
| Variable_name | Value |
+-----------------------+----------------+
| max_relay_log_size
| relay_log
| relay_log_basename
| relay_log_index
| relay_log_info_file
| relay_log_info_repository
| relay_log_purge
| relay_log_recovery
| relay_log_space_limit
| sync_relay_log
| sync_relay_log_info
+-----------------------+----------------+
參數詳細解釋:
2.1 max_relay_log_size:
標記relay log 允許的最大值,如果該值爲0,則默認值爲max_binlog_size(1G);如果不爲0,則max_relay_log_size則爲最大的relay_log文件大小;
2.2 relay_log:
定義relay_log的位置和名稱,如果值爲空,則默認位置在數據文件的目錄(datadir),文件名爲host_name-relay-bin.nnnnnn(By default, relay log file names have the form host_name-relay-bin.nnnnnn in the data directory);
2.3 relay_log_index:
同relay_log,定義relay_log的位置和名稱;一般和relay-log在同一目錄
2.4 relay_log_info_file:
設置relay-log.info的位置和名稱(relay-log.info記錄MASTER的binary_log的恢復位置和relay_log的位置)
2.5 relay_log_purge:
是否自動清空不再需要中繼日誌時。默認值爲1(啓用)。
2.6 relay_log_recovery:
當slave從庫宕機後,假如relay-log損壞了,導致一部分中繼日誌沒有處理,則自動放棄所有未執行的relay-log,並且重新從master上獲取日誌,這樣就保證了relay-log的完整性。默認情況下該功能是關閉的,將relay_log_recovery的值設置爲 1時,可在slave從庫上開啓該功能,建議開啓。
2.7 relay_log_space_limit:
防止中繼日誌寫滿磁盤,這裏設置中繼日誌最大限額。但此設置存在主庫崩潰,從庫中繼日誌不全的情況,不到萬不得已,不推薦使用;
2.8 sync_relay_log:
這個參數和sync_binlog是一樣的,
當設置爲1時,slave的I/O線程每次接收到master發送過來的binlog日誌都要寫入系統緩衝區,然後刷入relay log中繼日誌裏,這樣是最安全的,因爲在崩潰的時候,你最多會丟失一個事務,但會造成磁盤的大量I/O。
當設置爲0時,並不是馬上就刷入中繼日誌裏,而是由操作系統決定何時來寫入,雖然安全性降低了,但減少了大量的磁盤I/O操作。這個值默認是0,可動態修改,建議採用默認值。
2.9 sync_relay_log_info:
這個參數和sync_relay_log參數一樣,當設置爲1時,slave的I/O線程每次接收到master發送過來的binlog日誌都要寫入系統緩衝區,然後刷入relay-log.info裏,這樣是最安全的,因爲在崩潰的時候,你最多會丟失一個事務,但會造成磁盤的大量I/O。當設置爲0時,並不是馬上就刷入relay-log.info裏,而是由操作系統決定何時來寫入,雖然安全性降低了,但減少了大量的磁盤I/O操作。這個值默認是0,可動態修改,建議採用默認值。
3、總結:以上只是簡單的介紹了每個參數的作用,這些參數具體的設置還是需要根據每個用戶的實際系統情況進行設置的;
四、相關連接
mysql主從複製原理 https://blog.csdn.net/qq_16399991/article/details/82749333
mysql搭建 主從複製 https://blog.csdn.net/qq_16399991/article/details/82740881
https://www.jianshu.com/p/19cb0f16dea4
https://www.cnblogs.com/myIvan/p/10164926.html
mysql複製-mysql雙主熱備實現 https://blog.csdn.net/qq_16399991/article/details/82771584
https://www.cnblogs.com/lzhdonald/archive/2020/04/13/12689712.html
怎麼查看mysql 的binlog日誌存放的位置 https://www.cnblogs.com/jpfss/p/11112283.html
CHANGE MASTER TO 語法詳解 https://blog.csdn.net/jesseyoung/article/details/41942809
relay log 詳細參數解釋 https://blog.51cto.com/douya/1788753
五、mysql 其他命令
flush logs; #生成新的log文件
reset slave; #重置master ,執行完可以重新執行 change master to 命令
reset master; #重置master binlog 日誌,刪除日誌和index文件
查看從庫的relay log
[root@mysqlb relaybin]# mysqlbinlog -vv slave-relay-bin.000010
六、如果主庫裏已經數據庫數據了,那還得進行以下操作:
刷新表然後鎖表(只允許查數據不允許寫數據):
flush tables with read lock;
然後備份要同步的數據庫的數據,然後拷貝到從庫裏面
mysqldump -uroot -p test1>test1.sql;
mysqldump -uroot -p test2>test2.sql;
#從庫要先創建數據庫test1和test2,然後導入數據
mysql -uroot -p test1<test1.sql;
mysql -uroot -p test1<test2.sql;
配置主從同步,然後解除鎖表
unlock table