mysql雙機熱備(主從,主主備份)以及基於gtid主備的配置

雙機熱備:保持兩個數據庫的狀態自動同步。對任何一個數據庫的操作都自動同步到另外一個數據庫,始終保持兩個數據庫數據一致。

說到mysql的備份,那就必須要瞭解(不是理解)mysql的備份原理,借用一整很多大神都用的圖:
這裏寫圖片描述

這個備份的過程分爲兩部分:
主(Master): 打開復制模式之後,主服務器Master, 會把自己的每一次改動都記錄到 二進制日誌 Binarylog 中。
從(Slave): 打開復制模式之後,從服務器Slave的I/O線程, 會用master上的賬號登陸到 master上, 讀取master的Binarylog, 寫入到自己的中繼日誌 Relaylog, 然後自己的sql線程會負責讀取這個中繼日誌,並執行一遍。 如是,主服務器上的更改就同步到從服務器上了。

實驗需求:
本次實驗用的是mysql5.7.20版本:

[root@ansible ~]# mysql -V
mysql  Ver 14.14 Distrib 5.7.20, for Linux (x86_64) using  EditLine wrapper

mysql5.7.20的安裝如果還有問題,可以借鑑:
http://blog.csdn.net/weixin_37998647/article/details/78649092

實驗兩臺主機的IP分別是:
192.168.1.121 我們稱之爲A,
192.168.1.185 我們稱之爲B,
方便起見,直接關掉防火牆,selinux

廢話已經太多了,下面直接開幹吧:
1、在A上給用於備份的用戶授權(我們直接用root用戶):

mysql> grant replication slave on *.* to 'root'@'192.168.1.185' identified by 'abc123';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
mysql> set global validate_password_policy=0;
Query OK, 0 rows affected (0.00 sec)
mysql> set global validate_password_length=6;
Query OK, 0 rows affected (0.00 sec)
mysql> grant replication slave on *.* to 'root'@'192.168.1.185' identified by 'abc123';
Query OK, 0 rows affected, 1 warning (0.01 sec)

(報錯是因爲密碼太簡單,該本版的mysql帶有密碼強壯度校驗的模塊,按照上面的方法設置一下就可以了。)
2. 開啓主服務器的 binarylog。

[root@ansible ~]# vim /etc/my.cnf

# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

log-bin = mysql-bin
binlog_format = mixed
server-id = 1

read-only = 0
binlog-ignore-db = information_schema
binlog-ignore-db = mysql
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
binlog-ignore-db = zabbix
auto-increment-increment = 10
auto-increment-offset = 1

在最後面加了一些參數:
log-bin = mysql-bin
binlog_format = mixed
server-id = 1
read-only = 0
binlog-ignore-db = information_schema
binlog-ignore-db = mysql
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
binlog-ignore-db = zabbix
auto-increment-increment = 10
auto-increment-offset = 1
解釋一下這些參數的的意義:
server-id 必須保證每個服務器不一樣。 這可能和循環同步有關。 防止進入死循環。

binlog-do-db 用來表示,只把哪些數據庫的改動記錄到binary日誌中。 可以寫上關注hello數據庫。 也可以把它註釋掉了。 只是展示一下。 可以寫多行,表示關注多個數據庫。

binlog-ignore-db 表示,需要忽略哪些數據庫。我這裏忽略了其他的5個數據庫。

後面兩個用於在 雙主(多主循環)互相備份。 因爲每臺數據庫服務器都可能在同一個表中插入數據,如果表有一個自動增長的主鍵,那麼就會在多服務器上出現主鍵衝突。 解決這個問題的辦法就是讓每個數據庫的自增主鍵不連續。 我假設需要將來可能需要10臺服務器做備份, 所以auto-increment-increment 設爲10. 而 auto-increment-offset=1 表示這臺服務器的序號。 從1開始, 不超過auto-increment-increment。
這樣做之後, 我在這臺服務器上插入的第一個id就是 1, 第二行的id就是 11了, 而不是2,(同理,在第二臺服務器上插入的第一個id就是2, 第二行就是12, 這個後面再介紹) 這樣就不會出現主鍵衝突了。

保存, 重啓mysql。

  1. 獲取主服務器狀態, 和同步初態。
