1、相关概念介绍:html
一、MGR简介:前端
MySQL Group Replication(简称MGR)是MySQL官方推出的一种基于paxos协议的状态机复制,实现了分布式下数据的最终一致性。MySQL组复制提供了高可用、高扩展、高可靠的MySQL集群解决方案。相关网址https://dev.mysql.com/doc/refman/5.7/en/group-replication.html。node
二、MGR特性:mysql
(1)高一致性:基于原生复制及paxos协议的组复制技术,并以插件的方式提供,保证数据一致性git
(2)高容错性:只要不是大多数节点宕机就能够继续工做,有自动检测机制,当不一样节点产生资源争用冲突时,不会出现错误,按照先到者优先原则进行处理,而且内置自动化脑裂防御机制github
(3)高扩展性:节点的新增和移除都是自动的,新节点加入后,会自动从其它节点同步状态,直到新节点和其它节点保持一致,若是某节点被移除了,其它节点自动更新组信息web
(4)高灵活性:有单主模式和多主模式,单主模式下会自动选择主节点,全部更新操做都在主节点上进行;多主模式下全部server均可以同时处理更新操正则表达式
三、MGR局限性:算法
(1)仅支持InnoDB表,而且每张表必定要有一个主键,用于write set的冲突检测sql
(2)必须启用GTID特性,二进制日志格式必须设置为ROW,用于选主与write set
(3)COMMIT可能会致使失败,相似于快照事务隔离级别的失败场景
(4)目前一个MGR集群最多支持9个节点
(5)不支持外键于save point特性,没法作全局间的约束检测与部分回滚
(6)二进制日志不支持binlog event checksum
四、MGR集群架构:
五、MGR与其它复制方式的对比:
(1)MySQL异步复制:
master节点事务的提交不须要通过slave节点的确认,slave节点是否接收到master节点的binlog,master节点并不关心。slave节点接收到master节点的binlog后先写relay log,最后异步地去执行relay log中的sql应用到本地。因为master节点的提交不须要确保slave节点的relay log是否被正确接收,当slave节点接收master节点的binlog失败或relay log应用失败,master节点没法感知。假设master节点发生宕机且binlog还未被slave节点接收,而切换程序将slave节点提高为新的master节点,就会出现数据不一致的状况。另外,在高并发的状况下,传统的主从复制,slave节点可能会与master节点产生较大的延迟。
(2)MySQL半同步复制:
基于传统异步复制存在的缺陷,MySQL在5.5版本中推出半同步复制,能够说半同步复制是传统异步复制的改进,在master节点事务commit以前,必须确保一个slave节点收到relay log且响应给master节点之后,才能进行事务的commit,可是slave节点对于relay log的应用仍然是异步进行的。
(3)MySQL组复制:
基于传统异步复制和半同步复制的缺陷,即数据的一致性问题没法保证,MySQL官方在5.7.17版本中正式推出组复制(MySQL Group Replication,简称MGR)。由若干个节点共同组成一个复制组,一个事务的提交,必须通过组内大多数节点(N/2+1)决议并经过,才能得以提交。由三个节点组成一个复制组,Consensus层为一致性协议层,在事务提交过程当中,发生组间通信,由两个节点决议(certify)经过这个事务,事务才能最终得以提交并响应。一个复制组由若干个节点(数据库实例)组成,组内各个节点维护各自的数据副本,经过一致性协议实现原子消息和全局有序消息,来实现组内实例数据的一致。
六、ProxySQL简介:
ProxySQL是MySQL的一款中间件产品,是灵活强大的MySQL代理层,能够实现读写分离,可自定义基于用户、基于schema、基于语句的规则对SQL语句进行路由,支持动态指定某个SQL进行缓存,支持动态加载配置、故障转移和一些SQL的过滤功能,能够实现简单的sharding。
七、ProxySQL的多层配置系统:
ProxySQL有一套很完整的配置系统,方便DBA对线上的操做。整套配置系统分为三层,顶层为RUNTIME,中间层为MEMORY,底层也就是持久层的DISK和CONFIG FILE。配置结构以下图所示:
(1)RUNTIME:ProxySQL当前生效的生产环境正在使用的配置,包括global_variables、mysql_servers、mysql_users、mysql_query_rules等,没法直接修改RUNTIME的配置,必需要从下一层“load”进来,也就是说RUNTIME这个顶级层,就是ProxySQL运行过程当中实际采用的那一份配置,这一份配置就是要影响实际生产环境的。
(2)MEMORY:用户能够将MySQL客户端链接到此接口(admin接口),并查询不一样的表和数据库是在MySQL命令行修改的main数据库中的配置,能够认为是SQLite数据库在内存的镜像,也就是说MEMORY这个中间层,上面链接着生产配置项RUNTIME层,下面链接着持久化层DISK和CONFIG FILE。MEMORY也是修改ProxySQL的惟一正常入口。修改一个配置通常都是先在MEMORY层完成,确认无误后再加载到RUNTIME和持久化到磁盘上,也就是说在这层能够正常操做ProxySQL配置,MEMORY层中的配置修改不会影响生产环境,也不影响磁盘中保存的数据,经过此接口能够修改main数据库中以mysql_开头的表(如:mysql_servers、mysql_users、mysql_query_rules)和global_variables表等。
(3)DISK和CONFIG FILE:持久化配置信息,通常保存在/var/lib/proxysql/proxysql.db数据文件中,重启后内存中的配置信息会丢失,因此须要将配置信息保留在磁盘中。重启时,能够从磁盘快速加载回来。配置文件/etc/proxysql.cnf只在第一次初始化时用到。DISK和CONFIG FILE这一层是持久化层,作的任何配置更改,若是不持久化,重启后,配置将丢失。
八、ProxySQL相关网址:
(1)GitHub官网:https://github.com/sysown/proxysql/releases
(2)Percona官网:https://www.percona.com/downloads/proxysql/
2、准备工做(四个节点都须要执行以下操做):
一、 演示环境:
IP |
操做系统 |
主机名 |
角色 |
软件包版本 |
安装方式 |
192.168.1.143 |
CentOS 7.6 x86_64 |
node1 |
proxysql |
2.0.4-percona-1.2 |
yum |
192.168.1.144 |
CentOS 7.6 x86_64 |
node2 |
master |
5.7.26-log MySQL Community Server |
rpm |
192.168.1.145 |
CentOS 7.6 x86_64 |
node3 |
slave1 |
5.7.26-log MySQL Community Server |
rpm |
192.168.1.146 |
CentOS 7.6 x86_64 |
node4 |
slave2 |
5.7.26-log MySQL Community Server |
rpm |
二、实验架构:
三、关闭SELinux和firewalld
四、配置epel源
五、配置节点时间同步
六、配置主机名
七、配置/etc/hosts文件:
# vim /etc/hosts
192.168.1.143 node1
192.168.1.144 node2
192.168.1.145 node3
192.168.1.146 node4
八、下载MySQL 5.7软件包,https://dev.mysql.com/downloads/mysql/5.7.html#downloads
3、构建MGR单主高可用集群(如未特殊说明,在master、slave1和slave2节点中分别执行以下操做):
一、安装配置MySQL:
(1)卸载CentOS 7.6自带的MariaDB:
# rpm -qa | grep -i mariadb --> mariadb-libs-5.5.60-1.el7_5.x86_64
# rpm -e --nodeps mariadb-libs-5.5.60-1.el7_5.x86_64
(2)若是以前安装过MySQL,先卸载:# rpm -qa | grep -i mysql
(3)若是存在/etc/my.cnf配置文件,先删除:# rm -rf /etc/my.cnf
(4)将软件包上传至主机/tmp目录下:
mysql-community-client-5.7.26-1.el7.x86_64.rpm
mysql-community-libs-5.7.26-1.el7.x86_64.rpm
mysql-community-common-5.7.26-1.el7.x86_64.rpm
mysql-community-libs-compat-5.7.26-1.el7.x86_64.rpm
mysql-community-devel-5.7.26-1.el7.x86_64.rpm
mysql-community-server-5.7.26-1.el7.x86_64.rpm
(5)安装MySQL软件包:# yum -y localinstall *.rpm
(6)初始化MySQL数据:# mysqld --initialize --user=mysql --datadir=/var/lib/mysql
备注:初始化以前确保/var/lib/mysql目录为空
(7)修改MySQL配置文件:
# mv /etc/my.cnf /etc/my.cnf.bak
# vim /etc/my.cnf
master节点:
[mysqld]
port=3306
socket=/var/lib/mysql/mysql.sock
datadir=/var/lib/mysql
pid-file=/var/run/mysqld/mysqld.pid
log-error=/var/log/mysqld.log
lower_case_table_names=1
character_set_server=utf8mb4
collation_server=utf8mb4_general_ci
innodb_file_per_table=1
skip_name_resolve=1
slow_query_log=1
slow_query_log_file=mysql-slow.log
symbolic-links=0
explicit_defaults_for_timestamp=1
log_bin=mysql-bin
log_bin_index=mysql-bin.index
binlog_format=row
server_id=1
gtid_mode=on
enforce_gtid_consistency=on
master_info_repository=table
relay_log_info_repository=table
binlog_checksum=none
log_slave_updates=on
备注:
a、slave1节点中server_id=2,增长read_only=1,其它参数保持不变
b、slave2节点中server_id=3,增长read_only=1,其它参数保持不变
(8)启动MySQL服务:
# systemctl start mysqld.service
# ss -tunlp | grep mysqld
# systemctl enable mysqld.service
# systemctl status mysqld.service
(9)查看root@localhost用户的初始密码:# grep password /var/log/mysqld.log
(10)配置MySQL安全向导:# mysql_secure_installation
二、安装group_replication插件:
# mysql -uroot -p
mysql> install plugin group_replication soname 'group_replication.so';
mysql> show plugins;
备注:插件位于/usr/lib64/mysql/plugin/group_replication.so
三、修改MySQL配置文件,增长MGR相关配置:
# vim /etc/my.cnf
master节点:
[mysqld]
transaction_write_set_extraction=XXHASH64
group_replication_group_name='aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
group_replication_start_on_boot=off
group_replication_local_address='192.168.1.144:24901'
group_replication_group_seeds='192.168.1.144:24901,192.168.1.145:24901,192.168.1.146:24901'
group_replication_bootstrap_group=off
group_replication_enforce_update_everywhere_checks=off
group_replication_single_primary_mode=on
# systemctl restart mysqld.service
备注1:
(1)slave1节点中group_replication_local_address='192.168.1.145:24901',其它参数保持不变
(2)slave2节点中group_replication_local_address='192.168.1.146:24901',其它参数保持不变
备注2:参数说明
(1)gtid_mode=on:启用GTID模式
(2)enforce_gtid_consistency=on:启用强制GTID一致性
(3)master_info_repository=table:将master.info元数据保存在系统表中
(4)relay_log_info_repository=table:将relay.info元数据保存在系统表中
(5)binlog_checksum=none:禁用二进制日志事件校验
(6)log_slave_updates=on:启用级联复制
(7)transaction_write_set_extraction=XXHASH64:使用XXHASH64哈希算法将其编码为散列
(8)group_replication_group_name='aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa':加入或建立的组名称,值必须是有效的UUID
(9)group_replication_start_on_boot=off:server启动时不自动启动组复制
(10)group_replication_local_address='192.168.1.144:24901':该节点的MGR模块通讯地址,自定义端口24901用于与组中的其它成员进行内部通讯
(11)group_replication_group_seeds='192.168.1.144:24901,192.168.1.145:24901,192.168.1.146:24901':组成员的IP和端口
(12)group_replication_bootstrap_group=off:不执行MGR复制组的初始化操做,若是该参数设置为on,表示会建立一个MGR复制组,在此处master是第一个初始化节点,动态开启该参数,而后再启动MGR
(13)group_replication_enforce_update_everywhere_checks=off:该参数设置为off,表示启用单主模式,设置为on,表示启用多主模式
(14)group_replication_single_primary_mode=on:该参数设置为on,表示启用单主模式,设置为off,表示启用多主模式
四、建立具备复制权限的用户repluser:
mysql> set sql_log_bin=0;
mysql> create user 'repluser'@'192.168.1.%' identified by '123456';
mysql> grant replication slave on *.* to 'repluser'@'192.168.1.%';
mysql> flush privileges;
mysql> set sql_log_bin=1;
备注:组复制使用异步复制协议来实现分布式恢复,在将组成员加入组以前将其同步,该用户为故障恢复的异步复制通道group_replication_recovery所用,复制通道用于在组成员之间传输事务
五、构建MGR集群:
mysql> change master to master_user='repluser',master_password='123456' for channel 'group_replication_recovery';
六、启动MGR集群:
master节点执行以下操做:
mysql> set global group_replication_bootstrap_group=on;
mysql> start group_replication;
mysql> set global group_replication_bootstrap_group=off;
slave1和slave2节点分别执行以下操做,加入复制组:
mysql> set global group_replication_allow_local_disjoint_gtids_join=on;
mysql> start group_replication;
备注:
(1)set global group_replication_bootstrap_group=on:只需在master节点中执行,表示之后加入集群的成员以master节点为准,且只需执行一次
(2)set global group_replication_bootstrap_group=off:确保master节点下一次启动时不会再进行初始化,致使复制组出现分裂
七、查看MGR状态信息:
mysql> select * from performance_schema.replication_group_members;
备注:按照MEMBER_ID进行升序排序,每一个节点执行结果相同
mysql> select * from performance_schema.replication_connection_status\G
master节点:
slave1节点:
slave2节点:
mysql> show global variables like '%group_replication%';
mysql> select if((select @@server_uuid)=(select variable_value from performance_schema.global_status where variable_name='group_replication_primary_member'),1,0) as is_primary_mode,@@server_id;
master节点:
备注:is_primary_mode的值为1说明此节点为master节点
slave1节点:
slave2节点:
八、master节点建立测试数据:
mysql> create database db;
mysql> use db;
mysql> create table tb(id int unsigned auto_increment primary key not null,age int not null);
mysql> desc tb;
mysql> insert into tb(age) values(35),(40);
mysql> select * from tb;
九、slave1和slave2节点分别查看测试数据:
mysql> show databases like 'db';
mysql> select * from db.tb;
4、安装配置ProxySQL(如未特殊说明,在proxysql节点中执行以下操做):
一、配置percona源:
# yum -y install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
# yum repolist
二、安装MySQL客户端工具:# yum -y install Percona-Server-client-57
三、安装ProxySQL:# yum list | grep -i percona # yum -y install proxysql2 # proxysql --version
备注:ProxySQL相关文件
(1)配置文件:/etc/proxysql-admin.cnf、/etc/proxysql.cnf
(2)SQLite数据文件:/var/lib/proxysql/proxysql.db
(3)日志文件:/var/lib/proxysql/proxysql.log
备注:若是存在proxysql.db数据文件,则ProxySQL启动过程当中将不会读取proxysql.cnf配置文件的内容来初始化ProxySQL
四、启动ProxySQL:
# systemctl start proxysql.service
# ss -tunlp | grep proxysql
备注:6032是ProxySQL的管理端口号,6033是对外服务的端口号
五、使用默认的admin用户(密码也为admin)登陆ProxySQL管理界面:
# mysql -uadmin -p -h127.0.0.1 -P6032 --prompt='proxysql> '
备注:若是须要建立一个新用户marion,密码为123456,则可执行以下操做
proxysql> update global_variables set variable_value='admin:admin;marion:123456' where variable_name='admin-admin_credentials';
proxysql> load admin variables to runtime;
proxysql> save admin variables to disk;
备注:不管执行任何操做,都须要执行load *** to runtime(从memory加载到runtime)、save *** to disk(持久化到磁盘)
六、master节点建立ProxySQL的监控用户monitor和对外访问用户proxysql,并赋予权限:
mysql> create user 'monitor'@'192.168.1.%' identified by '123456';
mysql> grant all on *.* to 'monitor'@'192.168.1.%';
mysql> create user 'proxysql'@'192.168.1.%' identified by '123456';
mysql> grant all on *.* to 'proxysql'@'192.168.1.%';
mysql> flush privileges;
七、添加主从服务器列表:
proxysql> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(10,'192.168.1.144',3306,1,'master'),(10,'192.168.1.145',3306,1,'slave1'),(10,'192.168.1.146',3306,3,'slave2');
proxysql> load mysql servers to runtime;
proxysql> save mysql servers to disk;
proxysql> select * from mysql_servers;
备注:
(1)表mysql_servers:后端能够链接MySQL主机的列表
(2)全部节点都是ONLINE状态
(3)slave2节点的查询权重调整为3,为了让更多的读请求路由到这台配置更好的主机上
(4)表mysql_servers经常使用字段说明:
字段 |
说明 |
hostgroup_id |
ProxySQL经过hostgroup的形式组织后端db实例,一个hostgroup表明同属于一个角色,默认为0 |
hostname |
后端实例IP |
port |
后端实例监听端口,默认为3306 |
status |
后端实例状态,默认为online,可取值为: Ø online:当先后端实例状态正常 Ø shunned:临时被剔除,可能由于后端too many connections error,或者超过了可容忍延迟阀值max_replication_lag Ø offline_soft:“软离线”状态,再也不接收新的链接,但已创建的链接会等待活跃事务完成 Ø offline_hard:“硬离线”状态,再也不接收新的链接,已创建的链接或被强制中断,当后端实例宕机或网络不可达时,会出现 |
weight |
后端实例权重,默认为1 |
max_connections |
容许链接到该后端实例的最大链接数,不能大于MySQL设置的max_connections,若是后端实例hostname:port在多个hostgroup中,以较大者为准,而不是各自独立容许的最大链接数,默认为1000 |
max_replication_lag |
容许的最大延迟,master节点不受此影响,默认为0,若是>0,monitor模块监控主从延迟大于阀值时,会临时把它变为shunned |
max_latency_ms |
mysql_ping响应时长,大于这个阀值会把它从链接池中剔除(即便是ONLINE状态),默认为0 |
comment |
备注 |
(5)查看表中的字段可以使用命令proxysql> show create table mysql_servers\G
(6)查看表中的数据可以使用命令proxysql> select * from mysql_servers\G
八、配置和注册监控用户monitor,并验证监控信息:
proxysql> set mysql-monitor_username='monitor';
proxysql> set mysql-monitor_password='123456';
proxysql> load mysql variables to runtime;
proxysql> save mysql variables to disk;
proxysql> select * from global_variables where variable_name in ('mysql-monitor_username','mysql-monitor_password');
proxysql> select * from monitor.mysql_server_connect_log order by time_start_us desc limit 6;
proxysql> select * from monitor.mysql_server_ping_log order by time_start_us desc limit 6;
九、配置ProxySQL主从分组信息:
proxysql> insert into mysql_replication_hostgroups values (10,20,'read_only','proxysql');
proxysql> load mysql servers to runtime;
proxysql> save mysql servers to disk;
备注:
(1)表mysql_replication_hostgroups经常使用字段说明:
字段 |
说明 |
writer_hostgroup |
写入组的编号,此处为10 |
reader_hostgroup |
读取组的编号,此处为20 |
check_type |
可取值为:'read_only'、'innodb_read_only'、'super_read_only',默认值为'read_only' |
comment |
备注 |
(2)查看表中的字段可以使用命令proxysql> show create table mysql_replication_hostgroups\G
(3)查看表中的数据可以使用命令proxysql> select * from mysql_replication_hostgroups\G
proxysql> select * from mysql_replication_hostgroups;
proxysql> select hostgroup_id,hostname,port,status,weight,comment from mysql_servers;
备注:ProxySQL会根据MySQL中read_only的取值将主机进行分组,read_only=0的master节点被分配到编号为10的写入组,而read_only=1的两个slave节点则被分配到编号为20的读取组
十、配置对外访问用户proxysql:
proxysql> insert into mysql_users(username,password,default_hostgroup) values('proxysql','123456',10);
proxysql> load mysql users to runtime;
proxysql> save mysql users to disk;
proxysql> select * from mysql_users\G
备注:
(1)表mysql_users:配置后端数据库用户和监控用户
(2)表mysql_users经常使用字段说明:
字段 |
说明 |
username |
前端链接ProxySQL,及ProxySQL将SQL语句路由给后端MySQL实例中所使用的用户名 |
password |
后端MySQL实例中用户名对应的密码,能够是明文密码,也能够是hash加密后的密文,若是想使用hash密码,能够先在某个MySQL节点中执行select password(PASSWORD),而后将加密结果复制到该字段 |
active |
只有active=1的用户才是有效的用户 |
default_hostgroup |
该用户名默认的路由目标,如:指定root用户的该字段值为10时,则使用root用户发送的SQL语句默认状况下将路由到hostgroup_id=10组中的某个节点,若是该用户的请求没有匹配到规则时,默认发送到这个hostgroup |
default_schema |
用户默认登陆后端MySQL实例时链接的数据库,若是为NULL,则由全局变量mysql-default_schema决定,默认为information_schema |
transaction_persistent |
默认为1,表示启用事务持久化,链接上ProxySQL的会话后,若是在一个hostgroup中开启了事务,那么在事务提交/回滚以前,全部的语句都路由到同一个组中,不管是否会匹配上其它路由规则,直到事务结束,避免语句分散到不一样组(更进一步的,它会自动禁用multiplexing,让同一个事务的语句从同一个链接路由出去,保证路由到同一个组的同一个节点),避免发生脏读、幻读等状况 |
(3)查看表中的字段可以使用命令proxysql> show create table mysql_users\G
(4)查看表中的数据可以使用命令proxysql> select * from mysql_users\G
十一、验证经过对外服务6033端口登陆的是master节点:
# mysql -uproxysql -p -h192.168.1.143 -P6033 -e 'select @@hostname;'
备注:node2为master节点的主机名
十二、配置路由规则,实现读写分离:
proxysql> insert into mysql_query_rules(active,match_pattern,destination_hostgroup,apply) values(1,'^select.*for update$',10,1),(1,'^select',20,1);
proxysql> load mysql query rules to runtime;
proxysql> save mysql query rules to disk;
proxysql> select rule_id,active,match_pattern,destination_hostgroup,apply from mysql_query_rules;
备注:
(1)select for update会产生一个写锁,对数据查询的时效性要求较高,因此将它分配到编号为10的写入组
(2)除了select for update之外全部select开头的语句所有分配到编号为20的读取组
(3)其它全部操做都默认路由到写入组(mysql_users表中字段default_hostgroup定义的值)
(4)表mysql_query_rules:指定query路由到后端不一样主机的规则列表
(5)表mysql_query_rules经常使用字段说明:
字段 |
说明 |
rule_id |
表主键,自增,规则处理是以rule_id的顺序进行 |
active |
默认为0,值为1时表示启用此路由规则 |
username |
若是不为空,该规则只匹配该用户 |
schemaname |
若是不为空,该规则只匹配该数据库名称,若是为NULL,不表明链接没有使用schema,而是不管任何schema都进一步匹配 |
client_addr |
匹配客户端来源IP |
proxy_addr |
匹配本地ProxySQL的IP |
proxy_port |
匹配本地ProxySQL的端口 |
match_digest |
描述规则的正则表达式,1.4版本之后,正则表达式支持pcre和pcre2两种,默认使用pcre,即perl语言支持的正则表达式,query digest是指对查询去掉具体值后进行“模糊化”后的查询 |
match_pattern |
正则表达式匹配查询 |
negate_match_pattern |
反向匹配,至关于对match_digest/match_pattern的匹配取反,默认为0 |
re_modifiers |
修改正则匹配的参数,如默认的:忽略大小写CASELESS、禁用GLOBAL,默认为CASELESS |
destination_hostgroup |
该路由规则发往哪一个组 |
cache_ttl |
用户查询缓存的时间阈值,单位为毫秒 |
timeout |
这一类查询执行的最大时间(单位为毫秒),超时则自动kill,这是对后端db的保护机制,默认mysql-default_query_timeout的值是10h |
retries |
语句在执行失败时,重试的次数,默认由mysql-query_retries_on_failure变量指定,默认为1 |
delay |
查询延迟执行,这是ProxySQL提供的限流机制,会让其它的查询优先执行 |
apply |
默认为0,值为1时表示该正则匹配后,将再也不接受其它匹配,直接转发 |
comment |
备注 |
(6)查看表中的字段可以使用命令proxysql> show create table mysql_query_rules\G
(7)查看表中的数据可以使用命令proxysql> select * from mysql_query_rules\G
1三、ProxySQL中的内置数据库及经常使用表、字段说明:
proxysql> show databases;
备注:默认已处于main数据库中
(1)main:内存配置数据库,即memory,表中存放后端db实例、用户验证、路由规则等信息
查看main数据库中的表:proxysql> show tables from main;
备注:表名以runtime_开头的表示ProxySQL当前正在运行的配置内容,不能经过DML语句修改,但能从其它层级加载,只能修改对应的不以runtime_开头的表,而后load *** to runtime(从memory加载到runtime)、save *** to disk(持久化到磁盘)
(2)disk:持久化到磁盘的配置,SQLite数据文件
查看disk数据库中的表:proxysql> show tables from disk;
(3)stats:ProxySQL将收集的统计数据存储在stats数据库中,包括到后端各命令的执行次数、流量、processlist、查询种类汇总/执行时间等等
查看stats数据库中的表:proxysql> show tables from stats;
a、表stats_mysql_commands_counters:统计各类SQL类型的执行次数和时间
表stats_mysql_commands_counters经常使用字段说明:
字段 |
说明 |
Command |
已执行的SQL命令的类型,如:FLUSH、INSERT、KILL、SELECT等 |
Total_Time_us |
执行该类型命令的总时间(以微秒为单位) |
Total_cnt |
执行该类型命令的总数 |
cnt_100us、cnt_500us、cnt_1ms、cnt_5ms、cnt_10ms、cnt_50ms、cnt_100ms、cnt_500ms、cnt_1s、cnt_5s、cnt_10s、cnt_INFs |
在指定的时间内执行该类型的命令总数和前一个命令的总数 |
b、表stats_mysql_connection_pool:链接后端MySQL的链接池信息
表stats_mysql_connection_pool经常使用字段说明:
字段 |
说明 |
hostgroup |
后端主机所属的主机组,单个后端主机能够属于多个主机组 |
srv_host |
后端主机正在侦听链接的IP |
srv_port |
后端主机正在侦听链接的TCP Port |
status |
后端实例状态,默认为online,可取值为: Ø online:当先后端实例状态正常 Ø shunned:临时被剔除,可能由于后端too many connections error,或者超过了可容忍延迟阀值max_replication_lag Ø offline_soft:“软离线”状态,再也不接收新的链接,但已创建的链接会等待活跃事务完成 Ø offline_hard:“硬离线”状态,再也不接收新的链接,已创建的链接或被强制中断,当后端实例宕机或网络不可达时,会出现 |
ConnUsed |
ProxySQL当前使用多少个链接来向后端主机发送查询 |
ConnFree |
目前有多少个空闲链接 |
ConnOK |
成功创建了多少个链接 |
ConnERR |
没有成功创建多少个链接 |
Queries |
路由到此特定后端主机的查询数 |
Bytes_data_sent |
发送到后端主机的数据量 |
Bytes_data_recv |
从后端主机接收的数据量 |
Latency_us |
从monitor报告的当前ping(以毫秒为单位)的延迟时间 |
c、表stats_mysql_global:与MySQL相关的代理级别的全局统计
表stats_mysql_global经常使用字段说明:
字段 |
说明 |
Client_Connections_aborted |
因为无效凭据或max_connections而致使的前端链接数已达到 |
Client_Connections_connected |
当前链接的前端链接数 |
Client_Connections_created |
到目前为止建立的前端链接数 |
Questions |
从前端发送的查询总数 |
Slow_queries |
在全局变量中定义的运行时间超过阈值的毫秒数的查询数mysql-long_query_time |
d、表stats_mysql_processlist:相似MySQL的show processlist的命令,查看各线程的状态
表stats_mysql_processlist经常使用字段说明:
字段 |
说明 |
ThreadID |
ProxySQL线程ID |
SessionID |
ProxySQL会话ID,经过此ID能够进行kill操做 |
user |
经过MySQL客户端链接ProxySQL的用户 |
db |
当前选择的数据库 |
cli_host |
链接ProxySQL的MySQL客户端IP |
cli_port |
链接ProxySQL的TCP端口 |
hostgroup |
当前主机组,若是正在处理查询,则是查询已被路由或将要路由的主机组,或默认主机组,能够查看该SQL究竟是路由到哪一个主机组中 |
l_srv_host |
ProxySQL的IP |
l_srv_port |
ProxySQL的TCP端口 |
srv_host |
后端MySQL服务器的IP |
srv_port |
后端MySQL服务器的TCP端口 |
command |
正在执行的MySQL查询类型 |
time_ms |
命令执行的时长(以毫秒为单位) |
info |
正在执行的SQL |
e、表stats_mysql_query_rules:统计路由命中次数
表stats_mysql_query_rules经常使用字段说明:
字段 |
说明 |
rule_id |
路由规则的id与main.mysql_query_rules的id对应 |
hits |
此路由规则的匹配总数,若是当前传入的查询符合规则,则会记录一次命中 |
(4)monitor:存储monitor模块收集的信息,主要是对后端db的健康/延迟检查
查看monitor数据库中的表:proxysql> show tables from monitor;
表名 |
说明 |
mysql_server_connect_log |
链接全部MySQL主机以检查它们是否可用,该表用来存放检测链接的日志,由变量mysql-monitor_connect_interval来控制其检测的时间间隔,由参数mysql-monitor_connect_timeout控制链接是否超时(默认为200毫秒) |
mysql_server_ping_log |
使用mysql_ping API ping后端MySQL主机检查它们是否可用,该表用来存放ping的日志,由变量mysql-monitor_ping_interval控制ping的时间间隔,默认为10000(单位毫秒,至关于10秒) |
mysql_server_replication_lag_log |
后端MySQL服务主从延迟的检测,由参数mysql-monitor_replication_lag_interval控制检测时间间隔,由mysql_servers.max_replication_lag列控制,默认为10000(单位毫秒,至关于10秒) |
备注:
a、查看表中的字段可以使用命令proxysql> show create table 表名\G
b、查看表中的数据可以使用命令proxysql> select * from 表名\G
5、测试ProxySQL:
一、测试读写分离:
(1)清空stats_mysql_query_digest表:
# mysql -uadmin -p -h127.0.0.1 -P6032 --prompt='proxysql> '
proxysql> select * from stats_mysql_query_digest_reset;
proxysql> select * from stats_mysql_query_digest;
# mysql -uproxysql -p -h192.168.1.143 -P6033
mysql> select * from db.tb;
mysql> insert into db.tb(age) values(0),(100);
mysql> select * from db.tb for update;
备注:
a、表stats_mysql_query_digest:SQL的执行次数、时间消耗等
b、表stats_mysql_query_digest经常使用字段说明:
字段 |
说明 |
hostgroup |
发送查询的主机组,值为-1表示查询的是查询缓存 |
schemaname |
查询的数据库 |
username |
链接ProxySQL的用户名 |
digest_text |
参数剥离的实际SQL文本 |
count_star |
执行查询的总次数 |
first_seen |
unix时间戳,查询经过代理路由查询的第一时刻 |
last_seen |
unix时间戳,查询经过代理路由查询的最后一刻(到目前为止) |
sum_time |
执行此类查询的总时间(以微秒为单位) |
min_time |
执行此类查询时指望的持续时间范围,min_time表示到目前为止所看到的最小执行时间 |
max_time |
执行此类查询时指望的持续时间范围,max_time表示最大执行时间,以微秒为单位 |
c、查看表中的字段可以使用命令proxysql> show create table stats.stats_mysql_query_digest\G
d、查看表中的数据可以使用命令proxysql> select * from stats.stats_mysql_query_digest\G
e、表stats_mysql_query_digest_reset和表stats_mysql_query_digest结构一致
(2)经过查询stats_mysql_query_digest表来监控查询状态:
proxysql> select hostgroup,schemaname,username,digest_text from stats_mysql_query_digest;
备注:
a、select * from tb for update语句已经自动路由到编号为10的写入组,即master节点
b、select * from tb语句已经自动路由到编号为20的读取组,即slave节点
二、测试读请求负载均衡:
# for i in {1..12}; do mysql -uproxysql -p123456 -h192.168.1.143 -P6033 -e 'select @@hostname' -s -N; done
选项说明:
(1)-s:以制表符做为分隔符打印结果
(2)-N:结果中不包含列名
备注:上述命令执行结果可得出读请求在两台slave节点间切换,且node3和node4的出现比例接近1:3
三、测试ProxySQL故障转移:
(1)单主模型脚本gr_sw_mode_checker.sh,https://github.com/ZzzCrazyPig/proxysql_groupreplication_checker
备注:共有三个脚本提供下载
a、proxysql_groupreplication_checker.sh:用于multi-primary模式,能够实现读写分离及故障转移,同一时间点多个节点均可以写
b、gr_mw_mode_cheker.sh:用于multi-primary模式,能够实现读写分离及故障转移,但在同一时间点只能有一个节点能够写
c、gr_sw_mode_checker.sh:用于single-primary模式,能够实现读写分离及故障转移
(2)将下载的脚本gr_sw_mode_checker.sh放置至/var/lib/proxysql目录中,并赋予执行权限和修改属主属组:
# chmod +x /var/lib/proxysql/gr_sw_mode_checker.sh
# chown proxysql.proxysql /var/lib/proxysql/gr_sw_mode_checker.sh
(3)下载addition_to_sys.sql,https://github.com/lefred/mysql_gr_routing_check/
(4)master节点建立表sys.gr_member_routing_candidate_status:# mysql -uroot -p < addition_to_sys.sql
mysql> select * from sys.gr_member_routing_candidate_status;
master节点:
slave1节点:
slave2节点:
(5)配置scheduler:
proxysql> insert into scheduler(active,interval_ms,filename,arg1,arg2,arg3,arg4) values(1,5000,'/var/lib/proxysql/gr_sw_mode_checker.sh',10,20,1,'/var/lib/proxysql/gr_sw_mode_checker.log');
proxysql> load scheduler to runtime;
proxysql> save scheduler to disk;
备注1:
a、表scheduler经常使用字段说明
字段 |
说明 |
active |
值为1时容许计划程序按期执行提供的脚本,默认为1 |
interval_ms |
每隔多少毫秒执行一次脚本,5000毫秒为5秒 |
filename |
脚本的存放路径 |
arg1~arg4 |
脚本接收到的输入参数 |
comment |
备注 |
b、查看表中的字段可以使用命令proxysql> show create table scheduler\G
c、查看表中的数据可以使用命令proxysql> select * from scheduler\G
d、问题排查可查看日志文件/var/lib/proxysql/gr_sw_mode_checker.log
备注2:脚本gr_sw_mode_checker.sh用法
gr_sw_mode_cheker.sh <hostgroup_id write> <hostgroup_id read> [write node can be read : 1(YES: default) or 0(NO)] [log_file]
a、arg1:hostgroup_id write
b、arg2:hostgroup_id read
c、arg3:write node can be read : 1(YES: default) or 0(NO)
d、arg4:log_file, default: './checker.log'
proxysql> select * from scheduler\G
(6)查看MGR状态信息:
proxysql> select hostgroup_id,hostname,port,status,weight,comment from mysql_servers;
mysql> select * from performance_schema.replication_group_members;
mysql> select if((select @@server_uuid)=(select variable_value from performance_schema.global_status where variable_name='group_replication_primary_member'),1,0) as is_primary_mode,@@server_id;
master节点:
备注:is_primary_mode的值为1说明此节点为master节点
slave1节点:
slave2节点:
(7)master节点模拟MySQL服务故障:# systemctl stop mysqld.service
(8)查看MGR状态信息:
proxysql> select hostgroup_id,hostname,port,status,weight,comment from mysql_servers;
mysql> select * from performance_schema.replication_group_members;
mysql> select if((select @@server_uuid)=(select variable_value from performance_schema.global_status where variable_name='group_replication_primary_member'),1,0) as is_primary_mode,@@server_id;
slave1节点:
slave2节点:
备注:当master节点意外宕机或下线,在知足大多数节点存活的状况下,group内部发起选举,选出下一个可用的读节点,提高其为master节点。master节点选举根据group内剩余存活节点的UUID按字典升序排列,而后选择排在最前的节点做为新的master节点。is_primary_mode的值为1说明slave2节点已经被选举为新的master节点。
mysql> select * from sys.gr_member_routing_candidate_status;
slave1节点:
slave2节点:
备注:slave2节点中的read_only参数的值已经自动修改成0
(9)slave2节点建立测试数据:
mysql> insert into db.tb(age) values(60),(80);
mysql> select * from db.tb;
(10)slave1节点查看测试数据:
mysql> select * from db.tb;
(11)原master节点恢复MySQL服务:# systemctl start mysqld.service
(12)原master节点加入复制组:mysql> start group_replication;
(13)查看MGR状态信息:
proxysql> select hostgroup_id,hostname,port,status,weight,comment from mysql_servers;
mysql> select * from performance_schema.replication_group_members;
mysql> select if((select @@server_uuid)=(select variable_value from performance_schema.global_status where variable_name='group_replication_primary_member'),1,0) as is_primary_mode,@@server_id;
原master节点:
备注:新上线的原master节点现已变为slave节点
slave1节点:
slave2节点:
mysql> select * from sys.gr_member_routing_candidate_status;
原master节点:
备注:原master节点中的read_only参数的值已经自动修改成1
slave1节点:
slave2节点:
(14)原master节点已经复制了最新的测试数据:
mysql> select * from db.tb;
四、使用sysbench进行压测:
(1)安装sysbench:# yum -y install sysbench
(2)将用户proxysql的transaction_persistent值修改成0:
proxysql> update mysql_users set transaction_persistent=0 where username='proxysql';
proxysql> load mysql users to runtime;
proxysql> save mysql users to disk;
(3)prepare:
# sysbench --threads=8 --events=100000000 --time=2000 --report-interval=5 --mysql-host=192.168.1.143 --mysql-port=6033 --mysql-user=proxysql --mysql-password=123456 --mysql-db=db /usr/share/sysbench/tests/include/oltp_legacy/oltp.lua prepare
备注:经常使用选项说明
a、--threads:使用的线程数
b、--events:事件总数
c、--time:以秒为单位的总执行时间
d、--report-interval:以秒为单位按期报告具备指定间隔的中间统计信息
e、--mysql-host:ProxySQL所在主机的IP
f、--mysql-port:ProxySQL对外服务的端口号
g、--mysql-user:MySQL user
h、--mysql-password:MySQL password
i、--mysql-db:在db数据库中建立表sbtest1,并插入10000条数据
(4)run:
# sysbench --threads=8 --events=100000000 --time=2000 --report-interval=5 --mysql-host=192.168.1.143 --mysql-port=6033 --mysql-user=proxysql --mysql-password=123456 --mysql-db=db /usr/share/sysbench/tests/include/oltp_legacy/oltp.lua run
备注:不要Ctrl + c终止压测
(5)压测过程当中复制会话,观察读写分离状态:
proxysql> select hostgroup,schemaname,username,digest_text from stats_mysql_query_digest\G
备注:上述命令执行结果可得出写请求都路由到编号为10的写入组,而读请求都路由到编号为20的读取组
五、测试查询缓存:
ProxySQL的查询缓存和MySQL的查询缓存有点相似,但不彻底同样,ProxySQL的查询缓存若是在指定时间大小范围内发送的SQL一摸同样,那么直接返回结果集,而返回的结果集可能并非准确的查询结果,因此须要设置合适的时间范围,既能提高性能,又得知足业务需求,即查询结果足够的“新”。针对一些查询频率很高但结果并不须要太精确的业务,能够单独给这些SQL配置查询缓存。
(1)启用查询缓存:
proxysql> update mysql_query_rules set cache_ttl=2000 where active=1 and destination_hostgroup=20;
proxysql> load mysql query rules to runtime;
proxysql> save mysql query rules to disk;
(2)压测:
# sysbench --threads=8 --events=100000000 --time=2000 --report-interval=5 --mysql-host=192.168.1.143 --mysql-port=6033 --mysql-user=proxysql --mysql-password=123456 --mysql-db=db /usr/share/sysbench/tests/include/oltp_legacy/oltp.lua run
(3)压测过程当中复制会话,观察读写分离状态:
proxysql> select hostgroup,digest_text,sum_time from stats_mysql_query_digest\G
备注:能够看到hostgroup的值部分为-1,表示这些查询使用了查询缓存,且耗时为0
六、启用Web统计功能:
(1)查看变量admin-web_enabled是否启用:
proxysql> select * from global_variables where variable_name like 'admin-web%';
(2)启用变量admin-web_enabled:
proxysql> set admin-web_enabled='true';
proxysql> load admin variables to runtime;
proxysql> save admin variables to disk;
proxysql> select * from global_variables where variable_name like 'admin-web%';
(3)查看登陆Web界面的用户名、密码和端口:
proxysql> select * from global_variables where variable_name like 'admin-web%' or variable_name LIKE 'admin-stats%';
(4)浏览器中访问192.168.1.143:6080,用户名和密码均为stats: