跳至内容

如何解决 Amazon Redshift 中的"Serializable isolation violation on table"或"Relation does not exist"错误?

2 分钟阅读
0

当我在不同的会话中运行并发 Amazon Redshift 操作时,我收到了"Serializable isolation violation on table"或"Relation does not exist"错误。

简短描述

Amazon Redshift 中的并发写入操作必须是可序列化的,这样事务才能按顺序运行。串行执行还必须产生与事务并行运行时相同的结果。有关详细信息,请参阅可序列化隔离

解决方法

要解决可序列化隔离错误,请使用以下方法之一。

重试已取消的事务

如果 Amazon Redshift 检测到并发工作负载不可序列化,则表明应用程序逻辑中可能存在漏洞。重试导致错误的已取消事务。

使用中间提交

当发出提交或回滚指令时,事务即完成。如果事务在“从表中删除”操作运行之前提交,则系统会创建一个新事务并保留可序列化隔离。

以下示例使用中间 COMMIT 命令:

DELETE FROM XXXXX WHERE date = XXXXX';
→COMMIT;
BEGIN TRANSACTION;
DELETE FROM XXXXX WHERE date = XXXXX';

将非原子操作移出事务外

当两个事务中的单个操作相互交叉引用,这可能会影响另一个事务的结果时,请使用此方法。

如果其他操作的结果不需要具有原子性,请将 SELECT 语句移出其事务之外。

以下示例将 SELECT 语句移出其事务之外:

Session1_Redshift=# BEGIN;Session1_Redshift = # insert into tab1 values (1)Session1_Redshift = # END;
Session1_Redshift # select * from tab2;

Session2_Redshift # select * from tab1;Session2_Redshift =# BEGIN;
Session2_Redshift = # insert into tab2 values (1)
Session2_Redshift = # END;

前面的事务是可序列化的。如果您按顺序运行事务,则结果与您并行运行事务时的结果相同。

锁定每个会话中的所有表以强制序列化

LOCK 命令会阻止可能导致可序列化隔离错误的操作。运行 LOCK 命令时,请完成以下步骤:

  • 锁定事务影响的所有表,包括事务内部只读 SELECT 语句影响的表。
  • 无论执行操作的顺序如何,都以相同的顺序锁定表。
  • 在执行操作之前,在事务开始时锁定所有表。

对并发事务使用快照隔离

可序列化隔离可实现严格的序列化。当 Amazon Redshift 无法将结果映射到同时运行的事务的序列顺序时,事务可能会失败。

快照隔离允许更高的并发性,因此可以成功完成对同一表中不同行的并发修改。

事务继续在数据库的最新提交版本或快照上运行。

您可以在数据库上设置快照隔离,并在 CREATE DATABASEALTER DATABASE 命令中包含 ISOLATION LEVEL 参数。

要查看数据库使用的并发模型,请运行以下 STV_DB_ISOLATION_LEVEL 查询:

SELECT * FROM stv_db_isolation_level;
The database can then be altered to SNAPSHOT ISOLATION:
ALTER DATABASE sampledb ISOLATION LEVEL SNAPSHOT;

更改数据库的隔离级别时,请遵循以下最佳实践:

  • 要更改数据库隔离级别,必须具有超级用户或 CREATE DATABASE 权限。
  • 您无法更改数据库环境的隔离级别。
  • 您无法更改事务块内的隔离级别。
  • 当其他用户连接到数据库时,更改隔离级别命令失败。
  • 更改隔离级别命令可以更改当前会话的隔离级别设置。

有关详细信息,请参阅如何修复可序列化的隔离错误

相关信息

ERROR:1023 DETAIL: Serializable isolation violation on a table in Redshift

ERROR:1018 DETAIL: Relation does not exist

管理并发写入操作

AWS 官方已更新 10 个月前
没有评论

相关内容