改变数据类型的列在一个大表几乎总是一个痛苦。它可以锁定整个表的阅读和写作,因为互斥型锁通过ALTER table语句更改数据类型。在这篇文章中,我们将看一个影响最小的执行这样的操作的可能性,以最小化锁。它适用于任何数据类型;让我们看看整数大整数变化为例。

示例用例

假设我们有一个表有很多列。其中一个是类型的整数(INT, 4个字节)价值观逐步增长。过了一会儿,我们开始消息日志错误:整数的范围,这意味着我们要插入的值大于整数限制(最大价值2147483647)。简单的选择将改变其类型大整数(长整型数字8字节)。这里是如何做到这一点几乎“在线”。

首先,我们将需要创建一个新的新的数据类型的列。新列创建空的,所以它应该在毫秒。

以确保它没有引起太多的锁,我们可以编写一个小的SQL脚本,将超时命令如果需要很长时间才能完成,即。

Statement_timeout将终止ALTER TABLE命令如果它运行超过100毫秒,因为ON_ERROR_STOP添加到psql参数,其过程将退出一个错误。因此“打破”将不会执行超时之后因为& &操作符预计第一部分的退出代码为0,这意味着成功,在执行下一个。

接下来,我们将创建一个函数和一个触发器,将复制的价值order_id order_id_tmp新插入和更新的行。

我们准备用数据填充新列。表中更大的尺寸,我们可以创建一个支持表来帮助这个进展。它应该包含主键,在这种情况下,列“ID”big_table,新的长整型数字列空行。

我们将填充数据块,Postgres不喜欢大规模更新因为MVCC多版本并发控制机制和autovacuum作品。更新会更新所有元组,将导致巨大的膨胀,和表规模将增长两倍。

运行上面的事务在一个循环中,直到临时表,temp_order_id_bigint,是空的。

使用限制,最好适合你;根据行大小,您可以实现更好的结果较低或较高的值。在我的测试用例,5000年是最优的,每5 k行完成在不到300 ms。

填充数据后,我们准备执行列转换。我们可以用类似的方法while循环,如前所述。它将确保锁不是和阻塞其他会话等待太久。

果不其然,我们只是改变了列从整数到整数大不到一秒的锁定。操作本身可能需要更长的时间比仅仅改变现有的列的数据类型,因为所有的准备工作,数据人口等。但我们避免了停机或维护窗口,需要使用标准的方法。

享受吧!

雷竞技下载官网Percona分布PostgreSQL提供最好的和最关键的企业组件从开源社区在一个分布,设计和测试一起工作。

raybet52

订阅
通知的
客人

0评论
内联反馈
查看所有评论