1. 程式人生 > >MySQL 資料同步雙機互備

MySQL 資料同步雙機互備

               

在這個大資料的時代,資料的安全性是不得不考慮的一個問題。雞蛋放在一個籃子裡面,一旦籃子翻了,所有雞蛋都毀了;同樣的,資料如果只放在一臺伺服器中,一旦機器宕機,資料不可避免的將要丟失,整個系統陷入癱瘓。所以資料的備份至關重要。

本 Chat 將會介紹下如何實現兩臺伺服器上的 MySQL 資料實時同步,互為主備。通過這次 Chat,您將會學會以下內容:

  1. Linux 上 MySQL 的安裝;
  2. Linux 下 MySQL 的基本使用;
  3. 在兩臺伺服器上配置 MySQL 資料同步;
  4. 資料實時同步的測試(為方便,使用 Navicat 工具);
  5. 配置資料同步過程中的問題解決方式。

前言

在這個大資料的時代,資料的安全性是不得不考慮的一個問題。雞蛋放在一個籃子裡面,一旦籃子翻了,所有雞蛋都毀了,也就沒有雞蛋可吃了;同樣的,資料如果只放在一臺伺服器中,一旦機器宕機,資料不可避免的將要丟失,整個系統陷入癱瘓。所以資料的備份至關重要。

本 Chat 將會介紹下如何實現兩臺伺服器上的 MySQL 資料實時同步,互為主備。通過這次 Chat,您將會學會以下內容:

1.LinuxMySQL 的安裝;2.LinuxMySQL 的基本使用;3.在兩臺伺服器上配置 MySQL 資料同步;4.資料實時同步的測試(為方便,使用 Navicat 工具);5.配置資料同步過程中的問題解決方式。

Linux 下 MySQL 的安裝

(1)檢視系統版本
    [[email protected] ~]# uname -a    Linux sts 3.10.0-514.26.2.el7.x86_64 #1 SMP Tue Jul 4 15:04:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
(2)下載 mysql 之前,請先確認是否已安裝 mysql,若已安裝,確認下是否需要重新安裝

檢查是否安裝 mysql:

    rpm -qa |grep mysql    mysql-community-libs-5.7.23-1.el7.x86_64    mysql57-community-release-el7-10.noarch    mysql-community-client-5.7.23-1.el7.x86_64    mysql-community-server-5.7.23-1.el7.x86_64    mysql-community-common-5.7.23-1.el7.x86_64    mysql-community-libs-compat-5.7
.23-1.el7.x86_64

可以看到已經安裝 mysql,如需重新安裝,請將上述命令查詢出結果一一解除安裝,解除安裝前請停止 mysql 服務:

    service mysqld stop     //停止mysql服務    rpm -e --nodeps +包名    //解除安裝對應服務
(3)去 mysql 官網下載適合的 mysql 版本進行下載:

我選擇的是 mysql5.7 版本的,所以先跳轉到 5.7 版本 mysql 頁面:

enter image description here

選擇對應的 mysql 版本資訊:

enter image description here

選擇具體的包進行下載:

enter image description here

第一個包為 mysql 的各部分元件安裝的 rpm 壓縮包,下載後解壓會有以下列表:

    -rw-r--r--  1 7155 31415  23901968 3月   5 10:24 mysql-community-client-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415    339860 3月   5 10:24 mysql-community-common-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415   3715796 3月   5 10:24 mysql-community-devel-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415  39466536 3月   5 10:24 mysql-community-embedded-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415 137541708 3月   5 10:24 mysql-community-embedded-devel-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415   2177784 3月   5 10:24 mysql-community-libs-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415   1723716 3月   5 10:24 mysql-community-libs-compat-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415 160384292 3月   5 10:24 mysql-community-server-5.7.23-1.el7.x86_64.rpm

各包之間存在依賴關係,安裝時需要注意各包的安裝順序。安裝順序為 common–>libs–>client–>server->devel->libs-compat,其中 libs-compat 為 hue 安裝需要依賴的包,若不安裝,hue 安裝會報錯,本 chat 暫不涉及。

