我们目前正在将 MySQL 实例迁移到 Spanner。我们找到了一种通过多个操作运行 ALTER TABLE 语句的方法(例如,通过一些额外的检查删除并重新创建约束)。确切的 DDL:
ALTER TABLE our_table
DROP CONSTRAINT chk_constraint_1
ADD CONSTRAINT chk_constraint_1 CHECK(acted_type IN ('some', 'values', 'here'))
ALTER COLUMN some_column INT64 NULL
我们能否确认上述语句本质上是否是原子的,以及 Spanner 是如何在幕后执行它们的?
Cloud Spanner PostgreSQL 仅支持每个
ALTER TABLE
语句执行一项操作,这意味着您不能在同一语句中同时组合 DROP CONSTRAINT
和 ADD CONSTRAINT
。这是开源 PostgreSQL 和 Cloud Spanner PostgreSQL 之间的区别之一。请参阅 https://cloud.google.com/spanner/docs/reference/postgresql/data-definition-language#alter_table 了解完整的差异列表。
但是,您可以将上述示例重写为三个单独的语句,并将它们作为一批发送到 Cloud Spanner。如果您正在使用 Cloud Spanner 的客户端库之一,则可以通过将它们作为语句列表发送到
UpdateDatabaseDdl
方法来实现此目的。
如果您将 PostgreSQL 驱动程序与 PGAdapter 结合使用,那么您可以使用
START BATCH DDL
和 RUN BATCH
语句来创建如下批处理:
START BATCH DDL;
ALTER TABLE our_table DROP CONSTRAINT chk_constraint_1;
ALTER TABLE our_table
ADD CONSTRAINT chk_constraint_1 CHECK(acted_type IN ('some', 'values', 'here'));
ALTER TABLE our_table
ALTER COLUMN some_column TYPE varchar,
ALTER COLUMN some_column DROP NOT NULL;
RUN BATCH;
上述批处理不保证是原子的,可能有些语句执行成功,而另一些语句执行失败。在执行之前,会检查批处理是否存在典型错误,例如语法错误和拼写错误的表名。这意味着,如果您在脚本中途出现拼写错误,通常不会得到执行到一半的脚本。 然而,如果由于现有数据而导致添加检查约束失败,或者由于并行执行其他 DDL 语句而导致语句无效。
有关 DDL 批次如何在 Cloud Spanner 上工作的更多详细信息,请参阅 https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.database.v1#updatedatabaseddlrequest(此信息适用于PostgreSQL 和 GoogleSQL 方言数据库)。