安装配置mariadb galera实现数据库master-master集群
0x01 前言
我 博客 的后端服务器放置在我家里的T620中,但在腾讯云有一个性能较低的VPS作为备份节点。当我家出现停电、服务崩溃等异常情况时,前端服务器会自行将流量引导至腾讯云的节点。
在这里有个问题,我博客有统计数据和一些脚本需要用到由mariadb提供的数据库服务,如果采用主从模式,则无法实现我需要的功能。
为避免出现上述问题,我采用了主主同步模式的数据库集群。
0x02 基础
mariadb galera簇可以实现多个mariadb master服务之前的数据同步,而且只支持XtraDB/InnoDB引擎。目前有以下几个特点:
- 同步复制
- 主动且多主的拓扑
- 读写任意节点
- 自动的成员资格控制,失效的成员会自动剔除
- 节点自动加入
- row级别的并行复制
- 各节点可供客户端直接连接
集群至少需要2个节点,但建议不少于3个节点。当集群只有2个节点时,若某一节点异常,而不是由systemd或init手动关闭,另一节点的状态会转变为nonoperational。这是为了确保数据的完整性,禁止任何数据的传入或传出,直至手动干预。
为避免出现上述情况,建议至少将2个节点放置在极为可靠的云服务商中,其他节点则可以部署在生产环境或备用节点等一般环境中。
当某一节点新加入集群时,它会向集群发送一个状态转移的请求,然后根据配置文件中的信息向集群中的某个节点拉取数据,并填充到自身。而这一过程为State Snapshot Transfers(SST),SST支持rsync, mysqldump, xtrabackup, xtrabackup-v2, mariabackup等方式,默认为rsync。
在节点的配置文件中可以手动指定节点和主节点的地址,设置可以指定多个主节点地址,而这些地址可以通过域名代替。但需要注意的是,一旦域名被解析并在集群中注册,除非被剔除,否则将不会自行更改。因此DDNS环境不适合通过该方式建立集群。
默认的galera端口为TCP 4567;另外还需要注意SST方式的端口,例如mysqldump的端口为TCP 3306,请务必保证各个节点的这些端口相互可达。
0x03 准备
在本篇文章中,我利用我的T620建立测试环境而不使用我博客实际的环境进行讲解。因为我实际应用的环境还涉及安全隧道的相关知识,这一部分内容请在近期关注我的 博客(https://ngx.hk) 。
而这三个节点分别用以下域名代替IP地址,方便识别:
然后根据以下文章对系统进行预配置:
添加mariadb的镜像源,这里选用中科大的镜像源:
[root@web ~]# cat /etc/yum.repos.d/mariadb-10.2.repo
# MariaDB 10.2 CentOS repository list - created 2018-07-23 13:47 UTC
# http://downloads.mariadb.org/mariadb/repositories/
[mariadb]
name = MariaDB
baseurl = https://mirrors.ustc.edu.cn/mariadb/yum/10.2/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
上面的镜像源是10.2版本的mariadb,如果需要新版本的mariadb,请留意中科大镜像站的版本号并手动修改或查阅mariadb官方网站。
随后在每个节点通过以下命令安装、启动与初始化mariadb:
# 安装
[root@mariadb-t1 ~]# yum install MariaDB-server MariaDB-client -y
# 关闭自动自动
[root@mariadb-t1 ~]# systemctl disable mariadb.service && systemctl disable mysql
Removed symlink /etc/systemd/system/multi-user.target.wants/mariadb.service.
Removed symlink /etc/systemd/system/mysql.service.
Removed symlink /etc/systemd/system/mysqld.service.
mysql.service is not a native service, redirecting to /sbin/chkconfig.
Executing /sbin/chkconfig mysql off
# 立即启动mariadb
[root@mariadb-t1 ~]# systemctl start mariadb.service
# 初始化mariadb
[root@mariadb-t1 ~]# /usr/bin/mysql_secure_installation
最后还需要建立集群数据读写的用户:
# 登入数据库
[root@db-t1 ~]# mysql -u root -p
Enter password:
# 建立名为cluster_user,密码为cluster_passwd的用户,指定hostname为localhost
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO cluster_user@localhost IDENTIFIED BY 'cluster_passwd';
Query OK, 0 rows affected (0.00 sec)
# 建立名为cluster_user,密码为cluster_passwd的用户,指定hostname为%
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'cluster_user'@'%' IDENTIFIED BY 'cluster_passwd';
Query OK, 0 rows affected (0.01 sec)
# 刷新权限表
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
# 登出数据库
MariaDB [(none)]> exit;
Bye
0x04 第一个节点
集群中的第一个节点有点特殊,因为它是第一个启动的,并没有其他节点可连接,也就没有数据可以拉取。因此它的配置文件有点特殊。
注意!如果你的集群正从故障状态中恢复,请不要参照本节内容进行操作,请关注下文。
其实配置非常简单,各个节点只需要修改IP地址等参数即可完成配置,以下是第一个节点的配置文件:
[root@mariadb-t1 ~]# cat /etc/my.cnf.d/server.cnf
... ...
[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_name='wsrep_cluster'
wsrep_cluster_address='gcomm://'
wsrep_node_address='mariadb-t1:4567'
wsrep_sst_receive_address='mariadb-t1:3306'
binlog_format=row
wsrep_node_name='db-1'
wsrep_sst_auth='cluster_passwd:cluster_passwd'
wsrep_sst_method=mysqldump
bind-address=0.0.0.0
... ...
- wsrep_on:在10.1以上版本的mariadb中,该参数的默认值为OFF,意为该节点的事务将不会发送给集群中的其他节点;
- wsrep_provider:wsrep库的路径,请自行确认;
- wsrep_cluster_name:集群名称,可自定义;
- wsrep_cluster_address:第一个启动的节点务必设置为以上代码中的值;
- wsrep_node_address:定义本节点的wsrep地址与端口,默认端口为4567;
- wsrep_sst_receive_address:定义本节点接受传入请求的域名或IP,可附带端口,默认的端口根据wsrep_sst_method定义的快照传输方式的不同而不同;
- wsrep_node_name:本节点名称,在集群中需唯一;
- wsrep_sst_auth:快照传输方式的验证信息;
- wsrep_sst_method:定义快照传输方式;
- bind-address:数据库监听的IP地址。
默认情况下,wsrep会监听TCP 4567端口,当有新节点加入时,新节点会通过wsrep_cluster_address中设定的节点信息,拉取该节点的信息。
当没有设定wsrep_node_address或wsrep_sst_receive_address,galera将监听数据库bind-address中设定的IP地址,如果没有设定bind-address,则监听默认的IP地址。
如果mariadb服务器有多个IP地址,则可以通过上面两个变量设定监听特定的IP地址或端口。例如在腾讯云环境中,系统中的IP地址为10开头的内网IP,公网请求则通过NAT的方式传入,此时就需要设定上面的两个变量,指定域名或公网IP,否则galera集群将无法正常工作。
如果内网IP可达,则无需设定上面两个变量。
wsrep_sst_method可以设定不同的数据库同步方式,默认是使用rsync,请根据实际情况设定并在防火墙中放行特定的端口。
准备好后即可将他们写入配置文件:
而后停止正在运行的mariadb服务,然后通过以下命令启动起一个节点:
[root@mariadb-t1 ~]# service mysql start --wsrep-new-cluster
Starting mysql (via systemctl): [ OK ]
注意!只是启动集群中的第一个节点需要只用以上命令启动,并且wsrep_cluster_address的值需要设定为’gcomm://’。
成功启动后使用以下命令检查服务是否正常:
[root@mariadb-t1 ~]# mysql -e "SHOW STATUS LIKE 'wsrep_%'; " -p
在返还的表格中需要注意3个内容:
- wsrep_cluster_size:集群节点数量;
- wsrep_ready:服务状态;
- wsrep_incoming_addresses:本节点域名信息。
如果wsrep_ready的值为OFF,请检查数据库日志,排查原因;如果为ON,则服务正常。
然后检查wsrep_incoming_addresses的值,可以发现第一个节点的信息为: mariadb-t1.t.com:3306 ,也就是wsrep_sst_receive_address设定的值。
至此,集群的一个节点已完成启动,接下来只需要添加节点即可。
0x05 添加
节点的添加非常简单,只需要完成配置文件,利用systemd启动即可。以下分别是第二个与第三个节点的配置信息:
# 第二个节点
[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_name='wsrep_cluster'
wsrep_cluster_address='gcomm://mariadb-t1:4567'
wsrep_node_address='mariadb-t2:4567'
wsrep_sst_receive_address='mariadb-t2:3306'
binlog_format=row
wsrep_node_name='db-2'
wsrep_sst_auth='cluster_passwd:cluster_passwd'
wsrep_sst_method=mysqldump
bind-address=0.0.0.0
# 第三个节点
[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_name='wsrep_cluster'
wsrep_cluster_address='gcomm://mariadb-t1:4567'
wsrep_node_address='mariadb-t3:4567'
wsrep_sst_receive_address='mariadb-t3:3306'
binlog_format=row
wsrep_node_name='db-3'
wsrep_sst_auth='cluster_passwd:cluster_passwd'
wsrep_sst_method=mysqldump