一、主從複製的優點:
有利於數據庫構架的健壯性,提升訪問速度和易於維護管理
二、應用場景
1、主從服務器互爲備份(類似nfs 的rsync+secsever)
a、先掛主,在將主的binglog 日誌拉到從庫,再補充從庫
b、雙寫
c、應用程序每分鐘寫一次來進行判定,一旦出錯,將binglog 日誌拉到從庫,再補充從庫
d、Mysql 插件,半同步插件google 出品
2、主從服務器讀寫分離分擔網站壓力:讀寫分離
大中型公司:通過程序(php,java)
測試環境,代理軟件(mysql-proxy,amoeba)
門戶網站:分佈式dbproxy(讀寫分離,hash 負載均衡,健康檢查)
3、根據服務器拆分業務,拆分從庫
三、主從複製原理
Mysql的 Replication 是一個異步的複製過程,從一個 Mysql instace(我們稱之爲 Master)複製到另一個 Mysql instance(我們稱之 Slave)。在 Master 與 Slave 之間的實現整個複製過程主要由三個線程來完成,其中兩個線程(Sql線程和IO線程)在 Slave 端,另外一個線程(IO線程)在 Master 端。
要實現 MySQL 的 Replication ,首先必須打開 Master 端的Binary Log(mysql-bin.xxxxxx)功能,否則無法實現。因爲整個複製過程實際上就是Slave從Master端獲取該日誌然後再在自己身上完全 順序的執行日誌中所記錄的各種操作。打開 MySQL 的 Binary Log 可以通過在啓動 MySQL Server 的過程中使用 “--log-bin” 參數選項,或者在 my.cnf 配置文件中的 mysqld 參數組([mysqld]標識後的參數部分)增加 “log-bin” 參數項。
MySQL 複製的基本過程如下:
1.Slave 上面的IO線程連接上 Master,並請求從指定日誌文件的指定位置(或者從最開始的日誌)之後的日誌內容;
2. Master 接收到來自 Slave 的 IO 線程的請求後,通過負責複製的 IO 線程根據請求信息讀取指定日誌指定位置之後的日誌信息,返回給 Slave 端的 IO 線程。返回信息中除了日誌所包含的信息之外,還包括本次返回的信息在 Master 端的 Binary Log 文件的名稱以及在 Binary Log 中的位置;
3. Slave 的 IO 線程接收到信息後,將接收到的日誌內容依次寫入到 Slave 端的Relay Log文件(mysql-relay-bin.xxxxxx)的最末端,並將讀取到的Master端的bin-log的文件名和位置記錄到master- info文件中,以便在下一次讀取的時候能夠清楚的高速Master“我需要從某個bin-log的哪個位置開始往後的日誌內容,請發給我”
4. Slave 的 SQL 線程檢測到 Relay Log 中新增加了內容後,會馬上解析該 Log 文件中的內容成爲在 Master 端真實執行時候的那些可執行的 Query 語句,並在自身執行這些 Query。這樣,實際上就是在 Master 端和 Slave 端執行了同樣的 Query,所以兩端的數據是完全一樣的。
四、系統準備
使用兩臺服務器做測試
Master server | 192.168.200.180
| Centos 6.8 | Mysql5.5.53 |
Slave server | 192.168.200.140
| Centos 6.8 | Mysql5.5.53 |
注意:做主從服務器的原則是,MYSQL版本要相同,如果不能滿足,最起碼從服務器的MYSQL的版本必須高於主服務器的MYSQL版本
五、配置Master server
Notes:安裝mysql 的部分此處省略,如要了解請參考blog 中安裝mysql內容
5.1 開啓binlog 並設置server-id
[root@master mysql]# vi /etc/my.cnf ####在my.cnf 文件中開啓log-bin,設定server-id [root@master mysql]# egrep "log-bin|server" /etc/my.cnf # The MySQL server server-id= 1 log-bin=/application/mysql/data/mysql-bin
注意server-id 和binlog 日誌的參數均在[mysqld] 區域內進行設置。
5.2 設置slave server 訪問master server mysql 的帳號
創建rep 帳號,並授權帳號爲replication slave,密碼爲think
[root@master mysql]# ./bin/mysql -e "grant replication slave on *.* to 'rep'@'192.168.200.%’identified by 'think';" [root@master mysql]# ./bin/mysql -e "flush privileges;"
檢查是添加帳號是否成功
[root@master mysql]# ./bin/mysql -e "select user,host from mysql.user;" +------+---------------+ | user | host | +------+---------------+ | root | 127.0.0.1 | | rep | 192.168.200.% | | root | localhost | +------+---------------+
5.3 檢查master 設置狀態
5.3.1重啓mysql 服務
[root@mastermysql]# /etc/init.d/mysqld restart Shutting down MySQL. SUCCESS! Starting MySQL.. SUCCESS!
5.3.2檢查master binlog 日誌是否開啓
[root@mastermysql]# /application/mysql/bin/mysql -e "show variables like 'log_bin';" +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | ON | +---------------+-------+
5.4 備份master sql 數據庫
5.4.1鎖定master server 上的mysql 數據庫
[root@mastermysql]# ./bin/mysql -e "flush table with read lock;"
注意:5.1版本的mysql鎖表的語句爲 flush tables with read lock; 鎖表的時間由wait_timeout 和varactive_timeout 決定
5.4.2 檢查master server mysql 的狀態;
[root@mastermysql]# ./bin/mysql -e "show master status;" +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 328 | | | +------------------+----------+--------------+------------------+ [root@mastermysql]# ./bin/mysql -e "show master logs;" +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 328 | +------------------+-----------+
注意,需要記錄master postition 與file 的值,爲後面配置slave做準備
5.4.3備份master 數據庫數據
[root@master~]# /application/mysql/bin/mysqldump -uroot -p -A -B --events --master-data=2 >/application/mysql/data/rep.sql
命令行參數的含義 -A:轉儲所有數據庫中的所有表。與使用---database選項相同,在命令行中命名所有數據庫。 -B:轉儲幾個數據庫。通常情況,mysqldump將命令行中的第1個名字參量看作數據庫名,後面的名看作表名。使用該選項,它將所有名字參量看作數據庫名 --events:導出事件 --master-data:選項將二進制日誌的位置和文件名寫入到輸出中。該選項要求有RELOAD權限,並且必須啓用二進制日誌。如果該選項值等於1,位置和文件名被寫入CHANGE MASTER語句形式的轉儲輸出,如果你使用該SQL轉儲主服務器以設置從服務器,從服務器從主服務器二進制日誌的正確位置開始。如果選項值等於2,CHANGE MASTER語句被寫成SQL註釋。如果value被省略,這是默認動作。
5.4.4 主庫解鎖
mysql>unlocak tables;
六、配置Slave server
設置my.cnf
#skip-networking
server-id = 2;####不要與master 的server-id 一致
設置slave 連master的參數
[root@slave mysql]# ./bin/mysql -e "change master to \ master_host='192.168.200.180', \ master_port='3306', \ master_user='rep', \ masster_password='think', \ master_log_file='mysql-bin.000001', \ master_log_pos=328;"
檢查是否設置成功
[root@slave mysql]# cat ./data/master.info 18 mysql-bin.000001 328 192.168.200.180 rep think 3306 60 0 0 1800.000 0
導入master 備份出來的數據到slave
拷貝備份文件到slave server
[root@master data]# scp rep.sql [email protected]:/application/mysql/data The authenticity of host '192.168.200.140 (192.168.200.140)' can't be established. RSA key fingerprint is d9:dd:4a:7d:df:1c:36:b9:e2:4f:ac:2d:8b:e0:f7:9d. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.200.140' (RSA) to the list of known hosts. TTEMPT! [email protected]'s password: rep.sql 100% 541KB 541.4KB/s 00:00
導入master 備份文件到slave server
mysql> source ./data/rep.sql
重啓mysql 服務
開啓slave server 上的mysql slave 服務
Mysql>start slave;
檢查slave server 複製功能的狀態
mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.200.180 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000002 Read_Master_Log_Pos: 107 Relay_Log_File: bogon-relay-bin.000005 Relay_Log_Pos: 253 Relay_Master_Log_File: mysql-bin.000002 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: 107 Relay_Log_Space: 555 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: 1 1 row in set (0.00 sec)
注:Slave_IO_Runing 及Slave_SQL_Running 進程必須正常運行,即YES狀態,否則都是錯誤的狀態(如:其中一個NO均屬錯誤)。 以上操作過程,主從服務器配置完成。
七:主從服務器測試
主服務器Mysql,建立數據庫,並在這個庫中建表插入一條數據:
mysql> create database master01; Query OK, 1 row affected (0.00 sec) mysql> use master01 Database changed mysql> create table master(id int(3),name char(10)); Query OK, 0 rows affected (0.02 sec) mysql> insert into master values(001,'think'); Query OK, 1 row affected (0.02 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | master01 | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.31 sec)
從服務器Mysql查詢:
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | master01 | | mysql | | performance_schema | | test | | wordpress | +--------------------+ 6 rows in set (0.02 sec) mysql> use master01; Database changed mysql> select * from master; +------+-------+ | id | name | +------+-------+ | 1 | think | +------+-------+ 1 row in set (0.30 sec)
主從複製原理部署總結(重點):
1、主庫(Master)
A、開啓log_bin,設置server-id
B、爲slave 庫創建一個replication slave 的帳號
C、完整備份需要同步的數據庫,並同步給從庫(slave ),
D、鎖表查看master status並記錄相應的情況
2、從庫需要配置
A、設置server-id
B、設置change master 參數
CHANGE MASTER TO.
Master_host= master 主機地址
Master_port= master 主機mysql 端口
master_user= 登錄master 主機user
Master_password= 登錄master 主機的密碼
Master_file= log_bin 日誌的路徑
Master_pos= log_bin 日誌的開始位置;確保主從數據庫的位置點之前的數據是一致的
C、導入備份的master 數據庫
D、start slave;這個執行過程其實就是從庫打開開關的過程,其實就是讓IO和sql 兩個線程開始工作的過程
server
5.5 以上的mysql 在備份數據庫時可以使用如下命令,可以不需要進行鎖表操作,slave 服務器上也不需要在change master 中指定master_file 和Master_pos。有興趣的可以自行測試。
/application/mysql/bin/mysqldump -uroot -p -A -B -x --events --master-data=1 >/application/mysql/data/rep.sql
如果要做slave 級聯,則slave my.cnf 配置文件中需要開啓log-bin 與log-slave-update。
下篇文章會進行說明主主備份,一主多從的操作過程。