MaxScale


Maxscale介紹

MaxScale是maridb開發的一個mysql數據中間件,其配置簡單,能夠實現讀寫分離,並且可以根據主從狀態實現寫庫的自動切換。

注:MaxScale需要MariaDB至少 10.3.1 以上版本的支持,版本過低可能導致部分功能無法使用。

MariaDB MaxScale 2.2版本,在支持原有讀寫分離的基礎上,又添加了主從復制集群管理功能,

MariaDB MaxScale 2.5版本,實現了GUI圖形化、可視化監控管理web頁面。


功能概述

Mariadbmon守護進程,會實時探測主從復制狀態,可以通過執行故障轉移,在線切換和重新加入來修改復制群集。

1)Failover:用最新的slave替換發生故障的master,故障轉移分為Manual Failover和Automatic Failover。在當前已存在的主從復制環境中,MaxScale可以監控master主機故障,並且故障自動轉移。

需要把loss-less無損半同步復制(semi replication)開啟,參數rpl_semi_sync_master_wait_point=AFTER_SYNC,確保slave已經接收到了master的binlog,因為master宕機,MaxScale無法遠程拷貝scp那一缺失的binlog,那么數據就出現不一致了。

2)Switchover:在線主從切換,類似MHA的masterha_master_switch --master_state=alive。

如果機器需要維護,將master角色在線切換到其他主機上(例如更換原master壞掉的硬盤),這並不是master進程崩潰引起的故障轉移。在線切換通常在0.5-2秒左右,並且會阻塞寫(在原master上執行SET GLOBAL read_only=1命令設置全局只讀,且執行FLUSH TABLES把所有的表強制關閉),建議在凌晨業務低峰期執行在線切換。

3)Rejoin:重新加入到新集群作為slave,即死掉的原master如何與提升為新的master建立同步復制關系?由於Maxscale是基於GTID模式的主從復制,全局事務號是唯一的,會自動執行CHANGE MASTER TO NEW_MASTER, MASTER_USE_GTID = current_pos命令,無需人工參與。

(請確保所有MySQL主從節點參數log_slave_updates=ON開啟。)

(注意!Failover以及Switchover和Rejoin僅支持基於GTID的復制一起使用,並且僅適用於簡單的一主多從拓撲架構:即1個master后面跟着多個slave。)


Maxscale架構搭建

實現主從復制,讀寫分離和自動化故障轉移

實驗環境

操作系統: CentOS 7.6

數據庫: mariadb 10.5.5

數據庫代理: maxscale 2.5.4

Maxsclae:172.16.1.51,端口:3306

Master:172.16.1.51,端口:63132

Slave1:172.16.1.41,端口:63132

Slave2:172.16.1.31,端口:63132

集群網絡架構圖

集群網絡架構圖

MariaDB主從復制

MariaDB主從復制是通過二進制日志文件實現,在主服務器上完成所有的寫入操作,通過二進制日志文件,將數據庫改動發送給從服務器。從服務器接受到的二進制日志文件,會轉儲為relay log(中繼日志),然會再在數據庫中重建。
同時需要注意,主從復制集群具有單向性,在從服務器進行的任何寫入操作將不會同步至主服務器上。這個問題將通過 MaxScale 的讀寫分離模塊來解決。
還有一個不在本文范圍的問題,當有多太主服務器時,將會涉及到數據同步問題,很多公司耗費了大量的人力物力都沒法完全解決的文件,MariaDB 支持Galera 集群,這是一個高可用的解決方案,雖然降低了服務器性能,但是保證數據的一致性,可以用在讀取性能要求大於寫入性能的地方。


主服務器配置

設置主服務器(172.16.1.51)配置文件

[root@db01 ~]# cat > /etc/my.cnf.d/mysql-clients.cnf <<EOF
#
# These groups are read by MariaDB command-line tools
# Use it for options that affect only one utility
#

[mysql]

[mysql_upgrade]

[mysqladmin]

[mysqlbinlog]

[mysqlcheck]

[mysqldump]

[mysqlimport]

[mysqlshow]

[mysqlslap]

[mysqld]
# 指定全局唯一服務器ID,ID 可以為 1~65536 的任意一個。
server-id=100

# 指定二進制日志文件名稱,同時會開啟二進制日志文件
# 默認MariaDB使用的是混合二進制日志文件,也就是命令和二進制的數據庫改動將都將記錄到二進制日志中
log-bin=bin-log 

# 指定二進制日志文件的索引位置
log-bin-index=bin-log.index 
# 注意,以上兩個配置指定的文件路徑都是基於 datadir 配置的

# 指定服務器的監聽端口
# 這里我會將MaxScale配置監聽在3306端口上,所以需要修改MariaDB的默認監聽端口
# 如果開啟了SELinux,需要配置監聽在規定的特殊端口上,如果沒有則忽略。
# SELinux規定的監聽端口為:1186,3306,63132-63164
port=63132

# 只保留 30 天內的日志
expire_logs_days=30

# 二進制日志文件格式
binlog-format=ROW
# ROW格式下日志的級別
binlog-row-image=minimal
# 此兩項為打開從服務器崩潰二進制日志功能,信息記錄在事務表而不是保存在文件
master-info-repository=TABLE
relay-log-info-repository=TABLE

innodb_log_file_size=30M
innodb_log_buffer_size=512M
innodb_strict_mode=0
EOF

如果開啟防火牆,配置防火牆規則

firewall-cmd --add-port=63132/tcp --permanent
firewall-cmd --reload

啟動主服務器

systemctl start mariadb
systemctl enable mariadb

設置密碼,更新,進入MariaDB

[root@nfs ~]# mysqladmin password 123
[root@nfs ~]# mysql_upgrade -u root -p 123
Enter password: 123
[root@nfs ~]# mysql -uroot -p123

添加用戶

