首页 > 数据库 > PostgreSQL > 如何不改变 PostgreSQL 列类型
开发应用程序并在其背后操作数据库集群时,会遇到一个意想不到的问题是实践与理论、开发环境与生产之间的差异。这种不匹配的一个完美例子就是更改列类型。
关于如何在 PostgreSQL(以及其他符合 SQL 标准的系统)中更改列类型的常规知识是:

这显然是语义上正确的方式,但是在适当的情况下,您可能会遇到相当不愉快的意外。
让我们创建一个示例表并演示您可能观察到的孤立行为。让我们从 1000 万行开始(这实际上只是整个数据世界中的一小部分)。

我们将 id 类型从 INT 改为 BIGINT。

然后... 21 秒后,您就得到了更改。请注意,这是一个小表,其中大约有 600 MB 的数据。如果您要面对 100 倍于这个数量的情况怎么办?让我们看看幕后发生了什么。
更改数据类型(以及您可能会遇到的许多其他操作)并非易事,PostgreSQL 引擎必须执行多项任务:
如您所见,执行一些可能被理解为常规表维护的操作涉及很多内容。修改的数据的大小、磁盘 I/O 和容量以及一般系统拥塞都会发挥作用。
但真正的问题并没有就此结束。如果我们谈论的是任何类型的严肃生产部署,你必须考虑更多的事情:
如您所见,更改列数据类型并不像看起来那么简单。当前的 CI/CD 实践通常使软件开发人员能够非常轻松地提交数据库迁移并将其推广到生产环境,但几分钟后他们就会发现自己处于生产事件之中。虽然暂存部署可能会有所帮助,但它不能保证与生产具有相同的特征(无论是由于负载水平还是资金限制)。
因此,问题在于(我会重复一遍),修改的数据量的规模、系统的整体拥塞程度、 I/O 容量以及目标表在应用程序设计中的重要性。
归根结底,这转化为完成迁移所需的 总时间 ,以及您的企业可以或可能无法承受的独特限制。解决该问题最简单的方法是将计划维护安排在流量较低的时段并完成它。
如果您需要重写数百 GB 甚至 TB 的数据,并且无法承受超过最低限度的停机时间,该怎么办?让我们探索如何正确更改列类型。
让我们先从 坏消息 开始——你无法避免重写整个表,这将在此过程中生成大量 WAL 文件。这是必然的,你必须计划如何管理它。
好消息: 您可以将潜在的停机时间分散到比处理数据所需的更长的时间段。具体要求和限制将根据各个业务需求而有所不同,因此仔细规划至关重要。
完整的迁移可以概括为以下一系列步骤:
order_id
最终会得到新列
new_order_id
。此时,您已准备好执行切换本身。如果您可以验证所有行都已正确填充新列,那么是时候接受最困难的部分了。如果可能的话,在一个事务中或更短的计划停机时间内完成
考虑重新启动所有依赖于更改的表的应用程序是一种很好的做法,因为某些工具(ORM......我正在看你)可能会缓存 OID 并且不能很好地处理更改。
就是这样 - 但事实并非如此。删除列只会删除引用,数据本身将物理保留在磁盘上。这是您可能需要执行的场景
VACUUM FULL
- 这可能会锁定表并完全重写它 - 可能会破坏并发迁移的目的。这让我们回到了促使我撰写本指南的原始文章 - [[The Bloat Busters:pg_repack vs pg_squeeze]] 是必经之路。强烈建议提前准备并熟悉这些工具。
虽然更改 PostgreSQL 中的列类型可能像发出 ALTER TABLE 命令一样简单,但对于所有参与其中的人来说,了解与之相关的复杂性非常重要。无论您是请求更改的软件开发人员、审核人员,还是在没有仔细规划的情况下将此类更改部署到生产环境时负责解决事件的个人,深入了解此过程都至关重要。此外,掌握这一特定变化使您能够轻松地将洞察力投射到其他可能代价高昂的操作上。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69998444/viewspace-3020328/ ,如需转载,请注明出处,否则将追究法律责任。