亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

在遥远的将来的某个时候,自动删除不必要的数据将成为DBMS的重要任务之一[1]。 与此同时,我们自己需要负责删除不必要的数据或将不必要的数据移动到更便宜的存储系统。 假设您决定删除几百万行。 这是一个相当简单的任务,特别是如果条件已知并且有合适的索引。 “DELETE FROM table1 WHERE col1 = :value” - 还有什么更简单的,对吧?

视频:

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

  • 我从第一年(即 2007 年)起就一直是 Highload 项目委员会的成员。

  • 我自 2005 年以来一直在 Postgres 工作。 在很多项目中都使用过它。

  • 自 2007 年起也与 RuPostges 合作。

  • Meetup 的参与者已增至 2100 多人。 仅次于纽约,位居世界第二,长期被旧金山超越。

  • 我在加利福尼亚州生活了几年。 我更多地与美国公司打交道,包括大公司。 他们是 Postgres 的活跃用户。 还有各种各样有趣的事情。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

https://postgres.ai/ 是我的公司。 我们致力于自动化任务,以消除开发放缓。

如果你正在做某事,那么有时 Postgres 周围会有某种插件。 假设您需要等待管理员为您设置测试台,或者您需要等待 DBA 回复您。 我们在开发、测试和管理过程中发现了此类瓶颈,并尝试借助自动化和新方法来消除它们。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

https://www.seagate.com/files/www-content/our-story/trends/files/idc-seagate-dataage-whitepaper.pdf

我最近在洛杉矶的 VLDB。 这是最大的数据库会议。 并且有报道称,未来DBMS不仅会存储数据,还会自动删除数据。 这是一个新话题。

ZB 世界中的数据越来越多 - 即 1 PB。 据估计,现在全世界已经存储了超过 000 ZB 的数据。 而且这样的人越来越多。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

https://vldb2019.github.io/files/VLDB19-keynote-2-slides.pdf

该怎么办? 显然它需要被删除。 这是这份有趣报告的链接。 但到目前为止,这还没有在 DBMS 中实现。

会数钱的人想要两件事。 他们希望我们删除,所以从技术上来说我们应该能够做到。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

接下来我要讲的是一些抽象的情况,其中包括一堆真实的情况,即对我和周围数据库多年来实际发生的事情的一种汇编。 耙子无处不在,每个人都无时无刻不在踩着耙子。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

假设我们有一个或多个正在成长的基地。 而且有些记录显然是垃圾。 例如,用户开始在那里做某事,但没有完成。 一段时间后我们知道这个未完成的东西不能再被存储了。 也就是说,我们想清理一些垃圾东西,以节省空间、提高性能等。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

一般来说,任务是自动删除某些表中的特定事物、特定行。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

而我们有这样一个要求,今天我们要讲的就是垃圾清除。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

我们请了一位经验丰富的开发人员来做这件事。 他接受了这个请求,亲自检查了它 - 一切正常。 经过分期测试 - 一切都很好。 推出 - 一切正常。 我们每天运行一次——一切都很好。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

数据库不断增长。 每日删除的速度开始变慢。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

然后我们了解到,我们现在有了营销公司,流量会大几倍,所以我们决定暂时暂停一些不必要的事情。 并忘记返回。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

几个月后,他们想起来了。 该开发人员退出或忙于其他事情,指示另一个人将其退回。

他检查了开发、舞台——一切都很好。 当然,积累的东西还是需要清理的。 他检查一切正常。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

接下来发生什么? 然后一切对我们来说都崩溃了。 它会下降,以至于在某个时候一切都会下降。 所有人都震惊了,没有人明白发生了什么。 然后事实证明,问题出在这个DELETE上。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

出了些问题? 以下是可能出现问题的列表。 其中哪一个是最重要的?

  • 比如没有review,即DBA专家没有看。 他会立即以经验丰富的眼光发现问题,此外,他还可以访问已经积累了数百万行的产品。

  • 也许他们检查出了问题。

  • 也许硬件已经过时,你需要升级这个底座。

  • 或者数据库本身有问题,我们需要从Postgres迁移到MySQL。

  • 或者是操作有问题。

  • 也许工作安排出现了一些错误,你需要解雇某人并雇用最好的人?

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