第二個下載項為 mysql server 安裝包,若其他依賴元件已安裝,可下載這個,本文使用第一種方式進行安裝。

(4)下載安裝包

下載安裝包可通過兩種方式下載:本地下載上傳到伺服器以及直接伺服器下載,若伺服器配置可以以及網路環境良好可選擇直接在伺服器進行下載,我選擇的是本地下載然後上傳到伺服器。

(伺服器直接下載:使用 wget  命令)點選下載之後,會出現提示登入註冊的介面,在這個介面左下角會有 ‘ No thanks,just start my download ’,點選跳過登入,直接開始下載:

enter image description here

(5)下載完成後,將下載好的安裝包上傳到伺服器上,上傳目錄自定義
    [[email protected] /usr/local/drp/mysql]# ll    total 168960    -rw-r--r-- 1 root root 173011196 Jun 11 11:21 mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar
(6)解壓 mysql 安裝包
        tar -xvf mysql-5.7.18-1.el7.x86_64.rpm-bundle.tar         //解壓之後        -rw-r--r--  1 7155 31415  23901968 3月   5 10:24 mysql-community-client-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415    339860 3月   5 10:24 mysql-community-common-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415   3715796 3月   5 10:24 mysql-community-devel-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415  39466536 3月   5 10:24 mysql-community-embedded-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415 137541708 3月   5 10:24 mysql-community-embedded-devel-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415   2177784 3月   5 10:24 mysql-community-libs-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415   1723716 3月   5 10:24 mysql-community-libs-compat-5.7.23-1.el7.x86_64.rpm    -rw-r--r--  1 7155 31415 160384292 3月   5 10:24 mysql-community-server-5.7.23-1.el7.x86_64.rpm
(7)安裝 mysql

將上述包按 common–>libs–>client–>server->devel->libs-compat 順序進行安裝:

    rpm -ivh mysql-community-common-5.7.23-1.el7.x86_64.rpm    rpm -ivh mysql-community-libs-5.7.23-1.el7.x86_64.rpm    rpm -ivh mysql-community-client-5.7.23-1.el7.x86_64.rpm    rpm -ivh mysql-community-server-5.7.23-1.el7.x86_64.rpm    rpm -ivh mysql-community-embedded-devel-5.7.23-1.el7.x86_64.rpm    rpm -ivh mysql-community-libs-compat-5.7.23-1.el7.x86_64.rpm
(8)啟動 mysql

systemctl start  mysqld.service

檢視 mysql 狀態

    systemctl status  mysqld.service    ● mysqld.service - MySQL Server    Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)    Active: active (running) since Thu 2018-07-19 15:21:44 CST; 2 weeks 4 days ago     Docs: man:mysqld(8)     http://dev.mysql.com/doc/refman/en/using-systemd.html     Main PID: 979 (mysqld)     CGroup: /system.slice/mysqld.service     └─979 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid     Jul 19 15:21:41 sts systemd[1]: Starting MySQL Server...     Jul 19 15:21:44 sts systemd[1]: Started MySQL Server.
(9)修改 mysql 初始密碼

1、先修改配置檔案 /etc/my.cnf 令 MySQL 跳過登入時的許可權檢驗,在 [mysqld] 下加入一行:

skip-grant-tables

2、重啟 MySQL

systemctl restart mysqld.service

3、免密碼登入 MySQL

直接輸入mysql  回車,進入mysql

mysql>  use mysql;mysql> UPDATE user SET authentication_string = password('your-password') WHERE host = 'localhost' AND user = 'root';mysql> select host,user, authentication_string, password_expired from user; mysql> update user set password_expired='N' where password_expired='Y' //密碼不過期mysql> update user set host='%' where user='root' and host='localhost'; //遠端可訪問mysql> flush privileges; //重新整理mysql> exit;//退出

4、去掉 /etc/my.conf 中新增的 skip-grant-tables,重啟 mysql

5、輸入使用者名稱密碼登入 mysql:

mysql -u+使用者名稱 -p+密碼

