mysql/mariadb主從複製架構配置及過程當中出現的問題

兩臺CentOS7系虛擬主機:
分別是:主服務器172.16.75.1,從服務器172.16.75.2
使用的是mariadb-5.5.56,即centOS自帶的軟件版本
爲了使實驗結果顯示精準,此處關閉兩臺服務器的防火牆和SELinux:
[root@chenliang ~]# setenforce 0
[root@chenliang ~]# iptables -Fmysql

1、首先在主服務器172.16.75.1上配置:
在/etc/my.cnf中配置以下:
[mysqld]
###定義二進制日誌的存放位置###
log_bin=/var/lib/mysql/binlog
###配置server_id來保證服務器的惟一性###
server_id=101
innodb_file_per_table=ON
###跳過域名反解###
skip_name_resolve=ON
###每寫入一次二進制日誌事件,就會刷寫入磁盤一次,通常爲1,防止二進制日誌還沒有刷寫至磁盤時宕機致使數據丟失,保證數據完整###
sync_binlog=1
###事務每次提交都會將事務日誌緩衝區中的日誌寫入操做系統的緩衝區並當即調用fsync()刷寫到磁盤中,即便系統奔潰也不會丟失任何數據###
innodb_flush_log_at_trx_commit=1sql

保存退出,重啓mariadb服務。 shell

登陸mysql交互模式,在Master上建立一個用於實現複製功能的用戶帳戶,並受權Replication slave,Replication client權限:
MariaDB [(none)]> grant replication slave on . to 'repuser'@'%' identified by 'reppass';
Query OK, 0 rows affected (0.01 sec)
而後更新受權,防止刷新不及時,沒法登陸:
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.01 sec)
查看受權用戶:
MariaDB [(none)]> show grants for "repuser"@"%";
+--------------------------------------------------------------------------------------------------------------------+
| Grants for repuser@% |
+--------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE ON . TO 'repuser'@'%' IDENTIFIED BY PASSWORD '*304A91F0E46BBB1E641D3D95E225E9AAA27077CE' |
+--------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)數據庫

記錄下Master上開始複製前的二進制日誌文件名及位置座標,在從服務器上配置須要用到File文件名和響應的Position位置座標:
MariaDB [(none)]> show master status;
+---------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| binlog.000014 | 553 | | |
+---------------+----------+--------------+------------------+
1 row in set (0.01 sec)服務器

這裏實驗採用的是備份主服務器上的所有數據庫數據和表,能夠經過mysqldump命令來進行徹底備份:
[root@chenliang ~]# mysqldump --all-databases --lock-tables > alldb.sql
然後將備份的alldb.sql文件發送到從服務器端(這裏發送至從服務器的root的家目錄):
[root@chenliang ~]# scp alldb.sql 172.16.72.2:/root/session

2、在從服務器172.16.75.2上配置:
在/etc/my.cnf中配置以下:
[mysqld]
innodb_file_per_table=ON
skip_name_resolve=ON
#設置服務器id,區分主從#
server_id=201
#中繼日誌存放位置#
relay_log=/var/lib/mysql/slavelog
#設置從服務器全局只讀#
#read_only=ON或者set @@global.read_only=ON#
set @@global.read_only=ON架構

**補充**:關於read_only,能夠防止從服務器修改數據使得主從服務器端數據不一致(由於從服務器沒有開啓二進制日誌記錄,因此從服務器上修改的數據將不爲主服務器所知),可是該服務器參數僅能限制那些不具備"SUPER"權限的用戶的寫操做行爲(例如root用戶除外),在低版本的mariadb中能夠在從服務器上開啓mysql會話,並使用"flush tables with read lock;"給全部表加讀鎖,用來禁止root用戶在從服務器上進行寫操做;在後期的mariadb版本中,會提供限制root用戶在從服務器上的寫權限的參數:root_read_only。

保存退出,重啓Mariadb服務。異步