[root@ansible ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 775
Server version: 5.7.20-log MySQL Community Server (GPL)

Copyright (c) 2000, 2017, 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 |
| hello              |
| mysql              |
| performance_schema |
| sys                |
| zabbix             |
+--------------------+
8 rows in set (0.00 sec)

如果是剛安裝的就沒有“hello”和zabbix“”這兩個庫,上面我們已經設置了備份不管zabbix庫,這裏只關注hello庫就好了。

先鎖定 hello數據庫:

mysql> flush tables with read lock;
Query OK, 0 rows affected (0.15 sec)

導出數據,我們這裏只用導出hello數據庫,(如果你有多個數據庫作爲初態的話, 需要導出所有這些數據庫:)

[root@ansible ~]# mysqldump --master-data -uroot -p hello > hello.sql
Enter password:
[root@ansible ~]# ll
-rw-r--r-- 1 root root  2632 Jan 22 13:36 hello.sql

然後查看A服務器的binary日誌位置:

記住這個文件名和 位置, 等會在從服務器上會用到。

mysql> show master status\G;
*************************** 1. row ***************************
             File: mysql-bin.000001
         Position: 1277
     Binlog_Do_DB:
 Binlog_Ignore_DB: information_schema,mysql,performance_schema,sys,zabbix
Executed_Gtid_Set:
1 row in set (0.00 sec)

ERROR:
No query specified

Master上的操作已經OK了, 可以解除鎖定了:

mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

把導出的hello.sql傳到185上去。

[root@ansible ~]# scp hello.sql 192.168.1.185:
hello.sql                                  100% 2632     2.6KB/s   00:00
  1. 設置從服務器 B 需要複製的數據庫

打開從服務器 B 的 /etc/my.cnf 文件:

[root@localhost ~]# vim /etc/my.cnf

在配置文件最後加上:
log-bin = mysql-bin
binlog_format = mixed
server-id = 2

replicate-ignore-db = information_schema
replicate-ignore-db = mysql
replicate-ignore-db = performance_schema
replicate-ignore-db = sys
replicate-ignore-db = zabbix
relay_log = mysqld-relay-bin
log-slave-updates = ON

解釋一下參數:
server-id 必須保證每個服務器不一樣。 這可能和循環同步有關。 防止進入死循環。

replicate-ignore-db 複製時需要排除的數據庫, 我使用了,這個。 除開系統的幾個數據庫和zabbix之外,所有的數據庫都複製。

relay_log 中繼日誌的名字。 前面說到了, 複製線程需要先把遠程的變化拷貝到這個中繼日誌中, 在執行。

log-slave-updates 意思是,中繼日誌執行之後,這些變化是否需要計入自己的binarylog。 當你的B服務器需要作爲另外一個服務器的主服務器的時候需要打開。 就是雙主互相備份,或者多主循環備份。 我們這裏需要, 所以打開。
保存, 重啓mysql。

  1. 從上導入初態。
    把剛纔從A服務器上導出的 hello.sql 導入到 B的hello數據庫中, 如果B現在沒有hello數據庫,請先創建一個, 然後再導入:
    創建數據庫:
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hello              |
| mysql              |
| performance_schema |
| sys                |
| zabbix             |
+--------------------+
6 rows in set (0.00 sec)

mysql> drop database hello;
Query OK, 0 rows affected (0.01 sec)

mysql> create database hello default charset utf8;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hello              |
| mysql              |
| performance_schema |
| sys                |
| zabbix             |
+--------------------+
6 rows in set (0.00 sec)

把hello.sql 上傳到B上, 然後導入:

[root@localhost ~]# mysql -uroot -p hello < hello.sql
Enter password:

開啓同步, 在B服務器上執行:

mysql> change master to master_host='192.168.1.121',master_user='root',master_password='abc123',master_log_file='mysql-bin.000001',master_log_pos=1277;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

重啓mysql,查看slave狀態:

[root@localhost ~]# /etc/init.d/mysqld restart
Stopping mysqld:                                           [  OK  ]
Starting mysqld:                                           [  OK  ]
[root@localhost ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.7.20-log MySQL Community Server (GPL)

Copyright (c) 2000, 2017, 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 slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.121
                  Master_User: root
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 1277
               Relay_Log_File: mysqld-relay-bin.000003
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB: information_schema,mysql,performance_schema,sys,zabbix
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                   ……

至此,主從複製已經配置好了。現在測試一下:
在A上:

mysql> create database test;
Query OK, 1 row affected (0.03 sec)

B上show databases;

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hello              |
| mysql              |
| performance_schema |
| sys                |
| test               |
| zabbix             |
+--------------------+

說明主從複製已經成功了

如果只要求主從複製,那麼到這裏已經完成了,後面的內容可以不需再看

此時暫且不要在B上操作。
上面的結果已經看到A上的操作可以自動同步到B上,但是B上的操作還不能同步到A上。
如果要做B複製到A,跟上面的操作基本一樣,那下面的操作就不解釋了。
主主複製,即互爲主備,雙機熱備:
1. 在B中創建用戶;

mysql> grant replication slave on *.* to 'root'@'192.168.1.121' identified by 'abc123';
Query OK, 0 rows affected, 1 warning (0.01 sec)
  1. 打開 /etc/my.cnf , 開啓B的binarylog:
[root@localhost ~]# vim /etc/my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

log-bin = mysql-bin
binlog_format = mixed
server-id = 2

replicate-ignore-db = information_schema
replicate-ignore-db = mysql
replicate-ignore-db = performance_schema
replicate-ignore-db = sys
replicate-ignore-db = zabbix
relay_log = mysqld-relay-bin
log-slave-updates = ON


read-only = 0
binlog-ignore-db = information_schema
binlog-ignore-db = mysql
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
binlog-ignore-db = zabbix
auto-increment-increment = 10
auto-increment-offset = 2
  1. 此時不需要導出B的初態了,因爲它剛剛纔從A導過來。 直接記住它的master日誌狀態:
mysql> show master status\G;
*************************** 1. row ***************************
             File: mysql-bin.000003
         Position: 154
     Binlog_Do_DB:
 Binlog_Ignore_DB: information_schema,mysql,performance_schema,sys,zabbix
Executed_Gtid_Set:
1 row in set (0.00 sec)

ERROR:
No query specified
  1. 登錄到A 服務器。 開啓中繼:
[root@ansible ~]# vim /etc/my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

log-bin = mysql-bin
binlog_format = mixed
server-id = 1

read-only = 0
binlog-ignore-db = information_schema
binlog-ignore-db = mysql
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
binlog-ignore-db = zabbix
auto-increment-increment = 10
auto-increment-offset = 1

replicate-ignore-db = information_schema
replicate-ignore-db = mysql
replicate-ignore-db = performance_schema
replicate-ignore-db = sys
replicate-ignore-db = zabbix
relay_log = mysqld-relay-bin
log-slave-updates = ON
  1. 啓動同步:
mysql> change master to master_host = '192.168.1.185',master_user='root',master_password='abc123',master_log_file='mysql-bin.000003',master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.09 sec)

然後重啓mysql服務。

然後查看,slave狀態是否正常:

如果出現:
Slave_IO_Running: No
Slave_SQL_Running: No
解決辦法:先停掉mysql服務。 找到這三個文件,把他們刪掉。 一定要先停掉mysql服務。不然還是不成功。你需要重啓一下機器了。 或者手動kill mysqld。

[root@ansible ~]# cd /var/lib/mysql
[root@ansible mysql]# rm -fr relay-log.info ansible-relay-bin.000001 ansible-relay-bin.index

再登錄啓動同步,之後再重啓

mysql> change master to master_host = '192.168.1.185',master_user='root',master_password='abc123',master_log_file='mysql-bin.000003',master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.09 sec)

