

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Aurora PostgreSQL Limitless Database 中的分散式死鎖
<a name="limitless-query.deadlocks"></a>

在資料庫碎片群組中，分佈在不同路由器和碎片之間的交易之間可能會發生死鎖。例如，如下圖所示，會執行跨越兩個碎片的兩個並行分散式交易。

![兩個分散式交易上的分散式死鎖。](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/AuroraUserGuide/images/limitless_distributed_transaction_deadlock.png)


如下所示，這些交易會鎖定資料表，以及在兩個碎片中建立等待事件：

1. 分散式交易 1：

   ```
   UPDATE {{table}} SET {{value}} = 1 WHERE key = '{{shard1_key}}';
   ```

   這會在碎片 1 上保留鎖定。

1. 分散式交易 2：

   ```
   UPDATE {{table}} SET {{value}} = 2 WHERE key = '{{shard2_key}}';
   ```

   這會在碎片 2 上保留鎖定。

1. 分散式交易 1：

   ```
   UPDATE {{table}} SET {{value}} = 3 WHERE key = '{{shard2_key}}';
   ```

   分散式交易 1 正在等待碎片 2。

1. 分散式交易 2：

   ```
   UPDATE {{table}} SET {{value}} = 4 WHERE key = '{{shard1_key}}';
   ```

   分散式交易 2 正在等待碎片 1。

在此案例中，碎片 1 和碎片 2 都看不到問題：交易 1 正在等待碎片 2 上的交易 2，而交易 2 正在等待碎片 1 上的交易 1。透過全域檢視，交易 1 正在等待交易 2，交易 2 正在等待交易 1。在這種情況下，兩個不同碎片上的兩個交易正在彼此等待 (稱為分散式死鎖)。

Aurora PostgreSQL Limitless Database 可以自動偵測和解決分散式死鎖。資料庫碎片群組中的路由器會在交易等待太久而無法取得資源時收到通知。接收通知的路由器會開始從資料庫碎片群組中的所有路由器和碎片收集必要的資訊。然後，路由器會繼續將參與分散式死鎖的交易加以結束，直到資料庫碎片群組中的其餘交易可以繼續，而不會彼此封鎖。

當交易是分散式死鎖的一部分，接著由路由器結束時，您會收到下列錯誤：

```
ERROR: aborting transaction participating in a distributed deadlock
```

`rds_aurora.limitless_distributed_deadlock_timeout` 資料庫叢集參數會設定每個交易等待資源的時間，之後才會通知路由器檢查分散式死鎖。如果工作負載較不容易發生死鎖情況，您可以提高參數值。預設值為 `1000` 毫秒 (1 秒)。

找到並解析跨節點死鎖時，分散式死鎖週期會發佈至 PostgreSQL 日誌。作為死鎖一部分之每個程序的相關資訊包括下列項目：
+ 啟動交易的協調器節點
+ 協調器節點上交易的虛擬交易 ID (xid) (格式為 `{{backend_id}}/{{backend_local_xid}}`)
+ 交易的分散式工作階段 ID