進入Mariadb交互模式中,首先將備份好的數據導入到從服務器上:
MariaDB [(none)]> source /root/alldb.sql
而後給全部表加鎖,禁止root用戶進行寫操做:
MariaDB [(none)]> flush tables with read lock;
在Slave上使用CHANGE MASTER TO...語句來指定Master的相關屬性信息:
在指定以前確保,slave複製線程已經關閉:
MariaDB [(none)]> stop slave;
Query OK, 0 rows affected (0.06 sec)
開始指定master:
MariaDB [(none)]> change master to master_host='172.16.75.1', master_port=3306, master_user='repuser', master_password='reppass', master_log_file='binlog.000014', master_log_pos=553;
Query OK, 0 rows affected (0.02 sec)
在Slave上開啓複製線程:
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.01 sec)
查看主從複製架構狀態:
MariaDB [(none)]> show slave status\G;
1. row
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.75.1
Master_User: repuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000014
Read_Master_Log_Pos: 553
Relay_Log_File: slavelog.000002
Relay_Log_Pos: 526
Relay_Master_Log_File: binlog.000014
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 553
Relay_Log_Space: 813
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 101
1 row in set (0.00 sec)ide

ERROR: No query specified工具

Slave_IO_Running: Yes
Slave_SQL_Running: Yes
若是這IO線程和SQL線程都顯示YES,則表明搭建成功。

測試:在主服務器中搭建一個數據庫,若是從服務器相應的出現新建的數據庫,則表明測試沒有問題。
在主服務器172.16.75.1中mysql交互模式中:
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| backuptest |
| mysql |
| mytest |
| performance_schema |
+--------------------+
5 rows in set (0.00 sec)
建立新數據庫testdb:
MariaDB [(none)]> create database testdb;
Query OK, 1 row affected (0.07 sec)

在從服務器172.16.75.2上,查詢數據庫顯示以下,出現主服務器端新建的數據庫testdb:
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| backuptest |
| mysql |
| mytest |
| performance_schema |
| testdb |
| zabbix |
+--------------------+
7 rows in set (0.07 sec)

至此,mysql的主從複製架構搭建成功。

搭建配置過程當中出現的問題:
1.出現鏈接主服務器端不成功的問題:
MariaDB [(none)]> show slave status\G;
1. row
Slave_IO_State: Connecting to master
Master_Host: 172.16,75.1
Master_User: repuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000014
Read_Master_Log_Pos: 553
Relay_Log_File: slavelog.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: binlog.000014
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 553
Relay_Log_Space: 245
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 2005
Last_IO_Error: error connecting to master 'repuser@172.16,75.1:3306' - retry-time: 60 retries: 86400 message: Unknown MySQL server host '172.16,75.1' (2)
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0
1 row in set (0.01 sec)

ERROR: No query specified

此時須要,清理/var/lib/mysql/下的master.info和relay-log.info,清除上一次複製的標誌位記錄和中繼日誌記錄信息,而後重啓從服務器的mariadb服務,鏈接恢復正常:
[root@chenliang mysql]# rm -fr master.info
[root@chenliang mysql]# rm -fr relay
[root@chenliang mysql]# systemctl restart mariadb.service

2.出現禁止已經受權用戶的請求鏈接問題,Slave_IO_Running: Connecting:
MariaDB [(none)]> show slave status\G;
1. row
Slave_IO_State: Connecting to master
Master_Host: 172.16.75.1
Master_User: repuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000011
Read_Master_Log_Pos: 245
Relay_Log_File: slavelog.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: binlog.000011
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 245
Relay_Log_Space: 245
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 1045
Last_IO_Error: error connecting to master 'repuser@172.16.75.1:3306' - retry-time: 60 retries: 86400 message: Access denied for user 'repuser'@'172.16.75.2' (using password: YES)
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0
1 row in set (0.00 sec)

ERROR: No query specified

解決辦法:
這裏實驗所遇到的主要是主服務器端受權更新不及時,致使受權的用戶無效,天然沒法鏈接:
在主服務器端mariadb的交互模式中:
MariaDB [(none)]> flush privileges;
查看受權用戶是否生效:
MariaDB [(none)]> show grants for "repuser"@"%";
+--------------------------------------------------------------------------------------------------------------------+
| Grants for repuser@% |
+--------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE ON . TO 'repuser'@'%' IDENTIFIED BY PASSWORD '*304A91F0E46BBB1E641D3D95E225E9AAA27077CE' |
+--------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

這裏在查找Slave_IO_Running: Connecting的問題中,主要參考瞭如下博客(附上連接):
http://www.javashuo.com/article/p-kzchfvbe-kz.html
https://blog.csdn.net/sanbingyutuoniao123/article/details/50504321
https://blog.csdn.net/dsundsun/article/details/18707599

