主要观点:处理 15TB 以上的 PostgreSQL 大表时,常规数据归档任务极具挑战,即使有良好索引也如此。
关键信息:
- 初始采用基于标准 ID 的分页删除数据方法会超时,因数据库需扫描索引找旧记录、按 ID 排序、执行删除及维护索引,15TB 大表的查找操作昂贵。
- PostgreSQL 中每行有表示物理位置的 CTID(page_number 和 row_number),利用其可按页顺序处理表,如通过
WITH to_delete AS语句选择特定 CTID 范围的行进行删除,查找快速且不影响系统。 - 完整清理的 Ruby/Rails 示例代码,使用
REPEATABLE READ隔离来处理 CTID 稳定性问题,以可预测的物理存储块处理表,避免昂贵索引操作,维持数据库负载稳定。 - 该方法虽比基于索引的删除慢,但可靠、快速且不影响系统,可定期运行
ANALYZE。 - 单纯强制 PostgreSQL 使用顺序扫描不能解决超时问题,仍需顺序扫描每行。
重要细节: - 代码示例中的各种 SQL 语句及操作细节,如
BETWEEN条件、FOR UPDATE SKIP LOCKED等的作用。 - 强调在可能时使用索引,此案例中因特殊情况采用 CTID 分页作为临时缓解措施,且提及分区虽有帮助但因查询模式等原因目前不易实现,还介绍了在新工具
pg_flo中使用 CTID 分页。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。