离线安装Mysql Galera集群-Install MySQL Galera Cluster Offline

南宫炜
2023-12-01

离线安装Mysql Galera集群-Install MySQL Galera Cluster Offline

0. 准备

1. 准备服务器

官方文档:Preparing The Server

1.1. 禁用mysqld SELinux

SELinux(SELinux and MySQL)可能会阻止MySQL执行一些操作,有两种方法来配置SELinux:一种是仅仅对mysqld禁止SELinux,另外一种是直接关闭SELinux

1.1.1. disable SELinux for mysql

第一种方法是官方文档里的方法,不过需要先安装一个管理工具yum install policycoreutils-python,我没有用这种方法,心里感觉很虚,一点儿也不稳。

#检查SELinux状态
sestatus | grep 'SELinux status' | awk '{print $3}'
# output>>>>>>>>>
# enable
# output>>>>>>>>>

# 如果enable
# semanage 需要安装(policycoreutils-python)
semanage permissive -a mysqld_t

This command switches SELinux into permissive mode when it registers activity from the database server.1

1.1.2. 直接禁用SELinux

#检查SELinux状态
sestatus | grep 'SELinux status' | awk '{print $3}'
# output>>>>>>>>>
# enable
# output>>>>>>>>>

# 如果enable
vi /etc/selinux/config
# 修改 SELINUX=som_value_not_disabled -> SELINUX=disabled
reboot

上面这种方法很赞,但是要重启机器,如果不能重启,比如机器上还有其他服务在运行,那么可以用下面的方法

# command switches off SELinux enforcing until the next reboot
# 在下次重启之前SELinux都将被关闭
setenforce 0

# 然后修改/etc/selinux/config 设置 SELINUX=disabled
# 那么即使重启,SELinux也将被禁用

# 查看SELinux 状态
getenforce

更多信息请参考:SELinux and MySQL

1.2. 防火墙设置

Next, you need to update the firewall settings on each node so that they can communicate with the cluster.2

1.2.1. TCP互信

如果系统相对严格,不能随便对外开放端口,那么可以在组成集群的各个主机上配置对其他主机的TCP互信。假设构成集群的三台主机IP分别是192.168.0.11 192.168.0.12 192.168.0.13,那么在192.168.0.11上需要这样设置:

iptables --append INPUT --protocol tcp --source 192.168.0.12 --jump ACCEPT
iptables --append INPUT --protocol tcp --source 192.168.0.13 --jump ACCEPT
iptables-save > /etc/sysconfig/iptables

这种做法的好处是集群相对更加安全,官方文档是这么干的,但是这样配置不利于增删节点,每增加一个节点都要在每个节点上修改一下防火墙,我并没有使用这种方法。

1.2.2. 开放必要的端口

iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
iptables -I INPUT -p tcp --dport 4444 -j ACCEPT
iptables -I INPUT -p tcp --dport 4567 -j ACCEPT
iptables -I INPUT -p tcp --dport 4568 -j ACCEPT

iptables-save > /etc/sysconfig/iptables

3306mysql的端口,其它的都是wsrepgalera需要的端口。这样配置在增删节点的时候不需要修改那些已经在集群中节点的防火墙设置。

1.3. 禁用AppArmor

By default, some servers—for instance, Ubuntu—include AppArmor, which may prevent mysqld from opening additional ports or running scripts. You must disable AppArmor or configure it to allow mysqld to run external programs and open listen sockets on unprivileged ports.3

# 检查是否有Apparmor
whereis apparmor
service apparmor status

# 如果有
ln -s /etc/apparmor.d/usr /etc/apparmor.d/disable/.sbin.mysqld
service apparmor restart

没有在Ubuntu或其它安装有AppArmor的系统上测试过,只是做个记录。

2. 准备离线安装包

2.1 暴力离线安装包

太暴力了不建议使用,可能导致一些错误,比如覆盖原有的包或升级原有的包本来就是危险的,建议使用2.2的方法。

准备一台能连上公网的服务器,配置好yum源,比如alibaba或者souhu网易的都行,所有操作在CentOS 7.4 + mirrors.sohu.com + repotrack下完成,repotrack需要提前安装,如果yum无法安装,可以到第0部分Linux Packages Search查找并下载,使用rpm -ivhU xxx.rpm来手动安装。

