Amazon Redshift 中的隔离级别 - Amazon Redshift
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

从 2025 年 11 月 1 日起,Amazon Redshift 将不再支持创建新的 Python UDF。如果您想要使用 Python UDF,请在该日期之前创建 UDF。现有的 Python UDF 将继续正常运行。有关更多信息,请参阅博客文章

Amazon Redshift 中的隔离级别

在 Amazon Redshift 中,以保护性方式支持并发写入操作,即对表使用写入锁定和可序列化的隔离原则。可序列化的隔离会保留一种错觉,即对某个表运行的事务是对该表运行的唯一事务。

Amazon Redshift 数据库采用在事务开始时让每个操作使用其数据的最新提交版本或快照的方法,以此来支持并发写入操作。在大多数 SELECT 语句、DML 命令(例如 COPY、DELETE、INSERT、UPDATE 和 TRUNCATE)和以下 DDL 命令首次出现时,将在事务中创建数据库快照:

  • ALTER TABLE(添加或删除列)

  • CREATE TABLE

  • DROP TABLE

  • TRUNCATE TABLE

任何其他事务都无法更改此快照,这意味着事务是相互隔离的。也就是说,并发事务彼此不可见,它们不能相互检测对方的更改。

任意并发执行事务得到的结果,都必须与顺序执行这些事务得到的结果相同。如果这些事务的任何序列执行均不产生相同结果,则执行会破坏可序列性的语句的事务将被中止并回滚。

例如,假设用户尝试运行两个并发事务 T1 和 T2。运行 T1 和 T2 必须生成与以下至少一个场景相同的结果:

  • T1 和 T2 依次运行。

  • T2 和 T1 依次运行。

Amazon Redshift 中的隔离级别可以防止出现以下问题:

  • 脏读:在事务读取尚未提交的数据时,就会发生脏读。例如,假设事务 1 更新了一行。事务 2 在 T1 提交更新之前读取更新的行。如果 T1 回滚更改,则 T2 将读取未提交行中的数据,而 Amazon Redshift 现在认为这些数据从不存在。

  • 不可重复的读取:当某个事务两次读取同一行但每次均获得不同的数据时,就会发生不可重复的读取。例如,假设事务 1 读取了一行。事务 2 更新或删除该行并提交了更新或删除。如果 T1 再次读取该行,它会检索到不同的行值或发现该行已删除。

  • 幻象:幻象是指某行符合搜索条件,但该行并非最初看到的行。例如,假设事务 1 读取满足其搜索条件的一组行。事务 2 在 UPDATE 或 INSERT 语句中生成了新行,该行与 T1 搜索条件匹配。如果 T1 重新运行其搜索语句,就会得到一组不同的行。

SNAPSHOT 和 SERIALIZABLE 隔离

SERIALIZABLE 和 SNAPSHOT 隔离是 Amazon Redshift 中提供的两种可序列化隔离级别。

SNAPSHOT 隔离是创建预调配集群和无服务器工作组时的默认隔离级别,相比 SERIALIZABLE 隔离,此隔离让您可在更短的时间内处理更大量的数据。

SERIALIZABLE 隔离用时更长,但对并发事务实施了更严格的限制。此隔离级别仅允许提交一个事务,同时取消所有其他并发事务并给出可序列化隔离违规错误,从而防止写入偏斜异常等问题。

以下时间线示例说明使用 SNAPSHOT 隔离时,系统如何处理两个并发写入操作。系统允许提交每个用户的 UPDATE 语句,因为它们不会因为尝试更新相同的行而发生冲突。

时间 用户 1 操作 用户 2 操作
1 BEGIN;
2 BEGIN;
3 SELECT * FROM Numbers;

digits
------
0
1
4 SELECT * FROM Numbers;

digits
------
0
1
5 UPDATE Numbers SET digits=0 WHERE digits=1;
6 SELECT * FROM Numbers;

digits
------
0
0
7 COMMIT;
8 Update Numbers SET digits=1 WHERE digits=0;
9 SELECT * FROM Numbers;

digits
------
1
1
10 COMMIT;
11 SELECT * FROM Numbers;

digits
------
1
0
12 SELECT * FROM Numbers;

digits
------
1
0

如果使用可序列化的隔离运行同一场景,则 Amazon Redshift 因可序列化违规而终止用户 2 并返回错误 1023。有关更多信息,请参阅 可序列化隔离错误排查。在这种情况下,只有用户 1 可以成功提交。

注意事项

在 Amazon Redshift 中使用隔离级别时,请考虑以下事项:

  • 查询 STV_DB_ISOLATION_LEVEL 目录视图来查看数据库使用的隔离级别。有关更多信息,请参阅 STV_DB_ISOLATION_LEVEL

  • 查询 PG_DATABASE_INFO 视图来查看您的数据库支持多少个并发事务。有关更多信息,请参阅 PG_DATABASE_INFO

  • 系统目录表(PG)和其他 Amazon Redshift 系统表在事务中未锁定。因此,DDL 和 TRUNCATE 操作引起的数据库对象更改在提交到任何并发事务时均可见。

    例如,假设在两个并发事务(T1 和 T2)开始时,数据库中存在表 A。假设 T2 通过从 PG_TABLES 目录表中进行选择来返回表列表。然后 T1 删除表 A 并提交,T2 再次列出这些表。现在不再列出表 A。如果 T2 尝试查询已删除的表,则 Amazon Redshift 将返回“relation does not exist”错误。向 T2 返回表列表或检查表 A 是否存在的目录查询不受与针对用户表的操作相同的隔离规则的约束。

    更新这些表的事务在读取已提交 隔离模式下运行。

  • 前缀为 PG 的目录表不支持 SNAPSHOT 隔离。