在 PlanetScale,我们的使命是为开发者打造最好的数据库。因此,自创建以来,我们就一直使用 PlanetScale 作为我们的主数据库。我们对开发工作流程和开发速度有着高标准,并且深知客户也期待着同样的表现。简单来说,如果它对我们来说不够好,那它就不够好卖给你们。在这篇博客文章中,我会讲述我们如何利用如分支处理和非阻塞模式的架构更改功能,不断向用户交付新功能。

我们的本地开发环境

PlanetScale 的运作离不开很多动态组件。作为 Surfaces 团队的一名工程师(负责 UI、API 和 CLI 的团队),我的工作重点主要集中在两个核心代码库上。我的日常工作一般围绕 PlanetScale 前端进行开发,它基于 Next.js 和 TypeScript,同时还要处理为前端提供支持的 Ruby on Rails API。

为了简化流程并提升可用性,每个工程师都会在本地运行 Ruby on Rails 应用程序,并连接到本地的 MySQL 数据库。你可能会好奇:如果在本地开发中使用 MySQL,那么什么情况下会使用 PlanetScale?在需要修改数据库架构的时候,我们会利用 PlanetScale 的分支功能来部署更改,开启针对托管在 PlanetScale 上的生产数据库的优化过程。

架构更改是开发者的日常

在我们讨论如何处理 PlanetScale 中的迁移工作之前,先来了解一下为什么让架构更改变得简单是如此重要。

如果一个产品工程师在使用关系型数据库,那么无法避免对数据库架构进行更改。无论是向现有表中添加一列,还是创建能够支持新功能的表,对数据库的更改是开发者的日常流程。在我参与的以前的项目和工程团队中,将数据库更改部署到生产环境一直是一个主要的难题。

举例来说,有一次,架构迁移与应用程序部署的过程绑定在一起,服务会在启动之前尝试运行数据库迁移。这个方法的缺点是:如果数据库迁移耗时较长,会阻止其他应用程序版本在迁移完成之前进行部署。同时,如果在迁移期间出现意外错误,可能会影响应用程序部署过程。

我还曾亲历另一种团队架构:专门设置一个小组来处理数据库迁移。这种处理流程需要开发者递交一个包含 SQL 语句的工单,然后等待数据库团队审核并执行迁移。这种方式听起来不错,因为责任由其他人承担,但迁移的速度却依赖于该团队的空闲时间以及优先执行的其他迁移工作。这种漫长的等待严重影响了新产品功能到生产环境的测试和交付速度,最终损害了产品开发的效率。经过对这些架构迁移困境的深刻反思,我对 PlanetScale 在生产流量不中断的情况下部署架构更改的工作流程大为赞赏。

赋能开发者:数据库分支和部署请求

我的过往经历让我更加理解并欣赏 PlanetScale 提供的非阻塞架构更改的价值。首先,我们会像平时那样创建数据库迁移文件,使用 Ruby on Rails 提供的相关命令:

Bash1bundle exec rails g migration CreateAuditLogTable

这会生成一个迁移文件,我们可以用它来修改数据库架构。在应用这项更改时,我们通常会部署到两个地方:

  1. 本地的 MySQL 数据库,用来在开发过程中进行本地测试;
  2. PlanetScale 的专用数据库分支,这是生产数据库的一个隔离副本,我们可以在这个分支上进行更改。

在本地调试并完善好数据库更改后,我们会在 GitHub 上创建一个拉取请求,同时在 PlanetScale 提交一个部署请求。在这里,我不具体说明如何创建拉取请求(虽然 GitHub 有不错的指南),以下是我们创建和部署请求的工作流程:

创建新的数据库分支

使用 PlanetScale CLI,我们可以运行如下命令来创建和切换到数据库的一个新分支:

Bash1pscale branch switch add-audit-logs-table --database ourdatabase --create

此命令会存储用于本地连接到数据库分支的配置文件 .pscale.yml,此文件被 planetscale-ruby 用来根据需要连接分支数据。

通过 Rails 连接到新数据库分支

