红帽白皮书新鲜出炉!点击获取,让你的云战略更胜一筹! 了解详情
写点什么

Retool 如何升级主应用 4TB 的 PostgreSQL 数据库

  • 2022-05-05
  • 本文字数:3944 字

    阅读完需:约 13 分钟

Retool如何升级主应用4TB的PostgreSQL数据库

本文最初发布于 Retool 官方博客。


Retool 的云托管产品基于一个在微软 Azure 云中运行的 4TB 的 Postgres 数据库。去年秋天,我们把这个数据库从 Postgres 9.6 版升级到 13 版,而且停机时间极短。


我们是如何做到的呢?坦率地说,这不是一条从 A 到 B 的直线。在这篇文章中,我将为你讲述这个故事,并分享一些可以帮助你进行类似升级的技巧。

动机

你可能不了解 Retool,我们是一个快速构建内部工具的平台。你可以使用一个可拖放编辑器来构建 UI,并轻松将它们连接到自己的数据源,包括数据库、API 和第三方工具。你可以把 Retool 作为一个云托管产品(它基于我们在这篇文章中谈到的数据库),或者你可以自己托管它。从 4TB 的数据库可以看出,Retool 的许多客户正在云上构建许多应用。


去年秋天,我们决定升级我们的主 Postgres 数据库。我们有一个令人信服的理由——Postgres 9.6 将在 2021 年 11 月 11 日到达生命周期的终点,这意味着将不再有针对这个版本的 Bug 修复或安全更新。我们不想让客户的数据有任何风险,所以我们不能继续使用这个版本。事情就这么简单。

技术设计

升级涉及一些高级决策:

  • 应该升级到什么版本的 Postgres?

  • 应该用什么策略进行升级?

  • 应该如何测试升级?

在开始之前,我们回顾下我们的一些限制条件和目标,就只有下面这几个。

  • 在 2021 年 11 月 11 日之前完成升级。

  • 尽量减少停机时间,特别是在全球范围内周一至周五的工作时间里。这是截止日期之外最重要的考量因素,因为 Retool 对我们的许多客户而言至关重要。

  • 当在 4TB 的数据库上操作时,停机时间是特别需要考虑的一个因素。在这种规模下,原本简单的事情也会变得比较困难。

  • 我们希望维护窗口最多为一小时左右。

  • 在我们不得不再次升级之前,最大限度地增加这次升级为我们赢得的时间。

PostgreSQL 13

我们决定升级到 Postgres 13,因为它符合上述所有标准,特别是最后一个标准:在下一次升级之前为我们赢得最多的时间。


当我们开始准备升级时,Postgres 13 是 Postgres 的最新版本,其支持窗口到 2025 年 11 月。我们预计,在这个支持窗口结束时,我们将把数据库分片,并逐步完成下一次重大的版本升级。


Postgres 13 还提供了一些以前版本中没有的功能。这里是完整列表。以下是最让我们兴奋的几个:

  • 重大的性能改进,包括在并行查询执行方面。

  • 能够安全地添加默认值非空的列,这消除了一个常见的问题。在早期的 Postgres 版本中,添加默认值非空的列会导致 Postgres 执行表重写,并阻塞并发读和写,这可能会导致停机。

  • 并行索引清理。(Retool 有几个写流量很大的表,我们非常关心清理问题。)

升级策略

很好,我们已经选定了一个目标版本。现在,我们要如何实现这个目标呢?


一般来说,升级 Postgres 数据库版本最简单的方法是进行pg_dump和pg_restore。关闭应用程序,等待所有的连接终止,然后关闭数据库。在数据库处于冻结状态时,把它的内容转储到磁盘上,然后将其恢复到一个运行 Postgres 目标版本的新数据库服务器上。恢复完成后,把应用程序指向新的数据库,恢复服务。


这种升级方案很吸引人,因为它既简单,又能保证数据在新旧数据库之间完全同步。但我们马上就排除了这个选项,因为我们想尽量减少停机时间——4TB 的数据库完成转储和恢复,停机时间需要几天,而不是几小时或几分钟。


我们选择了一种基于逻辑复制的策略。通过这种方法,可以并行运行两个数据库的副本:要升级的主数据库和运行在 Postgres 目标版本上的从数据库。主数据库将持久性存储的变化(通过解码其预写日志)发布到从数据库上,使得从数据库可以快速复制主数据库的状态。这有效地消除了在 Postgres 目标版本上等待数据库恢复的时间,而且,目标数据库始终是最新的。


值得注意的是,这种方法需要的停机时间比“转储和恢复”策略少得多。我们不需要重建整个数据库,只需要停止应用,等旧的 v9.6 主数据库完成所有事务,再等 v13 主数据库复制完最新数据,就可以将应用指向主数据库。这可以在几分钟内完成,而不是几天。

测试策略

我们维护一个 Retool 云实例的过渡环境。我们的测试策略是在这个过渡环境上运行多次测试,并在这个过程中编制一份详细的操作手册并反复修改完善。


