基于已有的组件参数对容器化的参数进行校验
MySQL动态参数校验方案
1. 背景与目标
原始提示词
1. 通过比较上层目录template 和 template_oracle下的cn.json、dn.json、gtm.json、lds.json 得到template 文件里 增量 或者 不一样的参数 和 其参数值。targetMysqlParams
1)cluster.json 和 system.json 明确不用考虑。
2. 按照dn、cn、gtm、lds 依次在 template-cr/param_dynamic_cr/mysql/gdbparamdynamic_data.yaml 文件中的参数curMysqlParams查看是否存在第一步的目标参数targetMysqlParams。这些参数的属性是否匹配 -- 这些参数的key,value, file_name, section 都需要匹配。
1)dn下的参数max_table_record_size、innodb_page_size 不再统计范围内
2) 对fileName/section 匹配校验。json文件第一层为文件名,第二次为section
3)如果targetMysqlParams有不存在curMysqlParams的参数,报错 -- 有mysql params 未合入容器化模板中。
4)如果targetMysqlParams都存在于curMysqlParams的参数中,正常退出。
3. 同一个组件的同名参数检测,这个动作应该在 比较后的结果集(targetMysqlParams) 上做,而不是在原始JSON上做。如果出现同名参数,属于异常场景退出。当前容器化不支持。
template/ 目录存放MySQL模式的参数模板JSON文件,template-oracle/ 存放Oracle兼容模式的参数模板。当MySQL模板相对于Oracle基线有新增或变更参数时,这些差异参数(targetMysqlParams)必须已合入容器化动态参数CR模板(param_dynamic_cr/mysql/gdbparamdynamic_data.yaml)。
目标:自动化校验 MySQL模板的增量/差异参数是否已正确合入容器化YAML模板,防止遗漏。
2. 输入文件
| 类型 | 文件路径 | 说明 |
|---|---|---|
| MySQL模板JSON | template/{cn,dn,gtm,lds}.json |
MySQL模式参数定义 |
| Oracle模板JSON | template-oracle/{cn,dn,gtm,lds}.json |
Oracle兼容模式参数定义(对比基线) |
| 容器化YAML模板 | template-cr/param_dynamic_cr/mysql/gdbparamdynamic_data.yaml |
MySQL模式容器化动态参数CR |
明确排除:
cluster.json和system.json不参与比较。
3. JSON/YAML 结构约定
JSON 文件结构(template/ 和 template-oracle/)
{ "<fileName>": { "<section>": { "<paramKey>": "<paramValue>", ... } } }
- 第一层 key = 配置文件名(如
proxy.ini,my.cnf,gtm.ini,lds.ini) - 第二层 key = section名(如
GENERAL,SQLEXEC,mysqld,general) - 第三层 key = 参数名,value = 参数值
YAML 文件结构(gdbparamdynamic_data.yaml)
spec:
componentDynamicParams:
<component>: # dn / cn / gtm / lds
paramDetail:
cluster1:
<paramKey>:
fileName: <fileName>
section: <section>
paramValue: <value>
4. 算法流程
4.1 第一步:JSON 差异比较 → 得到 targetMysqlParams
目标:找出 template/ 中相对于 template-oracle/ 新增或值不同的参数。
算法:
对于每个组件 component in [dn, cn, gtm, lds]:
1. 加载 template/{component}.json, 展平为 Map:
key = "fileName||section||paramKey"
value = 字符串化的paramValue
→ templateMap
2. 加载 template-oracle/{component}.json, 同样展平:
key = "fileName||section||paramKey"
value = 字符串化的paramValue
→ oracleMap
3. 遍历 templateMap 中每个条目:
a) 如果 key 不在 oracleMap 中:
→ "增量参数"(MySQL模板独有), 加入 targetMysqlParams
b) 如果 key 在 oracleMap 中,但 value 不同:
→ "差异参数", 加入 targetMysqlParams
4. 对于 component == "dn",排除以下参数(不在统计范围内):
- max_table_record_size
- innodb_page_size
展平函数 flatten_json(json_obj):
def flatten_json(json_obj):
"""
输入: {"proxy.ini": {"GENERAL": {"key1": "v1"}, "SQLEXEC": {"key2": "v2"}}}
输出: {"proxy.ini||GENERAL||key1": "v1", "proxy.ini||SQLEXEC||key2": "v2"}
"""
result = {}
for file_name, sections in json_obj.items():
for section, params in sections.items():
for param_key, param_value in params.items():
flat_key = f"{file_name}||{section}||{param_key}"
result[flat_key] = str(param_value)
return result
targetMysqlParams 数据结构:
# list of dict
targetMysqlParams = [
{
"component": "cn", # 组件类型
"fileName": "proxy.ini", # 配置文件名
"section": "GENERAL", # section名
"paramKey": "oracle_mode_switch", # 参数名
"paramValue": "0", # template中的值
},
...
]
预期当前结果(基于现有数据):
| component | fileName | section | paramKey | paramValue |
|---|---|---|---|---|
| cn | proxy.ini | GENERAL | sync_metainfo_to_vengine | 0 |
| cn | proxy.ini | GENERAL | sql_mode_proxy | default |
| cn | proxy.ini | GENERAL | oracle_mode_switch | 0 |
| cn | proxy.ini | GENERAL | tmp_function_for_future | 0 |
| cn | proxy.ini | GENERAL | dictionary_info | 0 |
| cn | proxy.ini | GENERAL | ignore_mysql_errno | 1060,1061,1091,1507,8157 |
| cn | proxy.ini | SQLEXEC | autocommit | 1 |
| dn | my.cnf | mysqld | oracle_mode_switch | ALL_OFF |
| gtm | — | — | — | (无差异) |
| lds | — | — | — | (无差异) |
说明:
gtm.json两个目录完全一致,无差异参数。lds.json中 template-oracle 比 template 多parse_mode和sql_mode,但方向是 oracle→template,不属于"template增量",故不纳入。dn.json中max_table_record_size虽然值不同(64K vs 128K),但被排除规则过滤。
4.2 第二步:同名参数检测(在 targetMysqlParams 结果集上)
目标:同一个组件内不允许出现同名参数(当前容器化不支持同名参数跨section区分)。
算法:
对于 targetMysqlParams 按 component 分组:
统计每个 component 内 paramKey 的出现次数:
如果任何 paramKey 出现次数 > 1:
→ 报错退出:"{component}组件存在同名参数{paramKey},当前容器化不支持"
注意:此检测在比较后的结果集上做,不在原始JSON上做。JSON中同fileName同section下自然不会有重复key,但跨section的同名参数可能在flat比较中出现。
4.3 第三步:YAML 匹配校验
目标:验证 targetMysqlParams 中每个参数都在容器化YAML模板中存在且属性一致。
算法:
1. 加载 param_dynamic_cr/mysql/gdbparamdynamic_data.yaml
提取 curMysqlParams:
对于 component in [dn, cn, gtm, lds]:
如果 component 在 spec.componentDynamicParams 中:
提取 paramDetail.cluster1 中的所有参数:
key = paramKey
value = {fileName, section, paramValue}
→ curMysqlParams[component] = {paramKey: {fileName, section, paramValue}}
2. 对于 targetMysqlParams 中每个参数:
令 component, paramKey, paramValue, fileName, section = ...
a) 如果 component 不在 curMysqlParams 中:
→ 报错: "{component}组件未在容器化模板中找到,参数{paramKey}未合入"
b) 如果 paramKey 不在 curMysqlParams[component] 中:
→ 报错: "{component}组件的参数{paramKey}({fileName}/{section}={paramValue})未合入容器化模板"
c) 如果 paramKey 存在,匹配字段:
令 yaml_entry = curMysqlParams[component][paramKey]
校验:
- yaml_entry.paramValue == paramValue (值匹配)
- yaml_entry.fileName == fileName (文件名匹配)
- yaml_entry.section == section (section匹配)
如果任一不匹配:
→ 报错: "{component}组件的参数{paramKey}属性不匹配:
期望 fileName={fileName}, section={section}, value={paramValue}
实际 fileName={yaml.fileName}, section={yaml.section}, value={yaml.paramValue}"
3. 如果所有 targetMysqlParams 都匹配成功:
→ 正常退出(exit 0),输出 "所有MySQL差异参数已合入容器化模板"
匹配规则详解:
| 校验项 | 来源(JSON) | 来源(YAML) | 说明 |
|---|---|---|---|
| paramKey | 第三层key | YAML的key名 | 参数名 |
| paramValue | 第三层value | paramValue |
值比较前统一转字符串 |
| fileName | JSON第一层key | fileName |
如 proxy.ini, my.cnf |
| section | JSON第二层key | section |
如 GENERAL, SQLEXEC, mysqld |
5. 边界情况处理
| 场景 | 处理方式 |
|---|---|
cluster.json / system.json |
不参与比较,直接跳过 |
gtm.json 两目录一致 |
targetMysqlParams 为空,跳过后续检查 |
lds.json template不含oracle独有参数 |
反向差异不纳入,targetMysqlParams 为空 |
DN的 max_table_record_size |
排除,不纳入 targetMysqlParams |
DN的 innodb_page_size |
排除(虽仅在cluster.json出现,作为安全兜底) |
| 同组件同名参数(跨section) | 在第二步检测并报错 |
| YAML中不存在对应component | 报错退出(如gtm/lds未在YAML中定义但有差异参数时) |
| paramValue类型差异 | 统一转字符串后比较(JSON中string vs int等) |
| YAML中component有但target无参数 | 不报错(YAML可能比差异集有更多参数,正常) |
6. 实施文件
修改/创建以下文件:
| 文件 | 操作 | 说明 |
|---|---|---|
template-cr/checkMysqlDynamicParam.py |
编写 | 主校验脚本(当前为空占位符) |
可复用现有库:
template-cr/lib/print_log.py— 日志输出template-cr/lib/read_write_conf.py— JSON/YAML 读写(read_json_with_comment可处理含//注释的JSON)template-cr/lib/config.py— 路径常量和组件名常量
7. 执行方式
cd template-cr
python checkMysqlDynamicParam.py
退出码约定:
0:所有差异参数已合入,校验通过1:有参数未合入或属性不匹配,校验失败2:存在同名参数异常,校验失败
8. 校验结果预期(基于当前代码状态)
以当前 template/ 和 template-oracle/ 以及 mysql/gdbparamdynamic_data.yaml 的内容:
targetMysqlParams(第一步):
- cn: 7个参数
- dn: 1个参数(oracle_mode_switch)
- gtm: 0个
- lds: 0个
同名检测(第二步):
- cn: 7个参数名均唯一 ✓
- dn: 1个参数 ✓
YAML匹配(第三步):
- cn 全部7个参数在YAML中匹配 ✓
- dn 的 oracle_mode_switch 在YAML中匹配 ✓
预期结果:校验通过,exit 0。
9. 扩展性设计
- YAML文件路径可通过参数指定,默认读取
param_dynamic_cr/mysql/gdbparamdynamic_data.yaml - 排除参数列表(
max_table_record_size,innodb_page_size)应可配置 - 后续如需支持
systemTenant模式校验,可复用相同逻辑,切换YAML文件路径即可 - 如果json和yaml有差异,返回所有不匹配的参数
- 读json的函数,复用from lib.read_write_conf import read_json_with_comment

浙公网安备 33010602011771号