

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

# CPU
<a name="wait-event.cpu"></a>

此事件表示執行緒活躍於 CPU 中或正在等待 CPU。

**Topics**
+ [支援的引擎版本](#wait-event.cpu.context.supported)
+ [Context](#wait-event.cpu.context)
+ [等待變多的可能原因](#wait-event.cpu.causes)
+ [動作](#wait-event.cpu.actions)

## 支援的引擎版本
<a name="wait-event.cpu.context.supported"></a>

此等待事件資訊與所有 RDS for PostgreSQL 版本有關。

## Context
<a name="wait-event.cpu.context"></a>

*中央處理單元 (CPU)* 是執行指令的電腦元件。例如，CPU 指令執行算術運算，並在記憶體中交換資料。如果查詢增加更多指令來透過資料庫引擎執行，則查詢會執行更久。*CPU 排程*將 CPU 時間撥給程序。排程由作業系統的核心協調。

**Topics**
+ [如何得知發生這種等待](#wait-event.cpu.when-it-occurs)
+ [DBLoadCPU 指標](#wait-event.cpu.context.dbloadcpu)
+ [os.cpuUtilization 指標](#wait-event.cpu.context.osmetrics)
+ [CPU 排程的可能原因](#wait-event.cpu.context.scheduling)

### 如何得知發生這種等待
<a name="wait-event.cpu.when-it-occurs"></a>

此 `CPU` 等待事件表示後端程序活躍於 CPU 中或正在等待 CPU。當查詢顯示下列資訊時，就表示發生此事件：
+ `pg_stat_activity.state` 欄具有值 `active`。
+ `pg_stat_activity` 中的 `wait_event_type` 和 `wait_event` 欄皆為 `null`。

若要查看正在使用或等待 CPU 的後端程序，請執行下列查詢。

```
SELECT * 
FROM   pg_stat_activity
WHERE  state = 'active'
AND    wait_event_type IS NULL
AND    wait_event IS NULL;
```

### DBLoadCPU 指標
<a name="wait-event.cpu.context.dbloadcpu"></a>

CPU 的績效詳情指標為 `DBLoadCPU`。`DBLoadCPU` 的值與 Amazon CloudWatch 指標 `CPUUtilization` 的值可能不同。後者是從 HyperVisor 為資料庫執行個體收集的指標。

### os.cpuUtilization 指標
<a name="wait-event.cpu.context.osmetrics"></a>

績效詳情作業系統指標提供 CPU 使用率的詳細資訊。例如，您可以顯示下列指標：
+ `os.cpuUtilization.nice.avg`
+ `os.cpuUtilization.total.avg`
+ `os.cpuUtilization.wait.avg`
+ `os.cpuUtilization.idle.avg`

績效詳情以 `os.cpuUtilization.nice.avg` 報告資料庫引擎的 CPU 使用率。

### CPU 排程的可能原因
<a name="wait-event.cpu.context.scheduling"></a>

 作業系統核心會處理 CPU 的排程。CPU *作用中*時，程序可能需要等待排程。CPU 在執行運算時處於作用中狀態。當它具有未執行的閒置執行緒 (亦即，等待記憶體 I/O 的執行緒) 時，也是處於作用中狀態。此類型的 I/O 主導典型資料庫工作負載。

滿足下列條件時，程序可能等待排定使用 CPU：
+ CloudWatch `CPUUtilization` 指標接近 100%。
+ 平均負載大於 vCPU 數目，表示負載過重。您可以在績效詳情的作業系統指標區段中找到 `loadAverageMinute` 指標。

## 等待變多的可能原因
<a name="wait-event.cpu.causes"></a>

CPU 等待事件比平時更常發生時，可能表示有效能問題，典型原因包括下列各項。

**Topics**
+ [突然激增的可能原因](#wait-event.cpu.causes.spikes)
+ [長期頻繁的可能原因](#wait-event.cpu.causes.long-term)
+ [罕見情況](#wait-event.cpu.causes.corner-cases)

### 突然激增的可能原因
<a name="wait-event.cpu.causes.spikes"></a>

突然激增最可能的原因如下：
+ 應用程式對資料庫同時開啟太多連線。這種情況稱為「連線風暴」。
+ 應用程式工作負載出現下列任何變化：
  + 新查詢
  + 資料集變大
  + 維護或建立索引
  + 新函數
  + 新運算子
  + 平行執行查詢增加
+ 查詢執行計劃已變更。在某些情況下，變更可能造成緩衝區增加。例如，查詢原本使用索引，但現在使用循序掃描。在此情況下，查詢需要更多 CPU 才能完成相同的目標。

### 長期頻繁的可能原因
<a name="wait-event.cpu.causes.long-term"></a>

事件長期復發最可能的原因：
+ CPU 上同時執行太多後端程序。這些程序可能是平行工作者。
+ 查詢表現欠佳，因為需要大量緩衝區。

### 罕見情況
<a name="wait-event.cpu.causes.corner-cases"></a>

如果可能原因都不是真正原因，可能表示發生下列情況：
+ CPU 正在換入換出程序。
+ 如果*大型頁面*功能已關閉，則 CPU 可能正在管理頁面表格項目。除了微型、小型和中型資料庫執行個體類之外，所有資料庫執行個體類都預設開啟此記憶體管理功能。如需詳細資訊，請參閱[RDS for PostgreSQL 的巨型分頁](PostgreSQL.Concepts.General.FeatureSupport.HugePages.md)。

## 動作
<a name="wait-event.cpu.actions"></a>

如果 `CPU` 等待事件在資料庫活動中佔多數，則不見得表示有效能問題。效能降低時才需要回應此事件。

**Topics**
+ [調查資料庫是否造成 CPU 使用率上升](#wait-event.cpu.actions.db-CPU)
+ [判斷連線數目是否增加](#wait-event.cpu.actions.connections)
+ [回應工作負載變更](#wait-event.cpu.actions.workload)

### 調查資料庫是否造成 CPU 使用率上升
<a name="wait-event.cpu.actions.db-CPU"></a>

在績效詳情中檢查 `os.cpuUtilization.nice.avg` 指標。如果此值遠低於 CPU 使用率，表示佔用 CPU 以非資料庫的程序為主。

### 判斷連線數目是否增加
<a name="wait-event.cpu.actions.connections"></a>

在 Amazon CloudWatch 中檢查 `DatabaseConnections` 指標。您的動作取決於在 CPU 等待事件變多期間，連線數目是增加還是減少。

#### 連線增加
<a name="wait-event.cpu.actions.connections.increased"></a>

如果連線數目上升，請將耗用 CPU 的後端程序數目與 vCPU 數目做比較。可能的情況如下：
+ 耗用 CPU 的後端程序數目小於 vCPU 數目。

  在此情況下，連線數目不是問題。但您仍然可以嘗試降低 CPU 使用率。
+ 耗用 CPU 的後端程序數目大於 vCPU 數目。

  在此情況下，請考慮下列選項：
  + 將連線至資料庫的後端程序數目減少。例如，實作連線集區解決方案，例如 RDS Proxy。如需詳細資訊，請參閱 [Amazon RDS Proxy ](rds-proxy.md)。
  + 加大執行個體以取得更多 vCPU。
  + 如適用，請將一些唯讀工作負載重新導向至讀取器節點

#### 連線未增加
<a name="wait-event.cpu.actions.connections.decreased"></a>

在績效詳情中檢查 `blks_hit` 指標。尋找 `blks_hit` 增加與 CPU 使用率之間的關聯性。可能的情況如下：
+ CPU 使用率與 `blks_hit` 有關。

  在此情況下，請找出與 CPU 使用率最有關的 SQL 陳述式，並尋找計劃變更。您可以使用下列任一技巧：
  + 手動解釋計劃，並與預期的執行計劃做比較。
  + 查明每秒區塊命中數和每秒本機區塊命中數是否增加。在績效詳情儀表板的 **Top SQL** (常用 SQL) 區段中，選擇 **Preferences** (偏好設定)。
+ CPU 使用率與 `blks_hit` 無關。

  在此情況下，請判斷是否發生下列任何情形：
  + 應用程式與資料庫之間快速連線和斷線。

    請開啟 `log_connections` 和 `log_disconnections`，然後分析 PostgreSQL 日誌，以診斷此行為。考慮使用 `pgbadger` 日誌分析器。如需詳細資訊，請參閱 [https://github.com/darold/pgbadger](https://github.com/darold/pgbadger)。
  + 作業系統超載。

    在此情況下，績效詳情會指出後端程序耗用 CPU 比平常更久。在績效詳情 `os.cpuUtilization` 指標或 CloudWatch `CPUUtilization` 指標中查證。如果作業系統超載，請檢查增強型監控指標以進一步診斷。具體來說，請檢查程序清單及每個程序耗用的 CPU 百分比。
  + 常用 SQL 陳述式耗用太多 CPU。

    檢查與 CPU 使用率有關的陳述式，了解是否可以少用 CPU。執行 `EXPLAIN` 命令，專注於影響最大的計劃節點上。考慮使用 PostgreSQL execution plan visualizer。若要試用此工具，請參閱 [http://explain.dalibo.com/](http://explain.dalibo.com/)。

### 回應工作負載變更
<a name="wait-event.cpu.actions.workload"></a>

如果工作負載已變更，請尋找下列類型的變更：

新查詢  
檢查是否需要新的查詢。如果是，請確定其執行計劃和每秒執行次數合理。

資料集變大  
決定是否應該分割 (如果尚未分割)。此策略可以減少查詢需要擷取的分頁數。

維護或建立索引  
檢查是否需要排定維護。最佳實務是將維護活動排定在尖峰活動之外。

新函數  
檢查這些函數在測試期間是否正常執行。具體來說，請檢查每秒執行次數是否合理。

新運算子  
檢查在測試期間是否正常執行。

平行執行查詢增加  
判斷是否發生下列任何情況：  
+ 涉及的關聯或索引突然變大，明顯不同於 `min_parallel_table_scan_size` 或 `min_parallel_index_scan_size`。
+ 最近變更 `parallel_setup_cost` 或 `parallel_tuple_cost`。
+ 最近變更 `max_parallel_workers` 或 `max_parallel_workers_per_gather`。