24.6 实战:把 `pg36_shop` 纳入服务治理
本节把全章压成一条可重放的 L0 证明:
machine-check service card
-> calculate SLO and control objectives
-> bind observation sources and missing semantics
-> accept actionable alerts
-> reject actionless page
-> bind four SOPs to upstream drills
-> enforce high-risk authority
-> enforce evidence retention/redaction
-> rerun current ch19 deployment gate
-> hash-bind ch20–ch23 summaries
-> reject 20 adversarial mutations实验不会:
- 创建或修改 PostgreSQL 对象;
- 改 PgBouncer/HAProxy;
- 切换 leader;
- 运行 restore;
- 修改 role/credential/HBA/TLS;
- 部署 VMAlert rule;
- 发送真实 page;
- 删除或重置数据。
all 在本章表示“采集只读 gate 并验证全部合同”,不是“执行所有被引用的
高风险演练”。
实验合同:
24.6.1 发布服务卡、SLO、责任人与升级路径
目标环境
service pg36_shop
target pg36-l2-vagrant/pg-test
environment l2-sandbox
data synthetic teaching data
production traffic false
Pigsty v4.4.0
PostgreSQL major 18
host count 4
PG member count 4 across pg-meta and pg-test服务卡明确:
catalog_status teaching-reference
production_tier false
production_slo false因此 validator 会拒绝任何把它改成 production SLO 的 mutation。
文件布局
static/labs/ch24/
├── requirements.json
├── service-card.json
├── slo-policy.json
├── observation-contract.json
├── alert-candidates.json
├── sop-catalog.json
├── change-policy.json
├── evidence-retention.json
├── governance-adr.md
├── dependency-map.mmd
├── lab-contract.md
├── negative-cases.json
├── build_evidence.py
├── validate.py
├── review.py
├── task.sh
└── governance-run.json核心合同八份,其他文件负责解释、验证和保存公开摘要。
服务卡
customer journeys place-order, read-order
owner functions service, data, platform, security/privacy
dependencies 6
health layers 6
escalation SEV-1, SEV-2, ticket
known gaps 6四个 owner:
| function | role id | accountable |
|---|---|---|
| service | shop-service-owner | journey、SLO、release、业务决定 |
| data | shop-data-owner | 语义、保留、质量、隐私分类 |
| platform | database-platform-owner | PG/Pigsty、容量、恢复、执行 |
| security/privacy | security-privacy-duty | access、例外、披露、隐私 |
这些是 role contracts,没有写个人名字。route://... 也只是教学 route id,
不声称有真实 pager。
依赖图
user
-> pg36_shop application boundary
-> HAProxy / PgBouncer
-> PostgreSQL pg-test
-> Patroni / etcd
-> pgBackRest / WAL repository
all observable through
VictoriaMetrics / VictoriaLogs / VMAlert / Alertmanager / GrafanaMermaid 源文件:
dependency-map.mmd。
每项依赖带 failure semantics。例如:
victoria-observability fails
-> service state becomes unknown
-> do not interpret missing telemetry as healthy六层健康
process
endpoint
authentication
transaction
correctness
durability_and_recovery所有层的 sufficient_for_service_health=false,服务卡另有:
"service_health_requires_all_layers_and_user_contract": truevalidator 会把第一层改成 true,确认“process alive 即服务健康”被拒绝。
SLO policy
slo-policy.json 定义:
| ID | kind | target |
|---|---|---|
SLO-AVAILABILITY | ratio | 99.9% / rolling 28d |
SLO-LATENCY | ratio | 99% under 250 ms / rolling 28d |
SLO-FRESHNESS | ratio | 99% under 5 s / rolling 28d |
CTRL-CORRECTNESS | control | zero unexplained mismatch |
CTRL-RESTORE-READINESS | control | passing isolated restore ≤ 90d |
算术验证:
window seconds 2,419,200
availability target 0.999
sample eligible events 10,000,000
sample error budget events 10,000
equivalent time budget 2,419.2 s / 40.32 minPython validator 使用容差重新计算,而不是信任 JSON 中的答案。
exclusion
三个默认排除:
- admission 前的语法错误;
- 正确拒绝的未授权身份;
- admission 前客户端断开且没有 server outcome。
明确:
planned_maintenance_excluded false
retroactive_exclusion_allowed false一个新例外必须记录 id、时间、operation、independent approver、reason 和 before/after count。
error-budget state
healthy > 50%
watch > 25% and <= 50%
constrained > 0% and <= 25%
exhausted <= 0%每个状态都有 action。validator 把 exhausted actions 清空,确认“没有后果的 预算”被拒绝。
只做合同 lint
不连接任何 sandbox:
static/labs/ch24/task.sh lint输出:
status=validation-ok
schema=pg36-ch24-validation-report-v1
production_ch24_gate=pending
status=validation-ok
schema=pg36-ch24-negative-report-v1
counterexamples=20-rejected
production_ch24_gate=pending
status=lint-ok
counterexamples=20-rejected
mutation=none
production_ch24_gate=pendinglint 使用私密临时目录保存报告,并在结束时删除;不产生 repository 文件。
24.6.2 为备份、切换、权限和发布建立 SOP
四份 SOP
| ID | capability | risk | owner / approver |
|---|---|---|---|
SOP-BACKUP-RESTORE | backup and restore | L3 | platform / data |
SOP-ROLE-CHANGE | switch/failover | L3 | platform / service |
SOP-ACCESS-ROTATION | access/credential | L2 | security / platform |
SOP-SCHEMA-RELEASE | schema release | L2 | service / platform |
owner 与 approver 不同。每份包含:
- trigger;
- exact target;
- blast radius;
- prerequisites;
- procedure phases;
- stop conditions;
- verification;
- rollback/roll-forward;
- evidence;
- review interval。
恢复 SOP
输入:
source cluster
backup repository
recovery objective
target time/name
isolated destination
application invariants
space/WAL/authority停止:
- identity/target 模糊;
- destination 可接 production traffic;
- WAL/integrity 失败;
- 验收未事先固定。
通过:
- target marker 存在;
- post-target marker 不存在;
- database identity 正确;
- recovered server 已停止;
- timing 只称 sandbox observation。
validator 会把 verification 替换为:
backup command exited zero并拒绝。
role change SOP
先区分:
planned switchover
unplanned failover共同停止线:
- 多写主可能;
- DCS/fencing unknown;
- candidate 不符合 durability policy;
- unknown writes 不能核对。
验证:
one leader
timeline progression
acknowledged rows present
unknown classified
pool routes current leaderrollback 文案刻意写:
prefer safe roll-forward to one fenced leader;
a planned return is a new changetimeline 已推进后,不能把“切回”当撤销历史。
access rotation SOP
步骤:
new secret version out-of-band
-> new authentication test
-> bounded client/pool migration
-> old new-session auth rejected
-> revoke login/credential
-> explicit existing-session decision
-> verify final role and secret-free evidence若 suspected disclosure,不能 rollback 到旧 secret,只能再次向前轮换。
schema release SOP
expand schema
-> old/new app compatible
-> bounded idempotent backfill
-> constraint/reconciliation
-> feature switch
-> contract old representation later停止:
- lock 超时;
- WAL/lag/disk/budget 越界;
- old app 提前不兼容;
- backfill 不可恢复或不幂等。
上游实验绑定
三份 SOP 引用第 20、21、23 章;第 22 章作为入口/池证据也在本章 upstream manifest 中绑定。
| 章 | run id | SHA-256 | production |
|---|---|---|---|
| ch20 | 475e9b47-bc35-4687-87da-012f1d5ea455 | 602e932b...9d9a5d | pending |
| ch21 | run_20260729T201040Z_961665aa | c0b3589d...a212ca | pending |
| ch22 | 87a63891-d6bf-46b3-bb65-d70a8d7bac3a | 444a6521...e6a2 | pending |
| ch23 | 64b857a6-8d8f-46e2-9462-3f097a95a69f | e1548658...cb59 | pending |
完整 digest 见
governance-run.json。
绑定证明:
this governance contract references these exact public summaries不证明:
raw private evidence is embedded
the runs are fresh today
the actions were repeated in chapter 24
the sandbox results are production performance变更政策
change-policy.json 固定 L0–L3。
L2/L3:
requester_may_approve false
approver_may_execute false
requester_approver_executor_distinct true
shared_accounts_allowed false
independent_approver_qualified true
exact_target_and_blast_radius true
machine_preconditions true
confirmation_binds target/action/time truebreak-glass:
skip normal wait allowed
skip target/evidence forbidden
time-bounded identity required
after-action review required
credential rotation required正式 L0 运行
需要第 19 章 private mode-0600 inventory:
export PG36_CH19_INVENTORY=/absolute/private/baseline.yml
export PG36_EVIDENCE_DIR=/absolute/private/new-empty/ch24-run
static/labs/ch24/task.sh allrunner:
1 reject nonempty evidence directory
2 run ch19 task.sh all
3 build governance-evidence.json
4 hash current source files
5 bind ch20–ch23 summaries
6 positive validation
7 negative mutation validation
8 review permissions and secret patterns没有 reset action。
当前第 19 章 gate
正式运行观测:
captured 2026-07-29T21:57:40Z
Pigsty v4.4.0
PostgreSQL major 18
hosts 4
PG members 4
sandbox L2 accepted-with-exceptions
exceptions 6
production pending
mutation none六项例外:
- shared hypervisor;
- single etcd;
- single backup target;
- virtual storage;
- sandbox inventory secret handling;
- lab resource floor。
再次通过 gate 没有消除这些例外。
正式 evidence
run id 34909737-527a-460c-927c-d9d71c93aa13
captured 2026-07-29T21:57:40.539Z
mode read-only-contract-and-live-baseline-binding
mutation noneprivate evidence 保存:
- ch19 current capture;
- governance evidence;
- positive report;
- negative report;
- review output。
公开仓库只保存
governance-run.json。
24.6.3 输出观察契约,并拒绝没有动作的告警候选
观察契约
observation-contract.json 为五个目标绑定:
source
metric type
good/total selector
dimensions
recording rule
query template
missing semantics
fallbackPigsty component labels:
cls / ins / ipapplication labels:
service / operation_class / environment禁止:
customer_id / tenant_id / order_id / raw_sql / error_messagecomponent telemetry
四组:
| ID | sources | purpose |
|---|---|---|
PG-COMPONENT-ACTIVITY | activity/database/io | concurrency/error/I/O diagnosis |
PG-COMPONENT-REPLICATION | replication/receiver/LSN | replay and WAL risk |
PG-COMPONENT-ARCHIVE | archiver/pgBackRest | recovery-path risk |
PIGSTY-CORRELATION | Victoria stack | correlate PG/pool/LB/host/log |
它们不替代 user SLI。
accepted alerts
| alert | class | route |
|---|---|---|
PG36ShopAvailabilityFastBurn | symptom | page SEV-1 |
PG36ShopAvailabilitySlowBurn | symptom | page SEV-2 |
PG36ShopAvailabilityBudgetTicket | symptom | ticket |
PG36ShopCorrectnessMismatch | integrity | page SEV-1 |
PG36ShopFreshnessFastBurn | symptom | page SEV-2 |
PG36ShopCapacityHorizon | capacity | ticket |
PG36MonitoringPathBroken | metamonitoring | page SEV-2 |
其中:
symptom/integrity pages 4
metamonitoring pages 1
tickets 2所有 accepted item 都有:
- user impact;
- owner function;
- route;
- runbook;
- first safe action;
- verification;
- dashboard;
- missing semantics;
- silence policy;
- test id;
- review expiry。
rejected alert
PostgresInstanceDownWithoutAction字段:
proposed_route page
decision rejected
user_impact null
owner null
runbook null
first_safe_action nullreplacement:
correlate endpoint and user-event symptoms;
retain instance state on topology dashboard这不是漏填;它是一个特意保留的反例。若有人将 decision 改为 accepted,
validator 失败。
三个 diagnostic-only causes
PG36ReplicaReplayDistance
PG36PoolQueueDepth
PG36HostCpuHigh都不 page。它们进入 dashboard,只有 correlated user/integrity/durability 合同触发后才帮助定位。
metamonitoring
要求:
- application series freshness;
- VMAlert evaluation failures;
- Alertmanager notification canary;
- VictoriaMetrics query/ingestion;
- external blackbox probe。
missing_is_healthy=false。
二十个反例
| ID | mutation | 被哪类不变量拒绝 |
|---|---|---|
| N01 | 宣称 production SLO | scope |
| N02 | 删除 platform owner | ownership |
| N03 | process 即服务健康 | health chain |
| N04 | SLO target = 100% | ratio target |
| N05 | 排除 planned maintenance | exclusion |
| N06 | instance health = user SLI | measurement |
| N07 | missing = healthy | missing semantics |
| N08 | exhausted 无 action | budget policy |
| N09 | availability series 缺失算健康 | observation |
| N10 | 允许 unbounded labels | cardinality/privacy |
| N11 | page 无 first action | actionability |
| N12 | cause 直接 page | alert class |
| N13 | capacity 直接 page | route |
| N14 | 接受 actionless instance page | rejection |
| N15 | backup exit 0 即 restore | recovery evidence |
| N16 | 一人申请批准执行 | authority |
| N17 | break-glass 跳过 target/evidence | emergency boundary |
| N18 | access evidence 允许 secret | privacy |
| N19 | 伪造 ch21 run id | upstream identity |
| N20 | 沙箱切换称 production proof | claim boundary |
正式结果:
case_count 20
rejected_count 20
failure_count 0review 输出
status=review-ok
run_id=34909737-527a-460c-927c-d9d71c93aa13
service_card=complete
objectives=3-ratio+2-control
accepted_alerts=7
actionless_alerts=1-rejected
sops=4
counterexamples=20-rejected
ch19_live_gate=accepted-with-exceptions
upstream_runs=4-bound-by-hash
mutation=none
production_ch24_gate=pending
secret_material=absent为什么 production 仍 pending
机器验证通过,不等于生产批准。仍缺:
- 真实 service/data/platform/security owner;
- 真实 on-call schedule 与 notification test;
- 真实用户 traffic 的 eligible/good classifier;
- 生产 failure domains;
- 生产容量和 workload;
- 多次切换/恢复的分布,而非一次观察;
- 真实 RTO/RPO 谈判;
- 法律/隐私 retention authority;
- production secret/audit 路径;
- 第 25 章真实 instrumentation/rules/dashboards;
- 生产等价环境中的重复演练;
- 正式 exception 与 expiry。
所以本章结论:
governance contract pass
machine validation pass
adversarial validation pass
current sandbox baseline accepted-with-exceptions
upstream identity binding pass
real alert delivery not run
production SLO evidence absent
production approval pending重验已有 evidence
export PG36_EVIDENCE_DIR=/absolute/private/existing/ch24-run
static/labs/ch24/task.sh verify
static/labs/ch24/task.sh review修改任何受 hash 保护的 policy/script 后,旧 evidence 验证会失败。应:
retain old evidence with old source
create new empty evidence directory
run current contract again
compare decisions explicitly不能覆盖旧 evidence 让历史“自动符合”新政策。
本章验收
- service card 有 4 owner、6 dependencies、6 health layers;
- 3 个 ratio SLO 和 2 个 control objective 可计算;
- planned maintenance 未被隐藏;
- missing telemetry 不算健康;
- error budget 真实影响 change policy;
- 四类 SOP 有停止线与验证;
- L2/L3 权力分离;
- break-glass 仍需 target/evidence;
- 五个 observation source 有 query/missing/fallback;
- 7 个 accepted alerts 可行动;
- cause、capacity 与 symptom 分开;
- actionless page 明确拒绝;
- 六类 evidence 不允许 secret;
- ch19 live gate 重新只读通过;
- ch20–23 run 按 id/hash 绑定;
- 20 个 adversarial mutations 全拒绝;
- production gap 与 pending gate 保留。
第 25 章的任务不是重新发明这些语义,而是把它们实现为真实的应用 metric、 Pigsty recording/alert rules、dashboard、notification route 和 rule tests。
上一节:证据、审计与合规 · 返回本章目录 · 下一章:望闻问切:监控体系与可观测诊断 · 查看全书目录 · 查看索引中心