使用MySQL主從複製技術實現數據庫熱備
1 MySQL Replication
2 部署MySQL主從同步
3 部署MySQL主主雙向主從複製node
MySQL Replication
什麼是MySQL Replication
Replication能夠實現將數據從一臺數據庫服務器(master)複製到一臺或多臺數據庫服務器(slave)
默認狀況下屬於異步複製,無需維持長鏈接
經過配置,能夠複製全部的庫或者幾個庫,甚至庫中的一些表
是MySQL內建的,自己自帶的
Replication的原理
簡單的說就是master將數據庫的改變寫入二進制日誌,slave同步這些二進制日誌,並根據這些二進制日誌進行數據操做
DML:SQL操做語句,update, ×××ert,delete
Relay log :中繼日誌
Replication的做用
Fail Over 故障切換
Backup Server 備份服務,沒法對SQL語句執行產生的故障恢復,有限的備份
High Performance 高性能,能夠多臺slave,實現讀寫分離
Replication工做原理
總體上來講,複製有3個步驟:
master將改變記錄到二進制日誌(binary log)中(這些記錄叫作二進制日誌事件,binary log events)
slave將master的binary log events拷貝到它的中繼日誌(relay log)
slave重作中繼日誌中的事件,修改salve上的數據。
mysql
MySQL主從複製中:
第一步: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中的數據一致。sql
Replication常見方案
One master and Muti salve 一主多備
數據庫
通常用來作讀寫分離的,master寫,其餘slave讀,這種架構最大問題I/O壓力集中
在Master上<多臺同步影響IO>vim
2.M-S-S安全
使用一臺slave做爲中繼,分擔Master的壓力,slave中繼須要開啓bin-log,並配置log-slave-updates
Slave中繼可以使用Black-hole存儲引擎,不會把數據存儲到磁盤,只記錄二進制日誌服務器
M-M 雙主互備 (互爲主從)
不少人誤覺得這樣能夠作到MySQL負載均衡,實際沒什麼好處,每一個服務器須要作一樣的同步更新,破壞了事物的隔離性和數據的一致性。架構
M-M-M
監控三臺機器互相做對方的master併發
天生的缺陷:複製延遲,slave上同步要慢於master,若是大併發的狀況那延遲更嚴重
mysql在5.6已經自身能夠實現fail over故障切換
One slave Muti master 一從對多主
好處:節省成本,將多個master數據自動化整合
缺陷:對庫和表數據的修改較多負載均衡
部署MySQL主從同步 <M-S>
環境準備:
模式:C/S
端口:3306
配置主數據庫服務器node-1
安裝MySQL 5.7版本
上傳mysql-5.7.tar.gz到Linux主機上,並解壓:
注:mysql-5.7.tar.gz 中包括了安裝mysql5.7主要的軟件包。 這樣部署起來更方便
下載mysql 5.7 解壓並安裝
[root@node-1 ~]# wget https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar
[root@node-1 ~]# tar xvf mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar
mysql-community-embedded-devel-5.7.26-1.el7.x86_64.rpm
mysql-community-libs-5.7.26-1.el7.x86_64.rpm
mysql-community-embedded-5.7.26-1.el7.x86_64.rpm
mysql-community-test-5.7.26-1.el7.x86_64.rpm
mysql-community-embedded-compat-5.7.26-1.el7.x86_64.rpm
mysql-community-common-5.7.26-1.el7.x86_64.rpm
mysql-community-devel-5.7.26-1.el7.x86_64.rpm
mysql-community-client-5.7.26-1.el7.x86_64.rpm
mysql-community-server-5.7.26-1.el7.x86_64.rpm
mysql-community-libs-compat-5.7.26-1.el7.x86_64.rpm
[root@node-1 ~]# yum ×××tall ./mysql*.rpm
啓動mysql 並生成臨時密碼
[root@node-1 ~]# systemctl start mysqld
在MySQL的配置文件/etc/my.cnf 中關閉密碼強度審計插件,並重啓MySQl服務。
[root@node-1 ~]# vim /etc/my.cnf
#修改MySQL的配置文件,在[myqld]標籤處末行添加如下項
validate-password=OFF #不使用密碼強度審計插件
重啓mysqld
[root@node-1 ~]# systemctl restart mysqld
獲取臨時密碼
[root@node-1 ~]# grep 'password' /var/log/mysqld.log
2019-06-11T03:30:58.381293Z 1 [Note] A temporary password is generated for root@localhost: Ulw=h.3N1r/T
使用臨時密碼登錄mysql,注意臨時密碼須要引號
[root@node-1 ~]# mysql -u root -p"Ulw=h.3N1r/T"
修改root密碼
mysql> set password for root@localhost = password('123456');
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
mysql> exit
Bye
建立須要同步的數據庫:
[root@node-1 ~]# mysql -u root -p123456
mysql> create database HA;
Query OK, 1 row affected (0.01 sec)
mysql> use HA;
Database changed
mysql> create table T1(id int,name varchar(20));
Query OK, 0 rows affected (0.01 sec)
mysql> exit
Bye
[root@node-1 ~]# vim /etc/my.cnf
log-bin=mysql-bin-master #啓用二進制日誌
server-id=1 #本機數據庫ID 標示
binlog-do-db=HA #能夠被從服務器複製的庫, 二進制須要同步的數據庫名
binlog-ignore-db=mysql #不能夠被從服務器複製的庫
受權
[root@node-1 ~]# mysql -uroot -p123456
mysql> grant replication slave on . to slave@192.168.150.139 identified by "123456";
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
查看狀態信息
+-------------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------------+----------+--------------+------------------+-------------------+
| mysql-bin-master.000001 | 604 | HA | mysql | |
+-------------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
查看二進制文件
mysql> show binlog events\G
複製前要保證同步的數據庫一致
導出數據庫文件
[root@node-1 ~]# mysqldump -uroot -p123456 HA >HA.sql
將數據導出傳給從服務器
[root@node-1 ~]# scp HA.sql root@192.168.150.139:/root
配置從服務器node-2
下載數據庫
[root@node2 ~]# wget https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar
解壓mysql
[root@node2 ~]# tar xf mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar
[root@node2 ~]# yum ×××tall -y ./mysql*.rpm
mysql 啓動會生成臨時密碼
[root@node2 ~]# systemctl start mysqld
在MySQL的配置文件/etc/my.cnf 中關閉密碼強度審計插件,並重啓MySQl服務
[root@node2 ~]# systemctl restart mysqld
獲取臨時密碼
[root@node2 ~]# grep 'password' /var/log/mysqld.log
2019-06-13T02:38:35.490766Z 1 [Note] A temporary password is generated for root@localhost: ,%d&>aAaQ2!7
使用臨時密碼登錄 記住mysql 是單引號雙引號不識別
[root@node2 ~]# mysql -u root -p',%d&>aAaQ2!7'
修改root密碼
mysql> set password for root@localhost = password('123456');
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> exit
Bye
如今登錄node-1 服務器測試遠程可否登錄上數據庫是否一致
[root@node-1 ~]# mysql -u root -p123456
mysql> show variables like '%version%';
測試連接主服務器是否成功
若是遠程連接不上請開啓服務器端口
開放端口
[root@node-1 ~]# firewall-cmd --zone=public --add-port=80/tcp --permanent
success
[root@node-1 ~]# firewall-cmd --zone=public --add-port=1000-2000/tcp --permanent
success
重載服務
[root@node-1 ~]# firewall-cmd --reload
success
查看端口
[root@node-1 ~]# firewall-cmd --zone=public --query-port=80/tcp
yes
開放相應服務器端口
[root@node-1 ~]# firewall-cmd --zone=public --add-port=3306/tcp --permanent
success
重載服務
[root@node-1 ~]# firewall-cmd --reload
success
測試遠程數據庫連接是否是正常
出現如下服務表示服務器正常連接
[root@node2 ~]# mysql -u slave -p123456 -h 192.168.150.138
mysql: [Warning] Using a password on the command line interface can be ×××ecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.26-log MySQL Community Server (GPL)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.00 sec)
只有複製的權限, 是看不到其餘庫的。正常導入數據庫,和主數據庫服務器保持一致
mysql> exit
Bye
在node-2上建立相應數據庫
[root@node2 ~]# mysql -uroot -p123456
mysql> create database HA;
Query OK, 1 row affected (0.00 sec)
mysql> exit
Bye
導入數據庫
[root@node2 ~]# mysql -uroot -p123456 HA < HA.sql
如下提示是 不能再命令行下使用 提示不安全 其實已經導入數據庫文件進去了
mysql: [Warning] Using a password on the command line interface can be ×××ecure.
修改從服務器配置文件
從服務器不必開啓bin-log日誌
中止mysql 服務
[root@node2 ~]# systemctl stop mysqld
[root@node2 ~]# vim /etc/my.cnf
server-id = 2 #從服務器ID號,不要和主ID相同 ,若是設置多個從服務器,每一個從服務器必須有一個惟一的server-id值,必須與主服務器的以及其它從服務器的不相同。能夠認爲server-id值相似於IP地址:這些ID值能惟一識別複製服務器羣集中的每一個服務器實例。
啓動mysql 服務
[root@node2 ~]# systemctl restart mysqld
[root@node2 ~]# mysql -u root -p123456
中止slave
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
寫入主服務器
mysql> change master to master_host='192.168.150.138',master_user='slave',master_password='123456';
Query OK, 0 rows affected, 2 warnings (0.01 sec)
啓動slave
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
查看狀態
mysql> show slave status\G
Slave_IO_Running :一個負責與主機的IO通訊
Slave_SQL_Running:負責本身的slave mysql進程
兩個爲YES 就成功了!
再到主服務器查看狀態
[root@node-1 ~]# mysql -uroot -p123456
mysql> show processlist \G
mysql> use HA;
這句話的是意思是
讀取表信息以完成表和列名稱
您能夠關閉此功能以使用-A更快地啓動
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
從數據庫查看
mysql> ×××ert into T1 values (1,'man');
排錯
若是遇到主從不一樣步,看一下主從bin-log的位置,而後再同步。
mysql> show master status;
在主服務器上看二進制日誌事件列表
先中止從服務器
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
change master to master_log_file='mysql-bin-master.000001',master_log_pos=1164;
Query OK, 0 rows affected (0.01 sec)
#根據上面主服務器的show master status的結果,進行從服務器的二進制數據庫記錄迴歸,達到同步的效果
從新啓動slave同步服務
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G; #用show slave status\G;看一下從服務器的同步狀況
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
若是都是yes,那表明已經在同步
重啓從服務器,再查看狀態:
stop slave; #中止從服務器
start slave; #開啓從服務器
排錯思路:
二進制日誌沒有開啓
IPTABLES 沒有放開端口
對應的主機 IP地址寫錯了
SQL線程出錯主從服務器數據庫結構不統一,出錯後,數據少,能夠手動解決建立插入,再更新slave狀態。注:若是主上誤刪除了。那麼從上也就誤刪除了。 #所以主上要按期作mysqldump備份