没有DBA检查。 如果有一个 DBA,他会看到这几百万行,即使没有任何实验也会说:“他们不这样做。” 假设如果这段代码在GitLab、GitHub上,并且会有一个代码审查过程,并且没有这样的事情,没有DBA的批准,这个操作会在产品上进行,那么显然DBA会说:“这不能完成”。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

他会说你会遇到磁盘 IO 问题,所有进程都会变得疯狂,可能会有锁,而且你还会阻塞 autovacuum 几分钟,所以这不好。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

http://bit.ly/nancy-hl2018-2

第二个错误——他们检查错地方了。 我们事后看到,prod 上积累了很多垃圾数据,但开发人员在这个数据库中没有积累数据,并且没有人在 staging 时创建这些垃圾数据。 因此,很快就有了 1 行代码。

我们知道我们的测试很弱,也就是说,构建的过程无法发现问题。 没有进行充分的数据库实验。

理想的实验最好在相同的设备上进行。 并不总是可以在同一设备上执行此操作,但它是数据库的完整大小的副本非常重要。 这就是我多年来一直宣扬的。 一年前我谈到过这个,你可以在 YouTube 上观看。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

也许是我们的装备不好? 如果你看一下,就会发现延迟大幅增加。 我们看到利用率是100%。 当然,如果这些是现代 NVMe 驱动器,那么对我们来说可能会容易得多。 也许我们不会就此罢休。

如果您有云,那么升级就可以轻松完成。 在新硬件上提出新的副本。 切换。 一切都很好。 挺容易。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

是否有可能以某种方式接触较小的磁盘? 在这里,在 DBA 的帮助下,我们深入探讨了一个名为检查点调优的主题。 事实证明我们没有进行检查点调整。

什么是检查点? 它存在于任何 DBMS 中。 当内存中的数据发生变化时,它不会立即写入磁盘。 数据发生变化的信息首先写入预写日志。 在某些时候,DBMS 决定是时候将实际页面扔到磁盘上,这样如果出现故障,我们可以执行更少的 REDO。 它就像一个玩具。 如果我们被杀了,我们将从最后一个检查点开始游戏。 所有的 DBMS 都实现了它。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

Postgres 中的设置滞后。 它们专为 10-15 年的数据和交易量而设计。 检查点也不例外。

这是我们的 Postgres 检查报告中的信息,即自动健康检查。 这是一些几 TB 的数据库。 可以看出,几乎90%的情况下都强制检查点。

这是什么意思? 那里有两个设置。 检查点可以超时,例如 10 分钟。 或者当相当多的数据被填充时它可能会出现。

默认情况下 max_wal_saze 设置为 1 GB。 事实上,这种情况在 Postgres 中确实发生在 300-400 MB 之后。 您已经更改了如此多的数据,并且您的检查点发生了。

如果没有人调整它,服务增长了,公司赚了很多钱,有很多交易,那么检查点每分钟出现一次,有时每 30 秒一次,有时甚至重叠。 这很糟糕。

我们需要确保它出现的频率较低。 也就是说,我们可以提高 max_wal_size。 而且它的频率会降低。

但我们已经开发了一套完整的方法论,如何更正确地做到这一点,即如何根据具体数据做出有关选择设置的决定。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

因此,我们正在对数据库进行两个系列的实验。

第一个系列 - 我们更改 max_wal_size。 我们正在进行大规模行动。 首先,我们使用 1 GB 的默认设置。 我们对数百万行进行了大规模删除。

你可以看到我们有多难。 我们看到磁盘IO非常糟糕。 我们看看我们生成了多少个 WAL,因为这非常重要。 让我们看看检查点发生了多少次。 我们看到这并不好。