repotrack is a program for keeping track of a particular package and its dependencies. It will download one or more packages and all dependencies.4

You can use repotrack instead like this:
repotrack -a x86_64 -p /repos/Packages [packages]
Unfortunately there is a bug with the -a flag (arch). It will download i686 and x86_645

# 创建临时目录
mkdir ~/mysql-wsrep-galera
cd ~/mysql-wsrep-galera

# 下载mysql-wsrep
wget http://releases.galeracluster.com/mysql-wsrep-5.5/binary/mysql-wsrep-5.7.21-25.14-linux-x86_64.tar.gz

# 下载galera
wget http://releases.galeracluster.com/galera-3/source/galera-3-25.3.23.tar.gz

# 下载rpm依赖包
# 注释结构[packageName/moduleToUse]
# libaio/mysql
repotrack -p ~/mysql-wsrep-galera/libaio libaio
# rsync/wsrep
repotrack -p ~/mysql-wsrep-galera/rsync rsync
# lsof/wsrep
repotrack -p ~/mysql-wsrep-galera/lsof lsof
# gcc/galera
repotrack -p ~/mysql-wsrep-galera/gcc gcc
# gcc-c++/galera
repotrack -p ~/mysql-wsrep-galera/gcc-c++ gcc-c++
# boost-devel/galera
repotrack -p ~/mysql-wsrep-galera/boost-devel boost-devel
# check-devel/galera
repotrack -p ~/mysql-wsrep-galera/check-devel check-devel
# openssl-devel/galera
repotrack -p ~/mysql-wsrep-galera/openssl-devel openssl-devel
# scons/galera
repotrack -p ~/mysql-wsrep-galera/scons scons