3.在從服務器端導入備份好的主服務器數據庫文件時,第一次我採用了直接在shell命令行中輸入命令:mysql -uroot -p < alldb.sql ,發現等待很長時間無響應
這時候嗎,發如今主服務器端初次實驗時,備份全部數據庫和表以前加了讀鎖:
FLUSH TABLES WITH READ LOCK;
加讀鎖沒有問題,最重要的是在導入從服務器端時,切記要把讀鎖解開,不然就會出現我一萬年都導不進去的現象,若是要在不解鎖的狀況下導進去的話,只能在從服務器mariadb的交互模式中導入:
Mariadb [(none)]source /root/alldb.sql

以上就是mysql/mariadb一主一從複製架構的所有過程和小問題解析。

關於mysql雙主複製架構:
兩臺MySQL服務器之間互爲主從關係,因此要在兩臺服務器上都開啓二進制日誌和中繼日誌功能;
雙主架構的架構目的:爲了防止單點故障;

雙主架構可能存在的架構問題:
1.數據不一致的風險大幅提高;
2.在一些表的某個或某些字段中,若是使用auto_increment修飾符設置了字段的自動增加,可能會形成數據紊亂,結果會致使對數據的插入、修改或刪除等操做執行失敗;
定義其中一個服務器主節點的自動增加的值所有爲奇數;
auto_increment_increment=2
auto_increment_offset=1

定義另外一個服務器主節點的自動增加的值所有爲偶數;
    auto_increment_increment=2
    auto_increment_offset=2

使用上述方式設置的序列號,能夠避免主鍵衝突,可是有可能出現數值的不連續現象,也能夠專門提供一臺服務器,用來生成序列號;

配置方案:
在配置過程當中,須要注意如下幾個問題:
1.兩臺MySQL服務器的server_id必須設置爲不一樣的值;
2.均需啓動二進制日誌和中繼日誌,而且要保證mysql用戶對於兩種日誌文件都有寫權限;
3.對於存在自動增加ID的表,保證不會發生主鍵衝突的問題;
4.在兩臺MySQL服務器上均需受權用戶進行復制操做;
5.在兩臺MySQL服務器上均需使用CHANGE MASTER TO語句指定對方服務器的複製屬性值;

配置文件/etc/my.cnf中:
[mysqld]
innodb_file_per_table=ON
skip_name_resolve=ON
log_bin=binlog
server_id=101
sync_binlog=1
innodb_flush_log_at_trx_commit=1
relay_log=slavelog
auto_increment_offset=1
auto_increment_increment=2

受權用戶:
MariaDB [(none)]> grant replication slave on . to 'repuser'@'%' identified by 'reppass';

指定master爲另外一臺主服務器:
MariaDB [(none)]> change master to master_host='172.16.75.2',
master_user='repuser2',
master_password='reppass',
master_port=3306,
master_log_file='binlog.000001',
master_log_pos=245;

[mysqld]
innodb_file_per_table=ON
skip_name_resolve=ON
log_bin=binlog
server_id=202
sync_binlog=1
innodb_flush_log_at_trx_commit=1
relay_log=slavelog
auto_increment_offset=2
auto_increment_increment=2

受權用戶:
MariaDB [(none)]> grant replication slave on . to 'repuser2'@'%' identified by 'reppass';

指定master爲第一臺服務器:
MariaDB [(none)]> change master to master_host='172.16.75.1',master_user='repuser',master_password='reppass',master_port=3306,master_log_file='binlog.000005',master_log_pos=245;

在第一臺主服務器端和第二臺主服務器上分別啓動從複製線程:
start slave;

雙主架構和一主一從架構之間搭建過程中並無太多不一樣,除了設置增加步長的問題,還須要把以前一主一從架構中的從服務器中的只讀關閉,其餘遇到的問題基本與一主一從問題一致,有了一主一從的基本經驗,部署雙主架構不是問題。

關於半同步複製架構:
在一主多從的MySQL架構中,可讓Master與衆多的Slave中的一臺服務器保持同步複製,與其餘的Slave繼續使用默認的異步複製;

若是想要讓MySQL支持半同步複製,須要額外的插件;使用rpm包安裝的MySQL/MariaDB,插件默認存放於:/usr/lib64/mysql/plugin
semisync_master.so --> rpl_semi_sync_master;
semisync_slave.so --> rpl_semi_sync_slave;

安裝插件的方法:
MariaDB [(none)] > INSTALL PLUGIN plugin_name SONAME 'SO_FILE_NAME';

安裝半同步插件:
安裝主服務器的半同步插件:
MariaDB [(none)] > install plugin rpl_semi_sync_master soname 'semisync_master.so';