接下来我们增加 max_wal_size。 我们重复一遍。 我们增加,我们重复。 还有很多次。 原则上,10 分即可,其中 1、2、4、8 GB。 我们观察特定系统的行为。 很明显,这里的设备应该像产品上的那样。 您必须具有相同的磁盘、相同的内存量和相同的 Postgres 设置。

通过这种方式,我们将交换我们的系统,并且我们知道 DBMS 在发生不良批量删除时将如何表现,它将如何检查点。

俄语中的检查站是检查站。

示例:通过索引删除几百万行,行“分散”在页面上。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

这是一个例子。 这是一些基础。 并且 max_wal_size 默认设置为 1 GB,很明显我们的磁盘会上架进行记录。 这张图是一个病得很重的病人的典型症状,就是他真的感觉很糟糕。 而且只有一个操作,只是删除了几百万行。

如果产品中允许这样的操作,那么我们就会躺下,因为很明显,一个 DELETE 就会在架子上杀死我们。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

此外,16 GB 的地方,很明显牙齿已经消失了。 牙齿已经好多了,也就是说,我们正在敲天花板,但还没有那么糟糕。 那里有一些自由。 右边是记录。 以及操作数量 - 第二张图。 很明显,当我们达到 16 GB 时,呼吸已经轻松了一些。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

而64G的地方可以看到它已经变得完全好了。 牙齿已经明显,有更多的机会在其他手术中幸存下来并用磁盘做一些事情。

这是为什么?

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

我会稍微深入一些细节,但是这个主题,如何进行检查点调整,可以产生一个完整的报告,所以我不会加载太多,但我会概述一下存在的困难。

如果检查点发生得太频繁,并且我们不是按顺序更新行,而是通过索引查找,这很好,因为我们不删除整个表,那么可能会发生首先我们触及第一页,然后是千分之一,然后又回到了第一个。 如果在对第一页的这些访问之间,检查点已经将其保存到磁盘,那么它将再次保存它,因为我们第二次弄脏了它。

并且我们会多次强制检查点保存它。 怎么会有多余的操作给他呢。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

但这还不是全部。 Postgres 中的页面为 8 KB,Linux 中的页面为 4 KB。 还有一个 full_page_writes 设置。 默认情况下它是启用的。 这是正确的,因为如果我们将其关闭,那么存在崩溃时仅保存一半页面的危险。

写入前向日志的 WAL 的行为是这样的,当我们有一个检查点并且我们第一次更改页面时,整个页面(即所有 8 KB)都会进入前向日志,尽管我们只更改了行,重 100 字节。 我们必须写下整个页面。

在后续的更改中,只会有一个特定的元组,但我们第一次写下所有内容。

因此,如果检查点再次发生,那么我们必须再次从头开始并推送整个页面。 通过频繁的检查点,当我们遍历相同的页面时,full_page_writes = on 将超出其应有的数量,即我们生成更多的 WAL。 更多内容被发送到副本、存档、磁盘。

因此,我们进行了两次裁员。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

如果我们增加 max_wal_size,事实证明我们会让检查点和 wal writer 变得更容易。 那太好了。

让我们投入 XNUMX TB 并接受它。 这有什么不好呢? 这很糟糕,因为万一发生故障,我们将爬上几个小时,因为检查点是很久以前的事了,很多事情已经发生了变化。 我们需要重做所有这些。 所以我们做了第二系列的实验。

我们执行一个操作,看看检查点何时即将完成,我们故意杀死 -9 Postgres。

之后我们再次启动它,看看它会在该设备上上升多长时间,即在这种糟糕的情况下它会重做多少。

我会两次指出情况很糟糕。 首先,我们在检查站结束前就坠毁了,所以我们有很多损失。 其次,我们进行了大规模的行动。 如果检查点超时,那么自上一个检查点以来很可能会生成更少的 WAL。 也就是说,这是双输。

我们测量不同 max_wal_size 大小的情况,并了解如果 max_wal_size 为 64 GB,那么在双重最坏情况下,我们将爬升 10 分钟。 我们会考虑它是否适合我们。 这是一个商业问题。 我们需要把这张图拿给负责业务决策的人看,问:“如果出现问题,我们最多能躺多久? 最坏的情况下能躺3-5分钟吗? 然后你做出决定。

