feat(strategy): 支持策略历史安全清理并完善批量操作记录 - #11627
Conversation
|
请在 PR 中添加项目标签,例如: |
|
请在 PR 中添加类型标签,例如: |
There was a problem hiding this comment.
Pull request overview
该 PR 为策略历史(StrategyHistoryModel)引入“可控、安全、可重复执行”的过期数据清理机制,并补齐批量更新/删除在历史记录、缓存刷新与 AIOPS 同步侧的操作类型与事务一致性,避免历史表无限增长且清理误删可恢复快照。
Changes:
- 新增策略历史清理核心逻辑与两类管理命令(标准清理 + 旧数据兼容清理),支持 dry-run、分片扫描与分批删除。
- 批量更新/批量删除补齐历史操作类型(bulk_update/bulk_delete)并将“成功历史写入”与“业务写入/删除”纳入同一数据库事务。
- 策略缓存与 AIOPS 同步流程适配 bulk_delete,新增较完整的单测覆盖清理边界与事务路由场景。
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| bkmonitor/packages/monitor_web/strategies/resources/v2.py | 批量局部更新增加按路由库开启事务,并将历史类型改为 bulk_update 且写入成功状态 |
| bkmonitor/bkmonitor/strategy/new_strategy.py | 批量删除增加按路由库开启事务,历史类型改为 bulk_delete 且成功状态写入置 True,并调整写入时机到删除完成后 |
| bkmonitor/bkmonitor/strategy/history.py | 新增策略历史清理核心实现:保留窗口内历史、保留最近 N 条有效快照、为已删策略保留最新删除记录,支持兼容模式与批量删除 |
| bkmonitor/bkmonitor/models/strategy.py | 扩展 StrategyHistoryModel.operate choices,增加 bulk_update/bulk_delete |
| bkmonitor/bkmonitor/management/commands/clean_strategy_history.py | 新增标准清理管理命令:默认 dry-run,参数校验与输出 |
| bkmonitor/bkmonitor/management/commands/clean_strategy_history_compat.py | 新增兼容清理命令:在标准规则上额外兼容旧批量更新/删除状态问题,并输出弃用提示 |
| bkmonitor/alarm_backends/core/cache/strategy.py | 缓存刷新与 AIOPS 同步适配 bulk_delete 操作类型 |
| bkmonitor/bkmonitor/strategy/tests/test_strategy_history.py | 新增批量更新/删除历史类型、事务路由与缓存处理的单测 |
| bkmonitor/bkmonitor/strategy/tests/test_history_cleanup.py | 新增清理规则与兼容规则的单测覆盖 |
| bkmonitor/bkmonitor/strategy/tests/test_history_cleanup_command.py | 新增管理命令参数传递、dry-run/execute、错误处理的单测覆盖 |
| bkmonitor/bkmonitor/strategy/tests/test_clean_strategy_history_boundaries.py | 新增清理边界矩阵(窗口边界、幂等、分片、PK 空洞批删、命令端到端)的单测覆盖 |
| model = queryset.model | ||
| last_pk = None | ||
| deleted = 0 | ||
|
|
||
| while True: | ||
| batch = queryset.order_by("pk") | ||
| if last_pk is not None: | ||
| batch = batch.filter(pk__gt=last_pk) | ||
|
|
||
| history_ids = list(batch.values_list("pk", flat=True)[:batch_size]) | ||
| if not history_ids: | ||
| return deleted | ||
|
|
||
| deleted_count, _ = model._default_manager.filter(pk__in=history_ids).delete() | ||
| deleted += deleted_count | ||
| last_pk = history_ids[-1] |
unique0lai
left a comment
There was a problem hiding this comment.
发现 1 个滚动发布/回滚兼容性问题,详见 inline comment。
| create_user=cls._get_username(), | ||
| strategy_id=strategy_id, | ||
| operate="delete", | ||
| operate="bulk_delete", |
There was a problem hiding this comment.
[P1] 这里开始写入 operate="bulk_delete",但旧版本的 StrategyCacheManager 只把 "delete" 识别为删除;其余类型会读取 content["bk_biz_id"] 和 content["items"]。由于这条历史的 content 为空,在 Web 与 alarm backend 滚动发布、或版本回滚时,旧 consumer 会触发 KeyError,缓存增量刷新也可能因更新时间不再推进而持续失败。建议拆成两阶段发布:先让所有 reader 兼容 bulk_delete,后续版本再启用 writer;或者暂时继续写 delete,通过 feature flag 延迟新类型。
背景
策略历史表持续记录策略的创建、更新和删除操作。随着策略数量和变更频率增长,历史数据不断累积,目前缺少安全、可控的过期数据清理机制。
历史记录不能简单按时间全部删除:
改动内容
1. 新增策略历史清理逻辑
仅清理指定时间窗口之前的过期历史,窗口内记录全部保留。
对于窗口外的数据:
status=True且content非空的有效快照。create、update和bulk_update。delete或bulk_delete记录。2. 控制数据库处理压力
strategy_id分片扫描存在过期历史的策略。3. 新增管理命令
新增
clean_strategy_history:参数说明:
--days:保留最近 N 天的全部历史,最小为 30 天。--batch_size:单批删除数量,默认 1000。--keep_latest_snapshots:每个策略保留的有效快照数量,默认 1。--execute:执行真实删除;未传入时默认 dry-run,仅统计预计删除数量。建议先执行 dry-run:
确认预计删除数量后,再执行真实清理:
4. 兼容旧版批量操作历史
新增临时兼容命令
clean_strategy_history_compat。旧版批量更新历史复用了
update类型,且成功状态未正确回写。兼容命令会为窗口外满足以下条件的旧记录提供独立的快照保留名额:operate=updatestatus=Falsemessage为空content非空该命令默认同样为 dry-run,仅用于旧数据仍需兼容的过渡阶段。兼容期结束后应停用,恢复使用标准清理命令。
5. 完善批量操作历史记录
新增操作类型:
bulk_updatebulk_delete批量操作成功历史统一写入
status=True,使清理逻辑能够准确识别有效快照和删除记录。同时完成以下适配:
bulk_delete并正确清理缓存。bulk_delete并发送删除事件。6. 保证业务数据与历史记录一致
批量更新、批量删除及成功历史写入使用同一数据库事务:
清理规则
验证
策略历史相关测试:
主要覆盖以下场景:
清理规则
keep_latest_snapshots > 1时正确保留多个历史版本。操作类型与边界
create、update、bulk_update混合历史。delete、bulk_delete混合历史。strategy_id=0场景。分片与批量删除
dry-run 与管理命令
--execute后正确执行真实删除。事务与下游兼容
bulk_delete。其他检查:
git diff --check:通过。