成功登入即密碼修改成功,到此 mysql 的安裝講解完畢

注:修改密碼時可能會出現修改不成功的現象,提示密碼強度太弱,這是由於 mysql 開啟密碼強度校驗,可通過在 /etc/my.conf 的 [mysqld] 下新增 validate_password = off 關閉密碼校驗,也可參考 https://blog.csdn.net/maxsky/article/details/51171474 進行攔截設定。

mysql 的簡單使用

(1)檢視當前所有資料庫
    mysql>show databases    +--------------------+    | Database           |    +--------------------+    | information_schema |    | alarms             |    | dashboard          |    | drp_db             |    | falcon_portal      |    | graph              |    | hive               |    | mysql              |    | performance_schema |    | sys                |    | uic                |    +--------------------+    11 rows in set (0.07 sec)
(2)建立新的資料庫
    mysql> create database my_new_db;    Query OK, 1 row affected (0.08 sec)

使用 show databases;即可檢視到自己剛剛建立的資料庫。

(3)使用資料庫並在其中建立表
    mysql> create table my_test_table(        -> id int(10) not null primary key,        -> name varchar(20) ,        -> sex varchar(5),        -> age int(3)        -> );    Query OK, 0 rows affected (0.51 sec)
(4)向表中插入資料
    mysql> insert into my_test_table (id,name,sex,age) values(1,'小明','男',20);    ERROR 1366 (HY000): Incorrect string value: '\xE5\xB0\x8F\xE6\x98\x8E' for column 'name' at row 1

這是由於表中未設定編碼格式為 utf-8,修改一下建表語句如下:

    create table my_test_table(        id int(10) not null primary key,        name varchar(20) ,        sex varchar(5),        age int(3)    )ENGINE=InnoDB DEFAULT CHARSET=utf8;

將表中資料設定為 utf8 編碼格式即可。

或者也可使用:

    ALTER TABLE my_test_table MODIFY COLUMN name VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

將報錯欄位編碼格式設定為 utf8 格式。

修改之後即可成功插入資料:

    mysql> insert into my_test_table (id,name,sex,age) values(1,'小明','boy',20);    Query OK, 1 row affected (0.03 sec)
(5)查詢資料
    mysql> select * from my_test_table;    +----+--------+------+------+    | id | name   | sex  | age  |    +----+--------+------+------+    |  1 | 小明   | boy  |   20 |    +----+--------+------+------+    1 row in set (0.00 sec)    mysql> select name from my_test_table;    +--------+    | name   |    +--------+    | 小明   |    +--------+    1 row in set (0.00 sec)
(6)修改資料
    mysql> update my_test_table set name ='小紅' where id = 1;    Query OK, 1 row affected (0.05 sec)    Rows matched: 1  Changed: 1  Warnings: 0
    mysql> select * from my_test_table where id = 1;    +----+--------+------+------+    | id | name   | sex  | age  |    +----+--------+------+------+    |  1 | 小紅   | boy  |   20 |    +----+--------+------+------+    1 row in set (0.00 sec)    mysql> 
(7)刪除資料

delete from my_test_table where id = 1;

資料表的刪除操作使用需謹慎,一旦刪除不可還原,刪除時必須加上必要的條件,否則會將期望保留的資料也給刪掉。

(8)刪除資料庫
    mysql> drop database my_new_db;    Query OK, 1 row affected (0.08 sec)

同樣的,刪除資料庫時也需要格外小心,要保證內部的表中資料都不需要了方可刪除。

以上就是 linux 下 mysql 的簡單操作。

mysql 雙主機資料同步

該模組為本 chat 的核心內容。廢話少說,直接開始。

(1)前期準備

伺服器(至少兩臺):10.168.1.44、10.168.0.126執行環境: centos7mysql 版本:5.7.22

注:資料同步的前提要保證同步的伺服器之間可以互相 ping 通。

(2)修改 mysql 配置檔案

在 10.168.1.44 伺服器 /etc/my.conf 配置檔案中新增:

server_id=10log-bin=master_01    //開啟二進位制日誌,作用是另一個伺服器可以

通過該日誌來確定執行操作

binlog-do-db=test_db  //同步的庫binlog-do-db=my_test  //同步的庫

在 10.168.0.126 伺服器 /etc/my.conf 配置檔案中新增:

server_id=20log-bin=master_02    //開啟二進位制日誌,作用是另一個伺服器可以

通過該日誌來確定執行操作:

binlog-do-db=test_db  //同步的庫binlog-do-db=my_test  //同步的庫

新增之後執行命令 systemctl restart  mysqld.service 重啟資料庫使修改生效。

上述引數解析:

  1. server_ id 為當前 mysql 服務的識別 ID,必須唯一。
  2. log - bin 開啟二進位制日誌,每次資料操作都會將操作日誌記錄在裡面,以便從服務可以通過日誌確定執行了什麼操作。
  3. bin - do - db  需要同步的資料庫,如果有多個數據庫需要同步,寫多行。binlog - do - db = db1,db2,db3... 這種寫法是錯誤的,不會達到預期效果
(3)新增 mysql 賬戶,使用者資料複製

新增 mysql 賬戶,通過給其授權使用者執行資料同步:

10.168.1.44執行命令:GRANT FILE ON *.* TO 'copyuser'@'10.168.0.126' IDENTIFIED BY '[email protected]';GRANT REPLICATION SLAVE ON *.* TO 'copyuser'@'10.168.0.126' IDENTIFIED BY '[email protected]';flush privileges;10.168.0.126執行命令:GRANT FILE ON *.* TO 'copyuser'@'10.168.1.44' IDENTIFIED BY '[email protected]';GRANT REPLICATION SLAVE ON *.* TO 'copyuser'@'10.168.1.44' IDENTIFIED BY '[email protected]';flush privileges;
(4)配置從資料庫

分別在兩臺伺服器上進入 mysql,輸入 show master status; 命令檢視當前主機的狀態:

    mysql> show master status;    +------------------+----------+-----------------+------------------+-------------------+    | File             | Position | Binlog_Do_DB    | Binlog_Ignore_DB | Executed_Gtid_Set |    +------------------+----------+-----------------+------------------+-------------------+    | master_01.000008 |      749 | test_db,my_test |                  |                   |    +------------------+----------+-----------------+------------------+-------------------+    1 row in set (0.00 sec)

記錄下此時的 file 名以及 position;

在 10.168.1.44 執行:

    mysql>CHANGE MASTER TO    MASTER_HOST='10.168.0.126',   //所要同步的伺服器ip    MASTER_USER='copyuser',     //同步伺服器的mysql使用者名稱    MASTER_PASSWORD='[email protected]', //同步伺服器的mysql密碼,與上面建立時的密碼要匹配    MASTER_PORT=3306,    MASTER_LOG_FILE='master_02.000002',   //對應10.168.0.126的file名    MASTER_LOG_POS=1771,      //對應10.168.0.126的position    MASTER_CONNECT_RETRY=10;    在

10.168.0.126 執行:

    mysql>CHANGE MASTER TO    MASTER_HOST='10.168.1.44',    MASTER_USER='copyuser',    MASTER_PASSWORD='[email protected]',    MASTER_PORT=3306,    MASTER_LOG_FILE='master_01.000008',     //對應10.168.1.44的file名    MASTER_LOG_POS=154,            //對應10.168.0.126的position    MASTER_CONNECT_RETRY=10;

注:若 slave 開啟狀態無法執行以上命令,需要首先執行 stop slave;關閉 slave,執行完上述命令後執行 start slave;命令開啟 slave。

上述命令執行完後,檢視從服務狀態:

執行命令 show slave status\G:

enter image description here

Slave_IO_Running:  指的就是從伺服器上負責讀取主伺服器的執行緒工作狀態。 從伺服器用這個專門的執行緒連結到主伺服器上,並把日誌拷貝回來。

Slave_SQL_Running:指的就是專門執行 sql 的執行緒。它負責把複製回來的 Relaylog 執行到自己的資料庫中。 這兩個引數必須都為Yes 才表明複製在正常工作。

