归档
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled

This commit is contained in:
2026-09-20 10:46:34 +08:00
parent 1964c12ffa
commit 863607639f
9 changed files with 362 additions and 1 deletions

View File

@@ -74,6 +74,82 @@ DB_PASSWORD='<密码>' DB_NAME=<库名> DB_SSLMODE=<模式> \
迁移失败时不启动新二进制;按失败迁移的事务状态决定处理,必要时恢复已确认可用的数据库备份。启动失败时覆盖回部署前备份的二进制,再恢复数据库备份(如迁移已改变数据库)。
### 单槽单卡当前卡标识核对与受控修复
本节仅供生产维护者在已备份、已留存核对清单且具备回滚条件的维护窗口执行。Agent 只可通过 dbhub 做只读核对,不得执行下述写操作。
先执行只读核对,候选必须同时满足:设备未删除、最大槽位为 1、只有一条未删除的有效绑定、且没有任何有效绑定被标记为当前使用卡。
```sql
SELECT b.id AS binding_id, b.device_id, b.iot_card_id
FROM tb_device_sim_binding AS b
JOIN tb_device AS d ON d.id = b.device_id AND d.deleted_at IS NULL
WHERE b.deleted_at IS NULL
AND b.bind_status = 1
AND d.max_sim_slots = 1
AND NOT EXISTS (
SELECT 1
FROM tb_device_sim_binding AS current_binding
WHERE current_binding.device_id = b.device_id
AND current_binding.deleted_at IS NULL
AND current_binding.bind_status = 1
AND current_binding.is_current
)
AND (
SELECT count(*)
FROM tb_device_sim_binding AS active_binding
WHERE active_binding.device_id = b.device_id
AND active_binding.deleted_at IS NULL
AND active_binding.bind_status = 1
) = 1
ORDER BY b.device_id, b.id;
```
维护者审核并留存候选清单后,在事务中把批准的 `binding_id` 显式填入 `approved`。更新语句会再次核对全部条件;受影响行数与批准清单不一致时必须回滚,不得扩大条件或直接按设备全量更新。
```sql
BEGIN;
WITH approved(binding_id) AS (
VALUES
(CAST(<binding_id> AS bigint))
), eligible AS (
SELECT b.id
FROM tb_device_sim_binding AS b
JOIN approved AS a ON a.binding_id = b.id
JOIN tb_device AS d ON d.id = b.device_id AND d.deleted_at IS NULL
WHERE b.deleted_at IS NULL
AND b.bind_status = 1
AND d.max_sim_slots = 1
AND NOT EXISTS (
SELECT 1
FROM tb_device_sim_binding AS current_binding
WHERE current_binding.device_id = b.device_id
AND current_binding.deleted_at IS NULL
AND current_binding.bind_status = 1
AND current_binding.is_current
)
AND (
SELECT count(*)
FROM tb_device_sim_binding AS active_binding
WHERE active_binding.device_id = b.device_id
AND active_binding.deleted_at IS NULL
AND active_binding.bind_status = 1
) = 1
FOR UPDATE OF b
)
UPDATE tb_device_sim_binding AS target
SET is_current = TRUE, updated_at = NOW()
FROM eligible
WHERE target.id = eligible.id
RETURNING target.id AS binding_id, target.device_id, target.iot_card_id;
-- 核对返回行数、设备卡列表与资产信息;不一致时执行 ROLLBACK。
-- 全部一致后才执行 COMMIT。
```
修复后必须确认每个设备至多一条未删除的有效绑定满足 `is_current = TRUE`,并抽样核对设备卡列表和个人客户资产信息均按最新绑定事实返回。回滚时仅对本次留存清单中的绑定恢复 `is_current = FALSE`,不得影响运营商观测或显式切卡产生的其他当前卡事实。
### 商户池支付路由发布与回滚
本节是维护者操作清单不是已执行证据。迁移、生产发布、Redis 操作和富友真实渠道核验均由维护者执行;本轮未执行,不能以本地构建替代。