这是一个有趣的点。 我们在会议上收到了一些关于帕特罗尼的报道。 也许你正在使用它。 这是 Postgres 的自动故障转移。 GitLab 和 Data Egret 对此进行了讨论。

如果你有一个 30 秒内发生的自动故障转移,那么也许我们可以躺 10 分钟? 因为此时我们将切换到副本,一切都会好起来的。 这是一个有争议的问题。 我不知道一个明确的答案。 我只是觉得这个话题不仅仅是关于崩溃恢复。

如果我们在失败后有很长时间的恢复,那么我们在许多其他情况下都会感到不舒服。 例如,在同样的实验中,当我们做某件事时,有时需要等待10分钟。

即使我们有自动故障转移,我仍然不会走得太远。 一般来说,64、100 GB 等值都是不错的值。 有时甚至值得选择更少。 总的来说,这是一门微妙的科学。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

要做迭代,比如max_wal_size =1, 8,需要重复大量操作很多次。 你做到了。 在相同的基础上,您想再做一次,但您已经删除了所有内容。 该怎么办?

稍后我将告诉您我们的解决方案以及在这种情况下我们如何进行迭代。 而这才是最正确的做法。

但在这种情况下,我们很幸运。 如果像这里所说的“BEGIN、DELETE、ROLLBACK”,那么我们就可以重复DELETE。 也就是说,如果我们自己取消了,那么我们可以重复。 在您的物理位置上,数据将位于同一个位置。 你甚至没有任何肿胀。 您可以迭代此类 DELETE。

即使您没有正确部署的数据库实验室,这种带有 ROLLBACK 的 DELETE 也非常适合检查点调整。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

我们制作了一个带有一列“i”的盘子。 Postgres 有实用程序列。 除非特别要求,否则它们是不可见的。 它们是:ctid、xmid、xmax。

Ctid 是物理地址。 零页,页面中的第一个元组。

可以看出,ROOLBACK 之后元组仍保留在同一位置。 也就是说,我们可以再试一次,它会以同样的方式表现。 这是主要的事情。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

Xmax是元组的死亡时间。 它被标记了,但 Postgres 知道事务已回滚,因此无论它是 0 还是回滚事务都没有关系。 这表明可以迭代 DELETE 并检查系统行为的批量操作。 您可以为穷人建立数据库实验室。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

这是关于程序员的。 关于DBA也是如此,他们总是为此责骂程序员:“你为什么要做这么长而困难的操作?”。 这是一个完全不同的垂直话题。 以前有行政,现在有发展。

显然,我们还没有分裂。 天气晴朗。 不可能不将数百万行的 DELETE 分解为多个部分。 做20分钟,一切就都躺好了。 但不幸的是,即使是经验丰富的开发人员也会犯错误,即使是在非常大的公司中。

为什么打破很重要?

  • 如果我们发现磁盘很硬,那么让我们放慢速度。 如果我们被破坏了,那么我们可以添加暂停,我们可以放慢限制。

  • 而且我们不会长期封锁别人。 在某些情况下,这并不重要,如果您要删除没有人在处理的真正垃圾,那么很可能您不会阻止除 autovacuum 工作之外的任何人,因为它将等待事务完成。 但如果你删除了其他人可以请求的东西,那么他们就会被阻止,就会出现某种连锁反应。 应避免在网站和移动应用程序上进行长时间交易。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

https://postgres.ai/products/joe/

这很有趣。 我经常看到开发人员问:“我应该选择什么包装尺寸?”。

显然,bundle 大小越大,交易开销(即交易的额外开销)就越小。 但与此同时,这笔交易的时间也增加了。

我有一个非常简单的规则:尽可能多地获取,但每秒不要超过可执行文件。

