如何在AzureDevops Pipeline中实现RDS PostgreSQL实例数据自动清理
Azure DevOps流水线实现RDS PostgreSQL自动数据清理落地方案
核心实现思路
全程基于Azure DevOps原生能力实现,不需要额外部署常驻脚本的服务器:用托管代理按定时调度触发任务,通过Azure服务连接拿临时权限访问RDS实例,执行预定义的分批清理逻辑,自带执行日志留存、异常告警,权限遵循最小化原则,不硬编码数据库凭据。
前置准备
- 给Azure DevOps使用的服务连接配置对应RDS实例的最小访问权限,不要给订阅级Contributor等高权限,仅需授予RDS实例的连接权限、目标数据库的读写权限即可
- 提前梳理明确清理规则:确认需要清理的表、数据保留周期、关联表级联逻辑,先在测试环境把清理SQL跑通验证,确认不会误删业务数据
- 确认Azure DevOps项目内已经配置好对应Azure订阅的ARM服务连接,如果用自托管代理,需要放通代理到RDS实例5432端口的出站访问规则
具体配置步骤
- 创建新的YAML流水线,关闭代码提交自动触发,配置定时调度规则,调度时间选业务低峰窗口
trigger: none # 禁用代码提交触发 pr: none # 禁用PR触发 schedules: - cron: "0 18 * * *" # UTC时间,对应国内北京时间凌晨2点,按实际业务低峰调整 displayName: 每日PG历史数据定时清理 branches: include: - main always: true # 即使仓库无代码更新也按时执行 pool: vmImage: 'ubuntu-latest' # 用微软托管的Ubuntu代理即可,不需要自托管代理 - 添加Azure CLI任务,自动安装PG客户端、获取AAD临时访问凭据,不需要配置固定数据库密码
- task: AzureCLI@2 displayName: 初始化运行环境与数据库凭据 inputs: azureSubscription: '你提前配置好的Azure服务连接名称' scriptType: 'bash' scriptLocation: 'inlineScript' inlineScript: | # 安装PostgreSQL客户端 sudo apt-get update -y && sudo apt-get install -y postgresql-client # 配置数据库连接参数,通过AAD获取临时token作为密码 export PGHOST="你的RDS实例公网/内网地址,例:pg-prod.postgres.database.chinacloudapi.cn" export PGDATABASE="目标业务库名" export PGUSER="RDS配置的AAD管理员账号" export PGPASSWORD=$(az account get-access-token --resource-type oss-rdbms --query accessToken -o tsv) export PGPORT=5432 export PGSSLMODE=require # 将连接参数写入流水线变量,供后续步骤使用 echo "##vso[task.setvariable variable=PGHOST]$PGHOST" echo "##vso[task.setvariable variable=PGDATABASE]$PGDATABASE" echo "##vso[task.setvariable variable=PGUSER]$PGUSER" echo "##vso[task.setvariable variable=PGPASSWORD]$PGPASSWORD" echo "##vso[task.setvariable variable=PGPORT]$PGPORT" echo "##vso[task.setvariable variable=PGSSLMODE]$PGSSLMODE" - 添加清理执行步骤,按小批次循环删除,避免长事务锁表
- task: Bash@3 displayName: 执行分批数据清理 timeoutInMinutes: 60 # 设置1小时超时,避免异常SQL卡死 inputs: targetType: 'inline' script: | # 清理前打印待删数据量,留日志方便排查 echo "清理前待删除数据量:" psql -c "SELECT count(*) FROM user_operation_log WHERE create_time < now() - interval '90 days';" # 循环分批删除,每批1000条,根据表性能调整批次大小 while true; do del_count=$(psql -c "DELETE FROM user_operation_log WHERE ctid IN (SELECT ctid FROM user_operation_log WHERE create_time < now() - interval '90 days' LIMIT 1000);" | awk 'NR==2{print $2}') echo "本批次删除数据量:$del_count" if [ "$del_count" -eq 0 ]; then break fi sleep 1 # 每批删完等待1秒,释放资源给业务请求 done # 清理后打印剩余数据量,执行VACUUM回收空间、更新统计信息 echo "清理后剩余待删数据量:" psql -c "SELECT count(*) FROM user_operation_log WHERE create_time < now() - interval '90 days';" psql -c "VACUUM ANALYZE user_operation_log;" - 配置告警规则:直接在Azure DevOps项目设置-通知里,新增“流水线运行失败”的告警规则,指定运维/开发接收组,清理任务异常时自动发通知,不需要在流水线里额外写通知脚本。
生产环境避坑提示
- 绝对不能直接执行无LIMIT的全量DELETE语句,百万级以上的表执行这类语句会长时间持有行锁/表锁,直接阻塞线上业务请求,必须用小批次循环删除的逻辑
- 不要把数据库固定账号密码存在流水线变量、代码仓库里,用AAD临时token鉴权的方式没有凭据泄露风险,也不需要定期轮换密码
- 注意cron调度的时区是UTC,换算国内时间要减8小时,别误把任务跑在业务高峰时段,清理和VACUUM操作都会占用数据库IO、CPU资源
- 第一次上线前必须在测试环境用和生产同量级的数据跑全流程,估算清理耗时,验证不会误删数据,不要直接在生产环境第一次跑
- 如果单次要清理的数据量特别大,可以把清理任务拆成多轮次跑,不要单次跑太久,避免和业务抢资源
内容的提问来源于stack exchange,提问作者Admin
相关产品推荐
相关产品推荐

