- 后端
- 数据库
- 负载均衡
【免费下载链接】proxysql
High-performance proxy for MySQL and PostgreSQL
导读
本文基于 ProxySQL 仓库中的压测笔记 notes/run_sysbench_on_sqlite3.md,完整讲解如何把 ProxySQL 的 MySQL 流量路由到内置 SQLite3 Server(默认 6030 端口),并用 Sysbench 对它执行 OLTP 压测。你会掌握三件事:如何通过 Admin 接口配置mysql_servers/mysql_users/mysql_query_rules搭建"MySQL 客户端 → ProxySQL → SQLite3"链路;如何用三条查询规则把 MySQL 风格的建表语句改写为 SQLite 兼容语法;以及如何正确编写prepare与run两个阶段的 Sysbench 命令并读懂其参数含义。
一、为什么要用 Sysbench 压测 SQLite3 Server
ProxySQL 提供了一个可选的内置 SQLite3 Server:以--sqlite3-server参数启动后,ProxySQL 会在 6030 端口(默认值)监听 MySQL 协议,把 MySQL 客户端发来的 SQL 翻译成 SQLite 命令执行,再把结果按 MySQL 协议返回(功能说明详见 doc/SQLite3-Server.md)。
Sysbench 是最常用的 MySQL OLTP 压测工具,恰好可以充当该链路的"客户端压力源"。用 Sysbench 对 SQLite3 Server 压测的价值在于:
- 端到端验证协议翻译:Sysbench 走的是标准 MySQL 协议,压测过程能检验 ProxySQL 的 MySQL→SQLite 翻译层是否稳定;
- 轻量基准测试:无需搭建真实 MySQL 实例,即可获得一条"MySQL 客户端 → ProxySQL → SQLite"完整数据通路的性能基线;
- 回归保护:仓库自带的 test/legacy_python_tests/sysbench_test.py 正是用 Sysbench 验证"ProxySQL 在温和 Sysbench 负载下不崩溃",说明该场景是官方维护的测试路径之一。
二、前置准备:以 SQLite3 Server 模式启动 ProxySQL
proxysql --sqlite3-server启动后,端口分配如下(与 doc/SQLite3-Server.md 中的说明一致):
| 端口 | 角色 | 是否默认启用 | 说明 |
|---|---|---|---|
| 6032 | Admin 接口 | 总是启用 | 用于配置、查看 stats / monitor 库 |
| 6030 | SQLite3 Server | 需--sqlite3-server | 对外提供 MySQL 协议,内部落地到 SQLite |
| 6033 | MySQL 前端(proxy) | 随主服务启用 | Sysbench 等 MySQL 客户端连接的入口 |
源码佐证:在 src/main.cpp 中,只有当GloVars.global.sqlite3_server == true时才调用ProxySQL_Main_init_SQLite3Server();而 src/SQLite3_Server.cpp 中默认绑定地址即127.0.0.1:6030,并可通过mysql_ifaces变量调整监听地址。
三、Admin 接口配置:把流量路由到 SQLite3 Server
压测的关键一步,是在 ProxySQL 的 Admin 接口(mysql -h 127.0.0.1 -P 6032 -u admin -p admin)中声明一个后端,让 6033 端口收到的 MySQL 流量被路由到 6030 的 SQLite3 Server。以下 SQL 来自 notes/run_sysbench_on_sqlite3.md,逐段说明:
insert into mysql_servers (hostgroup_id, hostname, port) values (100,'127.0.0.1',6030); insert into mysql_users (username,password,default_hostgroup) values ('sqlite','sqlite',100); save mysql users to disk; load mysql users to runtime; save mysql servers to disk; load mysql servers to runtime;要点:
mysql_servers把一个"虚拟后端"注册进 hostgroup 100:主机名是127.0.0.1,端口是 SQLite3 Server 的6030。ProxySQL 会把它当作普通 MySQL 后端来建立连接、转发查询;mysql_users注册压测账号:用户名/密码均为sqlite,default_hostgroup=100保证该用户的所有流量默认进入 hostgroup 100;save ... to disk持久化配置,load ... to runtime将配置加载到运行态,两条命令必须成对执行才能让改动即时生效。
三条查询规则:把 MySQL 建表语句翻译成 SQLite
Sysbench 的prepare阶段会用 MySQL 语法创建sbtest表,但 SQLite 的 DDL 与 MySQL 存在三处差异,因此需要借助 ProxySQL 的查询重写(query rules)在转发前改写 SQL:
INSERT INTO mysql_query_rules (active,username,match_digest,match_pattern,replace_pattern,apply) values (1,'sqlite','^CREATE TABLE sbtest','id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT','id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT',0); INSERT INTO mysql_query_rules (active,username,match_digest,match_pattern,replace_pattern,apply) values (1,'sqlite','^CREATE TABLE sbtest',"pad CHAR\(60\) DEFAULT '' NOT NULL,","pad CHAR(60) DEFAULT '' NOT NULL",0); INSERT INTO mysql_query_rules (active,username,match_digest,match_pattern,replace_pattern,apply) values (1,'sqlite','^CREATE TABLE sbtest','PRIMARY KEY \(id\)','',0); save mysql query rules to disk; load mysql query rules to runtime;三条规则的作用与实现要点:
- 主键类型改写:
match_pattern='id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT'→replace_pattern='id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT'。SQLite 不支持AUTO_INCREMENT与INTEGER UNSIGNED,等价语法是INTEGER PRIMARY KEY AUTOINCREMENT; - 字段定义清理:
match_pattern="pad CHAR\(60\) DEFAULT '' NOT NULL,"→replace_pattern="pad CHAR(60) DEFAULT '' NOT NULL"。注意模式中\(\)是对圆括号的正则转义,替换时去除转义恢复字面括号; - 删除重复主键约束:
match_pattern='PRIMARY KEY \(id\)'→replace_pattern=''(空串)。因为第 1 条规则已在列定义中声明PRIMARY KEY,Sysbench 建表语句末尾若再出现PRIMARY KEY (id)会与 SQLite 的语法冲突,直接整体删除。
共同点:active=1启用规则;username='sqlite'仅对该压测账号生效;match_digest='^CREATE TABLE sbtest'限定只匹配建表语句,避免误伤后续的 DML;apply=0表示这是一条独立的改写规则(不继续匹配其他规则链)。最后同样通过save+load让规则进入运行态。
四、Sysbench prepare:生成测试数据
sysbench --db-driver=mysql --test=/usr/share/sysbench/tests/include/oltp_legacy/oltp.lua --oltp-tables-count=10 --oltp-table-size=10000 --mysql-host=127.0.0.1 --mysql-db=test --mysql-engine-trx=yes --mysql-port=6033 --mysql-user=sqlite --mysql-password=sqlite --num-threads=10 prepare参数逐一说明:
| 参数 | 值 | 含义 |
|---|---|---|
--db-driver=mysql | mysql | 以 MySQL 协议驱动连接 |
--test=.../oltp.lua | oltp_legacy | 使用经典 OLTP 脚本生成表结构与数据 |
--oltp-tables-count=10 | 10 | 生成 10 张sbtest表 |
--oltp-table-size=10000 | 10000 | 每张表插入 1 万行 |
--mysql-host/--mysql-port | 127.0.0.1 / 6033 | 连接 ProxySQL 前端(而非直连 6030) |
--mysql-user/--mysql-password | sqlite / sqlite | 对应上一步mysql_users中注册的账号 |
--mysql-db=test | test | 指定默认数据库(SQLite3 Server 中即mainschema 下的数据库概念) |
--num-threads=10 | 10 | prepare 阶段并发线程数 |
prepare | — | 执行建表与数据装载阶段 |
注意:Sysbench 的prepare阶段发出的建表语句会在经过 6033 前端时被第三条查询规则改写,最终以 SQLite 语法落在 SQLite3 Server 的存储中——这就是"MySQL 压测工具写 SQLite 数据"的关键链路。
五、Sysbench run:执行 OLTP 压测
sysbench --report-interval=3 --db-driver=mysql /usr/share/sysbench/tests/include/oltp_legacy/oltp.lua --time=15 --oltp-tables-count=10 --oltp-table-size=10000 --mysql-host=127.0.0.1 --mysql-db=test --mysql-engine-trx=yes --oltp-skip-trx=off --mysql-port=6033 --mysql-user=sqlite --mysql-password=sqlite --threads=10 run与 prepare 阶段相比,run阶段的关键差异参数:
--report-interval=3:每 3 秒输出一次实时吞吐统计(tps、qps、延迟分布),便于观察压力曲线;--time=15:压测持续 15 秒后自动结束;--oltp-skip-trx=off:开启事务语义,让每个 OLTP 请求按"BEGIN + 读写 + COMMIT"的真实事务流程执行,这正是验证 ProxySQL 事务转发链路(包括对 SQLite 的 BEGIN/COMMIT 翻译)的关键开关;--threads=10:10 个并发压测线程;- 其余参数与 prepare 保持一致,确保读的是同一批
sbtest表。
仓库测试用例对照
仓库 test/legacy_python_tests/proxysql_base_test.py 中的run_sysbench_proxysql()展示了官方测试采用的同类命令形态(prepare→run→cleanup三阶段),并特别说明 Sysbench 与 ProxySQL 部署在同一容器内以降低网络延迟对基准的影响。对应测试 test/legacy_python_tests/sysbench_test.py 的断言目标是"ProxySQL 在温和 Sysbench 负载下不崩溃"——这提示我们在本场景中更应关注:prepare是否成功(建表改写是否正确)、run是否报错(协议翻译是否稳定),而非单纯追求极限 TPS。
六、运行中的注意点与限制
结合 doc/SQLite3-Server.md 的 Limitations 与源码,压测时需留意:
- SQLite 单写者模型:SQLite 对写事务采用串行化(busy/locked 处理),高并发写时吞吐会明显低于真实 MySQL。源码 src/SQLite3_Server.cpp 中
SAFE_SQLITE3_STEP2宏对SQLITE_LOCKED/SQLITE_BUSY采用usleep(100)重试策略,说明并发写冲突是设计上就预期存在的现象,压测结果应结合这一前提解读; - 数据易失性:SQLite3 Server 的表与数据默认是临时的(除非使用外部创建的 SQLite 数据库),每次重启后需要重新
prepare; - 仅有一个数据库:SQLite3 Server 对外只暴露
mainschema,--mysql-db=test本质上是映射到该 schema,不要期待多数据库隔离; - 规则匹配范围:三条 query rules 的
match_digest只匹配^CREATE TABLE sbtest,若 Sysbench 版本/脚本生成的建表语句前缀不同,需要相应调整match_pattern; - 地址绑定:SQLite3 Server 默认只监听
127.0.0.1:6030,跨主机压测时需通过mysql_ifaces变量显式放开监听地址。
七、小结
以 Sysbench 压测 ProxySQL 内置 SQLite3 Server,是一条零依赖、可复现的端到端链路验证方案:Admin 配置(mysql_servers+mysql_users+ 三条 DDL 改写规则)打通路由,prepare验证建表翻译,run验证事务与读写转发。完整的配置脚本与命令均可直接在 notes/run_sysbench_on_sqlite3.md 中找到,结合 doc/SQLite3-Server.md 与 src/SQLite3_Server.cpp 源码,即可快速复现并对结果做出合理解读。
- 后端
- 数据库
- 负载均衡
【免费下载链接】proxysql
High-performance proxy for MySQL and PostgreSQL
相关推荐
ProxySQL 内置 SQLite3 Server 实战指南:用 MySQL 客户端直连 SQLite 的协议翻译层
ProxySQL 内置 SQLite3 Server 实战指南:用 MySQL 客户端直连 SQLite 的协议翻译层 本指南系统讲解 ProxySQL 内置
后端数据库负载均衡终极指南:Remotely远程控制解决方案的数据库配置详解(SQLite、SQL Server与PostgreSQL对比)
终极指南:Remotely远程控制解决方案的数据库配置详解(SQLite、SQL Server与PostgreSQL对比) Remotely是一款基于.NET
后端桌面应用运维LND 的 SQLite 数据库后端:配置项、默认 PRAGMA 与自动压缩实战指南
LND 的 SQLite 数据库后端:配置项、默认 PRAGMA 与自动压缩实战指南 本篇技术指南以 LND 官方文档 docs/sqlite.md https
区块链
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考