为什么要等一秒钟? 解释非常简单,每个人都可以理解,即使是非技术人员。 我们看到了反应。 我们以 50 毫秒为例。 如果事情发生了变化,我们的眼睛就会做出反应。 如果少了,那就更难了。 如果 100 毫秒后有响应,例如,您单击鼠标,它在 100 毫秒后响应您,您已经感受到了这种轻微的延迟。 第二个已经被认为是刹车。

因此,如果我们将大规模操作分成 10 秒的突发事件,那么我们就有屏蔽某人的风险。 它会起作用几秒钟,人们就会注意到它。 因此,我宁愿做的事情不超过一秒钟。 但同时,不要将其分解得非常细,因为事务开销会很明显。 基础会更硬,并且可能会出现其他不同的问题。

我们选择包装的尺寸。 在每种情况下,我们都可以采取不同的做法。 可以自动化。 我们对一包的处理效率深信不疑。 也就是说,我们删除一个包或更新。

顺便说一句,我所说的一切不仅仅是关于删除。 正如您所猜测的,这些是对数据的任何批量操作。

我们看到这个计划非常好。 可以看到索引扫描,仅索引扫描就更好了。 而且我们涉及的数据量很小。 不到一秒钟就满足了。 极好的。

我们仍然需要确保没有退化。 碰巧第一批很快就解决了,然后情况变得越来越糟。 这个过程是这样的,你需要进行很多测试。 这正是数据库实验室的用途。

我们仍然需要准备一些东西,以便我们能够在生产中正确遵循这一点。 例如,我们可以在日志中写入时间,我们可以写入我们现在在哪里以及我们现在删除了谁。 这将使我们能够了解稍后发生的事情。 并且一旦出现问题,能够快速找到问题所在。

如果我们需要检查请求的效率并且需要迭代多次,那么就存在“同伴机器人”这样的东西。 他已经准备好了。 每天有数十名开发人员使用它。 他知道如何在 30 秒内根据请求提供一个巨大的 TB 数据库,您自己的副本。 您可以在那里删除某些内容并说“重置”,然后再次删除它。 你可以用这种方法进行实验。 我看到了这件事的未来。 我们已经在这样做了。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

https://docs.gitlab.com/ee/development/background_migrations.html

什么是分区策略? 我看到包的开发人员正在使用 3 种不同的分区策略。

第一个很简单。 我们有一个数字 ID。 让我们将其分解为不同的时间间隔并进行处理。 缺点是显而易见的。 在第一个段中,我们可能有 100 行真正的垃圾,在第二个 5 行中或者根本没有,或者所有 1 行都将变成垃圾。 做工很不均匀,但很容易断裂。 他们拿走了最大的ID并把它砸碎了。 这是一种幼稚的做法。

第二个策略是平衡的方法。 它在 Gitlab 中使用。 他们拿起并扫描了桌子。 我们找到了 ID 包的边界,以便每个包恰好有 10 条记录。 并将它们放入队列中。 然后我们进行处理。 您可以在多个线程中执行此操作。

顺便说一句,在第一个策略中,您也可以在多个线程中执行此操作。 这并不难。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

https://medium.com/@samokhvalov/how-partial-indexes-affect-update-performance-in-postgres-d05e0052abc

但还有一种更酷、更好的方法。 这是第三个策略。 并且在可能的情况下,最好选择它。 我们根据一个特殊的索引来做到这一点。 在这种情况下,根据我们的垃圾条件和ID,它很可能是一个索引。 我们将包含 ID,以便它是仅索引扫描,这样我们就不会进入堆。

通常,仅索引扫描比索引扫描更快。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

我们很快就找到了要删除的 ID。 BATCH_SIZE 我们提前选择。 我们不仅得到它们,而且以一种特殊的方式得到它们并立即破解它们。 但我们正在锁定,这样如果它们已经被锁定,我们就不会锁定它们,而是继续前进并获取下一个。 这是为了更新跳过锁定。 如果需要,Postgres 的这个超级功能允许我们在多个线程中工作。 在一个流中这是可能的。 这里有一个 CTE——这是一个请求。 我们在这个 CTE 的二楼进行了真正的删除 - returning *。 你可以返回 id,但这样更好 *如果每行没有太多数据。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