到這裡,mysql 同步配置已完成,接下來測試下資料是否能正常實時同步。

測試資料同步

為方便操作,本次測試使用第三方工具 Navicat Premium 連線兩個資料庫測試資料的同步。

(1)配置連線兩個資料庫

enter image description here

(2)在10.168.0.126 的 my_ test 資料庫中建立表 test_  table:

enter image description here

檢視 10.168.1.44 的資料庫 my_ test,會發現  test_ table 表自動同步建立:

enter image description here

(若找不到,在表一欄右鍵重新整理即可)。

(3)在 10.168.1.44 上向 test_table 插入一條資料:

enter image description here

回到 10.168.0.126,檢視 test_table 表中資料,會發現資料已同步過來:

enter image description here

到此,兩臺伺服器上的 mysql 資料同步已測試完成。

可能出現的問題

1.檢視 slave 狀態時,會發現 Slave_IO_Running: Connecting

出現該問題主要有三個原因:

A.網路不通(互相 ping下試試看能否ping通)
B.密碼不對:檢視在配置 slave 時執行的命令中的密碼是否正確
C.Position 不正確:配置 slave 時對應 position 未填為正確的position(檢視對應從伺服器資料庫的 master 狀態:show master status 即可找到 )   

我出現這個問題的原因是隻在一個伺服器上建立了用於同步資料的使用者 ‘copyuser’,另一個伺服器資料庫中並未建立該使用者。建立之後 OK 了。

2.檢視 slave 狀態時,會發現 Slave_SQL_Running: No

出現這個現象的原因主要就是兩邊資料庫資料存在不同之處,也就是同步時沒有相同的初態,可以通過檢視 mysql 日誌定位具體哪塊資料出現異常(詳細參考下面備註)。

Mysql 日誌一般在 /var/log/mysqld.log

需要注意的是,如果你只配置了從資料庫同步主資料庫資料,而未設定為互相同步    ,修改從資料庫資料可能會導致同步失效。

備註

資料同步,一般需要是在同樣的初態下進行同步,這樣才有意義。所謂同樣的初態指的是同步之前兩伺服器所要同步的資料庫中資料完全一致,這樣才能保證同步之後兩資料庫資料的一致,否則,同步過程中會發生各種各樣的問題,諸如A中修改了表 a 的資料,而 B 中並未找到 a 表,雖然讀取到了日誌,但並不能成功執行,導致同步失敗。如何實現同樣的初態環境呢?

(1)匯出資料

匯出資料的時候,最好在 mysql 下執行命令 FLUSH TABLES WITH READ LOCK; 將資料庫上寫鎖,禁止資料的寫入,完成之後,再釋放鎖:UNLOCK TABLES;

    [[email protected] mysql]# mysqldump --master-data -uroot -p my_test > my_test.sql    Enter password:     [[email protected] mysql]# ll    總用量 4    -rw-r--r-- 1 root root 2927 8月   7 15:47 my_test.sql

如果有多個數據庫需要同步,需要將多個數據庫都匯出來一份。

(2)在從伺服器上匯入資料
  1. 將主伺服器上匯出的 sql 檔案傳到從伺服器 :   

    scp my_test.sql 10.168.0.126:/mysql/`
  2. my_test.sql 中的資料匯入進來,若從伺服器沒有 my_test 庫,建立;若有,清楚內部資料,然後執行:mysql -uroot -p my_test < my_test.sql

這樣就保證兩個伺服器的 my_test 庫擁有同樣的初態了。

如果有多個數據庫需要同步,逐一按照上面步驟操作即可。

結尾語

以上就是關於 mysql 雙機熱備的具體配置以及測試資訊,希望能給大家帶來幫助,若有什麼不足的地方,歡迎大家指正。我是小閒,一個正在爬坑的程式猿。

一場場看太麻煩?訂閱GitChat體驗卡,暢享300場chat文章!更有CSDN下載、CSDN學院等超划算會員權益!點選檢視