MariaDB主從同步
MariaDB/MySQL內建的復制功能是構建大型,高性能應用程序的基礎。將MySQL的數據分布到多個系統上去,這種分布的機制,是通過將MySQL的某一台主機的數據復制到其它主機(slaves)上,並重新執行一遍來實現的。復制過程中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。主服務器將更新寫入二進制日志文件,並維護文件的一個索引以跟蹤日志循環。這些日志可以記錄發送到從服務器的更新。當一個從服務器連接主服務器時,它通知主服務器從服務器在日志中讀取的最后一次成功更新的位置。從服務器接收從那時起發生的任何更新,然后封鎖並等待主服務器通知新的更新。
請注意當你進行復制時,所有對復制中的表的更新必須在主服務器上進行。否則,你必須要小心,以避免用戶對主服務器上的表進行的更新與對從服務器上的表所進行的更新之間的沖突。
1.mysql支持的復制類型:
(1):基於語句的復制:在主服務器上執行的SQL語句,在從服務器上執行同樣的語句。MySQL默認采用基於語句的復制,效率比較高。
一旦發現沒法精確復制時,會自動選着基於行的復制。
(2):基於行的復制:把改變的內容復制過去,而不是把命令在從服務器上執行一遍. 從mysql5.0開始支持
(3):混合類型的復制: 默認采用基於語句的復制,一旦發現基於語句的無法精確的復制時,就會采用基於行的復制。
2.復制解決的問題
MySQL復制技術有以下一些特點:
(1).數據分布 (Data distribution )
(2).負載平衡(load balancing)
(3).備份(Backups)
(4).高可用性和容錯行 High availability and failover
3.復制如何工作
整體上來說,復制有3個步驟:
(1).master將改變記錄到二進制日志(binary log)中(這些記錄叫做二進制日志事件,binary log events);
(2).slave將master的binary log events拷貝到它的中繼日志(relay log);
(3).slave重做中繼日志中的事件,將改變反映它自己的數據。
該過程的第一部分就是master記錄二進制日志。在每個事務更新數據完成之前,master在二日志記錄這些改變。MySQL將事務串行的寫入二進制日志,即使事務中的語句都是交叉執行的。在事件寫入二進制日志完成后,master通知存儲引擎提交事務。
下一步就是slave將master的binary log拷貝到它自己的中繼日志。首先,slave開始一個工作線程――I/O線程。I/O線程在master上打開一個普通的連接,然后開始binlog dump process。Binlog dump process從master的二進制日志中讀取事件,如果已經跟上master,它會睡眠並等待master產生新的事件。I/O線程將這些事件寫入中繼日志。
SQL slave thread(SQL從線程)處理該過程的最后一步。SQL線程從中繼日志讀取事件,並重放其中的事件而更新slave的數據,使其與master中的數據一致。只要該線程與I/O線程保持一致,中繼日志通常會位於OS的緩存中,所以中繼日志的開銷很小。
此外,在master中也有一個工作線程:和其它MySQL的連接一樣,slave在master中打開一個連接也會使得master開始一個線程。復制過程有一個很重要的限制――復制在slave上是串行化的,也就是說master上的並行更新操作不能在slave上並行操作。
二.復制配置過程簡介
有兩台MySQL數據庫服務器MASTER和SLAVE,MASTER為主服務器,SLAVE為從服務器,初始狀態時,MASTER和MASTER中的數據信息相同,當MASTER中的數據發生變化時,SLAVE也跟着發生相應的變化,使得MASTER和SLAVE的數據信息同步,達到備份的目的。
要點:
負責在主、從服務器傳輸各種修改動作的媒介是主服務器的二進制變更日志,這個日志記載着需要傳輸給從服務器的各種修改動作。因此,主服務器必須激活二進制日志功能。從服務器必須具備足以讓它連接主服務器並請求主服務器把二進制變更日志傳輸給它的權限。
配置主從復制的過程:
1).主節點操作步驟
(1)、啟用二進制日志
(2)、設置一個在當前集群中唯一的server-id;
(3)、創建一個有復制權限(replication slave,replication client)帳號;
2).slave節點的操作步驟
(1)、啟用中繼日志;
(2)、設置一個在當前集群中唯一的server-id;
(3)、使用有復制權限的用戶帳號連接至主服務器,並啟動復制線程;
注意:
(1)、服務器版本:主從服務器版本一致;
如果版本不一致,必須保證從服務器的版本高於主服務器的版本;
(2)、如果mysql數據庫的隔離級別為可讀,其二進制日志格式盡量使用基於行的;
實驗環境:
服務器版本為:CentOS 7.2
實驗拓撲圖
關閉SELinux
setenforce = 0
vim /etc/systemctl/selinux
SELINUX=permissive
開啟防火牆服務
systemctl mask iptables
firewall-cmd --permanent --add-service=mysql
firewall-cmd --reload
數據庫軟件版本為:
mariadb-5.5.46-linux-x86_64.tar.gz
MASTER的IP地址:192.168.1.10/24
SLAVE1的IP地址:192.168.1.20/24
SLAVE2的IP地址:192.168.1.30/24
若master數據庫已運行一段時間,可導出master數據庫內容,使用scp命令拷貝至從服務器並導入
具體命令如下:
mysqldump -uroot -p --quick --all-databases --flush-logs --delete-master-logs --single-transaction > sync.sql #導出數據庫
scp sync.sql root@slave1:/mydata #拷貝至從服務器
mysql -uroot -p <sync.sql #導入至從服務器
安裝Mariadb通用二進制包
下載二進制包:
]# wget http://mirrors.neusoft.edu.cn/mariadb//mariadb-5.5.56/bintar-linux-x86_64/mariadb-5.5.56-linux-x86_64.tar.gz
]# tar xf mariadb-5.5.56-linux-x86_64.tar.gz -C /usr/local
配置系統環境(主從服務器都適用)
(1).新建數據庫目錄,並設置屬主屬組
]# mkdir /mydata/{data,binlogs} -pv
mkdir: created directory ‘/mydata’
mkdir: created directory ‘/mydata/data’
mkdir: created directory ‘/mydata/binlogs’
]# chown mysql.mysql /mydata -R
(2).新建用戶並配置安裝包屬主為mysql
]# useradd -r -s /sbin/nologin mysql
]# id mysql
uid=992(mysql) gid=990(mysql) groups=990(mysql)
]# cd /usr/local
]# chown mysql.root mariadb-5.5.56-linux-x86_64/ -R
(3).鏈接安裝包目錄為mysql(便於管理)
]# ln -sv mariadb-5.5.56-linux-x86_64/ mysql
‘mysql’ -> ‘mariadb-5.5.56-linux-x86_64/’
]# ll mysql/
total 176
drwxr-xr-x. 2 mysql root 4096 May 22 19:47 bin
-rw-r--r--. 1 mysql root 17987 Apr 30 19:09 COPYING
drwxr-xr-x. 3 mysql root 17 May 22 19:47 data
-rw-r--r--. 1 mysql root 8245 Apr 30 19:09 EXCEPTIONS-CLIENT
drwxr-xr-x. 3 mysql root 18 May 22 19:47 include
-rw-r--r--. 1 mysql root 8694 Apr 30 19:09 INSTALL-BINARY
drwxr-xr-x. 3 mysql root 4096 May 22 19:47 lib
drwxr-xr-x. 4 mysql root 28 May 22 19:47 man
drwxr-xr-x. 11 mysql root 4096 May 22 19:47 mysql-test
-rw-r--r--. 1 mysql root 108813 Apr 30 19:09 README
drwxr-xr-x. 2 mysql root 29 May 22 19:47 scripts
drwxr-xr-x. 27 mysql root 4096 May 22 19:47 share
drwxr-xr-x. 4 mysql root 4096 May 22 19:47 sql-bench
drwxr-xr-x. 3 mysql root 4096 May 22 19:47 support-files
(4).拷貝並編輯my.cnf文件
]# cp support-files/my-large.cnf /etc/my.cnf
cp: overwrite ‘/etc/my.cnf’? y
master
]# vim /etc/my.cnf
log-bin=/mydata/binlogs/mysql-bin
datadir=/mydata/data
skip_name_resolve=on
innodb_file_per_table=on
(5).初始化數據庫並查看生成的文件
]# scripts/mysql_install_db --user=mysql --datadir=/myata/data
]# ls /mydata/{data,binlogs}
/mydata/binlogs:
mysql-bin.000001 mysql-bin.000002 mysql-bin.index
/mydata/data:
aria_log.00000001 aria_log_control mysql performance_schema test
(6).鏈接mysql運行所需的頭文件與庫文件
]# ln -sv /usr/local/mysql/include/ /usr/include/mysql
‘/usr/include/mysql’ -> ‘/usr/local/mysql/include/’
指定動態鏈接庫文件搜尋目錄
[root@master mysql]# vim /etc/ld.so.conf.d/mysql
/usr/local/mysql/lib
]# ldconfig
]# ldconfig -p | grep mysql 查看動態鏈接庫文件
libmysqld.so.18 (libc6,x86-64) => /usr/local/mysql/lib/libmysqld.so.18
libmysqld.so (libc6,x86-64) => /usr/local/mysql/lib/libmysqld.so
libmysqlclient.so.18 (libc6,x86-64) => /usr/lib64/mysql/libmysqlclient.so.18
libmysqlclient.so.18 (libc6,x86-64) => /usr/local/mysql/lib/libmysqlclient.so.18
libmysqlclient.so (libc6,x86-64) => /usr/local/mysql/lib/libmysqlclient.so
(7).編輯mariadb啟動單元,以systemctl控制
]# vim /etc/systemd/system/mariadb.service
[Unit]
Description=MariaDB database server
After=syslog.target
After=network.target
[Service]
Type=simple
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld_safe --basedir=/usr/local/mysql
TimeoutSec=300
PrivateTmp=false
[Install]
WantedBy=multi-user.target
]# chmod +x /etc/systemd/system/mariadb.service
]# systemctl daemon-reload #更新守護進程
(8).啟動mariadb,並查看端口狀態
]# systemctl start mariadb.service #如為未啟動成功,再次啟動一次即可(原因未知)
]# ss -nl | grep 3306
tcp LISTEN 0 50 *:3306 *:*
(9).配置系統環境變量
]# vim /etc/profile.d/mysql.sh #profile.d目錄下的文件開機會自動執行一次
export PATH=/usr/local/mysql/bin:$PATH
]# source /etc/profile.d/mysql.sh #讀取shell腳本
]# echo $PATH
/usr/local/mysql/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
(10).安全初始化數據庫
]# mysql_secure_installation
Enter current password for root (enter for none):
OK, successfully used password, moving on...
Set root password? [Y/n] y #是否設置root密碼
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
... Success!
Remove anonymous users? [Y/n] y #是否刪除匿名用戶
... Success!
Disallow root login remotely? [Y/n] y #是否允許root用戶遠程登錄
... Success!
Remove test database and access to it? [Y/n] y #是否刪除測試數據庫
- Dropping test database...
... Success!
- Removing privileges on test database...
... Success!
Reload privilege tables now? [Y/n] y #是否立即更新權限
... Success!
配置master服務器
(1).編輯master的my.cnf配置文件並重啟服務
[root@master mysql]# vim /etc/my.cnf
log-bin=/mydata/binlogs/mysql-bin #二進制日志文件路徑
datadir=/mydata/data #數據庫文件路徑
binlog_format=mixed #二進制日志文件保存格式為混合模式(語句,行)
server-id = 1 #服務器id號
[root@master mysql]# systemctl restart mariadb.service #重啟服務
(2).登錄mysql,並創建有復制權限的用戶
[root@master mysql]# mysql -uroot -p
MariaDB [(none)]> GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO 'backup1'@'slave1' IDENTIFIED BY 'backpass'; #創建有復制權限,並制定登錄主機的用戶
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW MASTER STATUS; #查看master的日志和pos點
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 1832 | | |
+------------------+----------+--------------+------------------+
配置slave1服務器
(1).編輯slave1的my.cnf配置文件並重啟服務
[root@slave1 mysql]# vim /etc/my.cnf
log-bin=/mydata/binlogs/mysql-bin
datadir=/mydata/data
relay-log=/mydata/binlogs/relay-bin #中繼日志文件路徑
relay-log_index=/mydata/binlogs/relay-bin.index #中繼日志文件索引路徑名稱
log_slave_updates=on #將復制事件寫進自己的二進制日志
skip_name_resolve=on #跳過名稱解析
innodb_file_per_table=on #開啟innodb引擎獨立表空間
read_only=on #開啟只讀防止改變數據
binlog_format=mixed #二進制日志文件保存格式為混合模式(語句,行)
server-id = 2 #id號不得與其他服務器相同
[root@slave1 mysql]# systemctl restart mariadb.service #重啟服務
(2)登錄slave1的數據庫
[root@slave1 mysql]# mysql -uroot -p
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='master',\ #主服務器主機名稱
-> MASTER_USER='backup1',\ #用於復制的用戶
-> MASTER_PASSWORD='backpass',\ #復制用戶的密碼
-> MASTER_PORT=3306,\ #連接使用的端口
-> MASTER_LOG_FILE='mysql-bin.000003',\ #起點日志文件
-> MASTER_LOG_POS=1832,\ #起點位置
-> MASTER_CONNECT_RETRY=10,\ #連接重試間隔
-> MASTER_HEARTBEAT_PERIOD=2; #心跳間隔時間
Query OK, 0 rows affected (0.00 sec)
(3).啟動同步並查看從服務器同步狀態
MariaDB [(none)]> START SLAVE; #啟動同步進程
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW SLAVE STATUS\G #查看從服務器線程的關鍵參數的信息
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: master
Master_User: backup1 #被用於連接主服務器的當前用戶
Master_Port: 3306
Connect_Retry: 10 #連接重試間隔
Master_Log_File: mysql-bin.000003 #I/O線程當前正在讀取的主服務器二進制日志文件的名稱
Read_Master_Log_Pos: 1832 #在當前的主服務器二進制日志中,I/O線程已經讀取的位置
Relay_Log_File: relay-bin.000003 #SQL線程當前正在讀取和執行的中繼日志文件的名稱
Relay_Log_Pos: 529 #在當前的中繼日志中,SQL線程已讀取和執行的位置
Relay_Master_Log_File: mysql-bin.000003 #由SQL線程執行的包含多數近期事件的主服務器二進制日志文件的名稱
Slave_IO_Running: Yes #I/O線程是否被啟動並成功地連接到主服務器上
Slave_SQL_Running: Yes #SQL線程是否被啟動
...
Master_Server_Id: 2
(4).建立有復制權限的用戶,讓slave2可以復制本地binlog
MariaDB [(none)]> GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO 'backup2'@'slave2' IDENTIFIED BY 'backpass';
Query OK, 0 rows affected, 1 warning (0.00 sec)
MariaDB [(none)]> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 1655 | | |
+------------------+----------+--------------+------------------+
配置slave2服務器
(1).編輯slave2的my.cnf配置文件並重啟服務
[root@slave2 mysql]# vim /etc/my.cnf
datadir=/mydata/data
relay-log=/mydata/binlogs/relay-bin #中繼日志文件路徑
relay-log_index=/mydata/binlogs/relay-bin.index #中繼日志文件索引路徑名稱
log_slave_updates=on #將復制事件寫進自己的二進制日志
skip_name_resolve=on #跳過名稱解析
innodb_file_per_table=on #開啟innodb引擎獨立表空間
read_only=on #開啟只讀防止改變數據
binlog_format=mixed #二進制日志文件保存格式為混合模式(語句,行)
server-id = 3 #id號不得與其他服務器相同
[root@slave2 mysql]# systemctl restart mariadb.service #重啟服務
(2).登錄slave2數據庫
[root@slave1 mysql]# mysql -uroot -p
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='slave1',\ #服務器主機名稱
-> MASTER_USER='backup2',\ #用於復制的用戶
-> MASTER_PASSWORD='backpass',\ #復制用戶的密碼
-> MASTER_PORT=3306,\ #連接使用的端口
-> MASTER_LOG_FILE='mysql-bin.000003',\ #起點日志文件
-> MASTER_LOG_POS=1655,\ #起點位置
-> MASTER_CONNECT_RETRY=10,\ #連接重試間隔
-> MASTER_HEARTBEAT_PERIOD=2; #心跳間隔時間
Query OK, 0 rows affected (0.00 sec)
(3)啟動同步並查看從服務器同步狀態
MariaDB [(none)]> START SLAVE; #啟動同步進程
Query OK, 0 rows affected, 1 warning (0.00 sec)
MariaDB [(none)]> SHOW SLAVE STATUS\G #查看從服務器線程的關鍵參數的信息
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: slave1
Master_User: backup2
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 3038
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 1912
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: Yes #I/O線程是否被啟動並成功地連接到主服務器上
Slave_SQL_Running: Yes #SQL線程是否被啟動
...
Master_Server_Id: 2
主從同步測試
(1).在主服務器導入數據庫(讓數據庫發生改變即可)
[root@master mysql]# mysql -uroot -p < hellodb.sql #導入數據庫文件
[root@master mysql]# mysql -uroot -p
MariaDB [(none)]> SHOW DATABASES; #查看數據庫
+--------------------+
| Database |
+--------------------+
| information_schema |
| hellodb |
| mysql |
| performance_schema |
+--------------------+
4 rows in set (0.00 sec)
MariaDB [(none)]> USE hellodb #進入數據庫
Database changed
MariaDB [hellodb]> SHOW TABLES; #查看表
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes |
| coc |
| courses |
| scores |
| students |
| teachers |
| toc |
+-------------------+
7 rows in set (0.00 sec)
(2).登錄slave2從服務器查看同步是否成功
[root@slave2 mysql]# mysql -uroot -p
MariaDB [(none)]> SHOW DATABASES; #查看數據庫同步是否更新
+--------------------+
| Database |
+--------------------+
| information_schema |
| hellodb |
| mysql |
| performance_schema |
+--------------------+
4 rows in set (0.00 sec)
MariaDB [(none)]> USE hellodb; #進入數據庫
Database changed
MariaDB [hellodb]> SHOW TABLES; #查看表
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes |
| coc |
| courses |
| scores |
| students |
| teachers |
| toc |
+-------------------+
7 rows in set (0.00 sec)
(3).查看slave2的主服務器的pos點,與本地的中繼pos點
MariaDB [(none)]> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: slave1
Master_User: backup2
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 10718 #在當前的主服務器二進制日志中,I/O線程已經讀取的位置已改變
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 9592 #在當前的中繼日志中,SQL線程已讀取和執行的位置已改變
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
同步成功,讀寫分離實驗待續。。。