为什么我们需要它? 这就是我们需要回报的。 实际上我们现在已经删除了很多行。 我们有 ID 或created_at 的边界,如下所示。 你可以做最小、最大。 还可以做点别的事。 这里可以放很多东西。 而且监控非常方便。

关于该索引还有一项注释。 如果我们决定为此任务需要一个特殊索引,那么我们需要确保它不会破坏仅堆元组更新。 也就是说Postgres有这样的统计数据。 这可以在表的 pg_stat_user_tables 中看到。 您可以查看是否正在使用热更新。

在某些情况下,您的新索引可以简单地切断它们。 而且所有其他更新都已经在起作用,放慢速度。 不仅仅是因为索引出现了(每个索引都会减慢更新速度,但是一点点),但在这里它仍然破坏了它。 并且不可能对这个表进行专门的优化。 有时会发生这种情况。 这种微妙之处很少有人记得。 而且这个耙子很容易踩到。 有时会出现这样的情况,你需要从对方找办法,但仍然不用这个新的索引,或者再做一个索引,或者用其他的方式,比如可以使用第二种方法。

但这是最优化的策略,如何分批,一个请求批量拍摄,删掉一点点等等。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

长交易 https://gitlab.com/snippets/1890447

阻止自动清理 - https://gitlab.com/snippets/1889668

阻塞问题—— https://gitlab.com/snippets/1890428

错误#5 是一个很大的错误。 来自 Okmeter 的 Nikolai 谈到了 Postgres 监控。 遗憾的是,理想的 Postgres 监控并不存在。 有的更近,有的更远。 Okmeter 已经足够接近完美,但还缺少很多内容,需要添加。 你需要为此做好准备。

例如,最好监控死元组。 如果桌子上有很多死东西,那就有问题了。 最好现在就反应,不然可能会退化,我们就可以躺下了。 它发生了。

如果有很大的IO,那么显然这样不好。

交易时间也长。 OLTP 上不应允许长事务。 这里有一个代码片段的链接,您可以使用该代码片段并已经对长交易进行一些跟踪。

为什么长交易不好? 因为所有的锁只有到最后才会被释放。 我们搞砸了所有人。 另外,我们阻止所有表的自动清理。 这一点都不好。 即使您在副本上启用了热备用,它仍然很糟糕。 一般来说,最好避免长时间交易。

如果我们有很多表没有被清理,那么我们需要有一个警报。 这里这种情况是可能的。 我们可以间接影响autovacuum的运行。 这是 Avito 的一个片段,我对其稍加改进。 事实证明,这是一个有趣的工具,可以让我们了解 autovacuum 的功能。 例如,有些桌子在那里等候,不会等待轮到他们。 您还需要将其置于监控并发出警报。

并发出区块。 块树森林。 我喜欢从别人那里获取一些东西并改进它。 在这里,我从 Data Egret 中获取了一个很酷的递归 CTE,它显示了锁树森林。 这是一个很好的诊断工具。 并且在它的基础上,还可以构建监控。 但这必须谨慎进行。 你需要为自己制定一个小的statement_timeout。 并且lock_timeout是可取的。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

有时所有这些错误都会同时发生。

在我看来,这里的主要错误是组织上的。 它是有组织的,因为技术不会拉动。 这是第二个——他们检查错地方了。

我们检查错了地方,因为我们没有易于检查的生产克隆。 开发人员可能根本无法访问生产环境。

我们检查了那里不存在。 如果我们在那里检查过,我们自己就会看到它。 即使没有 DBA,开发人员也能看到这一切,只要他在一个良好的环境中检查它,那里有相同的数据量和相同的位置。 他会看到这一切的堕落,他会感到羞愧。

有关自动真空的更多信息。 在我们完成了数百万行的大规模扫描之后,我们仍然需要进行 REPACK。 这对于索引尤其重要。 我们清理完那里的所有东西后,他们会感觉很糟糕。