# 監視賬戶
create user maxscale_monitor@'%' identified by "123456";
GRANT REPLICATION slave,replication client on *.* to maxscale_monitor@'%';
GRANT SUPER, RELOAD on *.* to 'maxscale_monitor'@'%';

# 路由賬戶用於用戶認證
create user maxscale_route@'%' identified by "123456";
GRANT SELECT ON mysql.* TO maxscale_route@'%';
GRANT SHOW DATABASES ON *.* TO maxscale_route@'%';

# 如果主服務器和管理機是一個, 添加這一用戶
GRANT ALL PRIVILEGES ON *.* TO 'maxscale_monitor'@'db01' IDENTIFIED BY '123456' WITH GRANT OPTION;
GRANT REPLICATION slave,replication client on *.* to maxscale_monitor@'db01';
GRANT SUPER, RELOAD on *.* to 'maxscale_monitor'@'db01';
GRANT ALL PRIVILEGES ON *.* TO 'maxscale_route'@'db01' IDENTIFIED BY '123456' WITH GRANT OPTION;
GRANT SELECT ON mysql.* TO maxscale_route@'db01';
GRANT SHOW DATABASES ON *.* TO maxscale_route@'db01';

# 刷新
flush privileges;

從服務器配置

設置從服務器(172.16.1.31和172.16.1.41)配置文件

[root@nfs ~]# cat > /etc/my.cnf.d/mysql-clients.cnf <<EOF
#
# These groups are read by MariaDB command-line tools
# Use it for options that affect only one utility
#

[mysql]

[mysql_upgrade]

[mysqladmin]

[mysqlbinlog]

[mysqlcheck]

[mysqldump]

[mysqlimport]

[mysqlshow]

[mysqlslap]

[mysqld]
# 注意,服務器ID必須為全局唯一
server-id=200

log-bin=bin-log 
log-bin-index=bin-log.index 

# 配置將中繼日志文件轉儲至relay-log中
# 可以不配置中繼日志,當服務器以從模式運行時,將會自動開啟
relay-log=relay-log
# 指定 relay 日志的索引文件。
relay-log-index=relay-log.index
# 指定從服務器默認為只讀模式,禁止任何寫入操作
read-only=ON
# 只保留 30 天內的日志
expire_logs_days=30
port=63132

innodb_log_file_size=30M
innodb_log_buffer_size=512M
innodb_strict_mode=0
EOF
[root@backup ~]# cat > /etc/my.cnf.d/mysql-clients.cnf <<EOF
#
# These groups are read by MariaDB command-line tools
# Use it for options that affect only one utility
#

[mysql]

[mysql_upgrade]

[mysqladmin]

[mysqlbinlog]

[mysqlcheck]

[mysqldump]

[mysqlimport]

[mysqlshow]

[mysqlslap]

[mysqld]
# 注意,服務器ID必須為全局唯一
server-id=300

log-bin=bin-log 
log-bin-index=bin-log.index 

# 配置將中繼日志文件轉儲至relay-log中
# 可以不配置中繼日志,當服務器以從模式運行時,將會自動開啟
relay-log=relay-log
# 指定 relay 日志的索引文件。
relay-log-index=relay-log.index
# 指定從服務器默認為只讀模式,禁止任何寫入操作
read-only=ON
# 只保留 30 天內的日志
expire_logs_days=30
port=63132

innodb_log_file_size=30M
innodb_log_buffer_size=512M
innodb_strict_mode=0
EOF

如果開啟防火牆,配置防火牆規則

firewall-cmd --add-port=63132/tcp --permanent
firewall-cmd --reload

啟動從服務器

systemctl start mariadb
systemctl enable mariadb

設置密碼,更新,進入MariaDB

[root@nfs ~]# mysqladmin password 123
[root@nfs ~]# mysql_upgrade -u root -p 123
Enter password: 123
[root@nfs ~]# mysql -uroot -p123

添加用戶

# 監視賬戶
create user maxscale_monitor@'172.16.1.%' identified by "123456";
grant replication slave,replication client on *.* to maxscale_monitor@'172.16.1.%';
GRANT SUPER, RELOAD on *.* to 'maxscale_monitor'@'172.16.1.%';
# 路由賬戶
create user maxscale_route@'172.16.1.%' identified by "123456";
GRANT SELECT ON mysql.* TO maxscale_route@'172.16.1.%';
GRANT SHOW DATABASES ON *.* TO maxscale_route@'172.16.1.%';

GRANT SELECT ON mysql.* TO root@'%';
GRANT SHOW DATABASES ON *.* TO root@'%';

# 刷新
flush privileges;

配置主服務器(172.16.1.51)指向

# 注意一定不要設置Master_Log_File,當主服務器切換記錄二進制日志文件時,從服務器將無法切換到對應的文件。留空將會自動進行配置。
CHANGE MASTER TO MASTER_HOST='172.16.1.51', MASTER_PORT=63132, MASTER_USER='maxscale_monitor', MASTER_PASSWORD='123456', MASTER_USE_GTID=current_pos;

啟動從狀態

MariaDB [(none)]> START SLAVE;

查詢從節點狀態信息

MariaDB [(none)]> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
                Slave_IO_State: Waiting for master to send event
                   Master_Host: 172.16.1.51
                   Master_User: maxscale_monitor
                   Master_Port: 63132
                 Connect_Retry: 60
               Master_Log_File: bin-log.000001
           Read_Master_Log_Pos: 326
                Relay_Log_File: relay-log.000002
                 Relay_Log_Pos: 623
         Relay_Master_Log_File: bin-log.000001
              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: 326
               Relay_Log_Space: 926
               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: 100
                Master_SSL_Crl: 
            Master_SSL_Crlpath: 
                    Using_Gtid: Current_Pos
                   Gtid_IO_Pos: 0-200-2970
       Replicate_Do_Domain_Ids: 
   Replicate_Ignore_Domain_Ids: 
                 Parallel_Mode: optimistic
                     SQL_Delay: 0
           SQL_Remaining_Delay: NULL
       Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
              Slave_DDL_Groups: 0