重啓之後再查看:

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.185
                  Master_User: root
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 154
               Relay_Log_File: mysqld-relay-bin.000003
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB: information_schema,mysql,performance_schema,sys,zabbix
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
      ……

出現連個NO的原因是:是因爲我們在配置A的中繼文件時改了中繼文件名,但是mysql沒有同步。

至此主主同步已經開啓了。
驗證一下,方法在B上插入數據,在A上查看。

===============================================

下面介紹一下基於gtid模式的複製配置:

配置文件的最後加上gtid_mode=on ; enforce_gtid_consistency=on 這兩項。即
主的配置:

# cat /etc/my.cnf
log-bin=mysql-bin
binlog_format=mixed
server-id=1
auto-increment-increment = 2
auto-increment-offset = 1
gtid_mode=on
enforce_gtid_consistency=on

從的配置:

gtid_mode=on
enforce_gtid_consistency=on
log-bin = mysql-bin
binlog_format = mixed
server-id = 2

主給從授權:

grant replication slave on *.* to 'root'@192.168.1.121 identified by 'abc123';

從找主:

change master to master_host='192.168.1.185',master_user='ha',master_password='Lockey+123',master_auto_position=1;

線上業務量比較大的時候,往往主庫會不停的寫入,此時就需要用到gtid 模式。他的好處就是,出庫不用鎖庫,而且自動找到position 的位置,不用擔心position不停變化而無法同步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章