MariaDB/MySQL內建的複製功能是構建大型,高性能應用程序的基礎。將MySQL的數據分佈到多個系統上去,這種分佈的機制,是經過將MySQL的某一臺主機的數據複製到其它主機(slaves)上,並從新執行一遍來實現的。複製過程當中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。主服務器將更新寫入二進制日誌文件,並維護文件的一個索引以跟蹤日誌循環。這些日誌能夠記錄發送到從服務器的更新。當一個從服務器鏈接主服務器時,它通知主服務器從服務器在日誌中讀取的最後一次成功更新的位置。從服務器接收從那時起發生的任何更新,而後封鎖並等待主服務器通知新的更新。
請注意當你進行復制時,全部對複製中的表的更新必須在主服務器上進行。不然,你必需要當心,以免用戶對主服務器上的表進行的更新與對從服務器上的表所進行的更新之間的衝突。mysql
1.mysql支持的複製類型:linux
(1):基於語句的複製:在主服務器上執行的SQL語句,在從服務器上執行一樣的語句。MySQL默認採用基於語句的複製,效率比較高。
一旦發現無法精確複製時,會自動選着基於行的複製。
(2):基於行的複製:把改變的內容複製過去,而不是把命令在從服務器上執行一遍. 從mysql5.0開始支持
(3):混合類型的複製: 默認採用基於語句的複製,一旦發現基於語句的沒法精確的複製時,就會採用基於行的複製。sql
2.複製解決的問題shell
MySQL複製技術有如下一些特色:
(1).數據分佈 (Data distribution )
(2).負載平衡(load balancing)
(3).備份(Backups)
(4).高可用性和容錯行 High availability and failover數據庫
3.複製如何工做vim
總體上來講,複製有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的緩存中,因此中繼日誌的開銷很小。tcp
此外,在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!
(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 | | | +------------------+----------+--------------+------------------+
(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 | | | +------------------+----------+--------------+------------------+
(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 ...
同步成功,讀寫分離實驗待續。。。