Slave_Non_Transactional_Groups: 0
    Slave_Transactional_Groups: 0
1 row in set (0.000 sec)

管理機配置

安裝

yum install libaio libaio-devel novacom-server libedit -y
rpm -ivh https://dlm.mariadb.com/1160524/MaxScale/2.5.4/yum/centos/7/x86_64/maxscale-2.5.4-1.rhel.7.x86_64.rpm
# 或者
wget https://dlm.mariadb.com/1160524/MaxScale/2.5.4/yum/centos/7/x86_64/maxscale-2.5.4-1.rhel.7.x86_64.rpm
yum -y install maxscale-2.5.4-1.rhel.7.x86_64.rpm

配置文件

[root@db01 ~]# cat > /etc/maxscale.cnf <<EOF
# MaxScale documentation:
# https://mariadb.com/kb/en/mariadb-maxscale-24/

# Global parameters
#
# Complete list of configuration options:
# https://mariadb.com/kb/en/mariadb-maxscale-24-mariadb-maxscale-configuration-guide/

# 全局模塊
[maxscale]
# 開啟線程個數,默認為1.設置為auto會同cpu核數相同
threads=auto
# timestamp精度
ms_timestamp=1
# 記錄info
log_info=1
# 日志遞增
log_augmentation=1
# 打開GUI圖形管理頁面
admin_host=0.0.0.0
# 不設置HTTPS服務
admin_secure_gui=false

# Server definitions
#
# Set the address of the server to the network
# address of a MariaDB server.
#

# 主機模塊
[server1]
type=server
# 指定服務器的unix socket路徑
# 如果 MaxScale 和 MariaDB 在同一台主機上,可以使用這種方法連接
# 注意,socket 與 address/port 沖突,只能選其一。
# 同時需要注意 MariaDB 的權限配置。
#socket=/var/lib/mysql/mysql.sock 
address=172.16.1.51
port=63132
protocol=MariaDBBackend

[server2]
type=server
address=172.16.1.41
port=63132
protocol=MariaDBBackend

[server3]
type=server
address=172.16.1.31
port=63132
protocol=MariaDBBackend

# Monitor for the servers
#
# This will keep MaxScale aware of the state of the servers.
# MariaDB Monitor documentation:
# https://mariadb.com/kb/en/mariadb-maxscale-24-mariadb-monitor/

# 故障轉移監控模塊
[MariaDB-Monitor]
type=monitor
# 核心監控模塊
module=mariadbmon
servers=server1,server2,server3
user=maxscale_monitor
password=123456
# 每隔2秒探測一次
monitor_interval=2000
# 打開自動故障轉移
auto_failover=true
# 打開自動重新加入
auto_rejoin=true
# slave 全部失效時 master 支撐全部請求
detect_stale_master=true

# Service definitions
#
# Service Definition for a read-only service and
# a read/write splitting service.

# ReadWriteSplit documentation:
# https://mariadb.com/kb/en/mariadb-maxscale-24-readwritesplit/

# 服務模塊
# 讀寫分離,基於statement SQL解析的方式
[Read-Write-Service]
type=service
router=readwritesplit
router_options=master,slave
servers=server1,server2,server3
# 默認禁止root用戶訪問,設置為1開啟
enable_root_user=1
# 路由賬號用於讀寫分離
user=maxscale_route
password=123456
# 當主服務器掛了時,客戶端的寫入操作將會返回錯誤,服務器以只讀模式運行。
# 如果沒有設置此值,那么當客戶端執行寫入操作時,MaxScale將會直接斷開連接。
master_failure_mode=error_on_write
# 配合上一個選項取消只讀模式,客戶端的寫入請求將會被重新處理。
master_reconnection=true

# 默認讀是不被路由到master,設置為true允許master用於讀取
#master_accept_reads=true
# 設置路由器會話隨時使用的最大從站數量
#max_slave_connections=2
#auth_all_servers=true
# 身份驗證失敗和警告的日志記錄,記錄那些試圖連接到MaxScale和來自哪里
#log_auth_warnings=true 
# 強制select走master
#filters=Hint  
#允許slave落后master多少秒
#max_slave_replication_lag=3600

# Listener definitions for the services
#
# These listeners represent the ports the
# services will listen on.
#

[Read-Write-Listener]
type=listener
service=Read-Write-Service
protocol=MariaDBClient
# 一定要指定!! 默認綁定IPv6
address=0.0.0.0
port=3306
EOF

啟動

systemctl start maxscale
systemctl enable maxscale

錯誤日志

tailf /var/log/maxscale/maxscale.log

使用MaxCtrl檢查MaxScale狀態

[root@db01 ~]# maxctrl list services
┌────────────────────┬────────────────┬─────────────┬───────────────────┬───────────────────────────┐
│ Service            │ Router         │ Connections │ Total Connections │ Servers                   │
├────────────────────┼────────────────┼─────────────┼───────────────────┼───────────────────────────┤
│ Read-Write-Service │ readwritesplit │ 1           │ 1                 │ server1, server2, server3 │
└────────────────────┴────────────────┴─────────────┴───────────────────┴───────────────────────────┘
[root@db01 ~]# maxctrl list servers
┌─────────┬─────────────┬───────┬─────────────┬─────────────────┬──────┐
│ Server  │ Address     │ Port  │ Connections │ State           │ GTID │
├─────────┼─────────────┼───────┼─────────────┼─────────────────┼──────┤
│ server1 │ 172.16.1.51 │ 63132 │ 1           │ Master, Running │      │
├─────────┼─────────────┼───────┼─────────────┼─────────────────┼──────┤
│ server2 │ 172.16.1.41 │ 63132 │ 1           │ Slave, Running  │      │
├─────────┼─────────────┼───────┼─────────────┼─────────────────┼──────┤
│ server3 │ 172.16.1.31 │ 63132 │ 1           │ Slave, Running  │      │
└─────────┴─────────────┴───────┴─────────────┴─────────────────┴──────┘
[root@db01 ~]# maxctrl list listeners Read-Write-Service
┌─────────────────────┬──────┬──────┬─────────┬────────────────────┐
│ Name                │ Port │ Host │ State   │ Service            │
├─────────────────────┼──────┼──────┼─────────┼────────────────────┤
│ Read-Write-Listener │ 3306 │ ::   │ Running │ Read-Write-Service │
└─────────────────────┴──────┴──────┴─────────┴────────────────────┘