如果你想恢复日常清洁工作,那么我建议更频繁地进行,但规模较小。 可以是每分钟一次,也可以是更频繁一点。 你需要监控两件事:这个东西没有错误,并且它没有落后。 我展示的技巧就能解决这个问题。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

我们所做的是开源的。 它发布在 GitLab 上。 我们这样做是为了让人们即使没有 DBA 也可以进行检查。 我们正在做一个数据库实验室,也就是说,我们称之为 Joe 目前正在开发的基础组件。 您还可以获取一份制作副本。 现在有 Joe for slack 的实现,您可以在那里说:“解释这样那样的查询”,然后立即获取数据库副本的结果。 你甚至可以删除那里,没有人会注意到它。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

假设您有 10 TB,我们将数据库实验室也设置为 10 TB。 借助同时 10 TB 的数据库,10 名开发人员可以同时工作。 每个人都可以做自己想做的事。 可以删除、删除等等。这真是天方夜谭。 我们明天再讨论这个。

亲爱的删除。 Nikolay Samokhvalov (Postgres.ai)

这称为精简配置。 这是微妙的配置。 这是某种幻想,可以极大地消除开发和测试方面的延迟,并使世界在这方面变得更加美好。 也就是说,它只是让您避免批量操作出现问题。

示例:5 TB 数据库,在 30 秒内获得副本。 而且它甚至不取决于大小,也就是说,多少 TB 并不重要。

今天你可以去 postgres.ai 并深入研究我们的工具。 您可以注册看看有什么。 您可以安装这个机器人。 免费。 写。

问题

在实际情况中,经常会发现表中应保留的数据远少于需要删除的数据。 也就是说,在这种情况下,当更容易创建新对象、仅复制必要的数据并中继旧表时,实现这种方法通常更容易。 很明显,在您即将进行切换时,此时需要一种程序化的方法。 这个方法怎么样?

这是一个非常好的做法,也是一个非常好的任务。 它与 pg_repack 所做的非常相似,与将 ID 设为 4 字节时必须执行的操作非常相似。 几年前很多框架都是这么做的,只是板块长大了,需要转换成8字节。

这个任务是相当困难的。 我们做到了。 你必须非常小心。 有锁等等。但是正在做。 也就是说,标准方法是使用 pg_repack。 你声明了这样一个标签。 在开始将快照数据上传到其中之前,您还需要声明一个跟踪所有更改的板。 有一个技巧,您甚至可能无法跟踪某些更改。 其中有微妙之处。 然后通过滚动更改进行切换。 当我们关闭所有设备时,会有短暂的停顿,但总的来说,这是正在完成的。

如果你查看 GitHub 上的 pg_repack,就会发现,当有一个任务将 ID 从 int 4 转换为 int 8 时,就会有使用 pg_repack 本身的想法。 这也是可能的,但有点麻烦,但它也适用于此。 您可以干预 pg_repack 使用的触发器并在那里说:“我们不需要这些数据”,即我们只传输我们需要的数据。 然后他就切换了,仅此而已。

通过这种方法,我们仍然获得表的第二个副本,其中数据已经被索引,并且通过漂亮的索引非常均匀地堆叠。

不存在膨胀,这是一个好方法。 但我知道有人尝试为此开发自动化,即制定通用解决方案。 我可以让您接触这种自动化。 它是用 Python 编写的,这是一件好事。

我对 MySQL 的世界还很陌生,所以我来听听。 我们使用这种方法。

但前提是我们达到了 90%。 如果我们有5%,那么就不太好用了。

感谢您的报告! 如果没有资源来制作完整的 prod 副本,是否有任何算法或公式来计算负载或大小?

好问题。 到目前为止,我们能够找到数 TB 的数据库。 即使那里的硬件不一样,例如内存少,处理器少,磁盘不完全相同,但我们仍然这样做。 如果绝对无处可去,那么你就需要思考了。 让我想想,直到明天,你来了,我们再谈谈,这是个好问题。

