返回 登录
4

Postgres中更好的数据库迁移

阅读5196

原文: http://www.craigkerstiens.com/2017/09/10/better-postgres-migrations/
作者:Craig Kerstiens
译者:夜风轻扬

译者注:在Postgres中进行数据库迁移时会遇到哪些问题?如何解决它们?请见下文。

随着数据库的增长与扩展,你需要对一些操作给予更多的关注。你可能没有完全意识到,在开发环境中执行应用程序时,执行某些操作的成本,与在生产环境中大相径庭。在某一时刻,我们中的大多数人都犯了错,在5分钟时开始运行一些迁移,过15分钟仍然在运行,突然间生产流量受到了影响。

有两种操作发生的很频繁,每种操作都有一些简单的方法可以减少停机时间。让我们看看每一个操作,它们是如何工作的,以及如何以更安全的方式来处理它们。

添加新列

在Postgres中添加一个新列实际上代价是很低的。当你这样做的时候,它会更新对于已有列时刻的跟踪,它几乎是瞬时的。当对某个列有一些约束时,这一部分就会变得很昂贵。一个约束可以是一个主键或者外键,或者是一些唯一性约束。 Postgres不得不扫描表中的所有记录以确保没有违反这些约束。添加诸如“非空”等一些约束时,可能会有一些违反,但这不是最常见的原因。

造成添加新列迟缓最常见的原因是大部分的框架中为新列设置缺省值太过简单。对于所有的新记录这是一回事,但是对于已有的表来说,这意味着数据库不得不要读取所有的记录并且向这些记录中重写新的缺省值。对于只有几百条记录的表来说,这还不算太糟,但是对于上千万条记录的表来说,这时间就无法容忍了 。

简而言之,在添加新列时,如果将其设为非空或者在创建是设置一个缺省值都会给你带来麻烦。解决之道是不要这样做。但是,如果你需要一个缺省值或者不想字段为空时该怎么办。这有一些你可以采取的简单步骤,将你的迁移工作从一步分为 四步:
1. 添加新列,允许其为空
2. 开始在所有新记录和更新中写入默认值
3. 逐步回填缺省值
4. 应用你的约束
是的,只是稍微多一点工作,对现有工作的影响很微小。

索引

类似大部分的DDL操作,创建索引时会加锁,这就意味着所有新的数据必须等待索引创建完成后才可以写入。对于新建的或者小规模的表,等待的时间不是很明显,但是对于大规模数据库,等待的时间可能是以分钟甚至小时计添加索引的本意是为了提高查询速度,但是实际的效果却是降低了速度,这真是有点讽刺。

Postgres中对于这个问题的答案是 CONCURRENT 创建索引。就是在后台逐步创建索引。你可以通过:CREATE INDEX CONCURRENTLY语句并发创建索引。一旦创建了索引,只要你做想做的事情,Postgres就会在查询中使用它。

可以提供帮助的工具

这是一个不错的实践活动,了解运行迁移时会发生什么,以及对于性能的影响。即便如此,你也不必只凭自己的力量去管理这些。至少对于Rails还有工具能帮组你掌握它。Strong migrations能够帮组你掌握很多这些昂贵的操作,如果你在使用Rails,你可以考虑看一看。
还要其他的工具和秘诀可以有助于Postgres中的数据迁移?给我留言,我会把它们加到列表中。


2017年9月23日,SDCC 2017之区块链技术实战线上峰会正式召开,邀请圈内顶尖的布道师、技术专家和技术引领者,共同探讨区块链技术栈架构与性能(架构与跨链操作)、智能合约安全、分层评测区块链项目难点与策略、贴近云计算的下一代区块链平台、区块链+AI等热门话题与技术。更有区块链技术在互联网公司的成功应用经验七位大牛与你相聚狂欢,详情查看所有嘉宾和议题,以及注册参会

评论