MySQL複製是從服務器複製到一個或多個從服務器的異步過程,整個複製過程主要由三個線程來完成,其中一個I/O線程在主服務器端,另外兩個線程(SQL線程和IO線程)在從服務端。要實現MySQL複製,首先要在主服務器上打開MySQL的Binary Log功能mysql
1、首先從服務器上的I/O線程鏈接上主服務器,而後請求從指定的日誌文件的日誌內容
2、主服務器在接收到來自從服務器的I/O線程請求後,經過自身的I/O線程,根據請求信息讀取指定的日誌信息,並返回給從服務器的I/O線程。
3、從服務器的I/O線程接收到信息後,將獲取到的日誌內容依次寫入從服務器端的中繼日誌文件(相似於mysql-relay-bin.xxxxx)的最後,而且將讀取到主服務器端的二進制日誌的文件名和位置記錄到一個名爲master-info文件中,以便下次讀取的時候能夠迅速定位從哪一個位置開始日後讀取日誌信息
4、從服務器的SQL線程在檢測到中繼日誌文件中新增長了內容後,會立刻解析該中繼日誌文件中的內容,將日誌內容解析爲SQL語句,而後再執行這些SQL,因爲服務器端和主服務器端執行了一樣的SQL操做,因此兩端的數據是徹底同樣的,至此整個複製過程結束sql
一主一從: 一個主服務器和一個從服務器,這是最多見的架構
一主多從: 一個主服務器個兩個或兩個以上的從服務器,常常用在寫操做不頻繁、查詢量比較大的業務環境中
雙主互備: 兩個MySQL服務器互相將對方做爲本身的主服務器,本身又同時做爲對方的從服務器來進行復制
雙主多從: 就是雙主互備,而後再加上多個從服務器數據庫
1、同一時刻只能有一個主服務器進行寫操做
2、一個主服務器能夠有多個從服務器
3、不管是主服務器仍是從服務器,都要確保各自服務器ID惟一
4、一個從服務器能夠將從服務器得到的更新信息傳遞給其餘的從服務器,依次類推vim
基於語句的複製
MySQL默認採用基於語句的複製,效率很高。基本方式是:在主服務器上執行的SQL語句,在從服務器上再次執行一樣的語句。而一旦發現無法精確複製時,會自動選擇基於行的複製bash
基於行的複製
基本方式:把主服務器上改變的內容複製過去,而不是把SQL語句在從服務器上執行一遍,從MySQL5.0開始支持基於行的複製服務器
混合類型的複製
其實就是上面兩種類型的組合,默認採用基於語句的複製,若是發現基於語句的複製沒法精確完成,就會採用基於行的複製網絡
ip地址 | hostname | 系統版本 | 數據庫版本 | 角色 |
192.168.88.1 | c1.heboan.com | CentOS7.2.1511 | 5.5.56-MariaDB | master |
192.168.88.2 | c2.heboan.com | CentOS7.2.1511 | 5.5.56-MariaDB | salve |
安裝架構
yum -y install mariadb-server mariadb systemctl start mariadb mysqladmin -uroot -p password '123456' #設置root密碼 #安裝完成後的目錄結構 /var/lib/mysql/ 數據文件存放路徑,可自定義 /etc/my.cnf 配置文件 /usr/lib64/mysql 庫文件路徑 /usr/bin/mysql* 二進制可執行文件路徑 /var/log/mariadb/ /var/log/mariadb/mariadb.log 日誌文件地址
主服務器環境配置(192.168.88.1)異步
在生產環境中,可能在咱們尚未部署數據複製前,數據庫中就已經存在大量的數據。因此這裏事先建立一個測試用數據庫及數據表,用來演示如何對已經存在的數據進行數據同步。ide
create database hr; use hr; create table employees( employee_id int not null auto_increment, name char(20) not null, e_mail varchar(50), primary key(employee_id)); insert into employees values (1,'TOM','tom@example.com'), (2,'Jerry','jerry@example.com');
在主服務器上開啓二進制日誌並設置服務器ID,編輯/etc/my.cnf,在[mysqld]段添加相應的配置選項
vim /etc/my.cnf [mysqld] ... log_bin = mysql-bin server-id = 1 #則全部的服務器ID編號都必須是惟一的。能夠考慮將服務器ID編號與服務器IP地址關聯 ... systemctl restart mariadb
檢查配置是否生效
MariaDB [(none)]> show variables like 'log_bin'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | ON | +---------------+-------+
從服務器環境配置(192.168.88.2)
設置服務器ID
vim /etc/my.cnf [mysqld] ... server-id=2 ... systemctl restart mariadb
對複製而言,MySQL從服務器上二進制日誌功能是不須要開啓的。可是,你也能夠經過啓用從服務器的二進制日誌功能,實現數據備份與恢復。此外,在一些更復雜的拓撲環境中,MySQL從服務器也能夠扮演其餘從服務器的主服務器
在主服務器上建立複製帳號
執行數據複製時,全部從服務器都須要使用帳戶與密碼鏈接MySQL主服務器,因此在主服務器上必須存在至少一個用戶帳戶及相應的密碼供從服務器鏈接。這個帳戶必須擁有REPLICATION SLAVE權限,你能夠爲不一樣的從服務器建立不一樣的帳戶與密碼,也可使用統一的帳戶和密碼。MySQL可使用CREATE USER語句建立用戶,使用GRANT語句爲帳戶賦權。若是該用戶僅爲數據庫複製所用,則該帳戶僅須要REPLICATION SLAVE權限便可
MariaDB [(none)]> create user 'slave_cp'@'192.168.88.%' identified by '123123'; MariaDB [(none)]> grant replication slave on *.* to 'slave_cp'@'192.168.88.%'; MariaDB [(none)]> flush privileges;
獲取主服務器二進制日誌信息
在進行主從數據複製以前,咱們來了解一些主服務器的二進制日誌文件的基本信息,這些信息在對從服務器的設置中須要用到,它包括主服務器二進制文件名稱及當前日誌記錄位置,這樣從服務器就能夠知道從哪裏開始進行復制操做。咱們可使用以下操做查看主服務器二進制日誌數據信息。
MariaDB [(none)]> flush tables with read lock; #對全部數據庫的表執行只讀鎖定,防止在查看二進制日誌信息的同時有人對數據進行修改操做 MariaDB [(none)]> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 573 | | | +------------------+----------+--------------+------------------+ #其中,File列顯示的是二進制日誌文件名,Position爲當前日誌記錄位置 MariaDB [(none)]> unlock tables; #對全局鎖執行結束操做
對現有數據進行備份
若是在使用二進制日誌進行數據複製之前,MySQL數據庫系統中已經存在大量的數據資源,對這些資料進行數據備份的一種方法是使用mysqldump工具,在主服務器上使用該工具對數據備份後,便可對從服務器上進行數據還原。當但願的數據達到一致後,就可使用數據複製功能進行自動同步操做。
[root@c1 ~]# mysqldump -uroot -p --all-databases --lock-all-tables >/tmp/dbdumps.sql [root@c1 ~]# scp /tmp/dbdumps.sql 192.168.88.2:/tmp [root@c2 ~]# mysql -uroot -p </tmp/dbdumps.sql #從服務器導入備份數據
配置從服務器鏈接主服務器進行數據複製
數據複製的關鍵操做是配置從服務器去鏈接主服務器進行數據複製,咱們須要告知從服務器創建網絡鏈接全部必要的信息。使用CHANGE MASTER TO 語句完成該項工做
#這些信息保存在數據目錄/var/lib/mysql/master.info中 MariaDB [(none)]> change master to -> master_host='192.168.88.1', -> master_port=3306, -> master_user='slave_cp', -> master_password='123123', -> master_log_file='mysql-bin.000001', -> master_log_pos=573; MariaDB [(none)]> start slave;
查看主從狀態
MariaDB [(none)]> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.88.1 Master_User: slave_cp Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 851 Relay_Log_File: mariadb-relay-bin.000002 Relay_Log_Pos: 807 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes --------------->顯示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: 851 Relay_Log_Space: 1103 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
最後,咱們能夠再主服務器上進行寫操做來驗證,是否主從同步