感谢您的报告! 你一开始就知道有一个很酷的 Postgres,它有这样那样的局限性,但它正在发展。 总的来说,这都是一个拐杖。 这不是与 Postgres 本身的开发相冲突吗?在 Postgres 中,会出现一些 DELETE deferent 或其他应该将我们试图用一些奇怪的手段涂抹的东西保持在较低水平的东西?

如果我们在SQL中说在一个事务中删除或更新多条记录,那么Postgres如何在那里分发它呢? 我们的行动受到物理限制。 我们仍将长期这样做。 而我们此时会锁定等等。

完成索引。

我可以假设相同的检查点调整可以自动化。 有一天可能会这样。 但后来我真的不明白这个问题。

问题是,是否存在这样一个发展向量,到处都是,而你的却是平行的? 那些。 他们还没想过吗?

我讲了现在可以用的原则。 还有另一个机器人 南希,这样您就可以进行自动检查点调整。 有一天它会出现在 Postgres 中吗? 我不知道,甚至还没有讨论过。 我们离那还很远。 但有些科学家制造了新系统。 他们将我们推入自动索引。 有进展。 例如,您可以查看自动调整。 它自动选择参数。 但他还不会为你做检查点调整。 也就是说,它会提高性能、shell 缓冲区等。

对于检查点调整,您可以这样做:如果您有一千个集群和不同的硬件,云中的不同虚拟机,您可以使用我们的机器人 南希 做自动化。 max_wal_size 将根据您的目标设置自动选择。 但不幸的是,到目前为止,这在核心方面还没有接近。

下午好您谈到了长期交易的危险。 你说在删除的情况下自动清理会被阻止。 它还如何伤害我们? 因为我们更多地谈论释放空间并能够使用它。 我们还缺少什么?

自动真空可能不是这里最大的问题。 而且长事务可能会锁定其他事务,这种可能性更加危险。 她可能会也可能不会。 如果她遇到了,那就很糟糕了。 对于 autovacuum - 这也是一个问题。 OLTP 中长事务存在两个问题:锁和 autovacuum。 如果您在副本上启用了热备用反馈,那么您仍然会在主服务器上收到自动真空锁,它将从副本到达。 但至少不会有锁。 并且会有洛克。 我们正在讨论数据更改,因此锁是这里的一个重要点。 如果这一切持续很长很长一段时间,那么越来越多的交易将被锁定。 他们可以偷别人的东西。 乐树出现了。 我提供了该片段的链接。 而且这个问题比 autovacuum 的问题变得更加明显,而 autovacuum 只会累积。

感谢您的报告! 您在报告一开始就说您的测试不正确。 我们继续我们的想法,即我们需要采用相同的设备,并以相同的方式建立基础。 假设我们为开发人员提供了一个基础。 他答应了这个要求。 而且他看起来很好。 但他不检查直播,而是直播,比如我们负载有60-70%。 而且即使我们使用这种调整,效果也不是很好。

团队中拥有专家并使用能够预测真实后台负载会发生什么情况的 DBA 专家非常重要。 当我们刚刚进行干净的更改时,我们看到了图片。 但更先进的方法是,当我们再次做同样的事情时,但使用模拟生产的负载。 这很酷。 在那之前,你必须长大。 这就像一个成年人。 我们只看我们拥有什么,也看我们是否有足够的资源。 这是个好问题。

当我们已经在进行垃圾选择并且我们有一个已删除标志时

这就是 Postgres 中 autovacuum 自动执行的操作。

哦,他会做吗?

Autovacuum 是垃圾收集器。

谢谢大家!

感谢您的报告! 是否有一个选项可以立即设计一个分区数据库,使所有垃圾都从主表的某个地方变脏?

当然有。

如果我们锁定了不应该使用的表,是否可以保护自己?

当然有。 但这就像一个先有鸡还是先有蛋的问题。 如果我们都知道未来会发生什么,那么我们当然会做得很酷。 但业务正在发生变化,有新的栏目、新的要求。 然后 - 哎呀,我们想删除它。 但这种理想的情况,在生活中确实会发生,但并不总是如此。 但总的来说这是一个好主意。 只需截断即可。

来源: habr.com

添加评论