查看主從復制集群狀態信息

maxctrl list services

image-20201008172021372

查看服務狀態信息

maxctrl list servers

image-20201008172032639

查看服務監聽狀態信息

maxctrl list listeners Read-Write-Service

image-20201008172044403

通過GUI WEB圖形頁面訪問http://172.16.1.51:8989查看,登錄名admin,密碼mariadb:

image-20201010201025497

主從復制測試

讀寫分離測試

  1. 先在 master 上創建一個測試用戶
create user 'root'@'%' identified by '123';
grant ALL PRIVILEGES on *.* to 'rtest'@'%';
  1. 使用 Mysql 客戶端到連接 MaxScale
mysql -uroot -p'123' -h'172.16.1.51' -P3306

查看數據庫服務器名確認當前所在數據庫

MariaDB [(none)]> Select @@hostname;
+------------+
| @@hostname |
+------------+
| nfs        |
+------------+
1 row in set (0.002 sec)

MariaDB [(none)]> start transaction;
Query OK, 0 rows affected (0.002 sec)

MariaDB [(none)]> Select @@hostname;
+------------+
| @@hostname |
+------------+
| db01       |
+------------+
1 row in set (0.002 sec)

MariaDB [(none)]> rollback;
Query OK, 0 rows affected (0.002 sec)

MariaDB [(none)]> Select @@hostname;
+------------+
| @@hostname |
+------------+
| backup     |
+------------+
1 row in set (0.002 sec)

故障轉移測試

slave故障轉移

在 slave 發生故障時,MaxScale 可以自動識別出來,並移除路由列表,當故障恢復重新上線后,MaxScale 也能自動將其加入路由,過程透明。

# 首先先檢查以下服務器
maxctrl list servers
# 手動關閉主服務器
systemctl stop mariadb
# 再次查看服務器
# 注意,這里需要稍微等待以下大概2~4秒,並不是立即生效的
maxctrl list servers
# 這里再重新啟動服務器,看看是否會重新加入
systemctl start mariadb
# 注意,從服務器默認並沒有設置 gtid_binlog_pos 值,當提升為主服務器時,此時其余的服務器
# 並不會指向該服務器(也就是server2),需要在server2上提交一個事務才能生成 gtid_binlog_pos
# 值,其余服務器才能將主服務器指向該 server2。如果 server2 已經設置了 gtid_binlog_pos
# 那么將不會有這些問題。這里我們可以先查看以下服務器狀態:
maxctrl list servers
# 當我們向 MaxScale 提交事務后,就可以正常使用了。
mysql -uroot -p123 -P63132 -h172.16.1.41 -e'create table test (id int)' somata
# 此時我們再查看server1服務器狀態,它就會發生改變了
# 同時我們也能發現,GTID也發送了改變
maxctrl list servers
# 如果有需求,可以使用命令將主服務器重新遷移回 server1
maxctrl call command mariadbmon switchover MariaDB-Monitor server1 server2
# 再次查看服務器
maxctrl list servers

場景一:Automatic Failover故障轉移

Failover細節:

1)選擇最新的slave作為master,依照以下順序標准排列:

  1. gtid_IO_pos(中繼日志中的最新事件)。
  2. gtid_current_pos(處理最多的事件)。
  3. log_slave_updates已開啟。
  4. 磁盤空間不低。
  5. 如果以上條件都滿足,按照maxscale.cnf主機模板的順序進行故障轉移,例如server2掛了,將切換到server3上,依次類推。

2)如果最新的slave具有未處理的中繼日志,會根據參數failover_timeout=90等待90秒,超過90秒數據未同步完,則關閉故障轉移。通過判斷gtid_binlog_pos和gtid_current_pos值是否相等。

3)准備新的master

① 在最新的slave上,關閉復制進程執行命令:

SET STATEMENT max_statement_time=1 FOR STOP SLAVE;

並清空同步復制信息執行命令。

SET STATEMENT max_statement_time=1 FOR RESET SLAVE ALL;

② 在最新的slave上,關閉只讀read_only 執行命令。

SET STATEMENT max_statement_time=1 FOR SET GLOBAL
read_only=0

③ 在最新的slave上,啟用EVENT事件(MySQL定時任務)。

④ 接收客戶端讀寫請求。

4)重定向所有slave指向新的master進行同步復制

① 停止同步復制,執行命令

SET STATEMENT max_statement_time=1 FOR STOP SLAVE

② 指向新的master進行復制,執行命令

SET STATEMENT

max_statement_time=1 FOR CHANGE MASTER '' TO

MASTER_HOST = '127.0.0.1', MASTER_PORT = 3314,

MASTER_USE_GTID = current_pos, MASTER_USER = 'admin',

MASTER_PASSWORD = '123456'

③ 開啟同步復制,執行命令

SET STATEMENT max_statement_time=1 FOR START SLAVE

5)檢查所有slave復制是否正常,執行命令SHOW ALL SLAVES STATUS判斷Slave_IO_Running和Slave_SQL_Running值是否都為雙Yes。

場景二:Manual Failover故障轉移

通過以下命令可以實現手工故障切換:

# maxctrl call command mariadbmon failover MariaDB-Monitor

這里的切換細節跟自動故障轉移是一樣的

場景三:Switchover在線平滑切換

目前的主是server1,從是server2。

通過以下命令可以實現在線切換:

# maxctrl call command mariadbmon switchover MariaDB-Monitor server2 server1