为了在本地 MySQL 数据库和 PlanetScale 数据库分支之间切换,我们使用了一个名为 ENABLE_PSDB 的环境变量。当启用该变量时,Rails 应用程序就会连接到 PlanetScale 数据库分支。我们可以完全隔离开发环境与生产数据库,在分支上进行任意调整。

以下是如何在 config/database.yml 和自定义文件 config/planetscale.rb 中启用该变量的示例:

Yaml1development:
2  primary:
3    <<: *default
4    port: <%= ENV['ENABLE_PSDB'] ? 3305 : nil %>
5    database: <%= ENV['ENABLE_PSDB'] ? 'ourdatabase' : 'psdb_development' %>
6  primary_replica:
7    <<: *default
8    port: <%= ENV['ENABLE_PSDB'] ? 3305 : nil %>
9    database: <%= ENV['ENABLE_PSDB'] ? 'ourdatabase' : 'psdb_development' %>
10    replica: true
Ruby1# Connect to the main production database and start PlanetScale Proxy
2if Rails.env.production?
3    PlanetScale.start(
4      org: 'planetscale',
5      db: 'ourdatabase',
6      branch: 'main'
7    )
8elsif Rails.env.development? && ENV['ENABLE_PSDB']
9  PlanetScale.start(org: 'planetscale')
10end

应用架构更改并创建部署请求

当执行迁移时,我们运行如下命令:

Bash1ENABLE_PSDB=1 bundle exec rake db:migrate

该命令会对数据库分支应用架构更改。接着,我们可以通过 PlanetScale 应用程序打开部署请求,也可以使用 CLI 创建部署请求:

Bash1pscale deploy-request create ourdatabase add-audit-logs-table

通常,我会访问对应数据库的 “Deploy requests” 页面,并复制部署请求的 URL,或者从部署请求编号构造 URL。创建者会将该 URL 粘贴到 GitHub 的拉取请求正文中,方便审阅者同时查看两者。部署请求会列出每个表的 DDL 语句(如 CREATE、ALTER、DROP),并以逐行差异展示,这样团队成员可以很清楚地看到即将发生的更改。

使用 PlanetScale 构建 PlanetScale插图
使用 PlanetScale 构建 PlanetScale插图1
使用 PlanetScale 构建 PlanetScale插图2

部署架构更改

在团队成员批准部署请求后,创建者可以将架构更改部署到主生产分支。这些更改可以被放入部署队列中,因此队列中的其他队友可以接着部署自己的更改。

如果迁移过程中出现问题(比如尝试在 NOT NULL 的列中插入 NULL 值),部署会自动停止并提示相关错误。修复后,可以重新启动部署。一旦部署成功完成,GitHub 的拉取请求就可合并,我们的应用程序也随之更新至生产环境。

如果数据库架构需要进一步调整,完全可以按照上述流程创建新的部署请求,将更改流畅地推送到 GitHub 的拉取请求中。

这个流程的美妙之处在于:

  • 它将架构更改的部署与应用程序部署过程解耦;
  • 不需要数据库管理员来处理这些更改。

架构迁移不再可怕

这种架构部署的流程没有宕机风险,也没有锁定生产数据库表的情况发生。自从我们开始使用数据库分支和部署请求来管理生产环境的架构后,我在开发新特性或进行架构更改时感到充满信心。即使面对耗时较长的迁移任务(甚至需要数日),也不会感到恐惧。

我们可以在部署之前,通过部署请求查看操作的具体内容。非阻塞架构更改让我们可以快速推进开发,交付新功能,同时保护生产数据库的稳定性。

“我感觉在开发新功能或进行架构更改时充满信心,再也不需要害怕改动数据库。”

无论你是一名喜欢业余时间开发项目的开发者,还是工程团队的一员,我都希望你能体验使用 PlanetScale 的愉悦。今天就注册试用吧,祝你开发顺利!



使用 PlanetScale 构建 PlanetScale插图3

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:http://www.choupangxia.com/2025/05/20/planetscale-planetscale/