跳到主要内容

ProxySQL安装

· 阅读需 6 分钟
GavinTan
DevOps Engineer

安装

cat <<EOF | tee /etc/yum.repos.d/proxysql.repo
[proxysql_repo]
name= ProxySQL YUM repository
baseurl=https://repo.proxysql.com/ProxySQL/proxysql-2.1.x/centos/\$releasever
gpgcheck=1
gpgkey=https://repo.proxysql.com/ProxySQL/repo_pub_key
EOF

yum install proxysql -y

添加mysql集群节点

提示

同一个节点可以存在多个hostgroup里

mysql -u admin -padmin -h 127.0.0.1 -P 6032

INSERT INTO mysql_servers(hostgroup_id, hostname, port, use_ssl) VALUES (0,'192.168.70.71',3306,1);
INSERT INTO mysql_servers(hostgroup_id, hostname, port, use_ssl) VALUES (0,'192.168.70.72',3306,1);
INSERT INTO mysql_servers(hostgroup_id, hostname, port, use_ssl) VALUES (0,'192.168.70.73',3306,1);


# 保存配置
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

查看

SELECT * FROM mysql_servers;

添加客户端登录用户

注意

用户必须在mysql节点中存在账号密码一样,目前proxysql只支持mysql_native_password密码插件,在mysql节点添加用户时候必须指定插件为mysql_native_password。

# mysql节点中执行
CREATE USER 'root'@'%' IDENTIFIED WITH mysql_native_password by '123456';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;

通过定义default_hostgroup我们指定用户应该默认连接到指定相同hostgroup_id后端服务器

# proxysql中执行
INSERT INTO mysql_users (username,password,default_hostgroup) VALUES ('root','123456',0);
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

默认明文密码通过下面生成加密密码

load mysql users to runtime
save mysql users to memory;
save mysql users to disk;

查看

SELECT * FROM mysql_users;

连接

admin管理接口,默认端口为6032。该端口用于查看、配置ProxySQL。

接收SQL语句的接口,默认端口为6033,该端口用于mysql客户端连接。