测试运行和操作手册都对我们很有帮助。在下一节中你将看到,我们在维护窗口期间执行了许多手动步骤。在最后切换时,这些步骤基本上都顺利完成,因为我们在前几周进行了多次彩排,这帮助我们创建了一个非常详细的操作手册。


我们的主要疏忽是没有在过渡环境中用一个有代表性的工作负荷进行测试。过渡数据库比生产数据库小,即使理论上讲,我们可以借助逻辑复制策略处理更大的生产工作负载,但我们遗漏了一些细节,导致 Retool 的云服务出现中断。我们将在下面的章节中进行详细介绍,但这里我们希望传达的最重要的信息是:用有代表性的工作负载进行测试非常重要

实施计划:技术细节

实现逻辑复制

我们最终使用了Warp。值得注意的是,Azure 的单服务器 Postgres 产品不支持Postgres扩展pglogical,而我们的研究使我们相信,这是 Postgres 在 10 版本之前实现逻辑复制的最佳选项。


我们初期走过的一个弯路是尝试Azure的数据库迁移服务(DMS)。DMS 会首先对源数据库做个快照,然后将其恢复到目标数据库服务器。一旦初始转储和恢复完成,DMS 就会启动逻辑解码,这是 Postgres 的一项功能,将数据库的持久性变化发送给外部订阅者。


然而,在我们 4TB 的生产数据库上,最初的转储和恢复一直未能完成:DMS 遇到了一个错误,但没有向我们报告。与此同时,尽管没有取得任何进展,DMS 还是在我们的 9.6 主数据库中保留了事务。这些长期运行的事务反过来又阻碍了 Postgres 的自动清理功能,因为vacuum进程不能清理长期运行的事务开始后产生的死亡元组。随着死亡元组的堆积,9.6 主服务器的性能开始受到影响。这导致了我们上面提到的故障。(我们后来增加了监控,跟踪 Postgres 中未清理元组的数量,使我们能够主动发现危险的情况)。


Warp 的功能与 DMS 类似,但提供更多的配置选项。特别是 Warp 支持并行处理,可以加速初始转储和恢复。


Warp 希望所有的表都有一个单列主键,所以我们不得不做一些小动作来骗过它。我们把复合主键转换成唯一约束,并增加标量主键。除此之外,Warp 非常简单易用。

跳过大表复制

我们进一步优化了我们的方法,让 Warp 跳过两个特别大的表,这两个表左右了转储和恢复的运行时间。我们这样做是因为 pg_dump 不能在单个表上进行并行操作,所以最大的表将决定最短迁移时间。


为了处理在 Warp 中跳过的两个特别大的表,我们写了一个Python脚本,将数据从旧数据库服务器批量转移到新服务器。其中比较大的一个表有 2TB,这是应用程序中一个仅限追加的事件审计表,它很容易迁移:我们等切换后再迁移其中的数据,因为即使该表是空的,Retool 产品的功能也不受影响。我们还选择将非常老的审计事件转移到一个备份存储解决方案中,以减少表的大小。


另一个表是一个仅限追加的大小几百 GB 的日志表,记录了对所有 Retool 应用的所有编辑(即 page_saves),这个表比较棘手。这张表是所有 Retool 应用的真相来源,所以在维护完成的那一刻需要保证最新。为了解决这个问题,我们在维护窗口前的几天里迁移了大部分内容,并在窗口期间迁移了剩余的内容。虽然这个方法很有效,但我们注意到,它确实增加了风险,因为我们现在有更多的工作要在有限的维护窗口内完成。

编制操作手册

以下是我们在维护窗口期间执行的一个大概的步骤:

  • 停止 Retool 服务,等待所有未完成的数据库事务提交。

  • 等待 Postgres 13 从数据库赶上逻辑解码的进度。

  • 同时,把剩余的 page_saves 行复制过来。

  • 在所有数据都迁入 Postgres 13 服务器后,启用主键约束(Warp 要求禁用这些约束)。

  • 启用触发器(Warp 要求禁用触发器)。

  • 重置所有的序列值,这样一旦应用程序重新上线,就可以使用序列分配整数主键了。

  • 重新上线 Retool 服务,指向新的数据库,执行健康检查。

启用外键约束

从上面的操作手册中可以看到,我们必须做的一个步骤是禁用然后重启外键约束检查。复杂之处在于,默认情况下,Postgres 在启用外键约束时,会运行一次全表扫描,以验证当前所有的行是否满足新的约束。对于大型数据库来说,这是一个问题:Postgres 根本不可能在一小时的维护窗口内扫描数 TB 的数据。


为了解决这个问题,我们最终选择在几个大表中不启用外键约束。我们认为这可能没什么问题,因为 Retool 的产品逻辑会执行它自己的一致性检查,而且也不会从被引用的表中删除,这意味着我们不太可能留下一个悬空的引用。尽管如此,这也是一种风险;如果我们的推理不正确,那么我们最终会有一堆无效的数据需要清理。


