Describe the bug
在为 store 层适配 PostgreSQL 的过程中,逐条执行 store/mysql 中的 SQL 时发现 5 处缺陷。它们与具体数据库无关,在 MySQL 部署下同样存在,其中 3 处会导致对应功能完全不可用。
1. namespace 的 metadata 未持久化
位置:store/mysql/namespace.go
DDL 中 namespace 表有 metadata 列,model.Namespace 有 Metadata 字段,namespace/namespace.go:357 也会把它放进 API 响应,但 store 层的 INSERT / UPDATE / SELECT 三处都没有涉及该列(全文搜索 metadata 命中 0 次)。结果是写入被丢弃、读取恒为空。
store/boltdb/namespace.go 对该字段是完整支持的(存取共 6 处),因此只有使用 MySQL 的部署受影响。
影响:polaris-console 依赖 namespace 的 metadata 判断全局注册中心(checkGlobalRegistry),该函数因此恒返回 false;同时前端对 undefined 调用 Object.entries 会导致命名空间等页面白屏。
2. client_stat 的列名错误
位置:store/mysql/client.go:235、store/mysql/client.go:458
// 235: FROM 中只有 client_stat,并无 client 表
str := "select `target`, `port`, `protocol`, `path` from client_stat where client.id = ?"
// 458: cliend_id 是 client_id 的拼写错误
deleteStr := "delete from client_stat where cliend_id = ?"
client_stat 表只有 client_id 列。两条 SQL 执行必然报 Unknown column。
影响:GetClientStat 与 updateClientStat 一直不可用。
3. BatchCleanDeletedClients 参数数量不匹配
位置:store/mysql/admin.go:536
mainStr := "delete from client where flag = 1 limit ?" // 1 个占位符
result, err := tx.Exec(mainStr, int32(timeout.Seconds()), batchSize) // 传入 2 个参数
除参数数量不符外,timeout 实际未参与过滤,与同文件中 BatchCleanDeletedInstances(按 mtime 过滤)的语义也不一致。
影响:客户端软删除数据的清理任务执行失败。
4. auth_role_principal 的列名与占位符错误
位置:store/mysql/role.go:68、store/mysql/role.go:73
// 68: 该表的关联列是 role_id,不存在 id 列
tx.Exec("DELETE FROM auth_role_principal WHERE id = ?", role.ID)
// 73: 列列表中出现函数;且四个列只给了三个占位符,而下方传入四个参数
insertTpl := "INSERT INTO auth_role_principal(role_id, principal_id, principal_role, IFNULL(extend_info, '')) VALUES (?, ?, ?)"
(同文件 270 行 SELECT 中的 IFNULL(extend_info, '') 是正常用法,不在此列。)
影响:角色携带 Users / UserGroups 时,savePrincipals 必然失败,即角色的成员关联功能不可用。
5. LaneCache.GetRule 空指针 panic
位置:cache/service/lane.go:430
func (lc *LaneCache) GetRule(id string) *model.LaneGroup {
rule, _ := lc.rules.Load(id)
return rule.LaneGroup
}
忽略了 SyncMap.Load 的 ok 返回值,直接对可能为 nil 的结果解引用。调用方 service/interceptor/auth/lane.go:128 写有 if saveRule != nil 判断,说明其预期该函数可以返回 nil。
创建泳道组时 req[i].GetId() 为空字符串,必然命中该路径。
影响:创建泳道组的请求触发 panic,连接被服务端断开(HTTP 无响应)。该功能完全不可用。
To Reproduce
问题 5 可直接复现:
curl -XPOST "http://127.0.0.1:8090/naming/v1/lane/groups" \
-H "X-Polaris-Token: $TOKEN" -H "Content-Type: application/json" \
-d '[{"name":"lane1","namespace":"default","description":"d"}]'
服务端日志:
http: panic serving 127.0.0.1:60605: runtime error: invalid memory address or nil pointer dereference
github.com/polarismesh/polaris/cache/service.(*LaneCache).GetRule
/cache/service/lane.go:432
github.com/polarismesh/polaris/service/interceptor/auth.(*Server).collectLaneRuleAuthContext
/service/interceptor/auth/lane.go:128
问题 1 可通过创建带 metadata 的命名空间后查询验证:写入的 metadata 不会返回,数据库中该列为空。
问题 2、3、4 为 SQL 语句本身的错误,执行即报错。
Expected behavior
- namespace 的 metadata 能够正常写入与读出,与 boltdb 实现保持一致
client_stat 相关语句使用正确的列名 client_id
BatchCleanDeletedClients 的占位符与参数数量一致,并按 timeout 过滤
auth_role_principal 的插入语句列名与占位符正确
LaneCache.GetRule 在 id 不存在时返回 nil 而非 panic
Environment
- Version: main(
df0ce073)
- OS: 与平台无关
Additional context
上述问题均在为 store 层适配 PostgreSQL 时,通过逐条执行 SQL 发现。PostgreSQL 侧已验证修复有效;MySQL 侧目前只跑了仓库内已有的单元测试(store/mysql 现有测试未覆盖这些路径),结论主要基于 SQL 语义与表结构的比对。
已准备好对应的修复,将提交 PR 关联本 issue。
Describe the bug
在为 store 层适配 PostgreSQL 的过程中,逐条执行
store/mysql中的 SQL 时发现 5 处缺陷。它们与具体数据库无关,在 MySQL 部署下同样存在,其中 3 处会导致对应功能完全不可用。1.
namespace的 metadata 未持久化位置:
store/mysql/namespace.goDDL 中
namespace表有metadata列,model.Namespace有Metadata字段,namespace/namespace.go:357也会把它放进 API 响应,但 store 层的 INSERT / UPDATE / SELECT 三处都没有涉及该列(全文搜索metadata命中 0 次)。结果是写入被丢弃、读取恒为空。store/boltdb/namespace.go对该字段是完整支持的(存取共 6 处),因此只有使用 MySQL 的部署受影响。影响:polaris-console 依赖 namespace 的 metadata 判断全局注册中心(
checkGlobalRegistry),该函数因此恒返回 false;同时前端对undefined调用Object.entries会导致命名空间等页面白屏。2.
client_stat的列名错误位置:
store/mysql/client.go:235、store/mysql/client.go:458client_stat表只有client_id列。两条 SQL 执行必然报Unknown column。影响:
GetClientStat与updateClientStat一直不可用。3.
BatchCleanDeletedClients参数数量不匹配位置:
store/mysql/admin.go:536除参数数量不符外,
timeout实际未参与过滤,与同文件中BatchCleanDeletedInstances(按mtime过滤)的语义也不一致。影响:客户端软删除数据的清理任务执行失败。
4.
auth_role_principal的列名与占位符错误位置:
store/mysql/role.go:68、store/mysql/role.go:73(同文件 270 行 SELECT 中的
IFNULL(extend_info, '')是正常用法,不在此列。)影响:角色携带 Users / UserGroups 时,
savePrincipals必然失败,即角色的成员关联功能不可用。5.
LaneCache.GetRule空指针 panic位置:
cache/service/lane.go:430忽略了
SyncMap.Load的 ok 返回值,直接对可能为 nil 的结果解引用。调用方service/interceptor/auth/lane.go:128写有if saveRule != nil判断,说明其预期该函数可以返回 nil。创建泳道组时
req[i].GetId()为空字符串,必然命中该路径。影响:创建泳道组的请求触发 panic,连接被服务端断开(HTTP 无响应)。该功能完全不可用。
To Reproduce
问题 5 可直接复现:
服务端日志:
问题 1 可通过创建带 metadata 的命名空间后查询验证:写入的 metadata 不会返回,数据库中该列为空。
问题 2、3、4 为 SQL 语句本身的错误,执行即报错。
Expected behavior
client_stat相关语句使用正确的列名client_idBatchCleanDeletedClients的占位符与参数数量一致,并按 timeout 过滤auth_role_principal的插入语句列名与占位符正确LaneCache.GetRule在 id 不存在时返回 nil 而非 panicEnvironment
df0ce073)Additional context
上述问题均在为 store 层适配 PostgreSQL 时,通过逐条执行 SQL 发现。PostgreSQL 侧已验证修复有效;MySQL 侧目前只跑了仓库内已有的单元测试(
store/mysql现有测试未覆盖这些路径),结论主要基于 SQL 语义与表结构的比对。已准备好对应的修复,将提交 PR 关联本 issue。