查看主服務器上的與半同步複製有關的服務器參數:
    MariaDB [hellodb]> show global variables like '%semi%';
    +------------------------------------+-------+
    | Variable_name                      | Value |
    +------------------------------------+-------+
    | rpl_semi_sync_master_enabled       | OFF   |
    | rpl_semi_sync_master_timeout       | 10000 |
    | rpl_semi_sync_master_trace_level   | 32    |
    | rpl_semi_sync_master_wait_no_slave | ON    |
    +------------------------------------+-------+

查看主服務器上與半同步複製有關的狀態參數:
    MariaDB [hellodb]> show global status like '%semi%';
    +--------------------------------------------+-------+
    | Variable_name                              | Value |
    +--------------------------------------------+-------+
    | Rpl_semi_sync_master_clients               | 0     |
    | Rpl_semi_sync_master_net_avg_wait_time     | 0     |
    | Rpl_semi_sync_master_net_wait_time         | 0     |
    | Rpl_semi_sync_master_net_waits             | 0     |
    | Rpl_semi_sync_master_no_times              | 0     |
    | Rpl_semi_sync_master_no_tx                 | 0     |
    | Rpl_semi_sync_master_status                | OFF   |
    | Rpl_semi_sync_master_timefunc_failures     | 0     |
    | Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
    | Rpl_semi_sync_master_tx_wait_time          | 0     |
    | Rpl_semi_sync_master_tx_waits              | 0     |
    | Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
    | Rpl_semi_sync_master_wait_sessions         | 0     |
    | Rpl_semi_sync_master_yes_tx                | 0     |
    +--------------------------------------------+-------+

安裝從服務器的半同步插件:
    MariaDB [(none)] > install plugin rpl_semi_sync_slave soname 'semisync_slave.so';

查看從服務器的與半同步複製相關的服務器參數:
    MariaDB [(none)]> show global variables like '%semi%';
    +---------------------------------+-------+
    | Variable_name                   | Value |
    +---------------------------------+-------+
    | rpl_semi_sync_slave_enabled     | OFF   |
    | rpl_semi_sync_slave_trace_level | 32    |
    +---------------------------------+-------+

查看從服務器的與半同步複製相關的狀態參數:
    MariaDB [(none)]> show global status like '%semi%';
    +----------------------------+-------+
    | Variable_name              | Value |
    +----------------------------+-------+
    | Rpl_semi_sync_slave_status | OFF   |
    +----------------------------+-------+

測試半同步複製的方法:
主服務器:
MariaDB [hellodb]> set @@global.rpl_semi_sync_master_enabled=ON;
從服務器:
MariaDB [(none)]> set @@global.rpl_semi_sync_slave_enabled=ON;

正常狀況下,主服務器上進行的全部的數據修改,會當即同步到開啓了半同步負責的從服務器上;

驗證半同步降級的方法:
    在從服務器上,關閉IO_THREAD線程,然後再在主服務器上進行數據修改操做,爲了等待從服務器的同步數據更新,主服務器會阻塞全部的其餘寫操做,直到收到從服務器的確認信息爲止;可是若是超過rpl_semi_sync_master_timeout服務器參數所規定的時間,主服務器仍然沒有收到從服務器數據同步的確認信息,則自動降級爲異步模式;

以上就是mysql/mariadb複製架構得配置,由低及高,從多到少,步步來,求穩。

下面附上覆制過程當中監控及相關的維護操做:
1.二進制日誌的監控和清理:
SHOW MASTER | BINARY LOGS;
SHOW MASTER STATUS;
SHOW BINLOG EVENTS IN 'binlog_file';
PURGE MASTER | BINARY LOGS TO 'log_name' | BEFORE datetimme_expr;

2.複製的監控:
        主服務器:
            SHOW MASTER | BINARY LOGS;
            SHOW MASTER STATUS;
            SHOW BINLOG EVENTS IN 'binlog_file';

        從服務器:
            SHOW SLAVE STATUS\G

    3.判斷主從節點的數據是否一致:
        在建立表時,使用CHECKSUM=1選項,爲此表開啓校驗和功能;
        爲了可以判斷表的校驗和,Percona提供了一個檢測工具:pt_table_checksum;

    4.主從節點數據不一致:
        修復的方法一般有兩種:
            1.刪除數據,從新複製;
            2.將主服務器的數據進行徹底備份,到從服務器上恢復;
相關文章
相關標籤/搜索