注:server2代表即將成為新的master,server1代表是原來舊的master。

Switchover細節

准備降級的舊master:

1)在舊的master上,開啟只讀read_only 執行命令。

SET STATEMENT max_statement_time=1 FOR SET GLOBAL

read_only=1禁止數據寫入。

2)終止SUPER權限超級用戶的連接,通過以下命令找到超級用戶連接Id:

SELECT DISTINCT * FROM (SELECT P.id,P.user FROM

information_schema.PROCESSLIST as P INNER JOIN mysql.user

as U ON (U.user = P.user) WHERE (U.Super_priv = 'Y' AND

P.COMMAND != 'Binlog Dump' AND P.id != (SELECT

CONNECTION_ID()))) as tmp;

然后執行KILL命令,因為read_only只讀不影響SUPER權限超級用戶更改數據。

3)執行FLUSH TABLES把所有表強制關閉。

4)執行FLUSH LOGS刷新二進制日志,以便所有binlog都刷到磁盤上。

5)在舊master上執行:SELECT @@gtid_current_pos, ,@@gtid_binlog_pos記錄gtid事務號。

在新master上執行:SELECT MASTER_GTID_WAIT('GTID');如果執行結果都為0,表示已經完成數據同步,可以進行下一步切換,否則需要一直等待完成。

6)后面的步驟跟故障轉移一樣。

MaxScale配置詳解

創建用戶

注意: 每個數據庫上創建相同的帳戶

創建MaxScale用戶帳戶

MaxScale檢查傳入的客戶端是否有效。為此,MaxScale需要從后端數據庫檢索用戶身份驗證信息。為此,您可以在數據庫集群的主服務器上執行以下SQL命令來創建一個特殊的用戶帳戶。

CREATE USER 'maxscale'@'%' IDENTIFIED BY 'maxscale_password';
GRANT SELECT ON mysql.user TO 'maxscale'@'%';
GRANT SELECT ON mysql.db TO 'maxscale'@'%';
GRANT SELECT ON mysql.tables_priv TO 'maxscale'@'%';
GRANT SELECT ON mysql.columns_priv TO 'maxscale'@'%';
GRANT SELECT ON mysql.proxies_priv TO 'maxscale'@'%';
GRANT SELECT ON mysql.roles_mapping TO 'maxscale'@'%';
GRANT SHOW DATABASES ON *.* TO 'maxscale'@'%';
# 創建用於用戶認證的用戶
CREATE USER 'maxscale'@'172.16.1.%' IDENTIFIED BY '123456';
# 授權對 mysql 數據庫的SELECT權限
GRANT SELECT ON `mysql`.* TO 'maxscale'@'172.16.1.%';
# 授予 SHOW DATABASES 權限
GRANT SHOW DATABASES ON *.* TO 'maxscale'@'172.16.1.%';
# 創建用於服務監控的用戶
CREATE USER 'maxscale_mon'@'172.16.1.%' IDENTIFIED BY '123456';
# 給予復制權限,用於復制服務器狀態類信息。
GRANT REPLICATION CLIENT ON *.* TO 'maxscale_mon'@'172.16.1.%'; 

創建客戶用戶帳戶

由於MariaDB MaxScale位於客戶端和后端數據庫之間,因此后端數據庫將看到所有客戶端,就好像它們是從MaxScale的地址進行連接一樣。這通常意味着每個用戶需要兩組授予。

例如,假設用戶'jdoe'@'client-host'存在並且MaxScale位於 maxscale-host。如果'jdoe'@'client-host'需要能夠通過MaxScale連接,則必須創建另一個用戶'jdoe'@'maxscale-host'。第二個用戶必須具有與'jdoe'@'client-host'相同的密碼和相似的授權。

最快的方法是首先創建新用戶:

CREATE USER 'jdoe'@'maxscale-host' IDENTIFIED BY 'my_secret_password';

然后執行SHOW GRANTS查詢:

MariaDB [(none)]> SHOW GRANTS FOR 'jdoe'@'client-host';
+-----------------------------------------------------------------------+
| Grants for jdoe@client-host                                           |
+-----------------------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO 'jdoe'@'client-host'   |
+-----------------------------------------------------------------------+
1 row in set (0.01 sec)

然后將相同的授權復制給'jdoe'@'maxscale-host'用戶。

GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO 'jdoe'@'maxscale-host';

生成兩個單獨帳戶的一種替代方法是使用一個具有通配符主機('jdoe'@'%')的帳戶,該主機覆蓋兩個主機。這比擁有特定的用戶帳戶更為方便,但安全性較低,因為它允許所有主機進行訪問。

# 創建一個用戶測試的用戶。
CREATE USER 'client'@'172.16.1.%' IDENTIFIED BY '123456';
# 創建一個測試用數據庫
CREATE DATABASE somata;
# 授權所有權限
GRANT ALL ON somata.* TO 'client'@'172.16.1.%';

密碼加密

主要是為了防止配置文件泄露導致密碼暴露。

創建密鑰文件

maxkeys

密鑰文件默認存放在/var/lib/maxscale/.secrets

創建加密密碼

maxpasswd 123456

注:如果不想在配置文件中使用加密的密碼,則需要刪除 .secrets 文件。

配置文件參數詳解:

① 故障轉移監控模板

[MariaDB-Monitor]

auto_failover=true

#打開自動故障轉移,false為關閉,需要人工執行命令去做故障轉移,通常為true。

auto_rejoin=true

#打開自動重新加入,false為關閉,需要人工執行CHANGE MASTER TO NEW_MASTER, MASTER_USE_GTID = current_pos命令,通常為true。

failcount=3

# 3次連接失敗,認定主庫down掉,開始啟動故障轉移,默認是5次嘗試。

failover_timeout=90

# 假定slave庫有延遲,在默認90秒時間內,沒有同步完,自動關閉故障轉移。通常默認值即可。

switchover_timeout=90