后来,在维护窗口结束后的清理工作中,我们恢复了当时去掉的外键约束。我们发现,Postgres 为我们的问题提供了一个干净的解决方案:ALTER TABLE的NOT VALID选项。添加一个带有 NOT VALID 选项的约束,Postgres 就会只对新数据执行约束验证,对现有数据则不执行,这样就可以绕过昂贵的全表扫描。之后,只需要运行 ALTER TABLE ... VALIDATE CONSTRAINT,它就会运行全表扫描并从约束中删除 NOT VALID 选项。当我们这样做的时候,发现表中并没有无效的数据,这让我们松了一口气。要是我们在维护窗口之前就知道这个选项就好了。

小结

我们把维护窗口安排在 10 月 23 日(星期六)晚些时候,在 Retool 云流量最低的时间段。通过上述配置,我们能够在大约 15 分钟内新建一个 13 版本的数据库服务器,并通过逻辑解码订阅我们 9.6 版本主服务器的变化。


最后,在 Warp 的帮助下,通过逻辑复制策略,以及在测试环境中的彩排,我们编制了一份可靠的操作手册,使我们能够将 4TB 的数据库从 Postgres 9.6 迁移到 13。在这个过程中,我们认识到了在真实的工作负载上进行测试的重要性,创造性地跳过了不那么关键的大表,并且了解到(有点晚),Postgres 允许我们选择只对新数据执行外键约束验证,而不是所有数据。希望你能从我们的经验中学到一些东西。


查看英文原文:How Retool upgraded our 4 TB main application PostgreSQL database


2022-05-05 17:442257

评论 1 条评论

发布
用户头像
对 Retool 和低代码感兴趣的话可以看看码匠(https://majiang.co/),码匠是国内类似 Retool 的低代码平台,UI组件丰富,整合了多款国内常见的数据源,更适合国内业务场景,支持云端访问/私有化部署,免费使用哦😉
2022-08-05 20:33
回复
没有更多了
发现更多内容

一文读懂可观测性与Opentelemetry

博睿数据

Apache ShardingSphere 企业行|走进中信云网

SphereEx

数据库 开源 企业 ShardingSphere SphereEx

百度交易中台之账房系统架构浅析

百度开发者中心

Python爬虫:看看舞蹈区哪个女网红最给力,如果爬虫不是为了爬视频

程序媛可鸥

Python 程序员 面试

区块链+供应链金融,中小微企业融资按下“快进键”

旺链科技

区块链 产业区块链 供应链金融

海量非结构化数据副本难保护,焱融科技携手英方推出联合解决方案

焱融科技

云计算 分布式 云原生 高性能 文件存储

Tapdata 在“疫”线:携手张家港市卫健委争分夺秒实时抗疫

tapdata

数据库 实时数据

吕氏餐饮:用宜搭智能考核绩效,人事管理更高效

一只大光圈

低代码 数字化 钉钉宜搭

Golang 1.18正式版发布,正式加入泛型语言家庭

学神来啦

Go golang Go 语言

Python所有方向的学习路线,你们要的知识体系在这,千万别做了无用功

程序媛可鸥

Python 程序员 面试

Python爬虫入门教程10:彼岸壁纸爬取,成功入职字节跳动

程序媛可鸥

Python 程序员 面试

数字空间里的普法课堂!最高法工作报告解读登陆百度希壤

百度开发者中心

高可用演练中堆叠切换失败分析

BUG侦探

高可用 堆叠 链路聚合

2月券商App行情刷新及交易体验报告,东方与安信升至领导者象限

博睿数据

【英雄大会】之谁说站在光里的才算英雄(上篇)

Anna

经历分享 作者 简介

python实现读取并显示图片的两种方法,15分钟的字节跳动视频面试

程序媛可鸥

Python 程序员 面试

云原生周报 | Prometheus 采用率处于领先地位;Linkerd 发布 K8s自动故障转移特性

百度开发者中心

AI+生物计算:用计算机视觉技术理解细胞生命

百度开发者中心

易观分析:应用数字孪生低代码平台,API开放性是选型关键

易观分析

数字孪生

经验分享 | 最佳文档协作软件推荐

小炮

架构实战营:模块五作业

刘璐

18M 超轻量系统开源

百度开发者中心

python爬虫JS逆向:X咕视频密码与指纹加密分析,程序员工作2年月薪12K

程序媛可鸥

Python 程序员 面试

Kubernetes 集群如何做到低成本高弹性

玄月九

Kubernetes 弹性 成本 降本 低成本高弹性

Python教程:抽象类与归一化,Python多线程断点续传

程序媛可鸥

Python 程序员 面试

Python爬取知乎上搞笑视频,一顿爆笑送给大家,程序员面试题精选100题

程序媛可鸥

Python 程序员 面试

python的默认参数的一个坑(1),快速学会

程序媛可鸥

程序员

如何在PC端应用中运行小程序?

FinClip

小程序 小程序框架 小程序容器

“易+”开源 | 网易会议开源之移动端篇

网易云信

开发

SpringCloud-Feign

昊运

SpringCloud

Python实现自动发送B站直播弹幕软件,Python开发环境

程序媛可鸥

Python 程序员 面试

Retool如何升级主应用4TB的PostgreSQL数据库_大数据_Peter Johnston_InfoQ精选文章