Gaea 2.4.2 配置参数详解
Gaea 2.4.2 两层配置体系逐项实测:gaea.ini 进程配置与 namespace.json 租户配置全字段,13 种分片规则类型(mod/mycat_mod/global/linked 实测生效与后端落点核验),配置变更、热重载与 7 条排障实录。
Gaea 2.4.2 配置参数详解
目标:逐项讲清 Gaea 2.4.2 的两层配置体系——本地配置
gaea.ini(进程行为)与 namespace 配置 JSON(多租户路由行为)——的字段含义、取值边界与实测生效效果,并沉淀一套配置排障实录。全部实测在 Ubuntu 22.04 服务器完成:Gaea 2.4.2 代理(10.89.71.5)以 file 配置模式运行,后端 MySQL 5.7.44 双节点(10.89.71.2、10.89.71.3),mysql 8.0 客户端(10.89.71.4)接入验证。
一、环境信息
| 角色 | 位置/版本 | 说明 |
|---|---|---|
| Gaea 代理服务器 | 10.89.71.5,Gaea 2.4.2(源码编译,BuildTime 2026-10-23) | file 配置模式,服务端口 13306 / 管理端口 13307 |
| 后端 slice-0 | 10.89.71.2:3306,MySQL 5.7.44 | 逻辑库 db_test,承载 kingshard 分表 tbl_user_0000/0001、mycat 分库 db_test_0/1 |
| 后端 slice-1 | 10.89.71.3:3306,MySQL 5.7.44 | 同上,承载 tbl_user_0002/0003、db_test_2/3 |
| 客户端 | 10.89.71.4,mysql 8.0.46 CLI | 前端账号 root / q1w2e3r4 |
| 管理端口凭据 | admin / q1w2e3r4 | Basic Auth |
| 配置目录 | /opt/gaea/etc/ | gaea.ini + etc/file/namespace/gaea_test.json |
软件版本与部署过程见 《Gaea 2.4.2 安装指南》。
二、配置体系与加载顺序
Gaea 的配置分两层,各有分工:
| 层 | 文件 | 决定什么 | 变更方式 |
|---|---|---|---|
| 本地配置 | etc/gaea.ini | 进程行为:配置体系开关(file/etcd/etcdv3)、监听端口、日志、管理端口凭据 | 改文件重启进程 |
| 租户配置 | etc/file/namespace/*.json(file 模式)或 etcd(生产模式) | 业务路由:逻辑库、后端实例、分片规则、前端账号、白名单、序列号 | file 模式重启生效;etcd 模式经 gaea-cc 下发热加载 |
加载流程实测结论:
- 启动时按
config_type初始化配置管理器,file 模式扫描file_config_path/namespace/目录下所有.json文件,逐个解析为 namespace; - 任一 JSON 语法错误都会导致整个代理启动失败,实测:在 namespace 目录放置坏文件
{bad json,启动报错并退出:
max use cpu : 4(default)init manager failed, error: invalid character 'b' looking for beginning of object key string
(进程退出,13306/13307 均未监听;删除坏文件重启即恢复。)
- 直接运行
./bin/gaea(不带-config)会加载工作目录下etc/gaea.ini;若config_type保持默认etcdv3而本机无 etcd,报init manager failed, error: client is nil——这是 file 模式体验者最常见的第一个坑(详见第八章 Q1)。
三、gaea.ini(本地配置)逐项详解
以下按 v2.4.2 源码 etc/gaea.ini 模板与实测行为整理(// 注释为说明):
; 配置类型:etcd / file / etcdv3 三选一
config_type=file
; file 模式的配置根目录(namespace 配置固定在其 namespace/ 子目录下)
file_config_path=./etc/file
; etcd/etcdv3 模式的配置中心地址与凭据
coordinator_addr=http://127.0.0.1:2379
username=root
password=root
; 环境标识(多套环境区分用)
environ=local
; 服务名(上报打点)
service_name=gaea_proxy
; 集群名(gaea-cc 管理多个集群时的隔离键)
cluster_name=gaea_default_cluster
; 日志
log_path=./logs
log_level=Notice
log_filename=gaea
log_output=file
; 日志保留天数与份数
log_keep_days=3
log_keep_counts=3
; 管理端口与 Basic Auth
admin_addr=0.0.0.0:13307
admin_user=admin
admin_password=q1w2e3r4
; 代理服务端口与协议类型(tcp4/tcp6)
proto_type=tcp4
proxy_addr=0.0.0.0:13306
; 对客户端声明的默认字符集
proxy_charset=utf8
; 慢 SQL 阈值(毫秒),超过则记录
slow_sql_time=100
; 前端会话空闲超时(秒)
session_timeout=3600
; 打点统计开关与周期(秒)
stats_enabled=true
stats_interval=10
; namespace 配置加密密钥(etcd 模式下加密存储的 namespace 密码字段)
encrypt_key=1234abcd5678efg*
; 对客户端握手时声明的服务端版本号
server_version=5.6.20-gaea
; 前端认证插件:mysql_native_password / caching_sha2_password / 留空
auth_plugin=mysql_native_password
关键字段实测行为:
| 字段 | 实测行为与注意事项 |
|---|---|
| config_type | file 改 namespace 需重启;etcd/etcdv3 需配置中心可用,否则启动即报 client is nil |
| proto_type | 设为 tcp4 时 netstat 显示 0.0.0.0:13306;缺省时可能双栈监听 |
| server_version | 客户端 status 显示 Server version: 5.6.20-gaea MySQL Community Server (GPL);而 SELECT VERSION() 返回后端真实版本 5.7.44(两者不一致属正常) |
| auth_plugin | mysql 8.0 客户端(mysql Ver 8.0.46)以 mysql_native_password 成功接入;若改为 caching_sha2_password,需后端 MySQL 支持且低版本客户端将无法连接 |
| log_level | Notice 为默认;设为 Debug 后日志量显著增加(含健康检查明细),建议仅在排查连接池问题时临时开启 |
| admin_addr/admin_user/admin_password | 错误凭据请求返回 HTTP/1.1 401 Unauthorized(实测 curl -u admin:wrong) |
| slow_sql_time | 本地配置与 namespace 内同名配置均可设置,namespace 级优先(本文 namespace 设 1000ms,实测 SELECT SLEEP(2) 被记录为慢 SQL) |
| stats_interval | Prometheus 指标上报周期,配合管理端口 GET /api/metric/metrics 抓取 |
💡 技术拓展:
gaea.ini属于「基础设施层」配置,业界同类代理(MyCat 的 server.xml、ShardingSphere-Proxy 的 server.yaml)同样采用「进程配置 + 租户/逻辑库配置」两层结构。理解两层职责的划分,是把中间件从「能用」调到「可控」的第一步——进程层管连接与可观测,租户层管路由与治理。
四、namespace 配置逐项详解
namespace 是 Gaea 的多租户单元:一个业务系统一个 namespace,可对应多个逻辑库。file 模式下每个 namespace 是一个独立 JSON 文件(文件名任意,name 字段才是真实租户名)。本文实测配置 /opt/gaea/etc/file/namespace/gaea_test.json 全文(带行内注释位说明):
4.1 顶层字段
| 字段 | 类型 | 说明 | 实测行为 |
|---|---|---|---|
| name | string | 租户名,前端账号通过它归属 | gaea_test |
| online | bool | 租户是否在线,false 时前端不可接入 | true |
| read_only | bool | 租户级只读开关 | false |
| allowed_dbs | map | 允许访问的逻辑库白名单 | {"db_test": true};未列入的库 USE 被拒 |
| slow_sql_time | string | 租户级慢 SQL 阈值(ms),覆盖 gaea.ini | "1000" |
| black_sql | []string | SQL 黑名单(拦截非法 SQL) | 实测空 |
| allowed_ip | []string | 前端来源 IP/IP 段白名单,空为不限制 | 实测空 |
| slices | []object | 后端实例组定义 | 见 4.2 |
| shard_rules | []object | 分片规则定义 | 见 4.3/4.4/4.5 |
| users | []object | 前端账号 | 见 4.6 |
| default_slice | string | 非分片 SQL 的默认路由分片 | slice-0;实测 SHOW TABLES 直通 slice-0 的物理表 |
| global_sequences | []object | 全局序列号定义 | 实测空(见 4.7) |
| max_sql_execute_time | int | 单条 SQL 最大执行时间(ms),0 不开启 | 0 |
| max_sql_result_size | int | 后端结果集最大行数限制,默认 10000,-1 不开启 | 未设(默认) |
| down_after_no_alive | int | 后端探活失败多久标记下线(ms) | 未设(默认) |
| seconds_behind_master | uint64 | 从库延迟超过该值(秒)标记 down,0 为无限大 | 未设 |
| check_select_lock | bool | SELECT ... FOR UPDATE 是否优先发主库 | 默认 true |
| local_slave_read_priority | int | 本机房从库优先级:0 关闭 / 1 优先 / 2 强制 | 未设 |
| support_multi_query | bool | 是否支持一次发多条分号分隔语句 | false |
| set_for_keep_session | bool | 会话保持(前端连接与后端连接一对一绑定) | false |
| client_qps_limit | uint32 | 客户端 QPS 限流,0 不开启 | 0 |
| support_limit_transaction | bool | 限流是否同时限制事务 | false |
| allowed_session_variables | map | 允许前端动态设置的会话变量白名单(2.4.0+) | 未设 |
4.2 slices:后端实例组
{
"name": "slice-0",
"user_name": "root",
"password": "q1w2e3r4",
"master": "10.89.71.2:3306",
"slaves": [],
"statistic_slaves": [],
"capacity": 12,
"max_capacity": 24,
"idle_timeout": 60,
"capability": 0,
"max_client_connections": 0,
"init_connect": ""
}
| 字段 | 说明 |
|---|---|
| name | 分片名,被 shard_rules 与 default_slice 引用 |
| user_name / password | 连接后端 MySQL 的账号(非前端账号) |
| master | 主库地址 ip:port |
| slaves | 从库地址数组,非空时配合 users 的 rw_split 做读写分离 |
| statistic_slaves | 统计类查询专用从库 |
| capacity / max_capacity | 后端连接池初始/最大连接数 |
| idle_timeout | 空闲连接存活秒数 |
| capability | 自定义 MySQL 协议 capability,默认 41477;支持 multi query 需 500357(谨慎设置) |
| max_client_connections | 租户最大前端连接数,0 无限制 |
| init_connect | 后端连接初始化 SQL,分号分隔多个(谨慎设置) |
4.3 kingshard 系分表规则(mod 实测生效)
{
"db": "db_test",
"table": "tbl_user",
"type": "mod",
"key": "id",
"locations": [2, 2],
"slices": ["slice-0", "slice-1"]
}
locations[i]表示slices[i]上放几个分表:[2,2]= slice-0 放tbl_user_0000/0001,slice-1 放tbl_user_0002/0003(物理表名四位补零,从 _0000 起编号);- 路由算法:
分表下标 = key % 分表总数,本例总数 4。 - 实测生效过程:前端插入 8 行(id 1~8),SELECT 聚合查询跨片合并成功:
mysql -h 10.89.71.5 -P 13306 -uroot -pq1w2e3r4 db_test \
-e "SELECT COUNT(*) AS cnt, SUM(age) AS sum_age, MIN(age) AS min_age, MAX(age) AS max_age FROM tbl_user;"
cnt sum_age min_age max_age
7 141 20 27
后端落点核验(id % 4):
slice-0 db_test.tbl_user_0000: id 4, 8 (id%4==0)
slice-0 db_test.tbl_user_0001: id 1, 5 (id%4==1)
slice-1 db_test.tbl_user_0002: id 2, 6 (id%4==2)
slice-1 db_test.tbl_user_0003: id 3, 7 (id%4==3)
- 单分片查询走精确路由:
WHERE id = 4只访问 tbl_user_0000;聚合(SUM/MAX/MIN/COUNT)与ORDER BY/GROUP BY支持跨片归并,AVG 不支持(见第八章 Q4)。
⚠️ 注意:kingshard 系规则(mod/hash/range/date_*)的物理表名都是四位补零编号;实测若后端建成
tbl_user_0,前端插入报ERROR 1146 (42S02): Table 'db_test.tbl_user_0001' doesn't exist。
4.4 mycat 系分库规则(mycat_mod 实测生效)
{
"db": "db_test",
"table": "tbl_order",
"type": "mycat_mod",
"key": "user_id",
"locations": [2, 2],
"slices": ["slice-0", "slice-1"],
"databases": ["db_test_[0-3]"]
}
databases用正则区间db_test_[0-3]展开物理库db_test_0~db_test_3,与locations [2,2]对齐:slice-0 持有db_test_0/db_test_1,slice-1 持有db_test_2/db_test_3;- mycat 方式是分库不分表:每个物理库一张同名表
tbl_order(与 kingshard 方式的_0000编号完全不同,混用是高频错误); - 实测生效过程:插入 6 行,按 user_id 落库:
mysql -h 10.89.71.5 -P 13306 -uroot -pq1w2e3r4 db_test \
-e "INSERT INTO tbl_order (order_id, user_id, amount) VALUES (1001, 1, 99.50), (1002, 2, 120.00), (1003, 3, 55.80), (1004, 4, 200.10), (1005, 1, 30.00), (1006, 5, 88.88);"
后端落点核验(user_id % 4 决定物理库):
slice-0 db_test_0.tbl_order: order_id 1004 (user_id=4)
slice-0 db_test_1.tbl_order: order_id 1001, 1005 (user_id=1), 1006 (user_id=5)
slice-1 db_test_2.tbl_order: order_id 1002 (user_id=2)
slice-1 db_test_3.tbl_order: order_id 1003 (user_id=3)
分片键查询(单库精确路由):
mysql -h 10.89.71.5 -P 13306 -uroot -pq1w2e3r4 db_test \
-e "SELECT SUM(amount) AS total FROM tbl_order WHERE user_id = 1;"
total
129.50
4.5 全局表与关联表(global / linked 实测生效)
全局表(每个分片各存一份全量数据,适合字典/配置表):
{
"db": "db_test",
"table": "tbl_config",
"type": "global",
"locations": [1, 1],
"slices": ["slice-0", "slice-1"]
}
- 实测生效:
INSERT(INSERT IGNORE写法)与UPDATE均广播到两个 slice,两节点数据保持一致:
slice-0 db_test.tbl_config: max_users=20000, site_name=quzuo
slice-1 db_test.tbl_config: max_users=20000, site_name=quzuo
⚠️ 注意(重要排障):全局表普通
INSERT在 v2.4.2 实测必然报主键冲突(广播重复写同一物理表),但数据实际已全部写入且各分片一致。规避写法:全局表插入统一用INSERT IGNORE INTO ...(实测前端无报错)。详见第八章 Q5。
关联表(子表跟随父表分片,避免跨片 JOIN):
{
"db": "db_test",
"table": "tbl_order_detail",
"type": "linked",
"key": "user_id",
"parent_table": "tbl_order"
}
- 子表物理布局与父表完全一致(db_test_0~3 各一张
tbl_order_detail),无需配置 slices/locations; - 实测生效:插入子表并做父子 JOIN(父表分片键等值条件,同片路由):
mysql -h 10.89.71.5 -P 13306 -uroot -pq1w2e3r4 db_test \
-e "INSERT INTO tbl_order_detail (detail_id, user_id, item) VALUES (1, 1, 'keyboard'), (2, 4, 'mouse'), (3, 2, 'monitor'); SELECT o.order_id, d.item FROM tbl_order o, tbl_order_detail d WHERE o.user_id = d.user_id AND d.user_id = 1;"
order_id item
1001 keyboard
1005 keyboard
4.6 users:前端账号
{
"user_name": "root",
"password": "q1w2e3r4",
"namespace": "gaea_test",
"rw_flag": 2,
"rw_split": 0,
"other_property": 0
}
| 字段 | 说明 |
|---|---|
| user_name / password | 前端登录凭据(与后端账号相互独立) |
| namespace | 归属租户,决定可访问的逻辑库与分片规则 |
| rw_flag | 2=读写,1=只读 |
| rw_split | 0=不分离;1=分离(slaves 非空时读走从库) |
| other_property | 保留字段 |
实测:前端以 root/q1w2e3r4 连接 10.89.71.5:13306 成功;密码错误返回 ERROR 1045 (28000): Access denied for user 'root'@'10.89.71.4:36190' (using password: Yes)。
4.7 global_sequences:全局序列号
v2.4.2 支持基于后端 MySQL 的全局序列(利用 REPLACE INTO 更新步长取号)与雪花算法等,字段含 type(mysql/snowflake)、pk_name 等。本文未启用(global_sequences: []),生产建议对自增主键场景启用,避免多分片自增冲突——配置语法见官方 docs/sequence-id.md。
五、分片规则类型全清单(v2.4.2 源码 models/shard.go)
Gaea 2.4.2 支持 13 种 shard_rules[].type(源码常量逐一核对),分三族:
| 族 | type | 分片逻辑 | 物理命名 |
|---|---|---|---|
| 通用 | default | 非分表,走 default_slice 直通 | 逻辑表名原样 |
| 通用 | global | 全局表,写广播到全部位置 | 逻辑表名原样(每物理库一份) |
| 通用 | linked | 关联表,跟随 parent_table 分片 | 与父表同库同分布 |
| kingshard 分表 | mod | 分表键取模 | 表名_0000 四位补零 |
| kingshard 分表 | hash | 分表键哈希后取模 | 同上 |
| kingshard 分表 | range | 分表键区间(table_row 区间定义) | 同上 |
| kingshard 分表 | date_year | 按年份列分表 | 同上 |
| kingshard 分表 | date_month | 按年月分表 | 同上 |
| kingshard 分表 | date_day | 按年月日分表 | 同上 |
| mycat 分库 | mycat_mod | 分库键取模(databases 正则展开) | 库按 db_[0-N] 展开,表名原样 |
| mycat 分库 | mycat_long | 分库键哈希分段(count/length) | 同上 |
| mycat 分库 | mycat_string | 字符串键哈希(prefixLength) | 同上 |
| mycat 分库 | mycat_murmur | murmur 哈希(seed/hashSlice) | 同上 |
| mycat 分库 | mycat_padding_mod | 补零 mod 分库(padding) | 同上 |
kingshard/mycat 老用户的核心迁移红利:分片规则字段语义与原系统一致,不迁移数据即可切换到 Gaea(官方 docs/shard.md 明确承诺)。完整规则字段示例见官方 docs/shard.md 与 docs/shard-example.md。
六、配置变更与生效方式实测
6.1 file 模式:改配置必须重启
修改 namespace JSON 后必须重启进程(systemctl restart gaea-proxy 或进程管理器重启)。实测流程:将全局表 locations 从 [2,2] 改为 [1,1] → 重启 → 新路由生效(全局表按每分片一份写入)。
6.2 管理端口热重载(限 proxy 本地配置)
日志级别等 proxy 本地配置可通过管理端口热重载,无需重启:
# 先把 /opt/gaea/etc/gaea.ini 的 log_level 改为 Debug,然后:
curl -X PUT -u admin:q1w2e3r4 http://10.89.71.5:13307/api/proxy/proxyconfig/reload
"OK"
实测热重载后日志文件出现:
[2026-10-23 15:40:47.934] [INFO] [100000001] [server] reload proxy config, old: {Addr:0.0.0.0:13306 User:root Pass: db:test, Charset:utf8, SlowSQLTime:0s, BlackSQL:[], AllowedIP:[], RW-Split:false}, new: {Addr:0.0.0.0:13306 User:root Pass: db:test, Charset:utf8, SlowSQLTime:0s, BlackSQL:[], AllowedIP:[], RW-Split:false}
⚠️ 注意:namespace 的 prepare/commit/delete 接口(
PUT /api/proxy/config/prepare/:name等)依赖 etcd 配置管理器,file 模式下调用会因 client 为 nil 而失败——file 模式的租户变更入口只有「改文件 + 重启」。
七、配置排障实录
以下问题均在本文环境实测复现,可直接对照处理:
Q1:init manager failed, error: client is nil
原因:config_type 为 etcd/etcdv3(或默认值)但配置中心不可用。单机体验改 config_type=file;生产则检查 coordinator_addr 与 etcd 健康度。
Q2:init manager failed, error: invalid character 'b' looking for beginning of object key string
namespace 目录混入了非法 JSON 文件(如编辑器临时文件、坏模板)。file 模式会解析目录下全部 JSON,一个坏文件拖垮整个启动。处理:ls /opt/gaea/etc/file/namespace/*.json 逐个 python3 -m json.tool 校验。
Q3:stmt type does not support shard now(CREATE TABLE / DESC 分片表)
Gaea 不为分片表做 DDL/DESC 路由。物理分表由 DBA 在后端按第五章命名规则预建:
ERROR 1105 (HY000) at line 1: get plan error, db: db_test, origin sql: CREATE TABLE tbl_user (...), err: build plan error: stmt type does not support shard now
Q4:聚合函数报错 Table: ... is a shard table, avg is not supported(AVG)
跨片聚合仅支持 SUM/MAX/MIN/COUNT(须在最外层)。AVG 改写为 SUM(col)/COUNT(col) 或业务侧计算。
Q5:全局表 INSERT 报 ERROR 1062 (23000): Duplicate entry 'max_users' for key 'PRIMARY'
v2.4.2 全局表 INSERT 广播的已知缺陷:报错但数据实际写全。统一用 INSERT IGNORE INTO tbl_config (k, v) VALUES (...) 规避(实测无报错、两分片一致)。
Q6:insert or replace must specify columns
分片表 INSERT 必须显式列名,INSERT INTO tbl_user VALUES (101, 'nocol', 1) 不支持(错误 SQL 会进指纹库,管理端口可查)。
Q7:跨分片事务无报错但没有原子性
实测 BEGIN; INSERT tbl_user(id=102...); INSERT tbl_order(user_id=103...); COMMIT; 在 v2.4.2 正常执行不报错,两条 SQL 分别路由 slice-0/slice-1 全部落库——即跨分片事务被放行,但无原子性保证(中途失败可能出现部分提交)。生产必须按分片键设计规避跨片事务,不要依赖报错拦截。
八、参考链接
- 官方配置文档(v2.4.2 源码包):docs/configuration.md、docs/shard.md、docs/shard-example.md、docs/sequence-id.md
- 源码分片类型定义:models/shard.go(本文第五章 13 种 type 的核对基准)
- 部署与安装:《Gaea 2.4.2 安装指南》
- 选型背景:《Gaea 2.4.2 介绍与选型指南》
- 管理端口与命令实操:《Gaea 2.4.2 常用命令与管理端口详解》
- 同组中间件配置实践:《BlazingMQ 0.95.20 配置参数详解》