# 假定slave庫有延遲,在默認90秒時間內,沒有同步完,自動關閉在線切換。通常默認值即可。

verify_master_failure=true

# 當Maxscale連接不上master時,開啟其他slave再次驗證master是否故障。這樣的好處是:防止網絡抖動誤切換(腦裂),造成數據不一致,其實現原理為:投票機制,當Maxscale無法連接MySQL主庫,會試圖從其他slave機器上去連接MySQL主庫,只有雙方都連接失敗,才認定MySQL主庫宕機。假如有一方可以連接MySQL主庫,都不會切。

類似MHA的masterha_secondary_check命令二次檢查,默認開啟,無需關閉。

master_failure_timeout=10

# 這個參數依賴於verify_master_failure,當開啟后,從庫在默認10秒內無法連接master,認定主庫down掉。通常默認值即可。

② 服務模板

這里我們要定義一個服務,路由選擇讀寫分離模塊。你可以分離一部分select讀取操作到slave從庫上。它是基於statement的,解析SQL語句。在這里前端程序不需要修改代碼,通過MaxScale對SQL語句解析,把讀寫請求自動路由到后端數據庫節點上,從而實現讀寫分離。開源Percona ProxySQL中間件也是基於statement方式實現讀寫分離。

[Read-Write-Service]

master_accept_reads=true

# 如果你擔心數據有延遲,擔心數據准確性問題,可以設置在主庫上查詢。默認讀是不被路由到master,設置為true允許master用於讀取。

max_slave_connections=2

# 允許兩個slave進行讀取

max_slave_replication_lag=1

# 定義超過延遲1秒,把請求轉發給master

causal_reads=local

# 由於Maxscale通過參數monitor_interval=2000,每隔2秒探測一次,可能存在主從延遲檢測不到的情況。

例如主庫上寫入了一條數據,從庫還沒來得寫入該記錄。那么可以通過設置causal_reads=local,此時客戶端在從庫上查詢會hang住,直至等待causal_reads_timeout=10,默認10秒,超時后請求會強制轉發給master。

# 全局配置段,配置MaxScale服務器的運行參數

[maxscale]
threads=auto

# 以下的所有段落為MaxScale對外提供服務所需要的參數
# 注意“節”名稱不能包含空格,如有需要可以使用-/_代替。
# 各個“節”有不同的作用,MaxScale根據type參數來判斷各個“節”是干什么的,
# 而不是根據“節”的名稱來判斷的。
# 這里這個配置文件一共有四個type: server(后端服務器)
# monitor(監控), service(服務,可以理解為路由)
# listener(監聽器,由於對外提供服務)
[server1] # 指定服務器一的配置
type=server
address=10.0.0.101 # 指定服務器地址
port=63132 # 指定服務器端口
# socket=/var/lib/mysql/mysql.sock # 指定服務器的unix socket路徑
# 如果 MaxScale 和 MariaDB 在同一台主機上,可以使用這種方法連接
# 不過需要注意,socket 用法與 address/port 是沖突的,只能選其一。
# 同時需要注意 MariaDB 的權限配置。
protocol=MariaDBBackend # 指定連接使用的協議。
# 這里使用的是 MariaDBBackend 是 MariaDB 開發的特殊協議,
# 可以加快 MaxScale 訪問 MariaDB 的訪問速度。

[server2]
type=server
address=10.0.0.102
port=3306
protocol=MariaDBBackend

[server3]
type=server
address=10.0.0.103
port=3306
protocol=MariaDBBackend

[MariaDB-Monitor]
type=monitor
module=mariadbmon # 指定啟用模塊 mariadbmon
# 此模塊為監控模塊,針對 MariaDB 服務器使用的監控模塊,基礎功能是用於監控服務器的健康狀態的。
# 同時此模塊能判斷主從,當主服務器發生故障時還能完成自動化故障轉移的操作,當然這些功能需要
# 手動開啟,這些會在后面說明的。
# 這些模塊都是以 so 形式保存在 /usr/lib64/maxscale/ 目錄中的。
# 注: 主服務器一定要確保關閉 read_only,否則將判定主服務器是一個不可用的服務器,這將導致整個集群不可用。
servers=server1,server2,server3 # 指定需要對哪些服務器進行監控
# 這里的 server1,server2,server3 與上面的后端服務器“節”名稱對應。
user=maxscale # 指定監控使用的用戶
password=111E15EBF48383FE639F9E134A956826 # 指定密碼
# 這里就是經過加密的密碼,密碼為123456。
monitor_interval=2000ms # 指定監控間隔事件這里是2秒

[Read-Write-Service]
type=service
router=readwritesplit # 指定啟用模塊,readwritesplit
# 注意雖然前面寫的是router,但是后面跟的還是模塊名稱。
# 此模塊為路由模塊,用於讀寫分離使用,它同通過監控模塊獲取服務器主從信息,自動完成讀寫分離。
# 它會將所有讀取類操作都優先分發給從服務器使用,而寫入類操作全部發送給主服務器,
# 修改變量類的操作將發送到所有服務器。
servers=server1,server2,server3
user=maxscale
# 注意,這里填寫的用戶是用來進行用戶認證的。
password=111E15EBF48383FE639F9E134A956826

[Read-Write-Listener]
type=listener
service=Read-Write-Service
# 這里指定的服務,需要與上面對應。
protocol=MariaDBClient
# 指定協議 MariaDBClient 也就是 MySQL 協議。
port=3306
# 指定端口
# 可以使用 UNIX 套接字,而不是端口監聽。
# socket=default
# 默認 UNIX sock 路徑為 /var/run/maxscale/maxscale.sock
# 注意 socket 和 port 是沖突的。

MaxScale 自動化故障轉移

GTID(全局事務ID),由域ID(默認值為0,可以通過gtid_domain_id變量來進行修改)、服務器ID和事務事務ID組成的的全局唯一標識符,例如:0-100-22。

