View a markdown version of this page

Aurora DSQL 中的并发控制 - Amazon Aurora DSQL

Aurora DSQL 中的并发控制

并发可让多个会话同时访问和修改数据,而不会损害数据完整性和一致性。Aurora DSQL 在实施现代、无锁并发控制机制的同时提供 PostgreSQL 兼容性。它通过快照隔离来保持完全的 ACID 合规性,同时确保数据一致性和可靠性。

Aurora DSQL 的一个关键优势是其无锁架构,这消除了常见的数据库性能瓶颈。Aurora DSQL 可防止慢速事务阻塞其它操作,并消除死锁风险。这种方法使 Aurora DSQL 对于性能和可扩展性至关重要的高吞吐量应用程序特别有价值。

并发控制响应

Aurora DSQL 使用乐观并发控制(OCC),其工作原理与传统的基于锁的系统不同。OCC 不使用锁,而是在提交时评估冲突。此提交时冲突评估过程也称为判定。Aurora DSQL 在检测到冲突时,会返回带有 SQLSTATE 代码 40001 的 PostgreSQL 序列化失败故障。响应消息包括标识冲突类型的 OCC 代码:

OC000:数据冲突

两个事务试图修改同一行。提交时间最早的事务成功,而冲突的事务则收到 OC000 响应:

ERROR: change conflicts with another transaction (OC000) (SQLSTATE 40001)
OC001:架构冲突

会话所缓存的架构目录已过期。Aurora DSQL 检测到自会话加载其缓存以来目录版本发生了更改,并且事务无法安全地重定基准到当前版本时,事务将收到 OC001 响应:

ERROR: schema has been updated by another transaction (OC001) (SQLSTATE 40001)

任何修改架构目录的操作都可能导致 OC001 响应,包括 CREATE TABLE 和 ALTER TABLE 等 DDL 语句,以及 GRANT 和 REVOKE 语句。有关更多信息,请参阅 Aurora DSQL 中的 DDL 和分布式事务。

设计应用程序以实施重试逻辑来处理这些响应。理想的设计模式是幂等的,尽可能将事务重试作为第一选择。建议采用的逻辑类似于标准 PostgreSQL 锁定超时或死锁情况下的中止和重试逻辑。然而,OCC 要求您的应用程序更频繁地实施此逻辑。

数据冲突类型

由于 Aurora DSQL 的并发控制机制,SELECT ... FOR UPDATE 和 SELECT ... FOR KEY SHARE 子句通过提交时的乐观冲突检测(而非锁定)来产生结果。在 Aurora DSQL 中,当一个事务写入某个行,并且另一个事务使用上述某个子句读取该行时,可能会在提交时发生冲突,具体取决于事务所使用的列。以下子句可决定 Aurora DSQL 检测这些冲突的方式。

键列定义

键列是指属于唯一、非部分、非表达式索引的列。所有其他列都为非键列。

SELECT ... FOR UPDATE

声明 Aurora DSQL 将按事务对选定行进行写入的方式来对这些行进行冲突判定。如果另一个事务在同一行上运行 UPDATE、DELETE、SELECT ... FOR UPDATE 或 SELECT ... FOR KEY SHARE,并且首先提交,则运行了 SELECT ... FOR UPDATE 的事务将失败,并返回 OC000 响应。此子句与对行进行的任何并发写入,以及并发的 FOR UPDATE 或 FOR KEY SHARE 读取发生冲突。

SELECT ... FOR KEY SHARE

声明事务依赖于选定行的键列。如果另一个事务删除行,更改其键列或运行 SELECT ... FOR UPDATE 且首先提交,则运行了 SELECT ... FOR KEY SHARE 的事务将失败,并返回 OC000 响应。对非键列进行的并发 UPDATE 操作不会产生冲突。

Aurora DSQL 不支持 NO KEY UPDATE 或 FOR SHARE 子句。不过,DML 隐式使用 NO KEY UPDATE 机制。以下矩阵汇总了访问同一行的两个并发事务发生冲突的情况。X 表示这两个操作发生冲突:无论哪个事务最后提交,都将失败并返回 OC000 响应。空白单元格表示两个事务都可提交。

操作 INSERT、DELETE、UPDATE(键列)或 SELECT ... FOR UPDATE UPDATE(仅限非键列) SELECT ... FOR KEY SHARE
INSERT、DELETE、UPDATE(键列)或 SELECT ... FOR UPDATE X X X
UPDATE(仅限非键列) X X
SELECT ... FOR KEY SHARE X

优化事务性能的准则

要优化性能,请尽量减少对单个键或小键范围的高度争用。要实现此目标,请按照以下准则设计架构,使其在集群键范围内分散更新:

  • 为表选择一个随机主键。

  • 避免使用会增加单个键争用的模式。即使在事务量增长的情况下,这种方法也能确保最佳性能。