sql - 如何归档一个巨大的 postgres 表?
问题描述
我们有一个名为 history 的 postgres 表,它几乎是 900GB,并且每天持续增加 10GB。微服务(购物车)正在访问此表。我们有 postgres 复制设置(一个 Master 和一个 Slave)。2 个微服务实例在生产中运行,其中 1 个实例使用主 postgres 连接为某些端点写入和读取数据,1 个另一个实例使用 postgres 从连接仅读取数据。
表定义:
id - uuid
data - jsonb column
internal - jsonb column
context - jsonb column
created_date - date
modified_date - date
现在在上表data
和internal
列中为每一行加载了大 json。我们已经得出结论,将data
andinternal
列清空将减少该表的总空间消耗。
问题:
- 如何归档这个巨大的桌子?(仅表示仅清理
data
和internal
列)。 - 如何在没有零停机时间/性能下降的情况下实现这一目标?
截至目前测试的方法。
- 使用 pg_repack(这是迄今为止最好的主意,但这里的问题是一旦 pg_repack 完成,整个新表需要与从属实例同步,这会导致 WAL 开销)。
- 只需单独取消
data
andinternal
列 - 这种方法的问题只是增加了表大小,因为 postgres 遵循 MVCC 模式。 - 使用临时表并克隆数据
- 创建一个 UNLOGGED 表 - historyv2
- 将原始表中的数据复制到 historyv2 表中,不带
data
andinternal
- 然后将表切换到 LOGGED。(我想这也会导致 WAL 开销)
- 然后重命名表。
你们能给我一些关于如何实现这一目标的指示吗?
Postgres 版本:9.5
解决方案
我总觉得像这样的问题将一些不同的想法混为一谈,这使得它们看起来比应该的更复杂。最小的性能影响是什么意思?生成大量 WAL 可能会增加文件 i/o 和 cpu 以及网络使用率,但在大多数情况下,它对系统的影响不足以产生面向客户端的影响。如果没有停机时间是最重要的事情,您应该专注于优化,而不是担心到达那里的过程是什么(在合理范围内)。
也就是说,如果我在你的鞋子里醒来,我会首先使用表继承为数据设置分区,以便将来可以更轻松地对数据进行分段和处理。(这不是完全必要的,但可能会使您将来的生活更轻松)。之后,我会编写一个脚本来慢慢地遍历旧数据并使用“已清空”数据创建新分区,交叉创建分区、删除数据和对主表进行清理。一旦它被自动化,你可以让它慢慢地或在下班时间搅拌,直到它完成。移动所有数据后,您可能需要对父级进行最后的重新打包或吸尘,但即使没有它也可能没问题。同样,这不是最简单的想法,可能不是最快的方法(如果你可以有停机时间),但最后,
推荐阅读
- sql-server - 如何向 T_SQL 存储过程添加可选参数?
- javascript - React.js this2.setState 不是函数?
- r - div容器中的脚本
- node.js - 从基于文件夹的 npm 依赖项导入模块
- javascript - 如何在点列表中附加光滑的箭头?
- bash - 使用 AppleScript + bash 发送文件对象
- javascript - Highcharts:向面积折线图添加多种颜色
- mfc - 如何使用 pywinauto 自动将“.txt”文件从本地加载到 MFC 应用程序?
- c# - Web API URI 版本未按预期工作
- excel - 将一列中的多个单元格连接成一个单元格