設立全局事務ID的目的是為了保證數據的高可用性,能非常輕松的實現中斷恢復,而不用擔心數據會有遺漏的問題,因為每一個事務都會標有一個全局唯一的GTID(記錄在二進制日志文件中),只需要從對應的GTID開始恢復即可。

注:MariaDB默認開啟了GTID功能,當有事務提交時,將會生成全局唯一的GTID。

因為 MaxScale 會通過監控模塊完成進行故障轉移操作,所以需要給予'maxscale_monitor'@'10.0.0.%' SUPER 和 RELOAD 權限。

GRANT SUPER, RELOAD ON *.* TO 'maxscale_monitor'@'172.16.1.%';

從服務器需要開啟二進制日志。

當主服務器掛了時,將會挑選一台從服務器提升主服務器使用,此時就需要使用二進制日志功能了。

從服務器可以選擇開啟read_only,MaxScale 會自動檢測該值,當需要將從服務器提升未主服務器時,會自動關閉該屬性。

三台數據庫修改服務配置文件:

[root@nfs ~]# cat > /etc/my.cnf.d/mysql-clients.cnf <<EOF

……
log-bin=bin-log
log-bin-index=bin-log.index
relay-log=relay-log
# 可選配置,MariaDB以從服務器運行時,將會開啟。
relay-log-index=relay-log.index
# 上同
server-id=100 #注意不要使用相同的服務器ID號。
……

編輯MaxScale的配置文件

# file: /etc/maxscale.cnf

……
[MariaDB-Monitor]
type=monitor
module=mariadbmon
servers=server1,server2,server3
user=maxscale_mon
password=111E15EBF48383FE639F9E134A956826
monitor_interval=2000ms
# 指定復制用戶的用戶名和密碼
# 如果未指定,將使用user和password
replication_user=maxscale_mon
replication_password=111E15EBF48383FE639F9E134A956826
# 指定開啟自動故障轉移
auto_failover=true
# 指定開啟自動加入集群(將以從服務器模式加入)
auto_rejoin=true
……
[Read-Write-Service]
type=service
router=readwritesplit
servers=server1,server2,server3
user=maxscale
password=111E15EBF48383FE639F9E134A956826
# 當主服務器掛了時,客戶端的寫入操作將會返回錯誤,服務器以只讀模式運行。
# 如果沒有設置此值,那么當客戶端執行寫入操作時,MaxScale將會直接斷開連接。
master_failure_mode=error_on_write
# 當此選項啟用時,並且master_failure_mode 設置為 fail_on_write|error_on_write 時,
# 將會取消只讀模式,客戶端的寫入請求將會被重新處理。
master_reconnection=true
……

配置從服務器使用GTID,兩台從服務器使用相同的命令即可:

# 停止從服務器
stop slave;
# 重置從服務器
reset slave;
# 配置指定主服務器,注意,這里指定主服務器使用GTID MASTER_USE_GTID=current_pos
# MASTER_USE_GTID一個有三個可選項 slave_pos、current_pos、no
# slave_pos 選項將使用 gtid_slave_pos 變量指定的值
# current_pos 選項將使用 gtid_current_pos 變量指定的值
# 注意,gtid_current_pos、gtid_binlog_pos值是只讀的
# gtid_current_pos 值是 gtid_binlog_pos 和 gtid_slave_pos 兩個變量的並集
# gtid_binlog_pos 當服務器有事務提交時將設置該變量
CHANGE MASTER TO MASTER_HOST='172.16.1.51', MASTER_PORT=63132, MASTER_USER='maxscale_monitor', MASTER_PASSWORD='123456', MASTER_USE_GTID=current_pos;
# 啟動從服務器
start slave;
# 注意,如果再從服務器上面提交了事務,那么它會產生 gtid_binlog_pos,這將有可能
# 導致 gtid_current_pos,需要使用以下命令來重置它:
# 注意,這樣同時會重置二進制日志文件,需要謹慎使用。
# 重啟 maxscale 服務器:
reset master;

MaxScale 遠程管理使用

MaxScale 開發了新的管理接口(reset API),使用了HTTP協議,用戶認證也將基於 HTTP 協議完成。如果需要基於 MaxScale 做開發也就會變得更加方便,同時新的管理工具 maxctrl 也使用了該接口,老版的管理工具 maxadmin 和 API 由於在安全方面存在問題即將被廢棄。
由於使用HTTP協議,所以可以MaxScale也支持 HTTPS,同時為了增強安全性,也開啟了證書的雙向認證。也就是說當客戶端連接服務器時需要提供客戶端的公鑰用於認證客戶端是否有效,客戶端也將驗證服務器證書,當然前提是這些證書都必須由同一CA頒發的,否者將無法完成認證。

默認 MaxScale 就開啟了reset API,現在創建一下證書文件,然后配置 MaxScale 使用證書即可。

# 首先是創建CA服務的證書文件
mkdir -p /etc/pki/CA/private
mkdir /etc/pki/CA/newcerts
cd /etc/pki/CA
openssl genrsa -out private/cakey.pem 2048
openssl req -new -x509 -key private/cakey.pem -out cacert.pem # 這里的證書創建過程就省略不寫了。
# 不過需要注意的是,必須要保證后面服務器證書申請的開頭部分必須與證書開頭相同,否則無法通過CA簽發證書。
# 同時需要注意,頒發的服務器名稱(commonName)需要與主機名稱(FQDN)對應,必須要能解析到。
touch index.txt
echo "01" > serial
# 創建 MaxScale 服務器證書
cd /var/lib/maxscale/
openssl genrsa -out maxscale.key 2048
openssl req -new -key maxscale.key -out maxscale.csr
openssl ca -in maxscale.csr -out maxscale.crt -days 365
# 創建客戶端證書
mkdir ~/.cert/
cd ~/.cert/
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr
openssl ca -in client.csr -out client.crt -days 365
配置 MaxScale 使用證書:

