山西十大杰出青年 發表於 2026-2-5 09:56:00

玩一玩 proxysql

<p><strong><font size="1" color="gray">作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!</font></strong></p>
<ul>
<li><font size="1" color="gray">cnblogs博客</font></li>
<li><font size="1" color="gray">zhihu</font></li>
<li><font size="1" color="gray">Github</font></li>
<li><font size="1" color="gray">公众号:一本正经的瞎扯</font><br>
<img src="https://img2022.cnblogs.com/blog/1457949/202202/1457949-20220216153819145-1193738712.png"></li>
</ul>
<hr>
<p>一个后端服务的性能不好,我怀疑是数据库拖慢了性能,为了便于不侵入代码而对性能进行分析,我尝试了 proxysql 组件:</p>
<p><code>在 mysql 客户端和 mysql 服务器之间搭建 proxysql 代理服务,通过 proxy 来记录日志、分析性能、做缓存</code>。</p>
<p>如下是使用过程:</p>
<h1 id="部署">部署</h1>
<h2 id="配置文件">配置文件</h2>
<p>如下是配置文件的格式: <code>proxysql.cnf</code></p>
<pre><code class="language-text">datadir="/var/lib/proxysql"
errorlog="/log/proxysql.log"
admin_variables=
{
admin_credentials="admin:admin"# 管理员账号
mysql_ifaces="0.0.0.0:6032"# mysql 协议管理端口
}

mysql_variables=
{
threads=4
max_connections=2048
interfaces="0.0.0.0:6033"# 代理端口
default_schema="information_schema"
monitor_username="monitor"
monitor_password="monitor"
#
mysql-eventslog_filename="/log/events.log"
mysql-eventslog_format=2          # JSON(可选)
mysql-eventslog_default_log=1   # 全量记录(可选)
}

# 先留空:你后面可用管理端口 6032 动态写入后端/用户/规则
mysql_servers =
(
)

mysql_users =
(
)
</code></pre>
<h2 id="启动服务">启动服务</h2>
<pre><code class="language-bash">docker run -d --rm --name proxysql \
          --network host \
          --cpus=1 -m=1024m \
                -p 6032:6032 -p 6033:6033 \
                -v "./proxysql.cnf:/etc/proxysql.cnf:ro" \
                -v "./data:/var/lib/proxysql" \
                -v "./log/":/log/ \
                proxysql/proxysql:latest
</code></pre>
<h2 id="配置规则">配置规则</h2>
<p>使用写入 sql 的方式来配置: <code>config.sh</code></p>
<pre><code class="language-bash">#!/usr/bin/env bash
set -euo pipefail

# ===== ProxySQL 管理端连接信息 =====
PROXYSQL_HOST="${PROXYSQL_HOST:-127.0.0.1}"
PROXYSQL_PORT="${PROXYSQL_PORT:-6032}"
PROXYSQL_ADMIN_USER="${PROXYSQL_ADMIN_USER:-admin}"
PROXYSQL_ADMIN_PASS="${PROXYSQL_ADMIN_PASS:-admin}"

# ===== 你要创建/更新的业务用户 =====
APP_USER="${APP_USER:-app}"
APP_PASS="${APP_PASS:-app_pw}"
DEFAULT_HOSTGROUP="${DEFAULT_HOSTGROUP:-10}"

mysql -h "${PROXYSQL_HOST}" -P "${PROXYSQL_PORT}" \
-u "${PROXYSQL_ADMIN_USER}" -p"${PROXYSQL_ADMIN_PASS}" \
--protocol=tcp --batch --raw --silent &lt;&lt;SQL

-- 1) 指定日志文件名(相对 datadir;也可以给绝对路径)
SET mysql-eventslog_filename='/log/events.log';

-- 2) JSON 格式(更好进 ELK/Loki)
SET mysql-eventslog_format=2;

-- 3) 默认记录所有查询
SET mysql-eventslog_default_log=1;

SET mysql-query_cache_size_MB = 512;


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


INSERT INTO mysql_servers(hostgroup_id, hostname, port, weight, max_connections)
VALUES (10, 'myserver.com', 3306, 100, 20);
INSERT INTO mysql_users(username, password, default_hostgroup, active)
VALUES ('my_user_name', 'password', 10, 1);


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

-- 规则尽量靠前(rule_id 小)
INSERT INTO mysql_query_rules
(rule_id, active, match_pattern, re_modifiers, cache_ttl, apply)
VALUES
(100, 1, '^SELECT\\s', 'CASELESS', 1000000, 1);-- 所有的 select 查询,对结果缓存 1000000 毫秒

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

-- 可选:打印确认
SELECT username, default_hostgroup, active
FROM mysql_users;

SQL

</code></pre>
<p>执行配置:</p>
<p>bash config.sh</p>
<h1 id="客户端">客户端</h1>
<p>客户端的 sql 服务器配置,把 host 修改为 proxysql 的 ip。例子中是 127.0.0.1<br>
端口修改为 proxysql 的端口, 例子中是 6033.</p>
<p>开启客户端运行后,在 proxysql 对应的 ./log/events.log.00000001 中,可以看到如下样式的日志:</p>
<pre><code class="language-json">{
    "client":"127.0.0.1:49606",
    "digest":"0x5F0C91291BB515C4",
    "duration_us":13992,
    "endtime":"2026-02-04 07:18:50.359984",
    "endtime_timestamp_us":1770189530359984,
    "errno":0,
    "event":"COM_QUERY",
    "hostgroup_id":10,
    "query":"SELECT * FROM `table1`\nWHERE `player_id` = 1234\n ORDER BY `update_time` DESC\n                  LIMIT 1",
    "rows_affected":0,
    "rows_sent":1,
    "schemaname":"my_db",
    "server":"server.com:3306",
    "starttime":"2026-02-04 07:18:50.345992",
    "starttime_timestamp_us":1770189530345992,
    "thread_id":4,
    "username":"my_user_name"
}
</code></pre>
<ul>
<li>duration_us 字段记录了 sql 的执行时间</li>
<li>query 字段可以看见具体的 sql</li>
</ul>
<h1 id="总结">总结</h1>
<p>这个组件至少能够在测试阶段做很多事情:</p>
<ul>
<li>把日志接入到日志分析系统,可以对慢查询等进行统计</li>
<li>便于做全局的 sql 治理的工作</li>
<li>通过 sql 查询结果缓存,提前评估数据缓存的收益</li>
</ul><br><br>
来源:https://www.cnblogs.com/ahfuzhang/p/19577621
頁: [1]
查看完整版本: 玩一玩 proxysql