一、环境信息
操作系统:AnolisOS8.8 #cat /etc/os-release
数据库版本:GreatSQL-8.0.32-25
软件目录:/usr/local/GreatSQL
数据目录:/data/greatsql/
注:本示例分别使用手动方式和MySQL Shell方式各部署一套MGR集群环境:
1、手动方式部署MGR环境集群(MGR1):192.168.68.101、192.168.68.102、192.168.68.103
2、MySQL Shell方式部署MGR环境集群(MGR2):192.168.68.104、192.168.68.105、192.168.68.106
二、安装准备
GreatSQL数据库支持RPM包、二进制包、Docker、Ansible、源码编译共5种安装方法,此示例以二进制包方式进行部署(实例端口:3306,通信端口:33061)。
1、关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
systemctl is-enabled firewalld #查看是否禁用服务
2、禁用SELINUX
setenforce 0
vi /etc/selinux/config
SELINUX=disabled
或者执行命令替换配置: sed -i '/^SELINUX=/c'SELINUX=disabled /etc/selinux/config
3、关闭swap
echo "vm.swappiness = 0">> /etc/sysctl.conf
sysctl -p
swapoff -a #禁用swap后还需要注释掉 /etc/fstab 中关于swap加载项
free -h
4、修改数据盘IO策略
将数据库的数据存放目录所在磁盘的IO测试设置为 noop / deadline
先查看当前设置(nvme0n1为磁盘分区)
cat /sys/block/nvme0n1/queue/scheduler
这样没问题,如果不是 noop 或 deadline,可以执行如下命令修改:
echo 'noop' > /sys/block/nvme0n1/queue/scheduler
这样修改后立即生效,无需重启。
5、确认CPU性能模式设置
先检查当前的设置模式,执行如下命令查看;
cpupower frequency-info --policy
如果输出内容不是 The governor "performance" 而是 The governor "powersave" 的话,则要注意了。
The governor "powersave" 表示 cpufreq 的节能策略使用 powersave,需要调整为 performance 策略。
如果是虚拟机或者云主机,则不需要调整,命令输出通常为 Unable to determine current policy。
6、关闭透明大页
建议关闭透明大页(Transparent Huge Pages / THP)。
OLTP型数据库内存访问模式通常是稀疏的而非连续的。当高阶内存碎片化比较严重时,分配 THP 页面会出现较高的延迟,反而影响性能。
先检查当前设置:
cat /sys/kernel/mm/transparent_hugepage/enabled
如果输出结果不是 never 的话,则需要执行下面的命令关闭:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
7、优化内核参数
建议调整优化下面几个内核参数:
echo "fs.file-max = 1000000" >> /etc/sysctl.conf
echo "net.core.somaxconn = 32768" >> /etc/sysctl.conf
echo "net.ipv4.tcp_syncookies = 0" >> /etc/sysctl.conf
echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
sysctl -p
8、修改mysql用户使用资源上限
修改 /etc/security/limits.conf 系统文件,调高mysql系统账户的上限:
vim /etc/security/limits.conf #添加如下配置项
mysql soft nofile 65535
mysql hard nofile 65535
mysql soft stack 32768
mysql hard stack 32768
mysql soft nproc 65535
mysql hard nproc 65535
9、确认NUMA模式
推荐开启NUMA模式以获得更好的性能表现。
以CentOS为例,打开/etc/default/grub文件,确保文件内容中没有 NUMA=OFF 字样,如果有的话就删掉:
如果修改了 /etc/default/grub 文件,需要重新生成UEFI启动文件:
grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
然后重启操作系统,使之生效。
操作系统层开启NUMA后,还要记得修改GreatSQL配置选项 innodb_numa_interleave = ON,确保InnoDB在分配内存时使用正确的NUMA策略。
如果采用手动方式启动GreatSQL服务进程,还可以在启动时加上 numactl --interleave=all,例如:
numactl --interleave=all /usr/local/GreatSQL-8.0.32-25-Linux-glibc2.28-x86_64/bin/mysqld &
如果采用 systemd 来启动 GreatSQL服务进程,则可以修改 /etc/systemd/system.conf 配置文件,增加如下的相关配置项:
[Manager]
NUMAPolicy=interleave
#NUMAMask=
修改完毕后,重新加载 systemd 配置,确保NUMA策略生效:
systemctl daemon-reload
10、时间服务及时区设置
时间服务建议使用chrony。
yum install -y chrony
systemctl start chronyd
systemctl is-enabled chronyd #systemctl enable chronyd
查看时间同步:
chronyc sources
显示当前语言环境状态:localectl status
查看LANG语言环境变量:echo $LANG
列出可用的语言环境:localectl list-locales | grep zh
注:如果需要可设置语言环境,相关命令如下:
编辑/etc/locale.conf文件
vi /etc/locale.conf
#中文 LANG=zh_CN.UTF-8
#英文 LANG=en_US.UTF-8
或,执行如下命令设置简体中文语言环境:
localectl set-locale LANG=zh_CN.UTF-8
简体英文语言环境:
localectl set-locale LANG=en_US.UTF-8
加载语言环境
source /etc/locale.conf
三、部署GreatSQL
二进制包文件下载地址:https://gitee.com/GreatSQL/GreatSQL/releases/tag/GreatSQL-8.0.32-25
注:查看机器的glibc版本,以选择正确的安装包:ldd --version
如果您的glibc版本为2.28或更高版本,请选择带有"glibc2.28"标识的安装包;如果您的glibc版本为2.17,请选择带有"glibc2.17"标识的安装包。
1、创建mysql用户
groupadd mysql
useradd -g mysql mysql -s /sbin/nologin
id mysql
2、安装jemalloc
建议采用jemalloc代替glibc自带的malloc库,其优势在于减少内存碎片和提升高并发场景下内存的分配效率,提高内存管理效率的同时还能降低数据库运行时发生OOM的风险。
yum install -y gcc gcc-c++ cmake tar bzip2 vim tree
tar -xvf jemalloc-5.3.0.tar.bz2
cd jemalloc-5.3.0
./configure
make && make install
vi /etc/ld.so.conf.d/greatsql.conf
/usr/local/lib/
/sbin/ldconfig
ldconfig -p | grep libjemalloc
添加/修改系统文件 /etc/sysconfig/greatsql
LD_PRELOAD=/usr/local/lib/libjemalloc.so
THP_SETTING=never
注:启动greatsql服务后,可执行命令查看是否使用的jemalloc内存管理:lsof -n | grep libjemalloc
3、安装依赖包
yum install -y pkg-config perl libaio-devel numactl-devel numactl-libs net-tools openssl openssl-devel perl-Data-Dumper perl-Digest-MD5 python2 perl-JSON perl-Test-Simple
建议提前安装DBA常用的辅助工具包:
yum install -y net-tools perf sysstat iotop tmux tree lsof
4、创建数据目录
mkdir -p /data/greatsql/greatsqldata3306/{mydata,binlog,innodb_log,innodb_ts,innodb_dblwr,innodb_undo,innodb_temp,relaylog,log,sock,tmpdir}
5、解压安装文件
将二进制安装包文件解压到/usr/local目录下,并建立软连接/usr/local/GreatSQL:
tar -xvf GreatSQL-8.0.32-25-Linux-glibc2.28-x86_64.tar.xz -C /usr/local/
ln -s /usr/local/GreatSQL-8.0.32-25-Linux-glibc2.28-x86_64 /usr/local/GreatSQL
#相关目录属主属性修改
chown -R mysql.mysql /data/greatsql /usr/local/GreatSQL-8.0.32-25-Linux-glibc2.28-x86_64 /usr/local/GreatSQL
6、配置环境变量
在配置文件/etc/profile中添加PATH信息:
vi /etc/profile
# set for GreatSQL
export MYSQL_HOME=/usr/local/GreatSQL
export MYSQL_USER=mysql
export PATH=$PATH:$MYSQL_HOME/bin
source /etc/profile
mysql -V
7、配置文件/etc/my.cnf
创建数据库配置文件:/etc/my.cnf
vi /etc/my.cnf #此已101服务器为例,其它修改server_id为相应值。
[mysql]
prompt = "(\R:\m:\s)[\u@GreatSQL][\d]>"
no-auto-rehash
loose-skip-binary-as-hex
default-character-set = utf8mb4
show-warnings
[mysqld]
user = mysql
port=3306
server_id=1013306
basedir=/usr/local/GreatSQL
datadir=/data/greatsql/greatsqldata3306/mydata
pid_file=/data/greatsql/greatsqldata3306/sock/greatsql.pid
socket=/data/greatsql/greatsqldata3306/sock/greatsql.sock
skip-name-resolve
log_bin=/data/greatsql/greatsqldata3306/binlog/greatsql-bin
log_bin_index=/data/greatsql/greatsqldata3306/binlog/greatsql-bin.index
binlog_format = ROW
log_slave_updates=1
relay_log_index=/data/greatsql/greatsqldata3306/relaylog/greatsql-relay-bin.index
relay_log=/data/greatsql/greatsqldata3306/relaylog/greatsql-relay-bin
log_error=/data/greatsql/greatsqldata3306/log/error.log
general_log_file=/data/greatsql/greatsqldata3306/log/general.log
slow_query_log_file=/data/greatsql/greatsqldata3306/log/slow-query.log
tmpdir=/data/greatsql/greatsqldata3306/tmpdir
slave-load-tmpdir=/data/greatsql/greatsqldata3306/tmpdir
innodb_buffer_pool_size=8G
innodb_buffer_pool_instances = 2
innodb_doublewrite_dir=/data/greatsql/greatsqldata3306/innodb_dblwr
innodb_undo_directory=/data/greatsql/greatsqldata3306/innodb_undo
innodb_temp_tablespaces_dir=/data/greatsql/greatsqldata3306/innodb_temp
innodb_data_home_dir=/data/greatsql/greatsqldata3306/innodb_ts
innodb_data_file_path=ibdata1:4096M:autoextend
innodb_log_group_home_dir=/data/greatsql/greatsqldata3306/innodb_log
gtid_mode = ON
enforce_gtid_consistency = TRUE
8、实例初始化
chown mysql.mysql /etc/my.cnf
/usr/local/GreatSQL/bin/mysqld --defaults-file=/etc/my.cnf --user=mysql --basedir=/usr/local/GreatSQL --datadir=/data/greatsql/greatsqldata3306/mydata --innodb_data_home_dir=/data/greatsql/greatsqldata3306/innodb_ts --innodb_data_file_path=ibdata1:4096M:autoextend --innodb_log_group_home_dir=/data/greatsql/greatsqldata3306/innodb_log --innodb-doublewrite-dir=/data/greatsql/greatsqldata3306/innodb_dblwr --innodb-undo-directory=/data/greatsql/greatsqldata3306/innodb_undo --innodb_temp_tablespaces_dir=/data/greatsql/greatsqldata3306/innodb_temp --initialize-insecure
9、实例启停脚本
编辑systemd系统服务文件,增加GreatSQL服务文件:
vim /lib/systemd/system/greatsql.service
[Unit]
Description=GreatSQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
# some limits
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=65535
# processes/threads
LimitNPROC=65535
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
User=mysql
Group=mysql
Type=notify
TimeoutSec=0
PermissionsStartOnly=true
#ExecStartPre=/usr/local/GreatSQL/bin/mysqld_pre_systemd
ExecStart=/usr/local/GreatSQL/bin/mysqld $MYSQLD_OPTS
EnvironmentFile=-/etc/sysconfig/greatsql
LimitNOFILE = 10000
Restart=on-failure
RestartPreventExitStatus=1
Environment=MYSQLD_PARENT_PID=1
PrivateTmp=false
重新加载systemd,使其生效:
systemctl daemon-reload
启动数据库实例、登录并修改管理员账号密码:
systemctl start greatsql
mysql -h localhost -u root -S /data/greatsql/greatsqldata3306/sock/greatsql.sock
alter user root@localhost identified with mysql_native_password by 'root@PWD123';
四、手动方式配置MGR
使用手动方式配置MGR集群步骤如下:
1、初始化MGR第一个节点
MGR的第一个节点,也称之为引导节点。
修改 /etc/my.cnf ,增加以下几行和MGR相关的配置参数:
plugin_load_add='group_replication.so;mysql_clone.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaabbbbbb"
group_replication_local_address= "192.168.68.101:33061"
group_replication_group_seeds= "192.168.68.101:33061,192.168.68.102:33061,192.168.68.103:33061"
report-host=192.168.68.101
选项 report-host 的作用是向MGR其他节点报告本节点使用的地址,避免某个服务器上有多个主机名时,可能无法正确找到对应关系而使得MGR无法启动的问题。此外,设置了 report-host 后,修改 /etc/hosts 系统文件加入各节点的地址及主机名这个步骤就不是必须的了。
另外,注意上面配置的端口写的是 33061 而不是 3306,这是为MGR服务指定专用的通信端口,区别于GreatSQL正常的读写服务端口。这里的 33061 端口号可以自定义,例如写成 12345 也可以,注意该端口不能被防火墙拦截。
重启GreatSQL,之后就应该能看到已经成功加载 group_replicaiton 插件了:
systemctl restart greatsql
mysql -h localhost -u root -S /data/greatsql/greatsqldata3306/sock/greatsql.sock -proot@PWD123
show plugins;
如果没正确加载,也可以登入GreatSQL,执行如下命令手动加载这个plugin:
install plugin group_replication soname 'group_replication.so';
install plugin clone soname 'clone.so';
接下来,创建MGR服务专用账户,并准备配置MGR服务通道:
#每个节点都要单独创建用户,因此这个操作没必要记录binlog并复制到其他节点
set session sql_log_bin=0;
create user repl@'%' identified with mysql_native_password by 'repl';
grant backup_admin, replication slave on *.* to `repl`@`%`;
set session sql_log_bin=1;
#配置MGR服务通道
change replication source to source_user='repl', source_password='repl' for channel 'group_replication_recovery';
执行下面的命令,将其设置为MGR的引导节点(只有第一个节点需要这么做)后即可直接启动MGR服务:
set global group_replication_bootstrap_group=ON;
reset master;
start group_replication;
set global group_replication_bootstrap_group=OFF;
提醒:当整个MGR集群重启时,第一个启动的节点也要先设置为引导模式,然后再启动其他节点。除此外,请勿设置引导模式。
查看MGR服务状态:
select * from performance_schema.replication_group_members G
如上图所示,第一个节点已成功运行。
2、配置MGR另外两个节点
修改 /etc/my.cnf ,增加以下几行和MGR相关的配置参数:
注:和第一个MGR不同的配置项是:group_replication_local_address、report-host
#192.168.68.102
plugin_load_add='group_replication.so;mysql_clone.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaabbbbbb"
group_replication_local_address= "192.168.68.102:33061"
group_replication_group_seeds= "192.168.68.101:33061,192.168.68.102:33061,192.168.68.103:33061"
report-host=192.168.68.102
#192.168.68.103
plugin_load_add='group_replication.so;mysql_clone.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaabbbbbb"
group_replication_local_address= "192.168.68.103:33061"
group_replication_group_seeds= "192.168.68.101:33061,192.168.68.102:33061,192.168.68.103:33061"
report-host=192.168.68.103
修改配置文件后,重启数据库服务:systemctl restart greatsql
执行如下命令,创建专用复制账号:
set session sql_log_bin=0;
create user repl@'%' identified with mysql_native_password by 'repl';
grant backup_admin, replication slave on *.* to `repl`@`%`;
set session sql_log_bin=1;
配置MGR服务通道,启动组复制
change replication source to source_user='repl', source_password='repl' for channel 'group_replication_recovery';
reset master;
start group_replication;
查看MGR集群成员状态:
注:如上图所示,MGR集群3个节点已成功配置运行,
3、测试验证MGR集群
登录MGR主节点,创建数据库对象并插入记录,查看数据是否成功同步从节点。
#在主节点192.168.68.101,执行如下命令:
create database testdb;
use testdb;
create table t1 (id int not null primary key, name varchar(30), crte_time timestamp);
insert into t1 values(1, '张三', now()), (2, '李四', now()), (3, '王五', now());
select * from t1;
select @@server_uuid;
#在从节点192.168.68.102、192.168.68.103,执行如下命令,查看数据是否成功同步:
use testdb;
select * from t1;
select @@server_uuid;
五、MySQL Shell方式配置MGR
使用脚本(MySQL Shell)方式配置MGR集群步骤如下:
1、安装MySQL Shell
#使用官方版本
tar -xvf mysql-shell-8.0.35-linux-glibc2.28-x86-64bit.tar.gz -C /usr/local/
ln -s /usr/local/mysql-shell-8.0.35-linux-glibc2.28-x86-64bit /usr/local/mysql-shell
export MYSQL_SHELL=/usr/local/mysql-shell
export PATH=$PATH:$MYSQL_SHELL/bin
2、修改配置文件
在192.168.68.104-106三个节点配置文件(/etc/my.cnf)中添加如下配置项后,重启数据库服务:
#节点192.168.68.104
plugin_load_add='group_replication.so;mysql_clone.so'
group_replication_local_address= "192.168.68.104:33061"
report-host=192.168.68.104
#节点192.168.68.105
plugin_load_add='group_replication.so;mysql_clone.so'
group_replication_local_address= "192.168.68.105:33061"
report-host=192.168.68.105
#节点192.168.68.106
plugin_load_add='group_replication.so;mysql_clone.so'
group_replication_local_address= "192.168.68.106:33061"
report-host=192.168.68.106
3、使用MySQL Shell构建MGR集群
利用MySQL Shell构建MGR集群比较简单,主要有几个步骤:
1)、检查实例是否满足条件。
2)、创建并初始化一个集群。
3)、逐个添加实例。
首先,用管理员账号 root 连接到第一个节点:
mysqlsh --uri root@localhost:3306 -proot@PWD123
执行命令 status 查看当前节点的状态,确认连接正常可用。
执行 dba.configureInstance() 命令开始检查当前实例是否满足安装MGR集群的条件,如果不满足可以直接配置成为MGR集群的一个节点:
提示当前的用户是管理员,不能直接用于MGR集群,需要新建一个账号(mgradmin/mgradmin@PWD123):
完成检查并创建完新用户后,退出当前的管理员账户,并用新创建的MGR专用账户登入,准备初始化创建一个新集群:
mysqlsh --uri mgradmin@192.168.68.104:3306 -pmgradmin@PWD123
mymgr = dba.createCluster('MGR2');
mymgr.status();
如上步骤完成了MGR集群的初始化并加入第一个节点(引导节点)。
接下来,用同样方法先用 root 账号分别登入到另外两个节点,完成节点的检查并创建最小权限级别用户(此过程略过。。。注意各节点上创建的用户名、密码都要一致),之后回到第一个节点,执行如下命令添加另外两个节点。
mymgr.addInstance('mgradmin@192.168.68.105:3306');
mymgr.addInstance('mgradmin@192.168.68.106:3306');
再次执行:mymgr.status(); 命令可查看到3个节点已正常创建,或者切换到SQL模式查看,如下:
sql
select * from performance_schema.replication_group_members G
4、测试验证MGR集群
登录MGR主节点,创建数据库对象并插入记录,查看数据是否成功同步从节点。
#在主节点192.168.68.104,执行如下命令:
mysql -h localhost -S /data/greatsql/greatsqldata3306/sock/greatsql.sock -proot@PWD123
create database testdb;
use testdb;
create table t1 (id int not null primary key, name varchar(30), crte_time timestamp);
insert into t1 values(1, '张三', now()), (2, '李四', now()), (3, '王五', now());
select * from t1;
select @@server_uuid;
#在从节点192.168.68.105、192.168.68.106,执行如下命令,查看数据是否成功同步:
mysql -h localhost -S /data/greatsql/greatsqldata3306/sock/greatsql.sock -proot@PWD123
use testdb;
select * from t1;
select @@server_uuid;
六、MGR管理维护
MGR集群的日常管理维护操作,包括集群启停、主节点切换、单主/多主模式切换等。
1、启停MGR集群
分别验证脚本(MySQL Shell)和手动实现方式。
1.1、脚本方式(MGR2)
使用MySQL Shell重启MGR集群,只需调用dba.rebootClusterFromCompleteOutage()函数即可,它会自动判断各节点的状态,选择其中一个作为Primary节点,然后拉起各节点上的MGR服务,完成MGR集群重启。
步骤如下(MGR2):
1、启动个节点数据库服务 systemctl start greatsql
2、使用MySQL Shell登录其中一个节点,调用脚本函数启动集群
mysqlsh --uri mgradmin@localhost:3306 -pmgradmin@PWD123
dba.rebootClusterFromCompleteOutage();
mymgr=dba.getCluster();
mymgr.status();
也可使用describe方法查看:
1.2、手动方式(MGR1)
正常情况下,MGR集群中的Primary节点退出时,剩下的节点会自动选出新的Primary节点。当最后一个节点也退出时,相当于整个MGR集群都关闭了。这时候任何一个节点启动MGR服务后,都不会自动成为Primary节点,需要在启动MGR服务前,先设置 group_replication_bootstrap_group=ON,使其成为引导节点,再启动MGR服务,它才会成为Primary节点,后续启动的其他节点也才能正常加入集群。
步骤如下(MGR1):
1、启动个节点数据库服务 systemctl start greatsql
2、启第一个节点作为引导节点
set global group_replication_bootstrap_group=ON;
start group_replication;
set global group_replication_bootstrap_group=OFF;
select * from performance_schema.replication_group_members;
3、启动另外两个节点
注:除第一个节点作为引导节点需要设置group_replication_bootstrap_group外,其他节点只需直接启动组复制服务即可。
start group_replication;
select * from performance_schema.replication_group_members G
2、切换主节点
分别验证脚本(MySQL Shell)和手动实现方式。
2.1、脚本方式(MGR2)
在MySQL Shell中,可以调用 setPrimaryInstance('IP:PORT') 函数进行切换:
mysqlsh --uri mgradmin@localhost:3306 -pmgradmin@PWD123
mymgr=dba.getCluster();
mymgr.status(); #查看当前主节点
当前主节点是192.168.68.104,执行如下命令切换为192.168.68.105
mymgr.setPrimaryInstance('192.168.68.105:3306');
再次查看当前主节点:
2.2、手动方式(MGR1)
在命令行模式下,可以使用group_replication_set_as_primary('SERVER_UUID')这个UDF实现切换。
mysql -h localhost -u root -S /data/greatsql/greatsqldata3306/sock/greatsql.sock -proot@PWD123
查看当前节点角色信息
select member_id, member_host, member_port, member_state, member_role from performance_schema.replication_group_members;
当前主节点为192.168.68.101,执行如下命令切换为192.168.68.102
select group_replication_set_as_primary('bd2775c5-014c-11ef-9ae3-005056380108');
再次查看节点角色,以修改192.168.68.102为主节点:
select member_id, member_host, member_port, member_state, member_role from performance_schema.replication_group_members;
3、切换单主/多主模式
分别验证脚本(MySQL Shell)和手动实现方式。
3.1、脚本方式(MGR2)
调用函数switchToMultiPrimaryMode()和switchToSinglePrimaryMode('IP:PORT')可以实现分别切换到多主、单主模式。
集群MGR2当前为单主模式,执行如下脚本函数切换为多主模式:
mymgr=dba.getCluster();
mymgr.switchToMultiPrimaryMode();
查看节点角色信息,都已是主节点角色:
sql
select member_id, member_host, member_port, member_state, member_role from performance_schema.replication_group_members;
执行如下脚本函数,重新切换回单主(192.168.68.104)模式:
js
mymgr.switchToSinglePrimaryMode('192.168.68.104:3306');
再次查看节点角色信息,已修改为单主模式:
sql
select member_id, member_host, member_port, member_state, member_role from performance_schema.replication_group_members;
3.2、手动方式(MGR1)
在命令行模式下,可以调用group_replication_switch_to_single_primary_mode('SERVER_UUID') 和 group_replication_switch_to_multi_primary_mode() 来切换单主/多主模式。
集群MGR1当前为单主模式,执行如下UDF函数切换为多主模式:
select group_replication_switch_to_multi_primary_mode();
查看节点角色信息,已切换为多主模式:
select member_id, member_host, member_port, member_state, member_role from performance_schema.replication_group_members;
继续执行如下UDF函数切换回单主模式,切换192.168.68.101为主节点:
select group_replication_switch_to_single_primary_mode('9e5c18ad-018c-11ef-abce-0050562957d9');
4、添加和删除节点
分别验证脚本(MySQL Shell)和手动实现方式。
MGR1和MGR2分别添加节点192.168.68.107、192.168.68.108
4.1、脚本方式(MGR2)
启动192.168.68.108到加入节点数据库服务:
systemctl start greatsql
调用函数 dba.configureInstance() 完成初始化检查工作,提示当前的用户是管理员,不能直接用于MGR集群,需要新建一个账号(mgradmin/mgradmin@PWD123):
mysqlsh --uri root@localhost:3306 -proot@PWD123
登录192.168.68.104节点,执行脚本函数将108节点加入集群:
mysqlsh --uri mgradmin@192.168.68.104:3306 -pmgradmin@PWD123
mymgr=dba.getCluster();
mymgr.describe();
mymgr.addInstance('mgradmin@192.168.68.108:3306');
再次查看节点信息,192.168.68.108已成功加入集群:
mymgr.describe();
删除节点比较简单,调用 removeInstance('USER@IP:PORT') 函数即可:
执行如下脚本函数,将刚才加入的节点踢出集群:
mymgr.removeInstance('mgradmin@192.168.68.108:3306');
这就将该节点踢出集群了,并且会重置 group_replication_group_seeds 和 group_replication_local_address 两个选项值,之后该节点如果想再加入集群,只需调用 addInstance('USER@IP:PORT') 重新加回即可。
4.2、手动方式(MGR1)
首先,要先完成MySQL Server初始化,创建好MGR专用账户、设置好MGR服务通道等前置工作。
接下来,直接执行命令 start group_replication 启动MGR服务即可,新增的节点会进入分布式恢复这个步骤,它会从已有节点中自动选择一个作为捐献者(donor),并自行决定是直接读取binlog进行恢复,还是利用Clone进行全量恢复。
如果是已经在线运行一段时间的MGR集群,有一定存量数据,这时候新节点加入可能会比较慢,建议手动利用Clone进行一次全量复制。还记得前面创建MGR专用账户时,给加上了 BACKUP_ADMIN 授权码,这时候就排上用场了,Clone需要用到这个权限。
#配置文件添加MGR相关配置项:
vi /etc/my.cnf
plugin_load_add='group_replication.so;mysql_clone.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaabbbbbb"
group_replication_local_address= "192.168.68.107:33061"
group_replication_group_seeds= "192.168.68.101:33061,192.168.68.102:33061,192.168.68.103:33061,192.168.68.107:3306"
report-host=192.168.68.107
#重启服务后,登录待加入节点 192.168.68.107
systemctl restart greatsql
mysql -h localhost -u root -S /data/greatsql/greatsqldata3306/sock/greatsql.sock -proot@PWD123
#创建复制账号
set session sql_log_bin=0;
create user repl@'%' identified with mysql_native_password by 'repl';
grant backup_admin, replication slave on *.* to `repl`@`%`;
set session sql_log_bin=1;
为了降低对Primary节点的影响,建议选择其他Secondary节点:
set global clone_valid_donor_list='192.168.68.102:3306';
#停掉mgr服务(如果有的话),关闭super_read_only模式,然后开始复制数据
#注意这里要填写的端口是3306(MySQL正常服务端口),而不是33061这个MGR服务专用端口
stop group_replication;
set global super_read_only=0;
clone instance from repl@192.168.68.102:3306 identified by 'repl';
注:克隆过程中可以另开窗口查看状态和进度:
select * from performance_schema.clone_status G
select * from performance_schema.clone_progress;
全量复制完数据后,该节点会进行一次自动重启。重启完毕后,再次确认 group_replication_group_name、group_replication_local_address、group_replication_group_seeds 这些选项值是否正确,如果没问题,执行 start group_replication 后,该节点应该就可以正常加入集群了。
登录主节点192.168.68.101,查看107节点已成功加入集群:
在命令行模式下,一个节点想退出MGR集群,直接执行 stop group_replication 即可,如果这个节点只是临时退出集群,后面还想加回集群,则执行 start group_replication 即可自动再加入。而如果是想彻底退出集群,则停止MGR服务后,执行 reset master; reset slave all; 重置所有复制(包含MGR)相关的信息就可以了。
5、使用MySQL Shell接管现存MGR集群
对于已经在运行中的MGR集群,也是可以用MySQL Shell接管的。只需要在调用 createCluster() 函数时,加上 adoptFromGR:true 选项即可。实际上不加这个选项的话,MySQL Shell也会自动检测到该MGR集群已存在,并询问是否要接管。
MGR1集群(192.168.68.101-103,107)当前是使用手动方式管理,现切换为使用MySQL Shell脚本方式接管。
#登录到当前集群所有节点,执行dba.configureInstance(); 创建MGR账号:
mysqlsh --uri root@localhost:3306 -proot@PWD123
dba.configureInstance();
#使用MGR账号登录当前主节点: 192.168.68.102
mysqlsh --uri mgradmin@192.168.68.102:3306 -pmgradmin@PWD123
mymgr=dba.createCluster('MGR1', {adoptFromGr:true});
#查看集群当前节点信息
mymgr.status(); #mymgr.describe();
6、使用MySQL Router构建读写分离
MySQL Router是一个轻量级的中间件,它采用多端口的方案实现读写分离以及读负载均衡,而且同时支持mysql和mysql x协议。
建议把MySQL Router部署在应用服务器上,每个应用服务器都部署一套,这样应用程序可以直接连接本机IP,连接的效率更高,而且后端数据库发生变化时,程序端也无需修改IP配置。
6.1、部署MySQL Router
rpm -ivh greatsql-mysql-router-8.0.32-25.1.el8.x86_64.rpm
MySQL Router第一次启动时要先初始化:
mysqlrouter --bootstrap mgradmin@192.168.68.101:3306 --user=mysqlrouter
参数解释参数:
--bootstrap 表示开始初始化参数
mgradmin@192.168.68.101:3306 是MGR服务专用账号
--user=mysqlrouter 是运行mysqlrouter进程的系统用户名
# 然后mysqlrouter开始自动进行初始化
# 它会自动读取MGR的元数据信息,自动生成配置文件
如果想自定义名字和目录,还可以在初始化时自行指定 --name 和 --directory 选项,这样可以实现在同一个服务器上部署多个Router实例。
列如:针对4306端口的服务,初始化一个router实例,可自行指定目录、实例名、端口号等多个选项
mysqlrouter --bootstrap mymgr@172.16.16.16:4306 --name=MyMGR --directory=/etc/mysqlrouter/MyMGR --user=mysqlrouter --conf-base-port=7446 --https-port=9443
6.2、启动myqlrouter服务
mysqlrouter 初始化时自动生成的配置文件是 /etc/mysqlrouter/mysqlrouter.conf,主要是关于R/W、RO不同端口的配置。可以根据需要自行修改绑定的IP地址和端口,也可以在初始化时指定 --conf-base-port 选项自定义初始端口号。
systemctl start mysqlrouter
6.3、验证读写分离
用客户端连接到6446(读写)端口,确认连接的是Primary节点:
mysql -h 192.168.68.107 -P 6446 -u mgradmin -pmgradmin@PWD123
select member_id,member_role from performance_schema.replication_group_members;
select @@server_uuid;
同样地,连接6447(只读)端口,确认连接的是Secondary节点:
mysql -h 192.168.68.107 -P 6447 -u mgradmin -pmgradmin@PWD123
select member_id,member_role from performance_schema.replication_group_members;
select @@server_uuid;
6.4、验证只读负载均衡
MySQL Router连接读写节点(Primary节点)默认的策略是 first-available,即只连接第一个可用的节点。Router连接只读节点(Secondary节点)默认的策略是 round-robin-with-fallback,会在各个只读节点间轮询。
保持6447端口原有的连接不退出,继续新建到6447端口的连接,查看变量值:server_uuid,这时应该会发现读取到的是其他只读节点的值,因为mysqlrouter的读负载均衡机制是在几个只读节点间自动轮询。在默认的round-robin-with-fallback策略下,只有当所有Secondary节点都不可用时,只读请求才会打到Primary节点上。
#在多台客户端连接6447端口,查看只读负载均衡情况:
mysql -h 192.168.68.107 -P 6447 -u mgradmin -pmgradmin@PWD123
select member_id,member_role from performance_schema.replication_group_members;
select @@server_uuid;
6.5、验证故障自动转移
模拟Primary节点宕机或切换时,mysqlrouter 也能实现自动故障转移。
#先查看当前集群中,各节点角色情况:
select member_host, member_port, member_state, member_role from performance_schema.replication_group_members;
注:当前集群主节点是192.168.68.101:3306
切换集群主节点到:192.168.68.102:3306
mymgr.setPrimaryInstance('192.168.68.102:3306');
sql
select member_host, member_port, member_state, member_role from performance_schema.replication_group_members;
注:如上所示,集群当前主节点已经切换为192.168.68.102:3306
再次登录mysqlrouter的6446端口查看:
mysql -h 192.168.68.107 -P 6446 -u mgradmin -pmgradmin@PWD123
select member_id,member_role from performance_schema.replication_group_members;
select @@server_uuid
注:如上图所示,再次登录6446端口,访问的是集群切换后的主节点。
7、MGR状态监控
MGR和传统主从复制类似,在运行过程中主要关注各节点的运行状态,以及Secondary节点的事务是否有延迟等。
7.1、节点状态监控
通过查询 performance_schema.replication_group_members 表即可知道MGR各节点的状态:
select member_id, member_host, member_port, member_state, member_role from performance_schema.replication_group_members;
输出结果中主要几个列的解读如下:
MEMBER_ID 列值就是各节点的 server_uuid,用于唯一标识每个节点,在命令行模式下,调用 udf 时传入 MEMBER_ID 以指定各节点。
MEMBER_ROLE 表示各节点的角色,如果是 PRIMARY 则表示该节点可接受读写事务,如果是 SECONDARY 则表示该节点只能接受只读事务。如果只有一个节点是 PRIMARY,其余都是 SECONDARY,则表示当前处于 单主模式;如果所有节点都是 PRIMARY,则表示当前处于 多主模式。
MEMBER_STATE 表示各节点的状态,共有几种状态:ONLINE、RECOVERING、OFFLINE、ERROR、UNREACHABLE 等,下面分别介绍几种状态。
ONLINE表示节点处于正常状态,可提供服务。
RECOVERING表示节点正在进行分布式恢复,等待加入集群,这时候有可能正在从donor节点利用clone复制数据,或者传输binlog中。
OFFLINE表示该节点当前处于离线状态。提醒,在正要加入或重加入集群时,可能也会有很短瞬间的状态显示为OFFLINE。
ERROR表示该节点当前处于错误状态,无法成为集群的一员。当节点正在进行分布式恢复或应用事务时,也是有可能处于这个状态的。当节点处于ERROR状态时,是无法参与集群事务裁决的。节点正在加入或重加入集群时,在完成兼容性检查成为正式MGR节点前,可能也会显示为ERROR状态。
UNREACHABLE当组通信消息收发超时时,故障检测机制会将本节点标记为怀疑状态,怀疑其可能无法和其他节点连接,例如当某个节点意外断开连接时。当在某个节点上看到其他节点处于 UNREACHABLE 状态时,有可能意味着此时部分节点发生了网络分区,也就是多个节点分裂成两个或多个子集,子集内的节点可以互通,但子集间无法互通。
当节点的状态不是ONLINE时,就应当立即发出告警并检查发生了什么。
在节点状态发生变化时,或者有节点加入、退出时,表 performance_schema.replication_group_members的数据都会更新,各节点间会交换和共享这些状态信息,因此可以在任意节点查看。
7.2、事务状态监控
可以执行下面的命令查看当前除了 PRIMARY 节点外,其他节点的 trx_tobe_certified 或 relaylog_tobe_applied 值是否较大:
select member_id as id, count_transactions_in_queue as trx_tobe_certified, count_transactions_remote_in_applier_queue as relaylog_tobe_applied, count_transactions_checked as trx_chkd, count_transactions_remote_applied as trx_done, count_transactions_local_proposed as proposed from performance_schema.replication_group_member_stats;
其中,relaylog_tobe_applied 的值表示远程事务写到relay log后,等待回放的事务队列,trx_tobe_certified 表示等待被认证的事务队列大小,这二者任何一个值大于0,都表示当前有一定程度的延迟。
还可以通过关注上述两个数值的变化,看看两个队列是在逐步加大还是缩小,据此判断Primary节点是否"跑得太快"了,或者Secondary节点是否"跑得太慢"。
注:如果启用流控(flow control)时,上述两个值超过相应的阈值时(group_replication_flow_control_applier_threshold 和 group_replication_flow_control_certifier_threshold 默认阈值都是 25000),就会触发流控机制。
7.3、其他监控
另外,也可以查看接收到的事务和已执行完的事务之间的差距来判断:
select received_transaction_set from performance_schema.replication_connection_status where channel_name = 'group_replication_applier' union all select variable_value from performance_schema.global_variables where variable_name = 'gtid_executed' G
注:当原来的主节点发生故障,想要手动选择某个节点做为新的主节点时,应该先判断哪个节点已执行的事务GTID值更大,应优先选择该节点。