其他配置

  1. 配置监控用户

    在mysql节点中执行创建监控用户

    CREATE USER 'proxysql'@'%' IDENTIFIED WITH mysql_native_password by '123456';
    GRANT USAGE ON *.* TO 'proxysql'@'%';

    在proxysql中执行设置监控用户账号密码

    UPDATE global_variables SET variable_value='proxysql' WHERE variable_name='mysql-monitor_username';
    UPDATE global_variables SET variable_value='123456' WHERE variable_name='mysql-monitor_password';

    LOAD MYSQL VARIABLES TO RUNTIME;
    SAVE MYSQL VARIABLES TO DISK;

    查看监控信息

    SELECT * FROM monitor.mysql_server_connect_log ORDER BY time_start_us DESC LIMIT 6;
    SELECT * FROM monitor.mysql_server_ping_log ORDER BY time_start_us DESC LIMIT 6;
  2. 配置read_only监控和读/写组

    mysql节点有read_only=0的hostgroup将自动设置为0,read_only=1设置成1

    INSERT INTO mysql_replication_hostgroups (writer_hostgroup,reader_hostgroup,comment) VALUES (0,1,'cluster1');

    LOAD MYSQL SERVERS TO RUNTIME;
    SAVE MYSQL SERVERS TO DISK;

    设置执行只读检查的频率,以毫秒为单位。

    UPDATE global_variables SET variable_value=5000 WHERE variable_name='mysql-monitor_read_only_interval';

    设置只读检查超时时间(以毫秒为单位)

    UPDATE global_variables SET variable_value=5000 WHERE variable_name='mysql-monitor_read_only_timeout';

    LOAD MYSQL VARIABLES TO RUNTIME;
    SAVE MYSQL VARIABLES TO DISK;

    # 查看
    SELECT * FROM monitor.mysql_server_read_only_log ORDER BY time_start_us DESC LIMIT 3;
  3. 启用前端的 SSL/TLS(zabbix连接之类)

    SET mysql-have_ssl="true";
    LOAD MYSQL VARIABLES TO RUNTIME;
    SAVE MYSQL VARIABLES TO DISK;

    # 查看
    SELECT * FROM global_variables WHERE variable_name LIKE 'mysql%ssl%';
  4. 设置返回给客户端的 MySQL 版本号(zabbix-server限定客户端版本之类)

    set mysql-server_version="8.0.27";
    LOAD MYSQL VARIABLES TO RUNTIME;
    SAVE MYSQL VARIABLES TO DISK;

    # 查看
    SELECT * FROM global_variables WHERE variable_name LIKE '%version%';
  5. 配置查询规则

    • 查询规则按rule_id从小到大顺序处理

    • 仅处理已active=1处理的规则

    • 第一个规则示例使用插入符号 ( ^) 和美元 ( $) :这些是特殊的正则表达式字符,用于标记模式的开始和结束,即在这种情况下match_digest或match_pattern应该完全匹配查询

    • 不使用插入符号或美元:匹配可以在查询中的任何位置

    • 问号被转义,因为它在正则表达式中具有特殊含义

    • apply=1表示如果当前规则匹配则不会继续匹配后的规则

    • match_digest:将正则表达式与去除 SQL 查询数据的查询摘要进行匹配(例如 SELECT c FROM sbtest1 WHERE id=?,如stats_mysql_query_digest.query_digest)

    • match_pattern:将正则表达式与查询的实际文本匹配(例如,SELECT c FROM sbtest1 WHERE id=2

    • 当入口值flagIN设置为0时,表示开始进入链式规则。

    • 如未显式指定规则的flagIN值,则默认都为0。当语句匹配完当前规则后,将记下当前规则的flagOUT值,如果flagOUT值非空(NOT NULL),则为该语句打上flagOUT标记。如果该规则的apply字段值不是1,则继续向下匹配。如果语句的flagOUT标记和下一条规则的flagIN值不同,则跳过该规则,继续向下匹配。直到匹配到flagOUT=flagIN的规则,则匹配该规则。该规则是链式规则中的另一条规则。直到某规则的apply字段设置为1,或者已经匹配完所有规则,则最后一次被评估的规则将直接生效,不再继续向下匹配。

    提示

    如果想对match_digest取反,即不被正则匹配的SQL语句才命中规则,则设置mysql_query_rules表中的字段negate_match_pattern=1。同样适用于下面的match_pattern匹配方式。

    摘要总是比查询本身小,对较小的字符串运行正则表达式会更快,建议(出于性能考虑)使用match_digest. 要重写查询或匹配查询文本本身,请使用match_pattern.

    查看语句匹配

    INSERT INTO mysql_query_rules (rule_id,active,username,match_digest,destination_hostgroup,apply) VALUES (10,1,'stnduser','^SELECT * FROM sbtest1 WHERE id=\?$',10,1);

    INSERT INTO mysql_query_rules (rule_id,active,username,match_digest,destination_hostgroup,apply) VALUES (10,1,'stnduser','^SELECT',10,1);

    数据库名称匹配(不利用 use databases 并且不命中其他规则,默认转发到用户 default_hostgroup)

    instert into mysql_query_rules (rule_id, active, schemaname, destination_hostgroup,apply) values(1,1,'aa', 10, 1);

    客户端IP匹配

    insert into mysql_query_rules (rule_id, active, client_addr, destination_hostgroup) values(2,1,'192.168.8.192', 10);

    禁止查询,可以配合客户端ip策略设置白名单

    insert into mysql_query_rules (rule_id, active, match_digest, error_msg) values(3,1,'.','error 9999');

    查询重写

    INSERT INTO mysql_query_rules (rule_id,active,username,match_pattern,replace_pattern,apply) VALUES (30,1,'root','DISTINCT(.*)ORDER BY c','DISTINCT\1',1);

    查询缓存 cache_ttl(毫秒)

    UPDATE mysql_query_rules set cache_ttl=5000 WHERE rule_id=10;

    保存规则配置

    LOAD MYSQL QUERY RULES TO RUNTIME;
    SAVE MYSQL QUERY RULES TO DISK;

    # 查看
    SELECT match_digest,destination_hostgroup FROM mysql_query_rules;

    SELECT rule_id, match_digest, match_pattern, replace_pattern, cache_ttl, apply FROM mysql_query_rules ORDER BY rule_id;
    # 查看hg(主机组)=-1为缓存查询
    SELECT hostgroup hg, sum_time, count_star, digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC limit 10;

全局变量

变量默认值说明
admin-admin_credentialsadmin:admin管理端口用户名和密码
admin-mysql_ifaces0.0.0.0:6032管理端口
admin-stats_credentialsstats:stats数据端口用户名和密码
mysql-commands_statstrue是否开启 SQL 统计,开启后会分析每条 SQL 语句
mysql-connection_max_age_ms0到 Backend 的连接空闲多久后会自动关闭
mysql-default_query_timeout86400000到 Backend 的查询超时时间(毫秒),超过后会主动停止查询,并从 Backend Kill 掉该连接
mysql-free_connections_pct10允许的 Backend 空闲连接数,是一个占 mysql-max_connections 数量的百分比
mysql-interfaces0.0.0.0:6033数据端口配置
mysql-max_connections2048ProxySQL 可接收的最大连接数。默认 10000。
mysql-server_version5.5.30ProxySQL 返回给客户端的 MySQL 版本号,有可能影响客户端行为
mysql-session_idle_show_processlisttrue管理端口进行 show processlist 时,是否显示空闲连接,开启后会影响性能
mysql-wait_timeout28800000客户端连接空闲超时时间(毫秒)

修改

set admin-admin_credentials='admin:admin;myuser:myuser';

# 使修改立即生效
load admin variables to runtime;
# 使修改永久保存到磁盘
save admin variables to disk;

查看

SELECT * FROM global_variables;
SELECT @@admin-stats_credentials;
SHOW VARIABLES LIKE "mysql-max_connections";