# 创建新文件夹把所有rpm包合并到一个文件夹
mkdir yum-source
# -n表示重复的不覆盖
cp -n libaio/* yum-source/
cp -n rsync/* yum-source/
...
...
...
cp -n openssl-devel/* yum-source/
cp -n scons/* yum-source/

# 因为repotrack -a选项的bug(脚注5),所有架构的包都被下下来了,我们只要x86_64的
# 所以把i686的包全部删除
cd /yum-source
rm -rf *.i686.*

# 最后把galera、mysql-wsrep、yum-source打包
cd ~/mysql-wsrep-galera
tar -cvzf mysql-wsrep-5.7.21-galera-3-linux-x86_64.tar.gz galera-3-25.3.23.tar.gz mysql-wsrep-5.7.21-25.14-linux-x86_64.tar.gz yum-source

最后得到的mysql-wsrep-5.7.21-galera-3-linux-x86_64.tar.gz就是完整的离线安装包。整个过程其实就是把mysql-wsrep+galera+yum source三个打包到一起了,需要yum包及对应依赖都以rpm包的形式下载下来,最终在目标机器上手动安装,是谓“离线”。
一般来说集群对应的目标机器操作系统都是一样的,完全可以把编译出来的galera插件事先就放到mysql-wsrep安装包里,这样就免去了scons编译过程,yum-source也会少很多,比如gcc/scons等,具体少哪些没有验证过。
针对不同的环境可能缺少不同的yum source,这里列举的包只是在精简版CentOS 7.2环境下最小安装包,不保证在其他环境和系统能完美运行。

2.2 更加优雅的离线包

两个优点足以证明更加优雅:

  1. 使用yum install安装,自动寻找依赖(当然是离线的)不再强制安装所有确保依赖都被安装;
  2. 需要的yum源更少。

思路:

  • 提前编译好galera插件并放入mysql的安装包内,这样就少了很多依赖,比如gcc scons等等;
  • 使用repotrack(yum install yum-utils)createrepo(yum install createrepo)这两个工具创建本地yum源,这样就可以使用yum install来安装,自动检查依赖并安装。
  • 在不需要编译galera后,目前只发现6个必需的依赖包:
    1. perl5.6版本的mysqlscripts文件夹下的脚本文件都是用perl写的,需要perl环境;
    2. perl-Data-Dumper:同样是5.6用到了Data::Dumper模块;
    3. net-tools(netstat):检查端口占用时需要;
    4. lsofwsrep检查端口占用时需要;
    5. rsyncgalera同步通信需要;
    6. libaiomysql需要的异步IO包。
# 创建临时目录
mkdir ~/mysql-wsrep-galera
cd ~/mysql-wsrep-galera

# 下载mysql-wsrep
wget http://releases.galeracluster.com/mysql-wsrep-5.5/binary/mysql-wsrep-5.7.21-25.14-linux-x86_64.tar.gz

# 下载galera
wget http://releases.galeracluster.com/galera-3/source/galera-3-25.3.23.tar.gz

# 解压mysql
tar -zvxf mysql-wsrep-5.7.21-25.14-linux-x86_64.tar.gz

# 编译Galera插件
tar -zvxf galera-3-25.3.23.tar.gz
cd galera-3-25.3.23
# scons过程稍长
scons
cp garb/garbd ../mysql-wsrep-5.7.21-25.14-linux-x86_64/bin/
cp libgalera_smm.so ../mysql-wsrep-5.7.21-25.14-linux-x86_64/lib/plugin/

# 重新打包mysql
cd ../
rm -rf mysql-wsrep-5.7.21-25.14-linux-x86_64.tar.gz
tar -cvzf mysql-wsrep-5.7.21-25.14-linux-x86_64.tar.gz mysql-wsrep-5.7.21-25.14-linux-x86_64
# 这个包就是包含galera插件的包了,拷贝到其他机器上不再需要编译插件

# 准备yum源
# 安装repotrack和createrepo
# 如果安装失败同样可以从第0部分手动安装
yum install -y repotrack
yum install -y createrepo

# 下载rpm包
repotrack -p libaio libaio
repotrack -p perl perl
# 这里可能找不到perl-Data-Dumper,可以先执行yum install centos-release-scl-rh
repotrack -p perl-Data-Dumperperl-Data-Dumper
repotrack -p net-tools net-tools
repotrack -p rsync rsync
repotrack -p lsof lsof

# 合并并删除32位的包
mkdir rpm
cp -n libaio/* rmp
cp -n perl/* rmp
cp -n perl-Data-Dumper/* rmp
cp -n net-tools/* rmp
cp -n rsync/* rmp
cp -n lsof/* rmp

rm -rf rpm/*i686*

# 创建repo
cd rpm 
# 后面有个点
createrepo .
# 这时rpm目录就可以作为一个yum源了

# 打包
cd ../
tar -cvzf mysql-galera-repo.el7.tar.gz rpm

# 使用
# 解压
tar -zvxf mysql-galera-repo.el7.tar.gz -C /data

# 配置repo
cd /etc/yum.repos.d/
mkdir bak
mv *repo bak/
vi local_rpm.repo
# >>>>>>>>>>input>>>>>>>>>>>>
[local_rpm] 
name=local_rpm
baseurl=file:///data/rpm 
gpgcheck=0 
enabled=1
# >>>>>>>>>>input>>>>>>>>>>>>

# 验证
yum clean all
yum makecache
# 不报错即成功,centos会提示没有注册,忽略掉就可以了

# 安装
yum -y install rsync

3. 安装MySQL Galera集群

3.1. 卸载Mysql

如果目标机器没有安装mysql,或者允许在同一个机器上安装多个mysql,这一步就没有了。

# 查找之前安装的mysql
rpm -qa|grep -i mysql

# 停止mysql服务
service mysqld stop

# 卸载 顺序很重要
rpm -ev mysql-community-server-5.7.19-1.el7.x86_64
rpm -ev mysql-community-client-5.7.19-1.el7.x86_64
rpm -ev mysql-community-libs-5.7.19-1.el7.x86_64
rpm -ev mysql-community-common-5.7.19-1.el7.x86_64

# 如果有依赖可以执行下面的命令
rpm -e --nodeps mysql-community-common-5.7.19-1.el7.x86_64

# 删除mysql文件夹和文件
find / -name mysql
# 查看是否可以删除

# 删除/etc/my.cnf
rm -rf /etc/my.cnf 

# 验证卸载
rpm -qa|grep -i mysql 

# 删除base-dir
# 这里可以查看/etc/my.cnf找到base-dir
# 默认是/var/lib/mysql
rm -rf /var/lib/mysql

3.2. 安装MySQL(第一个节点)

# 解压
tar -zvxf mysql-wsrep-5.7.21-galera-3-linux-x86_64.tar.gz

# 安装依赖
cd yum-source
# 因为不是用yum安装,无法检测依赖包顺序安装,所以--nodeps直接跳过依赖检查
# 对于已安装的包,直接--replacepkgs升级替换
rpm -ivhU *.rpm --nodeps --replacepkgs

# 解压数据库
cd ../
tar -zvxf mysql-wsrep-5.7.21-25.14-linux-x86_64.tar.gz
mv mysql-wsrep-5.7.21-25.14-linux-x86_64 /usr/local/mysql

# 安装Galera插件
tar -zvxf galera-3-25.3.23.tar.gz
cd galera-3-25.3.23
# scons过程稍长
scons
cp garb/garbd /usr/local/mysql/bin/
cp libgalera_smm.so /usr/local/mysql/lib/plugin/

# 准备初始化文件
cd /usr/local/mysql
vi init-root-pass.sql
# alter root for change password
ALTER USER 'root'@'localhost' IDENTIFIED BY 'root';
ESC :wq

# 创建mysql用户和用户组(如果没有的话)
groupadd mysql
useradd -r -g mysql mysql
chown -R mysql:mysql .

# 配置Galera/Mysql
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql
mkdir -p /var/lib/mysql
# 创建error log文件,否则启动报错找不到文件,据说是mysql的bug
echo '' > /var/lib/mysql/mysql.log
chown -R mysql:mysql /var/lib/mysql
vi /etc/my.cnf
# >>>>>>>>>>>>>>>>>>>>>>>>>>file>>>>>>>>>>>>>>>>>>>>>>>>
[client]
port = 3306
socket = /var/lib/mysql/mysql.sock

[mysqld_safe]
log-error = /var/lib/mysql/mysql.log
pid-file = /var/lib/mysql/mysql.pid

[mysqld]
wsrep_node_name = dbaas_galera_node1
wsrep_provider = /usr/local/mysql/lib/plugin/libgalera_smm.so
#wsrep_provider_options ='gcache.size=1G;socket.ssl_key=my_key;socket.ssl_cert=my_cert'
#wsrep_slave_threads=16
wsrep_sst_method = rsync
#wsrep_sst_auth=root:

port = 3306
socket = /var/lib/mysql/mysql.sock
user = mysql
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data

default_storage_engine=InnoDB
#innodb_buffer_pool_size=1G
#innodb_log_file_size=256M
innodb_autoinc_lock_mode=2
innodb_locks_unsafe_for_binlog=1
innodb_flush_log_at_trx_commit=0
innodb_doublewrite=0
innodb_file_per_table=1

binlog_format=ROW
log-bin=mysql-bin
server-id=101
relay-log=mysql-relay-bin
#read_only=1
log-slave-updates=1

ESC :wq
# >>>>>>>>>>>>>>>>>>>>>>>>>>file>>>>>>>>>>>>>>>>>>>>>>>>

# 首次启动,修改root密码
/usr/local/mysql/bin/mysqld --initialize-insecure --user=mysql --init-file=/usr/local/mysql/init-root-pass.sql

# 关闭mysql
service mysql stop

# 启动galera首个节点
# 因为是首个节点,所以wsrep_cluster_address是空的
service mysql start --wsrep_cluster_address=gcomm://

# 验证是否启动
# 可以把/usr/local/mysql/bin放到PATH
/usr/local/mysql/bin/mysql -uroot -proot
mysql> SHOW STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 1     |
+--------------------+-------+
1 row in set (0.01 sec)

# 值为1表示集群第一个节点启动成功

# 允许远程连接root(或其他用户)
mysql> use mysql;
mysql> UPDATE user SET host = '%' WHERE user = 'root';
# UPDATE user SET host = '%' WHERE user IS NOT NULL;

3.3 加入其它节点

安装方式一模一样,只是节点名称等个性化配置以及启动方式不一样。

...
...
vi /etc/my.cnf
# >>>>>>>>>>>>>>>>>>>>>>>>>>file>>>>>>>>>>>>>>>>>>>>>>>>
...
wsrep_node_name = dbaas_galera_node2
...
# >>>>>>>>>>>>>>>>>>>>>>>>>>file>>>>>>>>>>>>>>>>>>>>>>>>
...
...
# 关闭mysql
service mysql stop

# 将节点加入集群
# 假设集群中另外两台的ip是192.168.0.166和192.168.0.117
service mysql start --wsrep_cluster_address="gcomm://192.168.0.166:4567,192.168.0.117:4567"

# 验证是否成功
/usr/local/mysql/bin/mysql -uroot -proot
mysql> SHOW STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 2     |
+--------------------+-------+
1 row in set (0.01 sec)

# 值为2表示集群第二个节点加入成功,3表示第三个节点加入成功...
# 任何一个节点的wsrep_cluster_size值都应该是一样的

# 验证集群功能
# 在任意一个节点创建数据库,查看其他节点是否同步该库
# 在任意一个节点创建一张表,查看其他节点是否同步该表
# 在任意一个节点插入一条数据,查看其他节点是否同步该条数据
# 在任意一个节点更新一条数据,查看其他节点是否同步更新该条数据

4. 重启集群

4.1. 正常重启

To restart an entire Galera Cluster, complete the following steps:

  1. Identify the node with the most advanced node state ID.
  2. Start the most advanced node as the first node of the cluster.
  3. Start the rest of the node as usual.6
# 在一个运行的集群中,按任意顺序依次在各个节点执行service mysql stop
# 由此来模拟一个正常关闭的集群
# 在每个节点上找出最大的seqno,seqno表示最后一次提交的transaction ID,越大表示数据越新,越应该作为集群第一个节点启动

# 找出最大seqno,seqno记录在$data-dir/grastate.dat
cat /usr/local/mysql/data/grastate.dat | grep seqno
# 假设node1:5000,node2:5005,node3:5003
# 那么应该首先启动node2

# 假设每个节点的seqno都一样,那么再参考safe_to_bootstrap
# safe_to_bootstrap=1的节点应当作为第一个节点启动
# 否则会报错:[ERROR] WSREP: It may not be safe to bootstrap the cluster from this node. It was not the last one to leave the cluster and may not contain all the updates. To force cluster bootstrap with this node, edit the grastate.dat file manually and set safe_to_bootstrap to 1
cat /usr/local/mysql/data/grastate.dat | grep safe_to_bootstrap
# 假设仍然是node2的safe_to_bootstrap=1
# 那么依然应该首先启动node2

# 切换到node2
# 启动第一个节点
service mysql start --user=mysql --wsrep_cluster_address=gcomm://
# 启动node1
service mysql start --user=mysql --wsrep_cluster_address="gcomm://192.168.0.166:4567,192.168.0.117:4567"
# 启动node3
service mysql start --user=mysql --wsrep_cluster_address="gcomm://192.168.0.166:4567,192.168.0.116:4567"

4.2 异常重启

当每个节点的seqno都是-1的时候,并且每个节点的safe_to_bootstrap=0,那么可能是服务器所有节点同时宕机造成的,比如机房断电。此时启动方法稍微复杂些,大概步骤如下:
1. 按照非集群的方式启动某一个节点的数据库;
2. 恢复二进制日志记录;
3. 以此节点作为集群中第一个节点启动;
4. 其他节点依次加入。

具体方法参见:Galera Cluster mysql+keepalived集群部署#集群异常重启

5. 一些问题记录

  1. 启动数据库报错:Starting MySQL... ERROR! The server quit without updating PID file(/path/to/pid/file)。这个错误一般看看错误日志就能找到问题,但是如果报这个错,又没有错误日志的话,头就大了。这时首要问题是把错误日志弄出来,没有错误日志一般可能是修改了/etc/my.cnf[mysql-safe]log-error的值,指定了一个错误日志的路径,但是mysql没有这个文件夹或文件的读写权限。这时候注释掉这个配置,错误日志就会出现在/path/to/mysql/data/dir/host_name.err,其它问题导致的quit without updating PID file看看错误日志或者这里:mysql启动报错:Starting MySQL… ERROR! The server quit without updating PID file 找找灵感。
  2. 试过用rpm安装Galera Cluster,但是安装好启动完成后老是出现启动集群后状态不对,查找问题也不太方便,还是用免安装的版本好找问题。
 类似资料: