数据库架构安全更改
过去作为一名初级软件开发者,我非常害怕改动数据库架构。我们都听过那些可怕的故事:错误的命令一旦运行,整个数据库的数据可能瞬间被清空;或者数据库变更发布比预期耗时更久,最终严重影响用户。
与此同时,我从未被敦促提升数据库方面的技能。当时我在一个小型初创公司工作,主要专注于新产品功能的发布。我想更好地掌握 Python 和 JavaScript,而不是数据库。数据库从来都不是我的重点,因此它就一直让我感到害怕。
正如许多人知道的那样,我们不可能选择完全不对数据库进行更改。数据库必须随着应用和产品的变化而发展。如果我们想定期发布新功能,数据库更改的速度不能过慢。但从历史上看,安全推进通常意味着缓慢的推进。这种瓶颈可能源自多个方面,比如团队中数据库专家有限,或对更改的内容和时间进行严格限制。
在这篇博客中,我将重点介绍如何在没有这些阻碍的情况下安全地进行数据库架构更改。我会探讨数据库的最佳实践以及 PlanetScale 提供的功能,这些功能能够确保数据库架构更改的安全性。
小而频繁的更改
在讨论 PlanetScale 的具体功能之前,我想先介绍架构更改的规模问题。现代软件开发提倡尽早且频繁地发布代码,这也应该适用于我们的数据库更改。
我们应努力实现较小而频繁的架构更改,而不是大而复杂的更改。较小的更改更容易测试、验证,并且对于整个系统来说更安全。很难验证跨架构的大规模更改,尤其是涉及多个表的更改。而一小段 SQL 的更改比包含数百行 SQL 的更改更容易理解和验证。
当你和你的团队在应用代码方面是数据库的唯一消费者时(通常是初创公司阶段),情况可能较为简单。然而,随着公司增长,多个团队或部门会开始与数据库交互,这使较大规模更改的风险进一步增加。(如果涉及 Analytics 或 Data 团队,可以查看 PlanetScale Connect 功能。)
向后兼容的更改
任何时候,当你更改被应用代码使用的现有架构时,都应确保这些更改在过程的每一步都向后兼容。你可能听过一种称为“扩展与收缩”(expand and contract)的模型。以下是这种模型的简化过程:
- 扩展架构:通过新的更改更新现有架构;
- 更新应用代码:同时写入旧架构和新架构;
- 迁移数据:将旧架构的数据迁移到新架构;
- 更新应用代码:使其仅从新架构中读取数据;
- 再次更新应用代码:使其仅向新架构中写入数据;
- 收缩架构:移除不再被使用的旧架构。
扩展与收缩模型确保在整个架构更改过程中,应用代码始终能够正常工作,而不会因架构修改而发生故障。如需更多关于向后兼容架构更改的信息,请查看相关博客文章。
功能标志(Feature Flags)
你可能会问,功能标志与数据库架构更改有何关系?事实上,它们能够帮助我们更安全地进行数据库的渐进式更改。通过使用功能标志,我们可以基于更新的数据库架构逐步推出新的功能。如果过程中出现问题,通常可以回滚。当然,并不是所有更改都能回滚,并且功能标志的实现必须正确。但功能标志仍然是当我们希望逐步进行安全修改时可以用来配合数据库的有用工具。
分支功能(Branching)
在 PlanetScale 中进行安全的数据库架构更改的核心要素之一是分支功能。数据库分支提供生产数据库架构的一个独立副本,在这里你可以进行更改、试验和测试。启用安全迁移后,分支可以支持零停机时间的架构迁移、架构回滚、防止意外更改等功能,同时搭配部署请求(Deploy Requests)。
部署请求
当使用安全迁移将数据库分支部署到生产环境时,你必须在 PlanetScale 中打开一个部署请求。后台自动进行的操作包括:检查架构更改的兼容性,确保其可以安全地被部署。
PlanetScale 还会检查表是否在部署请求期间被真正废弃,并在最近有人查询了该表时发出警告。
部署请求会自动检查以下内容:
- 防止架构迁移的冲突,例如非法列或表的字符集、不允许为空的唯一键等;
- 提议的架构更改是否导致数据丢失;
- 团队成员之间的其他架构更改冲突。
这一流程免除了人力检查部署请求的负担,节约时间,减少误操作风险,同时避免了架构迁移中的可能错误。自动化的架构评审流程使架构更改的工作量大大降低,不需要整支团队的 DBA 来审核开发人员的架构修改。
架构评审
历史上,架构更改并没有像代码更改一样受到相同的审查待遇。在 PlanetScale 的部署请求中进行架构评审能够提供透明的审查流程。这一流程是可视化的,与我们审查代码的 pull requests 流程深度结合。
评审清楚显示了哪些表被创建、修改或删除,还展示了将运行的确切 SQL。如果 SQL 是由 ORM 创建的,这一功能也非常有用,因为 ORM 有时不会让你直接看到实际运行的 SQL。
无阻塞架构更改
无阻塞架构更改允许你在不锁定或导致生产数据库停机的情况下更新数据库表。例如,直接运行 ALTER TABLE
是一种阻塞操作,会使表完全无法访问(包括读操作)。通过使用在线架构更改工具,可以确保不会对应用造成停机。在 PlanetScale 中,部署请求自带在线架构更改功能。
受限部署(Gated Deployments)
在无阻塞架构更改流程中,当你部署请求时并不会直接修改表,而是创建表的副本,并在副本上应用更改。原始表和副本表的数据保持同步。一旦完成更改,会触发一个快速切换,将新表替换旧表。对于非常大的或复杂的数据库,整个流程可能需要数小时。
在某些情况下,你可能希望推迟部署完成后的表切换时间,例如架构迁移过程在非工作时间结束时。你需要参与监控更改确保没有问题。借助受限部署功能,你可以将部署请求添加到队列中。一旦完成后,可随时点击按钮完成表切换。
回滚功能
当架构更改未按预期进行时怎么办?我们作为开发者知道事情不可能总是 100% 按计划进行。错误的迁移总是会发生,但我们不应该害怕它们。相反,我们需要能够帮助处理迁移错误的工具。
PlanetScale 的回滚功能允许我们将生产数据库的架构迁移回到之前的状态,并在许多情况下保留丢失的数据。
这得益于 Vitess 的 VReplication,它是支持 PlanetScale 数据库的分片和管理系统之一,能够确保数据从源表到目标表的一致复制。VReplication 的独特实现还可以回溯到 MySQL 的事务级别,确保数据不会丢失。
Insights
一些工具通过抽象提升开发者体验,而 Insights 则相反,是一种揭示复杂性的工具。Insights 是 PlanetScale 仪表板中的查询性能分析工具,无需额外设置即可监控每个数据库查询的性能。这对于安全性而言尤为重要,通过 Insights 的性能监控功能你可以确保架构修改对数据库查询没有负面影响。
自动备份
使用数据库备份通常是最后的手段,但它是必不可少的。PlanetScale 允许你基于备份创建分支,测试分支并在准备好之后将其提升为生产分支。Scaler Pro 计划包括每 12 小时一次的备份,并支持手动更改备份时间或通过 UI 创建备份。
展望:安全的数据库架构更改
作为开发者体验的核心宗旨,你不应该在安全性和发布更多功能之间做选择。这篇博客希望能够告诉你如何在 PlanetScale 内外安全地进行数据库架构更改。如果你对在不同框架中使用安全功能感兴趣,可以查看我们关于 Laravel 和 Ruby on Rails 安全功能的博客文章。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
本文链接:http://folen.top/2025/09/13/safely-making-database-schema-changes/