紙上得來終覺淺,絕知此事要躬行。 概述 複製是指將主資料庫的DDL 和 DML 操作通過二進位日誌傳到從庫伺服器中,然後在從庫上對這些日誌重新執行(也叫重做),從而使得從庫和主庫的數據保持同步。 MySQL支持一臺主庫同時向多台從庫進行複製, 從庫同時也可以作為其他從伺服器的主庫,實現鏈狀複製。 優 ...
紙上得來終覺淺,絕知此事要躬行。
概述
複製是指將主資料庫的DDL 和 DML 操作通過二進位日誌傳到從庫伺服器中,然後在從庫上對這些日誌重新執行(也叫重做),從而使得從庫和主庫的數據保持同步。
MySQL支持一臺主庫同時向多台從庫進行複製, 從庫同時也可以作為其他從伺服器的主庫,實現鏈狀複製。
優勢
MySQL 複製的優點主要包含以下三個方面:
-
主庫出現問題,可以快速切換到從庫提供服務。
-
可以在從庫上執行查詢操作,從主庫中更新,實現讀寫分離,降低主庫的訪問壓力。
-
可以在從庫中執行備份,以避免備份期間影響主庫的服務。
原理
在詳細介紹如何設置複製之前,我們先看看MySQL實際上是如何複製數據的,總的來說,複製分為三個步驟:
- 當主庫在事務提交時,會把數據變更作為時間 Events 記錄在二進位日誌文件 Binlog 中。(這些記錄被稱為二進位日誌事件)
- 主庫推送二進位日誌文件 Binlog 中的日誌事件到從庫的中繼日誌 Relay Log 。
- slave重做中繼日誌中的事件,將改變反映它自己的數據。
第一步在主庫上記錄二進位文件(後續介紹設置)。在每次準備提交事務完成數據更新前,主庫將數據更新的事件記錄到二進位日誌中。MySQL會按照事務提交的順序而非每條語句的執行順序來記錄二進位日誌。在記錄二進位日誌之後主庫會告訴存儲引擎提交事務。
第二步,從庫將主庫的二進位日誌複製到其本地的中繼日誌。首先從庫會啟動一個工作線程稱為I/O線程,該線程跟主庫建立一個普通的客戶端連接,然後在主庫上啟動一個特殊的二進位轉儲線程,這個二進位轉儲線程會讀取主庫上二進位日誌事件,他不會對事件進行輪詢。如果該線程追趕上了主庫,他將進入睡眠狀態,直到主庫發送信號量通知從庫有新的事件才會被喚醒,然後線程將接受到的事件記錄到中繼日誌。
第三步,從庫中的線程從中繼日誌中讀取事件併在從庫執行,從而實現從庫數據的更新。
配置
Master配置
- 查看MySQL預設配置文件
mysql --help|grep 'my.cnf'
- 選擇一個配置文件輸入一下配置信息
# 必須,表示mysql配置文件
[mysqld]
# mysql 服務ID,保證整個集群環境中唯一
server-id=1
# mysql binlog 日誌的存儲路徑和文件名
log-bin=/var/lib/mysql/mysqlbin
# 錯誤日誌,預設已經開啟
# log-err
# mysql的安裝目錄
# basedir
# mysql的臨時目錄
# tmpdir
# mysql的數據存放目錄
# datadir
# 是否只讀,1 代表只讀, 0 代表讀寫
read-only=0
# 忽略的數據, 指不需要同步的資料庫
binlog-ignore-db=mysql
# 指定同步的資料庫
# binlog-do-db=db01
- 保存完畢之後,重啟服務
service mysql restart
- 創建同步數據的賬戶,並且進行授權操作
grant replication slave on *.* to '用戶名'@'從庫伺服器地地址' identified by '密碼';
# 例如:grant replication slave on *.* to 'root'@'192.168.192.131' identified by 'root';
flush privileges;
- 查看log-bin是否已打開
mysql> show variables like '%log_bin%';
+---------------------------------+-------------------------------+
| Variable_name | Value |
+---------------------------------+-------------------------------+
| log_bin | ON |
| log_bin_basename | /var/lib/mysql/mysqlbin |
| log_bin_index | /var/lib/mysql/mysqlbin.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
| sql_log_bin | ON |
+---------------------------------+-------------------------------+
6 rows in set (0.00 sec)
- 查看master狀態
mysql> show master status;
+-----------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------+----------+--------------+------------------+-------------------+
| mysqlbin.000001 | 154 | | mysql | |
+-----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
# File : 從哪個日誌文件開始推送日誌文件
# Position : 從哪個位置開始推送日誌
# Binlog_Ignore_DB : 指定不需要同步的資料庫
Slave配置
- 與Master一樣查找配置文件,輸入以下內容
# mysql服務端ID,唯一
server-id=2
# 指定binlog日誌
log-bin=/var/lib/mysql/mysqlbin
- 保存完畢之後,重啟服務
service mysql restart
- 登錄資料庫,輸入一下命令
change master to master_host= '192.168.192.130', master_user='主庫用戶名', master_password='主庫密碼', master_log_file='mysqlbin.000001', master_log_pos=413;
指定當前從庫對應的主庫的IP地址,用戶名,密碼,從哪個日誌文件開始的那個位置開始同步推送日誌。
- 開啟同步操作
start slave;
show slave status;
- 停止同步操作
stop slave;
測試配置同步
- 在主庫中創建資料庫,創建表,並插入數據 :
create database db01;
user db01;
create table user(
id int(11) not null auto_increment,
name varchar(50) not null,
sex varchar(1),
primary key (id)
)engine=innodb default charset=utf8;
insert into user(id,name,sex) values(null,'Tom','1');
insert into user(id,name,sex) values(null,'Trigger','0');
insert into user(id,name,sex) values(null,'Dawn','1');
- 在從庫中查詢數據,進行驗證 :
在從庫中,可以查看到剛纔創建的資料庫:
在該資料庫中,查詢user表中的數據: