墨墨导读:Proxysql读写分离的中间件,支持高可用 主从\ MGR \ PXC等环境,并提供连接池、缓存、日志记录等功能。

ProxySQL是用C++语言开发的,一个轻量级开源软件,性能和功能满足读写中间件所需的绝大多数功能,其配置数据基于SQLite存储,目前已到v2.0.13版本。

功能方面如下:

  • 最基本的读/写分离,且方式有多种。

  • 可定制基于用户、基于schema、基于语句的规则对SQL语句进行路由。换句话说,规则很灵活。基于schema和与语句级的规则,可以实现简单的sharding。
    不支持分表,可以分库,但利用规则配置实现分表。

  • 可缓存查询结果。基本ProxySQL的缓存策略实现了基本的缓存功能,绝大多数时候够用。
    1.支持动态加载配置,即一般可以在线修改配置,但有少部分参数还是需要重启来生效。
    2.支持query cache。
    3.支持对query的路由,可以针对某个语句进行分配执行实例。

  • 监控后端节点。ProxySQL可以监控后端节点的多个指标,包括:ProxySQL和后端的心跳信息,后端节点的read-only/read-write,slave和master的数据同步延迟性(replication lag)。

特性方面:

  • 连接池,而且是 multiplexing;

  • 主机和用户的最大连接数限制;

  • 自动下线后端DB;
        -  延迟超过阀值
        -  ping 延迟超过阀值
        -  网络不通或宕机

  • 强大的规则路由引擎;
       -  实现读写分离
       -  查询重写
       -  sql流量镜像

  • 支持prepared statement;

  • 支持Query Cache;

  • 支持负载均衡,与gelera结合自动failover;

  • 将所有配置保存写入到SQLit表中。

  • 支持动态加载配置,即一般可以在线修改配置,但有少部分参数还是需要重启来生效。

  • 支持query cache。

  • 支持对query的路由。

  • 不支持分表,可以分库,但是利用规则配置实现分表。

ProxySQL:
官方站点:https://www.proxysql.com/
官方github:https://github.com/sysown/proxysql/wiki
percona ProxySQL手册:https://www.percona.com/doc/percona-xtradb-cluster/LATEST/howtos/proxysql.html

下面基于2.0.10版本所有操作。

一、安装部署

安装地址:https://github.com/sysown/proxysql/releases
官方说明:https://github.com/sysown/proxysql/wiki
proxysql服务器上安装mysql客户端,用于在本机连接到ProxySQL的管理接口

1. tar.gz安装

[root@ss30 proxysql-2.0.10]# tar -xvf proxysql-2.0.10.tar.gz.gz
[root@ss30 proxysql-2.0.10]# cd proxysql-2.0.10/
[root@ss30 proxysql-2.0.10]# make -j 4
[root@ss30 proxysql-2.0.10]# make install DESTDIR=/opt/idc/proxysql-2.0.10
make[1]: Leaving directory `/opt/idc/softwares/proxysql-2.0.10/src'
[root@ss30 proxysql-2.0.10]# make install DESTDIR=/opt/idc/proxysql-2.0.10
install -m 0755 src/proxysql /usr/bin
install -m 0600 etc/proxysql.cnf /etc
if [ ! -d /var/lib/proxysql ]; then mkdir /var/lib/proxysql ; fi
Creating proxysql user and group
useradd -r -U -s /bin/false proxysql
install -m 0644 systemd/system/proxysql.service /usr/lib/systemd/system/
systemctl enable proxysql.service
Created symlink from /etc/systemd/system/multi-user.target.wants/proxysql.service to /usr/lib/systemd/system/proxysql.service.

卸载:make uninstall

2. rpm包安装

rpm解压即可,会在/usr/local/proxysql 生成文件

[root@ss30 softwares]# rpm -ivh proxysql-2.0.10-1-centos7.x86_64.rpm
Preparing...                          ################################# [100%]
Updating / installing...1:proxysql-2.0.10-1                warning: group proxysql does not exist - using root
warning: group proxysql does not exist - using root
################################# [100%]
Created symlink from /etc/systemd/system/multi-user.target.wants/proxysql.service to /etc/systemd/system/proxysql.service.

3. 启动服务

[root@ss30 softwares]# systemctl start proxysql
[root@ss30 softwares]# ps -ef | grep proxy
proxysql   3964      1  0 21:01 ?        00:00:00 /usr/bin/proxysql -c /etc/proxysql.cnf
proxysql   3965   3964  7 21:01 ?        00:00:00 /usr/bin/proxysql -c /etc/proxysql.cnf
root       3989  77420  0 21:01 pts/2    00:00:00 grep --color=auto proxy

服务命令:systemctl start | stop | restart | statu proxysql

4. 配置信息

ProxySQL很少停止或重启,因为绝大多数配置都可以在线修改。
服务启动配置文件

[root@ss30 proxysql-2.0.10]# vim /etc/systemd/system/proxysql.service
[Unit]
Description=High Performance Advanced Proxy for MySQL
After=network.target[Service]
Type=forking
RuntimeDirectory=proxysql
#PermissionsStartOnly=true
#ExecStartPre=/usr/bin/mkdir -p /var/run/proxysql /var/run/proxysql
#ExecStartPre=/usr/bin/chown -R proxysql: /var/run/proxysql/
ExecStart=/usr/bin/proxysql -c /etc/proxysql.cnf
#PIDFile=/var/lib/proxysql/proxysql.pid
#StandardError=null  # all output is in stderr
SyslogIdentifier=proxysql
Restart=no
User=proxysql
Group=proxysql
PermissionsStartOnly=true
UMask=0007
LimitNOFILE=102400
LimitCORE=1073741824
ProtectHome=yes
NoNewPrivileges=true
CapabilityBoundingSet=CAP_SETGID CAP_SETUID CAP_SYS_RESOURCE
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_ALG
ProtectSystem=full
PrivateDevices=yes[Install]
WantedBy=multi-user.target

5. 参数配置文件

[root@ss30 softwares]# vim /etc/proxysql.cnf
datadir="/var/lib/proxysql"
errorlog="/var/lib/proxysql/proxysql.log"admin_variables=
{admin_credentials="admin:admin"
#       mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock"mysql_ifaces="0.0.0.0:6032"
#       refresh_interval=2000
#       debug=true
}
......

二、ProxySQL结构

  • Qurey Processor 用于匹配查询规则并根据规则决定是否缓存查询或者将查询加入黑名单或者重新路由、重写查询或者镜像查询到其他hostgroup。

  • User Auth 为底层后端数据库认证提供了用户凭证。

  • Hostgroup manager – 负责管理发送SQL请求都后端数据库并跟踪SQL请求状态。

  • Connection pool – 负责管理后端数据库连接,连接池中建立的连接被所有的前端应用程序共享。

  • Monitoring – 负责监控后端数据库健康状态主从复制延时并临时下线不正常的数据库实例。

1. 启动过程

  • RUNTIME层
    代表的是ProxySQL当前生效的配置,包括 global_variables, mysql_servers, mysql_users, mysql_query_rules。无法直接修改这里的配置,必须要从下一层load进来

  • MEMORY层
    是平时在mysql命令行修改的 main 里头配置,可以认为是SQLite数据库在内存的镜像。该层级的配置在main库中以mysql_开头的表以及global_variables表,这些表的数据可以直接修改;

  • DISK|CONFIG FILR层
    持久存储的那份配置,一般在$(DATADIR)/proxysql.db,在重启的时候会从硬盘里加载。/etc/proxysql.cnf文件只在第一次初始化的时候用到,完了后,如果要修改监听端口,还是需要在管理命令行里修改,再 save 到硬盘。

注意:

如果找到数据库文件(proxysql.db),ProxySQL 将从 proxysql.db 初始化其内存中配置。因此,磁盘被加载到 MEMORY 中,然后加载到 RUNTIME 中。
如果找不到数据库文件(proxysql.db)且存在配置文件(proxysql.cfg),则解析配置文件并将其内容加载到内存数据库中,然后将其保存在 proxysql.db 中并在加载到 RUNTIME。

请务必注意,如果找到 proxysql.db,则不会解析配置文件。也就是说,在正常启动期间,ProxySQL 仅从持久存储的磁盘数据库初始化其内存配置。

2. 数据库结构

ProxySQL自身共有5个 库,分别为3个保存在内存中的库,和三个保存在磁盘的SQLite库。

通过6032管理端口登入后,默认就是main库,所有的配置更改都必须在这个库中进行,disk存档库不会直接受到影响。接下来看下

[root@ss30 proxysql-2.0.10]# mysql -uadmin -padmin -h127.0.0.1 -P6032
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.30 (ProxySQL Admin Module)
mysql> show databases;
+-----+---------------+-------------------------------------+
| seq | name          | file                                |
+-----+---------------+-------------------------------------+
| 0   | main          |                                     |
| 2   | disk          | /var/lib/proxysql/proxysql.db       |
| 3   | stats         |                                     |
| 4   | monitor       |                                     |
| 5   | stats_history | /var/lib/proxysql/proxysql_stats.db |
+-----+---------------+-------------------------------------+
5 rows in set (0.00 sec)
  • main:内存配置数据库,表里存放后端db实例、用户验证、路由规则等信息。表名以 runtime_开头的表示proxysql当前运行的配置内容,不能通过dml语句修改,只能修改对应的不以 runtime_ 开头的(在内存)里的表,然后 LOAD 使其生效, SAVE 使其存到硬盘以供下次重启加载。

  • disk:是持久化到硬盘的配置,sqlite数据文件。SQLite3 数据库,默认位置为 $(DATADIR)/proxysql.db,在重新启动时,未保留的内存中配置将丢失。因此,将配置保留在 DISK 中非常重要。(SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎)

  • stats:proxysql运行抓取的统计信息,包括到后端各命令的执行次数、流量、processlist、查询种类汇总/执行时间等等。

  • monitor:库存储 monitor 模块收集的信息,主要是对后端db的健康/延迟检查。

  • stats_history:统计信息历史库

3. 核心配置表






4. 命令

5. 小结

这些数据库的功能实现了实用化内容:

  • 允许轻松动态更新配置,便于运维管理,与MySQL兼容的管理界面可用于此目的。

  • 允许尽可能多的配置项目动态修改,而不需要重新启动ProxySQL进程

  • 可以毫不费力地回滚无效配置

  • 通过多级配置系统实现的,其中设置从运行时移到内存,并根据需要持久保存到磁盘

三、ProxySQL读写分离配置

1. MySQL里创建账号

数据库段创建访问用户,监控用户

[root@ss30 ~]# mysql -uroot -p123456 -h127.0.0.1 -P3410
mysql>  GRANT ALL PRIVILEGES ON *.* TO 'dbadmin'@'%' identified by '123456'  WITH GRANT OPTION;mysql> create user monitor@'%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> grant replication client on *.* to monitor@'%';
Query OK, 0 rows affected (0.01 sec)

2. 添加MySQL节点

hostgroup_id, hostname, port 组成一个主键

[root@ss30 ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032
Your MySQL connection id is 3
Server version: 5.5.30 (ProxySQL Admin Module)
mysql> use main
Database changed
mysql> insert into mysql_servers(hostgroup_id,hostname,port)  values(10,'192.168.244.130',3410);
mysql> insert into mysql_servers(hostgroup_id,hostname,port)  values(10,'192.168.244.130',3400);mysql> select * from mysql_servers\G;
*************************** 1. row ***************************hostgroup_id: 10hostname: 192.168.244.130port: 3410gtid_port: 0status: ONLINEweight: 1compression: 0max_connections: 1000
max_replication_lag: 0use_ssl: 0max_latency_ms: 0comment:
1 row in set (0.00 sec)
##加载到RUNTIME,并保存到disk
mysql> load mysql servers to runtime;
Query OK, 0 rows affected (0.00 sec)mysql> save mysql servers to disk;
Query OK, 0 rows affected (0.03 sec)

3. 用户配置

配置mysql_users表,将用户添加到该表中。

mysql> insert into mysql_users(username,password,default_hostgroup) values('dbadmin','123456',10);mysql> load mysql users to runtimemysql> save mysql users to disk;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from mysql_users\G;
*************************** 1. row ***************************username: dbadminpassword: 123456active: 1     #active=1表示用户生效,0表示不生效use_ssl: 0default_hostgroup: 10default_schema: NULLschema_locked: 0
transaction_persistent: 1   # 如果设置为1,连接上ProxySQL的会话后,如果在一个
hostgroup上开启了事务,那么后续的sql都继续维持在这个hostgroup上,不论是否会匹配上其它路由规则,直到事务结束。虽然默认是0fast_forward: 0backend: 1frontend: 1max_connections: 10000  #该用户允许的最大连接数comment:
1 row in set (0.00 sec)

注意两个字段:
只有active=1的用户才是有效的用户。
transaction_persistent字段,当它的值为1时,表示事务持久化:当某连接使用该用户开启了一个事务后,那么在事务提交/回滚之前,所有的语句都路由到同一个组中,避免语句分散到不同组。建议在创建完用户之后设置为1,避免发生脏读、幻读等现象.

mysql_users表有不少字段,最主要的三个字段为username、password和default_hostgroup:

  • username:前端连接ProxySQL,以及ProxySQL将SQL语句路由给MySQL所使用的用户名。

  • password:用户名对应的密码。可以是明文密码,也可以是hash密码。如果想使用hash密码,可以先在某个MySQL节点上执行
    select password(PASSWORD),然后将加密结果复制到该字段。

  • default_hostgroup:该用户名默认的路由目标。例如,指定root用户的该字段值为10时,则使用root用户发送的SQL语句默认
    情况下将路由到hostgroup_id=10组中的某个节点。

4. 监控后端MySQL节点

添加MySQL节点之后,还需要监控这些后端节点。对于后端是主从复制的环境来说,这是必须的,因为ProxySQL需要通过每个节点的read_only值来自动调整,它们是属于读组还是写组。

[root@ss30 ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032
mysql>  set mysql-monitor_username='monitor';
Query OK, 1 row affected (0.00 sec)
mysql>  set mysql-monitor_password='123456';
Query OK, 1 row affected (0.00 sec)
mysql>  load mysql variables to runtime;
Query OK, 0 rows affected (0.00 sec)
mysql>  save mysql variables to disk;
Query OK, 97 rows affected (0.01 sec)

加载,Monitor模块就会开始监控后端的read_only值,当监控到read_only值后,就会按照read_only的值将某些节点自动移动到读/写组。

例如,此处所有节点都在id=10的写组,slave1和slave2都是slave,它们的read_only=1,这两个节点将会移动到id=20的组。如果一开始这3节点都在id=20的读组,那么移动的将是Master节点,会移动到id=10的写组。

mysql> select hostgroup_id,hostname,port,status,weight from mysql_servers;
+--------------+-----------------+------+--------+--------+
| hostgroup_id | hostname        | port | status | weight |
+--------------+-----------------+------+--------+--------+
| 10           | 192.168.244.130 | 3410 | ONLINE | 2      |
| 10           | 192.168.244.130 | 3400 | ONLINE | 1      |
+--------------+-----------------+------+--------+--------+
mysql> insert into mysql_replication_hostgroups(writer_hostgroup,reader_hostgroup,check_type) values(10,20,'read_only');
Query OK, 1 row affected (0.00 sec)mysql> load mysql servers to runtime;
Query OK, 0 rows affected (0.00 sec)mysql>
mysql> save mysql servers to disk;
Query OK, 0 rows affected (0.04 sec)
mysql> select hostgroup_id,hostname,port,status,weight from mysql_servers;
+--------------+-----------------+------+--------+--------+
| hostgroup_id | hostname        | port | status | weight |
+--------------+-----------------+------+--------+--------+
| 10           | 192.168.244.130 | 3410 | ONLINE | 2      |
| 20           | 192.168.244.130 | 3400 | ONLINE | 1      |
+--------------+-----------------+------+--------+--------+

5. 配置路由规则

ProxySQL的路由规则非常灵活,可以基于用户、基于schema以及基于每个语句实现路由规则的定制。

mysql> insert into mysql_query_rules
(rule_id,active,match_digest,destination_hostgroup,apply)
VALUES (1,1,'^SELECT.*FOR UPDATE$',10,1), (2,1,'^SELECT',20,1);
Query OK, 2 rows affected (0.00 sec)mysql> load mysql query rules to runtime;
Query OK, 0 rows affected (0.00 sec)mysql> save mysql query rules to disk;
Query OK, 0 rows affected (0.01 sec)

验证

[root@ss30 ~]# mysql -udbadmin -p123456 -P6033 -h127.0.0.1 -e "select @@port"
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------+
| @@port |
+--------+
|   3400 |
+--------+
[root@ss30 ~]#
[root@ss30 ~]#
[root@ss30 ~]#
[root@ss30 ~]# mysql -udbadmin -p123456 -h127.0.0.1 -P6033 -e "start transaction;select @@port;commit;select @@port;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------+
| @@port |
+--------+
|   3410 |
+--------+
+--------+
| @@port |
+--------+
|   3400 |
+--------+

6. 信息查询
#read_only日志此时也为空(正常来说,新环境配置时,这个只读日志是为空的)

MySQL [(none)]> select * from mysql_server_read_only_log;

#replication_lag的监控日志为空

MySQL [(none)]> select * from mysql_server_replication_lag_log;

#注意:可能会有很多connect_error,这是因为没有配置监控信息时的错误,配置后如果connect_error的结果为NULL则表示正常。

MySQL [(none)]> select * from mysql_server_connect_log;

#以下是对心跳信息的监控(对ping指标的监控)

MySQL [(none)]> select * from mysql_server_ping_log;

查看路由的信息,可查询stats库中的stats_mysql_query_digest表。

mysql> select* from stats_mysql_query_digest;
mysql>SELECT hostgroup hg, sum_time, count_star, digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC;

7. 开启ProxySQL的Web统计功能

查看路由的信息,可查询stats库中的stats_mysql_query_digest表。

mysql> update global_variables set variable_value='true' where variable_name='admin-web_enabled';
Query OK, 1 row affected (0.01 sec)mysql> LOAD ADMIN VARIABLES TO RUNTIME;
Query OK, 0 rows affected (0.03 sec)mysql> SAVE ADMIN VARIABLES TO DISK;
Query OK, 35 rows affected (0.01 sec)

查看端口和登录web界面的用户名和密码,用户名和密码与stat账户一致:

mysql> select * from global_variables where variable_name LIKE 'admin-web%' or variable_name LIKE 'admin-stats%';
+----------------------------------------+----------------+
| variable_name                          | variable_value |
+----------------------------------------+----------------+
| admin-stats_credentials                | stats:stats    |
| admin-stats_mysql_connections          | 60             |
| admin-stats_mysql_connection_pool      | 60             |
| admin-stats_mysql_query_cache          | 60             |
| admin-stats_mysql_query_digest_to_disk | 0              |
| admin-stats_system_cpu                 | 60             |
| admin-stats_system_memory              | 60             |
| admin-web_enabled                      | true           |
| admin-web_port                         | 6080           |
+----------------------------------------+----------------+

查看web端口是否正常打开

[root@ss30 ~]# lsof -i:6080
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
proxysql 1295 proxysql   29u  IPv4 470544      0t0  TCP *:6080 (LISTEN)

访问http://192.168.244.130:6080并使用stats:stats登录即可查看一些统计信息。

8. scheduler打印状态到日志

编辑脚本和目录

[root@ss30 opt]# mkdir -p /opt/proxysql/log
[root@ss30 opt]# vim /opt/proxysql/log/status.sh
#!/bin/bash
DATE=`date "+%Y-%m-%d %H:%M:%S"`
echo "{\"dateTime\":\"$DATE\",\"status\":\"running\"}" >> /opt/proxysql/log/status_log[root@ss30 opt]# chmod 777 /opt/proxysql/log/status.sh

输入scheduler信息

mysql> insert into scheduler(active,interval_ms,filename) values (1,60000,'/opt/proxysql/log/status.sh');
Query OK, 1 row affected (0.00 sec)mysql> LOAD SCHEDULER TO RUNTIME;
Query OK, 0 rows affected (0.00 sec)mysql> SAVE SCHEDULER TO DISK;
Query OK, 0 rows affected (0.01 sec)mysql>  select * from global_variables where variable_name LIKE 'admin-web%' or variable_name LIKE 'admin-stats%';
+----------------------------------------+----------------+
| variable_name                          | variable_value |
+----------------------------------------+----------------+
| admin-stats_credentials                | stats:stats    |
| admin-stats_mysql_connections          | 60             |
| admin-stats_mysql_connection_pool      | 60             |
| admin-stats_mysql_query_cache          | 60             |
| admin-stats_mysql_query_digest_to_disk | 0              |
| admin-stats_system_cpu                 | 60             |
| admin-stats_system_memory              | 60             |
| admin-web_enabled                      | true           |
| admin-web_port                         | 6080           |
+----------------------------------------+----------------+
9 rows in set (0.01 sec)

查看日志:

[root@ss30 log]# tail -f status_log
{"dateTime":"2020-04-05 00:07:40","status":"running"}
{"dateTime":"2020-04-05 00:08:41","status":"running"}
{"dateTime":"2020-04-05 00:10:52","status":"running"}

9. 其他

自动回避复制延迟较大的节点

如果服务器将 max_replication_lag 设置为非零值,则 Monitor 模块会定期检查复制延迟。
下图中,当172.16.0.3的复制延迟超过了30秒会自动回避,设置max_replication_lag = 0,代表不检查复制延迟 。

mysql> select hostgroup_id,hostname,port,max_replication_lag from mysql_servers;
+--------------+-----------------+------+---------------------+
| hostgroup_id | hostname        | port | max_replication_lag |
+--------------+-----------------+------+---------------------+
| 20           | 192.168.244.130 | 3400 | 0                   |
| 10           | 192.168.244.130 | 3410 | 0                   |
+--------------+-----------------+------+---------------------+
2 rows in set (0.00 sec)mysql> update  mysql_servers set max_replication_lag=30 where hostgroup_id=10;
Query OK, 1 row affected (0.00 sec)mysql> select hostgroup_id,hostname,port,max_replication_lag from mysql_servers;
+--------------+-----------------+------+---------------------+
| hostgroup_id | hostname        | port | max_replication_lag |
+--------------+-----------------+------+---------------------+
| 20           | 192.168.244.130 | 3400 | 0                   |
| 10           | 192.168.244.130 | 3410 | 30                  |
+--------------+-----------------+------+---------------------+
2 rows in set (0.00 sec)

注意:
1.max_replication_lag主要来源Seconds_Behind_Master,该参数判断延迟准确性不高,顾个人建议为参考功能。
2.max_replication_lag 仅适用于从节点。如果服务器未启用复制,则 Monitor 不会执行任何操作。

#强制关闭与假死主库的连接,避免数据被写入的假死的老主库。Admin> update runtime_mysql_servers set status=“HARD_OFFLINE” where hostname=‘192.168.20.31’ and port=‘3306’

#将假死的旧主库提出集群,避免后续数据被写入到老主库Admin> delete from mysql_servers where hostname=‘192.168.20.31’ and port='3306’Admin> load mysql servers to runtimeAdmin> save mysql serbers to disk

四、MGR配置

1.  MySQL 配置

创建proxysql 监控mysql用户monitor 并赋予权限
sys库的读权限赋给ProxySQL配置的监控MySQL的账户

[root@ens8 ~]# mysql -uroot -p -S /opt/data8.0/mysql/mysql.sock
mysql> CREATE USER 'monitor'@'%'   IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.03 sec)
mysql> GRANT SELECT on sys.* to 'monitor'@'%';
Query OK, 0 rows affected (0.03 sec)

官方提供监控视图版本是5.7的 ,8.0的如下:
5.7版本参考:https://github.com/sysown/proxysql/wiki/Main-(runtime)#mysql_group_replication_hostgroups

USE sys;DELIMITER $$DROP FUNCTION IF EXISTS my_id;
CREATE FUNCTION my_id() RETURNS TEXT(36) DETERMINISTIC NO SQL RETURN (SELECT @@global.server_uuid as my_id);$$CREATE FUNCTION gr_member_in_primary_partition()RETURNS VARCHAR(3)DETERMINISTICBEGINRETURN (SELECT IF( MEMBER_STATE='ONLINE' AND ((SELECT COUNT(*) FROMperformance_schema.replication_group_members WHERE MEMBER_STATE NOT IN ('ONLINE', 'RECOVERING')) >=((SELECT COUNT(*) FROM performance_schema.replication_group_members)/2) = 0),'YES', 'NO' ) FROM performance_schema.replication_group_members JOINperformance_schema.replication_group_member_stats USING(member_id) where member_id=my_id());
END$$DROP VIEW IF EXISTS gr_member_routing_candidate_status;
CREATE VIEW gr_member_routing_candidate_status ASSELECTsys.gr_member_in_primary_partition() AS viable_candidate,IF((SELECT(SELECTGROUP_CONCAT(variable_value)FROMperformance_schema.global_variablesWHEREvariable_name IN ('read_only' , 'super_read_only')) != 'OFF,OFF'),'YES','NO') AS read_only,Count_Transactions_Remote_In_Applier_Queue AS transactions_behind,Count_Transactions_in_queue AS 'transactions_to_cert'FROMperformance_schema.replication_group_member_statsWHEREmember_id = MY_ID();$$
DELIMITER ;

确认信息如下:

mysql> select * from gr_member_routing_candidate_status;
+------------------+-----------+---------------------+----------------------+
| viable_candidate | read_only | transactions_behind | transactions_to_cert |
+------------------+-----------+---------------------+----------------------+
| YES              | NO        |                   0 |                    0 |
+------------------+-----------+---------------------+----------------------+
1 row in set (0.00 sec)

2. ProxySQL配置

添加服务器信息和 用户信息
主负责写、从负责读,当MGR主库切换后,代理自动识别主从。
ProxySQL代理每一个后端MGR集群时,都必须为这个MGR定义写组50、备写组60、读组70、离线组80

[root@ss30 ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032
Your MySQL connection id is 3
Server version: 5.5.30 (ProxySQL Admin Module)
mysql> use main
Database changed
mysql>insert into mysql_servers(hostgroup_id,hostname,port) values (50,'192.168.244.129',3380);
mysql>insert into mysql_servers(hostgroup_id,hostname,port) values (50,'192.168.244.129',3381);
mysql>insert into mysql_servers(hostgroup_id,hostname,port) values (50,'192.168.244.129',3382);mysql> insert into mysql_users(username,password,default_hostgroup) values('mgradmin','123456',50);mysql> insert into mysql_group_replication_hostgroups
(writer_hostgroup,backup_writer_hostgroup,reader_hostgroup, offline_hostgroup,active,max_writers,writer_is_also_reader,max_transactions_behind)
values (50,60,70,80,1,1,0,100);mysql>load mysql servers to runtime;
save mysql servers to disk;
load mysql users to runtime;
save mysql users to disk;
load mysql variables to runtime;
save mysql variables to disk;

查看服务器信息

mysql> select hostgroup_id, hostname,port, status  from runtime_mysql_servers;
+--------------+-----------------+------+--------+
| hostgroup_id | hostname        | port | status |
+--------------+-----------------+------+--------+
| 50           | 192.168.244.129 | 3380 | ONLINE |
| 70           | 192.168.244.129 | 3381 | ONLINE |
| 70           | 192.168.244.129 | 3382 | ONLINE |
+--------------+-----------------+------+--------+

验证是否正常通信

mysql> select  time_start_us, hostname,  port,  viable_candidate,  read_only, transactions_behind,  error  from mysql_server_group_replication_log
order by time_start_us desc   limit 6;
+------------------+-----------------+------+------------------+-----------+---------------------+-------+
| time_start_us    | hostname        | port | viable_candidate | read_only | transactions_behind | error |
+------------------+-----------------+------+------------------+-----------+---------------------+-------+
| 1586094196050264 | 192.168.244.129 | 3382 | YES              | YES       | 1                   | NULL  |
| 1586094196049313 | 192.168.244.129 | 3381 | YES              | YES       | 0                   | NULL  |
| 1586094196048453 | 192.168.244.129 | 3380 | YES              | NO        | 0                   | NULL  |
| 1586094191055906 | 192.168.244.129 | 3382 | YES              | YES       | 1                   | NULL  |
| 1586094191055905 | 192.168.244.129 | 3381 | YES              | YES       | 0                   | NULL  |
| 1586094191055901 | 192.168.244.129 | 3380 | YES              | NO        | 0                   | NULL  |
+------------------+-----------------+------+------------------+-----------+---------------------+-------+

配置读写分离规则:

sql> insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)-> VALUES (3,1,'^SELECT.*FOR UPDATE$',50,1),-> (4,1,'^SELECT',70,1);

验证:

[root@ss30 ~]# mysql -umgradmin -p123456 -h127.0.0.1 -P6033 -e "start transaction;select @@port;commit;select @@port;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------+
| @@port |
+--------+
|   3380 |
+--------+
+--------+
| @@port |
+--------+
|   3381 |
+--------+

查看路由规则:

mysql> select hostgroup,digest_text from stats_mysql_query_digest order by digest_text desc limit 5;
+-----------+----------------------------------+
| hostgroup | digest_text                      |
+-----------+----------------------------------+
| 50        | start transaction                |
| 50        | select @@version_comment limit ? |
| 70        | select @@port                    |
| 20        | select @@port                    |
| 50        | select @@port                    |
+-----------+----------------------------------+

五、总结

1.Proxysql整个使用上面,功能上面基本都能满足需求。
2.还有配置复杂度还是比较低的。
3.资源方面因为自己维护一套连接池,还是流量转发,配置不能太低。
4.性能损耗估计5%~18%以内。
5.autocommit=0相关bug,这样使用的场景 还是比较不多。对于这种问题,等官方修复,或可以先临时插入一张表,作为事务开始的之后前奏 。

https://github.com/sysown/proxysql/issues/2997

墨天轮原文链接:https://www.modb.pro/db/28841(复制到浏览器中打开或者点击“阅读原文”)

推荐阅读:144页!分享珍藏已久的数据库技术年刊


视频号,新的分享时代,关注我们,看看有什么新发现?

数据和云

ID:OraNews

如有收获,请划至底部,点击“在看”,谢谢!

点击下图查看更多 ↓

云和恩墨大讲堂 | 一个分享交流的地方

长按,识别二维码,加入万人交流社群

请备注:云和恩墨大讲堂

  点个“在看”

你的喜欢会被看到❤

万字详述 MySQL ProxySQL相关推荐

  1. ❤️ 万字Python MySQL从入门到精通详细教程❤️ 再也不用担心学不会数据库了❤️

    文章目录 前言 ⭐集合三万字基础教程⭐ 一.SQL详细教程 二.mysql入门详细教程 ⭐转python mysql⭐ 三.Python MySQL入门连接 3.1基本环境准备 3.2连接 四.Pyt ...

  2. 万字总结 MySQL核心知识,赠送25连环炮

    前言 大家好,我是老田,之前写过 JVM.并发编程连环炮.然后有很多小伙伴私下找我就我继续把MySQL的连环炮整理出来,但是由于本人比较懒,又加上最近有点忙,所以拖到了今天才发出来. 有志者,事竟成: ...

  3. 厉害了,3万字的MySQL精华总结 + 面试100问!

    这是我的第 202 期分享 作者 | 派大新 来源 | JavaKeeper(ID:JavaKeeper) 分享 | Java中文社群(ID:javacn666) ❝ 写在之前:不建议那种上来就是各种 ...

  4. 详述MySQL Using intersect交集算法

    墨墨导读:MySQL EXPLAIN下 Using intersect交集. 一次优化的过程中,MySQL执行计划选择了单独的3个二级索引中的2个索引,通过Using intersect算法进行ind ...

  5. 详述MySQL事务的实现原理

    相信大家都用过事务以及了解他的特点,如原子性(Atomicity),一致性(Consistency),隔离型(Isolation)以及持久性(Durability)等.今天想跟大家一起研究下事务内部到 ...

  6. 详述MySQL事务及ACID特性的实现原理

    " 事务是 MySQL 等关系型数据库区别于 NoSQL 的重要方面,是保证数据一致性的重要手段. 本文将首先介绍 MySQL 事务相关的基础概念,然后介绍事务的 ACID 特性,并分析其实 ...

  7. 超经典两万字,MySQL数据库快速入门。

    「作者主页」:士别三日wyx 「作者简介」:CSDN top100.阿里云博客专家.华为云享专家.网络安全领域优质创作者 「专栏简介」:此文章已录入专栏<MySQL数据库快速入门> MyS ...

  8. 万字详述 Flink SQL 4 种时间窗口语义!(收藏)

    DML:窗口聚合 大家好我是老羊,由于窗口涉及到的知识内容比较多,所以博主先为大家说明介绍下面内容时的思路,大家跟着思路走.思路如下: ⭐ 先介绍 Flink SQL 支持的 4 种时间窗口 ⭐ 分别 ...

  9. 详述MySQL服务在渗透测试中的利用

    本文作者:i春秋签约作家--Binghe 致力于书写ichunqiu社区历史上最长篇最细致最真实的技术复现文章. 文章目录: MySQL之UDF提权 MySQL之MOF提权 MySQL之常规写启动项提 ...

最新文章

  1. JavaScript入门(一)
  2. 成都python培训比较好的机构-成都Python培训班哪个好,怎样才能不走弯路学习
  3. java基础知识回顾之java Thread类学习(七)--java多线程安全问题(死锁)
  4. c语言药房系统书写指导书,C语言药房管理系统[文书借鉴]
  5. 计算机组成原理 位宽,数据总线宽度一般为存储单元位宽的整数倍 这怎么理解哦...
  6. Java 注解 Annotation
  7. Hybris Storefront里产品图片显示不出来的分析方法
  8. sprintf 详解
  9. 数据管理之元数据管理
  10. 光伏发电沦为白菜价 看光伏大佬们如何“割肉”
  11. wps在Linux上使用命令打开文档的方法
  12. RK系列(RK3568) 收音机tef6686芯片驱动,i2c驱动
  13. 对于模糊人脸图片和原图的清晰度评估——sobel算子
  14. 安卓的第三方sdk是html,第三方SDK目录
  15. SpringCloud之Eureka(微服务注册)
  16. next hop c语言实现,BGP_简单配置,next-hop-self
  17. s7300的db块详细说明_(转载)一张表搞清楚西门子S7系列标准DB块与优化DB块
  18. Python中ASCII码的获取
  19. 专转本计算机操作题库,专转本计算机题库
  20. 服务器系统可以使用软件吗,云服务器可以运行软件吗

热门文章

  1. ArcGIS 10.2.2利用Anaconda集成scipy和pandas
  2. asp代理商源代码_广告代理商的源代码是什么样的?
  3. blender 可视化编程_使用Blender可视化天体物理学数据
  4. (0)做开发必备软件
  5. Bootstrap3 表单静态控件
  6. HTML5 main元素
  7. CSS 语言伪类选择器
  8. 大数据的相关性和因果性
  9. 视觉SLAM十四讲学习笔记-第三讲-相似、仿射、射影变换和eigen程序、可视化演示
  10. python快速摄像机_Python骚操作:利用Python获取摄像头并实时控制人脸!