Gaea 2.4.2 配置参数详解

Gaea 2.4.2 两层配置体系逐项实测:gaea.ini 进程配置与 namespace.json 租户配置全字段,13 种分片规则类型(mod/mycat_mod/global/linked 实测生效与后端落点核验),配置变更、热重载与 7 条排障实录。

GaeaMySQL 中间件中间件2026/10/23

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-010.89.71.2:3306,MySQL 5.7.44逻辑库 db_test,承载 kingshard 分表 tbl_user_0000/0001、mycat 分库 db_test_0/1
后端 slice-110.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 / q1w2e3r4Basic 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_typefile 改 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_pluginmysql 8.0 客户端(mysql Ver 8.0.46)以 mysql_native_password 成功接入;若改为 caching_sha2_password,需后端 MySQL 支持且低版本客户端将无法连接
log_levelNotice 为默认;设为 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_intervalPrometheus 指标上报周期,配合管理端口 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 顶层字段

字段类型说明实测行为
namestring租户名,前端账号通过它归属gaea_test
onlinebool租户是否在线,false 时前端不可接入true
read_onlybool租户级只读开关false
allowed_dbsmap允许访问的逻辑库白名单{"db_test": true};未列入的库 USE 被拒
slow_sql_timestring租户级慢 SQL 阈值(ms),覆盖 gaea.ini"1000"
black_sql[]stringSQL 黑名单(拦截非法 SQL)实测空
allowed_ip[]string前端来源 IP/IP 段白名单,空为不限制实测空
slices[]object后端实例组定义见 4.2
shard_rules[]object分片规则定义见 4.3/4.4/4.5
users[]object前端账号见 4.6
default_slicestring非分片 SQL 的默认路由分片slice-0;实测 SHOW TABLES 直通 slice-0 的物理表
global_sequences[]object全局序列号定义实测空(见 4.7)
max_sql_execute_timeint单条 SQL 最大执行时间(ms),0 不开启0
max_sql_result_sizeint后端结果集最大行数限制,默认 10000,-1 不开启未设(默认)
down_after_no_aliveint后端探活失败多久标记下线(ms)未设(默认)
seconds_behind_masteruint64从库延迟超过该值(秒)标记 down,0 为无限大未设
check_select_lockboolSELECT ... FOR UPDATE 是否优先发主库默认 true
local_slave_read_priorityint本机房从库优先级:0 关闭 / 1 优先 / 2 强制未设
support_multi_querybool是否支持一次发多条分号分隔语句false
set_for_keep_sessionbool会话保持(前端连接与后端连接一对一绑定)false
client_qps_limituint32客户端 QPS 限流,0 不开启0
support_limit_transactionbool限流是否同时限制事务false
allowed_session_variablesmap允许前端动态设置的会话变量白名单(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_flag2=读写,1=只读
rw_split0=不分离;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_murmurmurmur 哈希(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 全部落库——即跨分片事务被放行,但无原子性保证(中途失败可能出现部分提交)。生产必须按分片键设计规避跨片事务,不要依赖报错拦截。

八、参考链接

  1. 官方配置文档(v2.4.2 源码包):docs/configuration.md、docs/shard.md、docs/shard-example.md、docs/sequence-id.md
  2. 源码分片类型定义:models/shard.go(本文第五章 13 种 type 的核对基准)
  3. 部署与安装:《Gaea 2.4.2 安装指南》
  4. 选型背景:《Gaea 2.4.2 介绍与选型指南》
  5. 管理端口与命令实操:《Gaea 2.4.2 常用命令与管理端口详解》
  6. 同组中间件配置实践:《BlazingMQ 0.95.20 配置参数详解》