Postgres 13 CloudSQL导入失败后磁盘空间未释放问题求助
用户提供的磁盘使用情况参考:
核心常见原因及对应解决方法
WAL日志未归档/被复制槽滞留
导入过程会产生远高于日常量级的WAL日志,CloudSQL需要先将WAL归档到后端对象存储后才会清理本地磁盘的WAL文件;如果实例配置了逻辑复制槽、只读副本,复制滞后的槽会强制保留对应的WAL文件不删除,就算删库也不会释放这部分空间。
排查命令:- 查看本地WAL总占用:
SELECT pg_size_pretty(SUM(size)) FROM pg_ls_waldir(); - 查看复制槽滞留的WAL大小:
SELECT slot_name, slot_type, active, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal FROM pg_replication_slots;
解决方法: - 无用的复制槽直接删除:
SELECT pg_drop_replication_slot('对应槽名'); - 无复制槽的情况下等待2-24小时待WAL归档完成,本地空间会自动释放。
- 查看本地WAL总占用:
导入产生的临时文件未清理
导入失败时,导入进程产生的排序临时文件、未提交的临时表文件可能因为进程异常退出成为孤儿文件,Postgres不会主动实时清理这部分文件。
解决方法:直接在CloudSQL控制台重启实例,重启会自动清理所有临时目录下的残留文件。系统库残留死元组未回收
导入过程中创建的大量表、角色等对象的元数据会记录在postgres、template1等默认系统库的系统表中,删库只会删除用户库的文件,系统表产生的死元组不会自动回收,依然占用磁盘空间。
解决方法:连接到默认postgres库执行VACUUM FULL ANALYZE;,执行前请确认业务低峰期,避免锁表影响正常业务,回收系统表的冗余空间。删库操作未实际执行成功
如果删库时存在活跃会话连接到目标库,DROP DATABASE会执行失败,数据库文件依然保留在磁盘中。
排查命令:SELECT datname FROM pg_database;确认目标库是否已经不在数据库列表中,若仍存在先断开所有连接到该库的会话后重新执行删库命令即可。CloudSQL底层物理块未回收
GCP CloudSQL的底层存储是厚制备的块存储,删除逻辑文件后,底层块的回收可能有最长48小时的延迟,如果以上操作都执行完空间仍未释放,可以提交GCP支持工单申请后台强制回收未使用的物理块。
内容的提问来源于stack exchange,提问作者toadjaune