[maxscale]
threads=auto
admin_host=0.0.0.0
# 指定監聽 0.0.0.0, 默認監聽 127.0.0.1
admin_port=8989
# 指定監聽端口,默認就是 8989
admin_ssl_key=/var/lib/maxscale/maxscale.key
# 指定服務器密鑰
admin_ssl_cert=/var/lib/maxscale/maxscale.crt
# 指定服務器公鑰
admin_ssl_ca_cert=/etc/pki/CA/cacert.pem
# 指定CA證書
# 注意,只有以上三個參數都配置了,HTTPS 才會生效,並且將強制使用HTTPS
……
這里偷個懶,在 hosts 文件中編寫主機名,最好是在DNS中配置,方便管理。

# file: /etc/hosts

……
10.0.0.101 server1 # 注意,這里我使用的主機名為 server1
# 如果使用不同的主機名需要手動修改。
然后再重新測試軟件

systemctl restart maxscale # 重啟服務器,使配置生效
# 測試是否可用
maxctrl -s --tls-key /root/.cert/client.key --tls-cert /root/.cert/client.crt --tls-ca-cert /etc/pki/CA/cacert.pem -h server1:8989 list servers
# 注意,一定要使用主機名,而不是IP地址,client會檢測證書是否與主機名對應,這也就是為什么需要配置 hosts 的原因。

maxctrl SSL 連接

maxctrl 簡易用法
maxctrl 使用方法:

maxctrl [OPTIONS] [COMMAND]
注:maxctrl 如果不指定 COMMAND 將會進入交互式,在交互式中可以直接輸入
COMMAND 即可,不過由於未知原因,當啟用 HTTPS 時,將無法使用交互式執行命令。
這些應該會在后續的更新中修復。

OPTIONS:
-u --user 指定用戶
-p --password 指定用戶密碼
-h --hosts 指定主機
-t --timeout 指定超時時間 [單位:毫秒]
-q --quiet 靜默輸出,將不輸出任何參數。
--tsv 使用 TAB 作為分隔符
-s --secure 指定啟用 HTTPS 請求 [Bool 默認: false]
--tls-key 指定連接使用的私鑰
--tls-passphrase 指定連接使用的私鑰密碼
--tls-cert 指定連接使用的公鑰
--tls-ca-cert 指定CA公鑰
-n --tls-verify-server-cert 檢測服務器證書是否有效 [Bool 默認: true]
--version 顯示軟件版本包
--help 查詢幫助信息

COMMAND:
# 以表格格式顯示基礎信息
list servers # 顯示所有后端服務器
list services # 顯示所有服務,例如讀寫分離服務等
list monitors # 顯示所有監控信息
list listeners # 顯示監聽信息
list threads # 顯示線程
list modules # 顯示模塊
list sessions # 顯示所有用戶進程
list commands # 顯示所有模塊的可用指令
# 在以上的基礎上顯示更加詳細的服務信息
show servers # 顯示所有后端服務器的詳細信息
show server # 顯示后端服務器的詳細信息
show service # 顯示服務的詳細信息
show services # 顯示所有服務的詳細信息
show monitor # 顯示監控的詳細信息
show monitors # 顯示所有監控的詳細信息
show session # 顯示用戶進程信息
show sessions # 顯示所有用戶進程信息
show module # 顯示模塊的詳細信息
show modules # 顯示所有模塊的詳細信息
# 對 MaxScale 做出修改類的命令,注意如果做出了修改,那么將會永久成效,默認配置文件 /etc/maxscale.cnf 中的沖突部分將不再生效。
# 實際上做出了修改之后,maxscale 的配置會存放至 /var/lib/maxscale/maxscale.cnf.d/ 目錄下。
clear server # 清除服務的指定屬性,例如 Maintenance(維護模式)
drain server # 等待指定服務的所有鏈接線程結束,會將服務器標注為維護模式(Maintenance),新的連接將不會發送給該服務器。
destroy server # 銷毀指定的服務器,指定服務器必須斷開service和monitor連接
link service # 指定后端服務器連接 服務。
link monitor # 指定后端服務器連接 監控
unlink service # 指定斷開服務與后端服務器的鏈接
unlink monitor # 指定斷開監控與后端服務器的鏈接
create user # 創建一個用戶,默認用戶具有只讀權限,如果想要創建為管理員用戶可以添加參數 --type=admin
destroy user # 刪除一個用戶

注:這里只是其中的一些命令,詳細可以去查看官方文檔。

SQL常用命令

# 導入數據庫
mysql -uroot -p123  < /tmp/mysql-all.sql

# 導出數據庫
mysqldump -uroot -p123 -A > /tmp/mysql-all.sql
# 查看MYSQL數據庫中所有用戶
SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM mysql.user;

# 查看數據庫中具體某個用戶的權限
show grants for 'zabbix'@'%';
select * from mysql.user where user='zabbix' \G

# 查看user表結構 需要具體的項可結合表結構來查詢
desc mysql.user;

# 創建數據庫
create database zabbix character set utf8 collate utf8_bin;
grant all privileges on zabbix.* to zabbix@localhost identified by '123456';

# 查看所有數據庫
show databases;

# 授權所有權限 grant all
# 授權所有庫所有表 *.*
# 將授權賦予給哪個用戶,這個用戶只能通過哪個網段過來(%所有) 'lzy'@'%'
# 授權該用戶登錄的密碼 identified by
grant all on *.* to 'root'@'%' identified by '123';

刪除用戶
Delete FROM mysql.user Where User='zabbix' and Host='localhost';

# 刷新
flush privileges;

# 重新記錄日志,將停止記錄當前日志,開始將日志寫入下一個日志。
FLUSH LOGS;
# 啟動從服務器
START SLAVE;
# 停止從服務器
STOP SLAVE;
# 重置從服務器配置
RESET SLAVE;
# 重置主服務器配置
RESET MASTER;
# 顯示二進制日志文件狀態
SHOW BINARY LOGS;
# 顯示主服務器狀態
SHOW MASTER STATUS;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM