

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Menyetel dengan peristiwa tunggu di RDS for PostgreSQL
<a name="PostgreSQL.Tuning"></a>

Peristiwa tunggu adalah alat penyetelan penting untuk RDS for PostgreSQL. Ketika Anda dapat mengetahui mengapa sesi menunggu sumber daya dan apa yang sedang dilakukan, Anda lebih mampu mengurangi kemacetan. Anda dapat menggunakan informasi di bagian ini untuk menemukan kemungkinan penyebab dan tindakan korektif. Bagian ini juga membahas konsep penyetelan dasar PostgreSQL.

Peristiwa tunggu di bagian ini spesifik untuk RDS for PostgreSQL.

**Topics**
+ [

# Konsep penting dalam penyetelan RDS for PostgreSQL
](PostgreSQL.Tuning.concepts.md)
+ [

# Peristiwa tunggu RDS for PostgreSQL
](PostgreSQL.Tuning.concepts.summary.md)
+ [

# Klien: ClientRead
](wait-event.clientread.md)
+ [

# Klien: ClientWrite
](wait-event.clientwrite.md)
+ [

# CPU
](wait-event.cpu.md)
+ [

# IO: BufFileRead dan IO: BufFileWrite
](wait-event.iobuffile.md)
+ [

# IO: DataFileRead
](wait-event.iodatafileread.md)
+ [

# IO: WALWrite
](wait-event.iowalwrite.md)
+ [

# IPC: Acara tunggu paralel
](rpg-ipc-parallel.md)
+ [

# IPC: ProcArrayGroupUpdate
](apg-rpg-ipcprocarraygroup.md)
+ [

# Lock:advisory
](wait-event.lockadvisory.md)
+ [

# Lock:extend
](wait-event.lockextend.md)
+ [

# Lock:Relation
](wait-event.lockrelation.md)
+ [

# Lock:transactionid
](wait-event.locktransactionid.md)
+ [

# Lock:tuple
](wait-event.locktuple.md)
+ [

# LWLock: BufferMapping (:buffer\$1mapping) LWLock
](wait-event.lwl-buffer-mapping.md)
+ [

# LWLock:Bufferio (IPC: Bufferio)
](wait-event.lwlockbufferio.md)
+ [

# LWLock:buffer\$1content (BufferContent)
](wait-event.lwlockbuffercontent.md)
+ [

# LWLock:lock\$1manager (manajer kunci) LWLock
](wait-event.lw-lock-manager.md)
+ [

# LWLock:pg\$1stat\$1statement
](apg-rpg-lwlockpgstat.md)
+ [

# LWLock:subtransslru (:) LWLock SubtransControlLock
](wait-event.lwlocksubtransslru.md)
+ [

# Timeout:PgSleep
](wait-event.timeoutpgsleep.md)
+ [

# Timeout:VacuumDelay
](wait-event.timeoutvacuumdelay.md)

# Konsep penting dalam penyetelan RDS for PostgreSQL
<a name="PostgreSQL.Tuning.concepts"></a>

Sebelum Anda menyetel basis data RDS for PostgreSQL, pastikan untuk mempelajari apa itu peristiwa tunggu dan mengapa peristiwa tersebut terjadi. Baca juga memori dasar dan arsitektur disk RDS for PostgreSQL. Anda dapat melihat diagram arsitektur yang berguna di wikibook [PostgreSQL](https://en.wikibooks.org/wiki/PostgreSQL/Architecture).

**Topics**
+ [

# Peristiwa tunggu RDS for PostgreSQL
](PostgreSQL.Tuning.concepts.waits.md)
+ [

# Memori RDS for PostgreSQL
](PostgreSQL.Tuning.concepts.memory.md)
+ [

# Proses RDS for PostgreSQL
](PostgreSQL.Tuning.concepts.processes.md)

# Peristiwa tunggu RDS for PostgreSQL
<a name="PostgreSQL.Tuning.concepts.waits"></a>

*Peristiwa tunggu* menunjukkan bahwa sesi sedang menunggu sumber daya. Misalnya, peristiwa tunggu `Client:ClientRead` terjadi ketika RDS for PostgreSQL menunggu untuk menerima data dari klien. Sesi biasanya menunggu sumber daya seperti berikut ini.
+ Akses thread tunggal ke buffer, misalnya, saat sesi mencoba memodifikasi buffer
+ Baris yang saat ini dikunci oleh sesi lain
+ Pembacaan file data
+ Penulisan file log

Misalnya, untuk memenuhi kueri, sesi mungkin melakukan pemindaian tabel lengkap. Jika data belum ada dalam memori, sesi menunggu disk I/O selesai. Ketika buffer dibaca ke dalam memori, sesi mungkin perlu menunggu karena sesi lain mengakses buffer yang sama. Basis data mencatat peristiwa tunggu dengan menggunakan peristiwa tunggu standar. Peristiwa tersebut dikelompokkan ke dalam kategori.

Dengan sendirinya, satu peristiwa tunggu tidak menunjukkan masalah performa. Misalnya, jika data yang diminta tidak ada dalam memori, data perlu dibaca dari disk. Jika satu sesi mengunci baris untuk pembaruan, sesi lain akan menunggu baris tersebut dibuka sehingga dapat memperbaruinya. Komit perlu menunggu penulisan ke file log selesai. Peristiwa tunggu merupakan bagian integral dari fungsi normal basis data. 

Di sisi lain, sejumlah besar peristiwa tunggu biasanya menunjukkan masalah performa. Dalam kasus seperti itu, Anda dapat menggunakan data peristiwa tunggu untuk menentukan tempat sesi menghabiskan waktu. Misalnya, jika laporan yang biasanya berjalan dalam hitungan menit sekarang berjalan selama berjam-jam, Anda dapat mengidentifikasi peristiwa tunggu yang berkontribusi paling besar terhadap total waktu tunggu. Jika Anda dapat menentukan penyebab peristiwa tunggu teratas, terkadang Anda dapat membuat perubahan yang meningkatkan performa. Misalnya, jika sesi Anda menunggu pada baris yang telah dikunci oleh sesi lain, Anda dapat mengakhiri sesi penguncian. 

# Memori RDS for PostgreSQL
<a name="PostgreSQL.Tuning.concepts.memory"></a>

Memori RDS for PostgreSQL dibagi menjadi bersama dan lokal.

**Topics**
+ [

## Memori bersama dalam RDS for PostgreSQL
](#PostgreSQL.Tuning.concepts.shared)
+ [

## Memori lokal dalam RDS for PostgreSQL
](#PostgreSQL.Tuning.concepts.local)

## Memori bersama dalam RDS for PostgreSQL
<a name="PostgreSQL.Tuning.concepts.shared"></a>

RDS for PostgreSQL mengalokasikan memori bersama saat instans dimulai. Memori bersama dibagi menjadi beberapa sub-area. Bagian berikut memberikan deskripsi yang paling penting.

**Topics**
+ [

### Buffer bersama
](#PostgreSQL.Tuning.concepts.buffer-pool)
+ [

### Buffer log write ahead (WAL)
](#PostgreSQL.Tuning.concepts.WAL)

### Buffer bersama
<a name="PostgreSQL.Tuning.concepts.buffer-pool"></a>

*Kumpulan buffer bersama* adalah area memori RDS for PostgreSQL yang menampung semua halaman yang sedang atau telah digunakan oleh koneksi aplikasi. *Halaman* adalah versi memori dari blok disk. Kumpulan buffer bersama menyimpan blok data yang dibaca dari disk. Kumpulan tersebut mengurangi kebutuhan untuk membaca ulang data dari disk, sehingga membuat basis data beroperasi lebih efisien.

Setiap tabel dan indeks disimpan sebagai array halaman dengan ukuran tetap. Setiap blok berisi beberapa tuple, yang sesuai dengan baris. Tuple dapat disimpan di halaman mana pun.

Kumpulan buffer bersama memiliki memori terbatas. Jika permintaan baru memerlukan halaman yang tidak ada dalam memori, dan memori sudah tidak ada lagi, RDS for PostgreSQL mengosongkan halaman yang jarang digunakan untuk mengakomodasi permintaan tersebut. Kebijakan pengosongan diimplementasikan oleh algoritma clock sweep.

Parameter `shared_buffers` menentukan berapa banyak memori server dikhususkan untuk menyimpan data dalam cache. Nilai default diatur ke `{DBInstanceClassMemory/32768}` byte, berdasarkan memori yang tersedia untuk instans DB.

### Buffer log write ahead (WAL)
<a name="PostgreSQL.Tuning.concepts.WAL"></a>

*Buffer log write-ahead (WAL)* menyimpan data transaksi yang kemudian ditulis RDS for PostgreSQL ke penyimpanan persisten. Menggunakan mekanisme WAL, RDS for PostgreSQL dapat melakukan hal berikut:
+ Memulihkan data setelah kegagalan
+ Kurangi disk I/O dengan menghindari sering menulis ke disk

Ketika klien mengubah data, RDS for PostgreSQL menulis perubahan ke buffer WAL. Ketika klien mengeluarkan `COMMIT`, proses penulis WAL menulis data transaksi ke file WAL.

`wal_level`Parameter menentukan berapa banyak informasi yang ditulis ke WAL, dengan nilai yang mungkin seperti`minimal`,`replica`, dan`logical`.

## Memori lokal dalam RDS for PostgreSQL
<a name="PostgreSQL.Tuning.concepts.local"></a>

Setiap proses backend mengalokasikan memori lokal untuk pemrosesan kueri.

**Topics**
+ [

### Area memori kerja
](#PostgreSQL.Tuning.concepts.local.work_mem)
+ [

### Area memori kerja pemeliharaan
](#PostgreSQL.Tuning.concepts.local.maintenance_work_mem)
+ [

### Area buffer sementara
](#PostgreSQL.Tuning.concepts.temp)

### Area memori kerja
<a name="PostgreSQL.Tuning.concepts.local.work_mem"></a>

*Area memori kerja* menyimpan data sementara untuk kueri yang melakukan pengurutan dan hash. Misalnya, kueri dengan klausa `ORDER BY` melakukan pengurutan. Kueri menggunakan tabel hash dalam gabungan dan agregasi hash.

`work_mem`Parameter jumlah memori yang akan digunakan oleh operasi pengurutan internal dan tabel hash sebelum menulis ke file disk sementara, diukur dalam megabyte. Nilai default-nya adalah 4 MB. Beberapa sesi dapat berjalan secara bersamaan, dan setiap sesi dapat menjalankan operasi pemeliharaan secara paralel. Karena alasan ini, total memori kerja yang digunakan dapat menjadi kelipatan dari pengaturan `work_mem`. 

### Area memori kerja pemeliharaan
<a name="PostgreSQL.Tuning.concepts.local.maintenance_work_mem"></a>

*Area memori kerja pemeliharaan* menyimpan data untuk operasi pemeliharaan. Operasi ini termasuk memvakum, membuat indeks, dan menambahkan kunci asing.

`maintenance_work_mem`Parameter menentukan jumlah maksimum memori yang akan digunakan oleh operasi pemeliharaan, diukur dalam megabyte. Nilai default-nya adalah 64 MB. Sebuah sesi basis data hanya dapat menjalankan satu operasi pemeliharaan dalam satu waktu.

### Area buffer sementara
<a name="PostgreSQL.Tuning.concepts.temp"></a>

*Area buffer sementara* menyimpan tabel sementara untuk setiap sesi basis data.

Setiap sesi mengalokasikan buffer sementara sesuai kebutuhan hingga batas yang Anda tentukan. Saat sesi berakhir, server menghapus buffer.

`temp_buffers`Parameter menetapkan jumlah maksimum buffer sementara yang digunakan oleh setiap sesi, diukur dalam megabyte. Nilai defaultnya adalah 8 MB. Sebelum penggunaan pertama tabel sementara dalam sesi, Anda dapat mengubah nilai `temp_buffers`.

# Proses RDS for PostgreSQL
<a name="PostgreSQL.Tuning.concepts.processes"></a>

RDS for PostgreSQL menggunakan beberapa proses.

**Topics**
+ [

## Proses postmaster
](#PostgreSQL.Tuning.concepts.postmaster)
+ [

## Proses backend
](#PostgreSQL.Tuning.concepts.backend)
+ [

## Proses latar belakang
](#PostgreSQL.Tuning.concepts.vacuum)

## Proses postmaster
<a name="PostgreSQL.Tuning.concepts.postmaster"></a>

*Proses postmaster* adalah proses pertama yang dimulai ketika Anda memulai RDS for PostgreSQL. Proses postmaster memiliki tanggung jawab utama berikut:
+ Membagi dan memantau proses latar belakang
+ Menerima permintaan autentikasi dari proses klien, dan mengautentikasi permintaan sebelum mengizinkan basis data untuk melayani permintaan

## Proses backend
<a name="PostgreSQL.Tuning.concepts.backend"></a>

Jika postmaster mengautentikasi permintaan klien, postmaster akan melakukan proses backend baru, juga disebut proses postgres. Satu proses klien terhubung ke persis satu proses backend. Proses klien dan proses backend berkomunikasi secara langsung tanpa intervensi oleh proses postmaster.

## Proses latar belakang
<a name="PostgreSQL.Tuning.concepts.vacuum"></a>

Proses postmaster membagi beberapa proses yang melakukan tugas backend yang berbeda. Beberapa hal yang lebih penting termasuk berikut ini:
+ Penulis WAL

  RDS for PostgreSQL menulis data dalam buffer WAL (log write ahead) ke file log. Prinsip log write ahead adalah bahwa basis data tidak dapat menulis perubahan pada file data sampai setelah basis data menulis catatan log yang menjelaskan perubahan tersebut ke disk. Mekanisme WAL mengurangi disk I/O, dan memungkinkan RDS for PostgreSQL untuk menggunakan log untuk memulihkan basis data setelah kegagalan.
+ Penulis latar belakang

  Proses ini secara berkala menulis halaman kotor (diubah) dari buffer memori ke file data. Sebuah halaman menjadi kotor ketika proses backend memodifikasinya dalam memori.
+ Daemon autovacuum

  Daemon terdiri dari hal-hal berikut:
  + Peluncur autovacuum
  + Proses pekerja autovacuum

  Saat autovacuum diaktifkan, autovacuum tersebut memeriksa tabel yang memiliki banyak tuple yang dimasukkan, diperbarui, atau dihapus. Daemon memiliki tanggung jawab sebagai berikut:
  + Memulihkan atau menggunakan kembali ruang disk yang ditempati oleh baris yang diperbarui atau dihapus
  + Memperbarui statistik yang digunakan oleh perencana
  + Melindungi dari kehilangan data lama karena wraparound ID transaksi

  Fitur autovacuum mengotomatiskan eksekusi `VACUUM` dan perintah `ANALYZE`. `VACUUM` memiliki varian berikut: standar dan penuh. Vakum standar berjalan secara paralel dengan operasi basis data lainnya. `VACUUM FULL` membutuhkan kunci eksklusif di tabel yang sedang dikerjakannya. Dengan demikian, tidak dapat berjalan secara paralel dengan operasi yang mengakses tabel yang sama. `VACUUM`menciptakan sejumlah besar I/O lalu lintas, yang dapat menyebabkan kinerja yang buruk untuk sesi aktif lainnya.

# Peristiwa tunggu RDS for PostgreSQL
<a name="PostgreSQL.Tuning.concepts.summary"></a>

Tabel berikut mencantumkan peristiwa tunggu untuk RDS for PostgreSQL yang paling sering menunjukkan masalah performa, dan meringkas penyebab paling umum dan tindakan korektifnya.


| Peristiwa tunggu | Definisi | 
| --- | --- | 
|  [Klien: ClientRead](wait-event.clientread.md)  |  Peristiwa ini terjadi ketika RDS for PostgreSQL menunggu untuk menerima data dari klien.  | 
|  [Klien: ClientWrite](wait-event.clientwrite.md)  |  Peristiwa ini terjadi ketika RDS for PostgreSQL menunggu untuk menulis data ke klien.  | 
|  [CPU](wait-event.cpu.md)  | Peristiwa ini terjadi saat thread aktif di CPU atau sedang menunggu CPU.  | 
|  [IO: BufFileRead dan IO: BufFileWrite](wait-event.iobuffile.md)  |  Peristiwa ini terjadi ketika RDS for PostgreSQL membuat file sementara.  | 
|  [IO: DataFileRead](wait-event.iodatafileread.md)  |  Peristiwa ini terjadi ketika koneksi menunggu pada proses backend untuk membaca halaman yang diperlukan dari penyimpanan karena halaman tidak tersedia dalam memori bersama.   | 
| [IO: WALWrite](wait-event.iowalwrite.md)  | Peristiwa ini terjadi ketika RDS for PostgreSQL sedang menunggu buffer write-ahead log (WAL) ditulis ke file WAL.  | 
|  [Lock:advisory](wait-event.lockadvisory.md)  |  Peristiwa ini terjadi ketika aplikasi PostgreSQL menggunakan kunci untuk mengoordinasikan aktivitas di beberapa sesi.  | 
|  [Lock:extend](wait-event.lockextend.md) |  Peristiwa ini terjadi ketika proses backend menunggu untuk mengunci relasi untuk memperpanjangnya selagi proses lain memiliki kunci pada relasi itu untuk tujuan yang sama.  | 
|  [Lock:Relation](wait-event.lockrelation.md)  |  Peristiwa ini terjadi ketika kueri menunggu untuk memperoleh kunci pada tabel atau tampilan yang saat ini dikunci oleh transaksi lain.  | 
|  [Lock:transactionid](wait-event.locktransactionid.md)  | Peristiwa ini terjadi ketika transaksi sedang menunggu kunci tingkat baris. | 
|  [Lock:tuple](wait-event.locktuple.md)  |  Peristiwa ini terjadi ketika proses backend menunggu untuk mendapatkan kunci pada tuple.  | 
|  [LWLock: BufferMapping (:buffer\$1mapping) LWLock](wait-event.lwl-buffer-mapping.md)  |  Peristiwa ini terjadi ketika sesi menunggu untuk mengaitkan blok data dengan buffer di kolam buffer bersama.  | 
|  [LWLock:Bufferio (IPC: Bufferio)](wait-event.lwlockbufferio.md)  |  Peristiwa ini terjadi ketika RDS untuk PostgreSQL sedang menunggu proses lain untuk menyelesaikan operasi (I/O) input/output mereka ketika secara bersamaan mencoba mengakses halaman.  | 
|  [LWLock:buffer\$1content (BufferContent)](wait-event.lwlockbuffercontent.md)  |  Peristiwa ini terjadi ketika suatu sesi menunggu untuk membaca atau menulis halaman data di memori selagi sesi lain mengunci halaman tersebut untuk penulisan.  | 
|  [LWLock:lock\$1manager (manajer kunci) LWLock](wait-event.lw-lock-manager.md)  | Peristiwa ini terjadi saat mesin RDS for PostgreSQL mempertahankan area memori kunci bersama untuk mengalokasikan, memeriksa, dan mendealokasikan kunci saat kunci jalur cepat tidak memungkinkan. | 
|  [LWLock:subtransslru (:) LWLock SubtransControlLock](wait-event.lwlocksubtransslru.md)  |  Peristiwa ini terjadi ketika proses sedang menunggu untuk mengakses cache sederhana yang paling tidak baru digunakan (SLRU) untuk subtransaksi.  | 
|  [Timeout:PgSleep](wait-event.timeoutpgsleep.md)  |  Peristiwa ini terjadi ketika proses server telah memanggil fungsi `pg_sleep` dan menunggu batas waktu tidur berakhir.   | 
|  [Timeout:VacuumDelay](wait-event.timeoutvacuumdelay.md)  | Peristiwa ini menunjukkan bahwa proses vakum sedang tidur karena perkiraan batas biaya telah tercapai.  | 

# Klien: ClientRead
<a name="wait-event.clientread"></a>

Peristiwa `Client:ClientRead` terjadi ketika RDS for PostgreSQL menunggu untuk menerima data dari klien.

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.clientread.context.supported)
+ [

## Konteks
](#wait-event.clientread.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.clientread.causes)
+ [

## Tindakan
](#wait-event.clientread.actions)

## Versi mesin yang didukung
<a name="wait-event.clientread.context.supported"></a>

Informasi peristiwa tunggu ini didukung untuk RDS for PostgreSQL versi 10 dan yang lebih tinggi.

## Konteks
<a name="wait-event.clientread.context"></a>

Instans DB RDS for PostgreSQL menunggu untuk menerima data dari klien. Instans DB RDS for PostgreSQL harus menerima data dari klien sebelum dapat mengirim lebih banyak data ke klien. Waktu instans menunggu sebelum menerima data dari klien adalah sebuah peristiwa `Client:ClientRead`.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.clientread.causes"></a>

Penyebab umum peristiwa `Client:ClientRead` muncul dalam peristiwa tunggu teratas mencakup yang berikut: 

**Peningkatan latensi jaringan**  
Mungkin terdapat peningkatan latensi jaringan antara instans DB RDS for PostgreSQL dan klien. Latensi jaringan yang lebih tinggi meningkatkan waktu yang dibutuhkan instans DB untuk menerima data dari klien.

**Peningkatan beban pada klien**  
Mungkin terdapat tekanan CPU atau saturasi jaringan pada klien. Peningkatan beban pada klien dapat menunda transmisi data dari klien ke instans DB RDS for PostgreSQL.

**Round trip jaringan yang berlebihan**  
Sejumlah besar round trip jaringan antara instans DB RDS for PostgreSQL dan klien dapat menunda transmisi data dari klien ke instans DB RDS for PostgreSQL.

**Operasi penyalinan besar**  
Selama operasi penyalinan, data ditransfer dari sistem file klien ke instans DB RDS for PostgreSQL. Mengirim sejumlah besar data ke instans DB dapat menunda transmisi data dari klien ke instans DB.

**Koneksi klien idle**  
Ketika klien terhubung ke instans DB RDS for PostgreSQL dalam status `idle in transaction`, instans DB ini mungkin menunggu klien mengirim lebih banyak data atau memberikan perintah. Koneksi dalam keadaan ini dapat menyebabkan peningkatan peristiwa `Client:ClientRead`.

**PgBouncer digunakan untuk penyatuan koneksi**  
PgBouncer memiliki pengaturan konfigurasi jaringan tingkat rendah yang disebut`pkt_buf`, yang diatur ke 4.096 secara default. Jika beban kerja mengirimkan paket kueri yang lebih besar dari 4.096 byte PgBouncer, kami sarankan untuk meningkatkan pengaturan menjadi 8.192. `pkt_buf` Jika pengaturan baru tidak mengurangi jumlah peristiwa `Client:ClientRead`, sebaiknya tingkatkan pengaturan `pkt_buf` ke nilai yang lebih besar, seperti 16.384 atau 32.768. Jika teks kueri berukuran besar, pengaturan yang lebih besar dapat sangat membantu.

## Tindakan
<a name="wait-event.clientread.actions"></a>

Kami merekomendasikan berbagai tindakan, tergantung pada penyebab peristiwa tunggu Anda.

**Topics**
+ [

### Tempatkan klien di Zona Ketersediaan dan subnet VPC yang sama dengan instans.
](#wait-event.clientread.actions.az-vpc-subnet)
+ [

### Skalakan klien Anda
](#wait-event.clientread.actions.scale-client)
+ [

### Gunakan instans generasi saat ini
](#wait-event.clientread.actions.db-instance-class)
+ [

### Meningkatkan bandwidth jaringan
](#wait-event.clientread.actions.increase-network-bandwidth)
+ [

### Pantau nilai maksimum untuk performa jaringan
](#wait-event.clientread.actions.monitor-network-performance)
+ [

### Pantau transaksi dalam status "idle dalam transaksi"
](#wait-event.clientread.actions.check-idle-in-transaction)

### Tempatkan klien di Zona Ketersediaan dan subnet VPC yang sama dengan instans.
<a name="wait-event.clientread.actions.az-vpc-subnet"></a>

Untuk mengurangi latensi jaringan dan meningkatkan throughput jaringan, tempatkan klien di Zona Ketersediaan dan subnet cloud privat virtual (VPC) yang sama dengan instans DB RDS for PostgreSQL. Pastikan bahwa klien secara geografis sedekat mungkin dengan instans DB.

### Skalakan klien Anda
<a name="wait-event.clientread.actions.scale-client"></a>

Menggunakan Amazon CloudWatch atau metrik host lainnya, tentukan apakah klien Anda saat ini dibatasi oleh CPU atau bandwidth jaringan, atau keduanya. Jika klien dibatasi, skalakan klien sesuai yang diperlukan.

### Gunakan instans generasi saat ini
<a name="wait-event.clientread.actions.db-instance-class"></a>

Dalam kasus tertentu, Anda mungkin tidak menggunakan kelas instans DB yang mendukung frame jumbo. Jika Anda menjalankan aplikasi di Amazon EC2, pertimbangkan untuk menggunakan instans generasi saat ini untuk klien. Selain itu, konfigurasikan unit transmisi maksimum (MTU) pada sistem operasi klien. Teknik ini dapat mengurangi jumlah round trip jaringan dan meningkatkan throughput jaringan. Untuk informasi selengkapnya, lihat [Jumbo frame (9001 MTU)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances) di Panduan Pengguna *Amazon EC2*.

Untuk informasi tentang kelas instans DB, lihat [ DB](Concepts.DBInstanceClass.md). Untuk menentukan kelas instans DB yang setara dengan jenis instans Amazon EC2, tempatkan `db.` sebelum nama jenis instans Amazon EC2. Misalnya, instans Amazon EC2 `r5.8xlarge` setara dengan kelas instans DB `db.r5.8xlarge`.

### Meningkatkan bandwidth jaringan
<a name="wait-event.clientread.actions.increase-network-bandwidth"></a>

Gunakan `NetworkReceiveThroughput` dan CloudWatch metrik `NetworkTransmitThroughput` Amazon untuk memantau lalu lintas jaringan masuk dan keluar pada instans DB. Metrik ini dapat membantu mengetahui apakah bandwidth jaringan cukup untuk beban kerja Anda. 

Jika bandwidth jaringan Anda tidak cukup, tingkatkan. Jika AWS klien atau instans DB Anda mencapai batas bandwidth jaringan, satu-satunya cara untuk meningkatkan bandwidth adalah dengan meningkatkan ukuran instans DB Anda. Untuk informasi selengkapnya, lihat [Jenis kelas instans DB](Concepts.DBInstanceClass.Types.md).

Untuk informasi selengkapnya tentang CloudWatch metrik, lihat[CloudWatch Metrik Amazon untuk Amazon RDS](rds-metrics.md). 

### Pantau nilai maksimum untuk performa jaringan
<a name="wait-event.clientread.actions.monitor-network-performance"></a>

Jika Anda menggunakan klien Amazon EC2, Amazon EC2 menyediakan nilai maksimum untuk metrik performa jaringan, termasuk bandwidth jaringan masuk dan keluar agregat. Amazon EC2 juga menyediakan pelacakan koneksi untuk memastikan paket dikembalikan sebagaimana diharapkan dan akses layanan tautan-lokal untuk layanan seperti Sistem Nama Domain (DNS). Untuk memantau nilai maksimum ini, gunakan driver jaringan yang ditingkatkan saat ini dan pantau performa jaringan untuk klien Anda. 

*Untuk informasi selengkapnya, lihat [Memantau kinerja jaringan untuk instans Amazon EC2 Anda](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-network-performance-ena.html) di Panduan *Pengguna Amazon EC2* [dan Memantau kinerja jaringan untuk instans Amazon EC2 Anda di Panduan Pengguna Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/monitoring-network-performance-ena.html).*

### Pantau transaksi dalam status "idle dalam transaksi"
<a name="wait-event.clientread.actions.check-idle-in-transaction"></a>

Periksa apakah Anda memiliki peningkatan jumlah koneksi `idle in transaction`. Untuk melakukannya, pantau kolom `state` dalam tabel `pg_stat_activity`. Anda mungkin dapat mengidentifikasi sumber koneksi dengan menjalankan kueri seperti yang berikut ini.

```
select client_addr, state, count(1) from pg_stat_activity 
where state like 'idle in transaction%' 
group by 1,2 
order by 3 desc
```

# Klien: ClientWrite
<a name="wait-event.clientwrite"></a>

Peristiwa `Client:ClientWrite` terjadi ketika RDS for PostgreSQL menunggu untuk menulis data ke klien.

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.clientwrite.context.supported)
+ [

## Konteks
](#wait-event.clientwrite.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.clientwrite.causes)
+ [

## Tindakan
](#wait-event.clientwrite.actions)

## Versi mesin yang didukung
<a name="wait-event.clientwrite.context.supported"></a>

Informasi peristiwa tunggu ini didukung untuk RDS for PostgreSQL versi 10 dan yang lebih tinggi.

## Konteks
<a name="wait-event.clientwrite.context"></a>

Proses klien harus membaca semua data yang diterima dari klaster DB RDS for PostgreSQL sebelum klaster dapat mengirim lebih banyak data. Waktu klaster menunggu sebelum mengirim lebih banyak data ke klien adalah sebuah peristiwa `Client:ClientWrite`.

Throughput jaringan yang berkurang untuk instans DB RDS for PostgreSQL dan klien dapat menyebabkan peristiwa ini. Tekanan CPU dan saturasi jaringan pada klien juga dapat menyebabkan peristiwa ini. *Tekanan CPU* adalah ketika CPU sepenuhnya digunakan dan ada tugas yang menunggu waktu CPU. *Saturasi jaringan* adalah saat jaringan antara basis data dan klien membawa lebih banyak data dari yang dapat ditanganinya. 

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.clientwrite.causes"></a>

Penyebab umum peristiwa `Client:ClientWrite` muncul dalam peristiwa tunggu teratas mencakup yang berikut: 

**Peningkatan latensi jaringan**  
Mungkin terdapat peningkatan latensi jaringan antara instans DB RDS for PostgreSQL dan klien. Latensi jaringan yang lebih tinggi meningkatkan waktu yang dibutuhkan klien untuk menerima data.

**Peningkatan beban pada klien**  
Mungkin terdapat tekanan CPU atau saturasi jaringan pada klien. Peningkatan beban pada klien menunda penerimaan data dari instans DB RDS for PostgreSQL.

**Data dalam volume besar yang dikirim ke klien**  
Instans DB RDS for PostgreSQL mungkin mengirimkan sejumlah besar data ke klien. Klien mungkin tidak dapat menerima data secepat klaster mengirimkannya. Aktivitas seperti penyalinan tabel besar dapat mengakibatkan peningkatan peristiwa `Client:ClientWrite`.

## Tindakan
<a name="wait-event.clientwrite.actions"></a>

Kami merekomendasikan berbagai tindakan, tergantung pada penyebab peristiwa tunggu Anda.

**Topics**
+ [

### Tempatkan klien di Zona Ketersediaan dan subnet VPC yang sama dengan klaster
](#wait-event.clientwrite.actions.az-vpc-subnet)
+ [

### Gunakan instans generasi saat ini
](#wait-event.clientwrite.actions.db-instance-class)
+ [

### Kurangi jumlah data yang dikirim ke klien Anda
](#wait-event.clientwrite.actions.reduce-data)
+ [

### Skalakan klien Anda
](#wait-event.clientwrite.actions.scale-client)

### Tempatkan klien di Zona Ketersediaan dan subnet VPC yang sama dengan klaster
<a name="wait-event.clientwrite.actions.az-vpc-subnet"></a>

Untuk mengurangi latensi jaringan dan meningkatkan throughput jaringan, tempatkan klien di Zona Ketersediaan dan subnet cloud privat virtual (VPC) yang sama dengan instans DB RDS for PostgreSQL.

### Gunakan instans generasi saat ini
<a name="wait-event.clientwrite.actions.db-instance-class"></a>

Dalam kasus tertentu, Anda mungkin tidak menggunakan kelas instans DB yang mendukung frame jumbo. Jika Anda menjalankan aplikasi di Amazon EC2, pertimbangkan untuk menggunakan instans generasi saat ini untuk klien. Selain itu, konfigurasikan unit transmisi maksimum (MTU) pada sistem operasi klien. Teknik ini dapat mengurangi jumlah round trip jaringan dan meningkatkan throughput jaringan. Untuk informasi selengkapnya, lihat [Jumbo frame (9001 MTU)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances) di Panduan Pengguna *Amazon EC2*.

Untuk informasi tentang kelas instans DB, lihat [ DB](Concepts.DBInstanceClass.md). Untuk menentukan kelas instans DB yang setara dengan jenis instans Amazon EC2, tempatkan `db.` sebelum nama jenis instans Amazon EC2. Misalnya, instans Amazon EC2 `r5.8xlarge` setara dengan kelas instans DB `db.r5.8xlarge`.

### Kurangi jumlah data yang dikirim ke klien Anda
<a name="wait-event.clientwrite.actions.reduce-data"></a>

Jika memungkinkan, sesuaikan aplikasi Anda untuk mengurangi jumlah data yang dikirim instans DB RDS for PostgreSQL ke klien. Penyesuaian ini akan mengurangi pertentangan CPU dan jaringan pada klien.

### Skalakan klien Anda
<a name="wait-event.clientwrite.actions.scale-client"></a>

Menggunakan Amazon CloudWatch atau metrik host lainnya, tentukan apakah klien Anda saat ini dibatasi oleh CPU atau bandwidth jaringan, atau keduanya. Jika klien dibatasi, skalakan klien sesuai yang diperlukan.

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

Peristiwa ini terjadi saat thread aktif di CPU atau sedang menunggu CPU.

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.cpu.context.supported)
+ [

## Konteks
](#wait-event.cpu.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.cpu.causes)
+ [

## Tindakan
](#wait-event.cpu.actions)

## Versi mesin yang didukung
<a name="wait-event.cpu.context.supported"></a>

Informasi peristiwa tunggu ini relevan untuk semua versi RDS for PostgreSQL.

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

*Central Processing Unit (CPU)* adalah komponen komputer yang menjalankan petunjuk. Misalnya, petunjuk CPU melakukan operasi aritmetika dan bertukar data dalam memori. Jika kueri meningkatkan jumlah petunjuk yang dilakukannya melalui mesin basis data, waktu yang dihabiskan untuk menjalankan kueri akan meningkat. *Penjadwalan CPU* memberikan waktu CPU untuk suatu proses. Penjadwalan diatur oleh kernel sistem operasi.

**Topics**
+ [

### Bagaimana cara mengetahui kapan peristiwa tunggu ini terjadi?
](#wait-event.cpu.when-it-occurs)
+ [

### DBLoadMetrik CPU
](#wait-event.cpu.context.dbloadcpu)
+ [

### Metrik os.cpuUtilization
](#wait-event.cpu.context.osmetrics)
+ [

### Kemungkinan penyebab penjadwalan CPU
](#wait-event.cpu.context.scheduling)

### Bagaimana cara mengetahui kapan peristiwa tunggu ini terjadi?
<a name="wait-event.cpu.when-it-occurs"></a>

Peristiwa tunggu `CPU` ini menunjukkan bahwa proses backend aktif di CPU atau sedang menunggu CPU. Anda mengetahuinya terjadi saat kueri menunjukkan informasi berikut:
+ Kolom `pg_stat_activity.state` memiliki nilai `active`.
+ Kolom `wait_event_type` dan `wait_event` di `pg_stat_activity` adalah `null`.

Untuk melihat proses backend yang menggunakan atau menunggu CPU, jalankan kueri berikut.

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

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

Metrik Wawasan Performa untuk CPU adalah `DBLoadCPU`. Nilai untuk `DBLoadCPU` dapat berbeda dari nilai untuk CloudWatch metrik Amazon`CPUUtilization`. Metrik terakhir dikumpulkan dari HyperVisor untuk instance database.

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

Metrik sistem operasi Wawasan Performa memberikan informasi terperinci tentang pemanfaatan CPU. Misalnya, Anda dapat menampilkan metrik berikut:
+ `os.cpuUtilization.nice.avg`
+ `os.cpuUtilization.total.avg`
+ `os.cpuUtilization.wait.avg`
+ `os.cpuUtilization.idle.avg`

Wawasan Performa melaporkan penggunaan CPU oleh mesin basis data sebagai `os.cpuUtilization.nice.avg`.

### Kemungkinan penyebab penjadwalan CPU
<a name="wait-event.cpu.context.scheduling"></a>

 Kernel sistem operasi (OS) menangani penjadwalan untuk CPU. Ketika CPU *aktif*, sebuah proses mungkin perlu menunggu untuk dijadwalkan. CPU aktif saat melakukan penghitungan. Ini juga aktif saat memiliki utas idle yang tidak berjalan, yaitu, utas idle yang menunggu memori I/O. This type of I/O mendominasi beban kerja database yang khas. 

Proses cenderung menunggu untuk dijadwalkan pada CPU saat kondisi berikut terpenuhi:
+  CloudWatch `CPUUtilization`Metriknya mendekati 100 persen.
+ Beban rata-rata lebih besar dari jumlah vCPUs, menunjukkan beban berat. Anda dapat menemukan metrik `loadAverageMinute` di bagian metrik OS dalam Wawasan Performa.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.cpu.causes"></a>

Saat peristiwa tunggu CPU terjadi lebih dari biasanya, yang mungkin menunjukkan adanya masalah performa, berikut adalah penyebab umumnya:

**Topics**
+ [

### Kemungkinan penyebab lonjakan mendadak
](#wait-event.cpu.causes.spikes)
+ [

### Kemungkinan penyebab frekuensi tinggi jangka panjang
](#wait-event.cpu.causes.long-term)
+ [

### Corner cases
](#wait-event.cpu.causes.corner-cases)

### Kemungkinan penyebab lonjakan mendadak
<a name="wait-event.cpu.causes.spikes"></a>

Penyebab lonjakan mendadak yang paling memungkinkan adalah sebagai berikut:
+ Aplikasi Anda membuka terlalu banyak koneksi bersamaan ke basis data. Skenario ini dikenal sebagai "connection storm".
+ Beban kerja aplikasi Anda berubah dengan salah satu cara berikut:
  + Kueri baru
  + Peningkatan ukuran set data
  + Pemeliharaan atau pembuatan indeks
  + Fungsi baru
  + Operator baru
  + Peningkatan eksekusi kueri paralel
+ Rencana eksekusi kueri Anda telah berubah. Dalam beberapa kasus, perubahan dapat menyebabkan peningkatan buffer. Misalnya, kueri sekarang menggunakan pemindaian berurutan saat sebelumnya menggunakan indeks. Dalam hal ini, kueri membutuhkan lebih banyak CPU untuk mencapai tujuan yang sama.

### Kemungkinan penyebab frekuensi tinggi jangka panjang
<a name="wait-event.cpu.causes.long-term"></a>

Berikut adalah penyebab paling memungkinkan dari peristiwa yang berulang dalam jangka waktu lama:
+ Terlalu banyak proses backend yang berjalan secara konkuren pada CPU. Proses-proses ini dapat berupa pekerja paralel.
+ Kueri beperforma suboptimal karena membutuhkan buffer dalam jumlah besar.

### Corner cases
<a name="wait-event.cpu.causes.corner-cases"></a>

Jika tidak ada kemungkinan penyebab yang merupakan penyebab sebenarnya, situasi berikut mungkin terjadi:
+ CPU menukar proses masuk dan keluar.
+ CPU mungkin mengelola entri tabel halaman jika fitur *huge page* telah dinonaktifkan. Fitur manajemen memori ini diaktifkan secara default untuk semua kelas instans DB selain kelas instans DB mikro, kecil, dan menengah. Untuk informasi selengkapnya, lihat [Halaman besar untuk RDS for PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.HugePages.md). 

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

Jika peristiwa tunggu `CPU` mendominasi aktivitas basis data, hal tersebut tidak selalu menunjukkan adanya masalah performa. Tanggapi peristiwa ini hanya saat performa menurun.

**Topics**
+ [

### Selidiki apakah basis data menyebabkan peningkatan CPU
](#wait-event.cpu.actions.db-CPU)
+ [

### Tentukan apakah jumlah koneksi meningkat
](#wait-event.cpu.actions.connections)
+ [

### Tanggapi perubahan beban kerja
](#wait-event.cpu.actions.workload)

### Selidiki apakah basis data menyebabkan peningkatan CPU
<a name="wait-event.cpu.actions.db-CPU"></a>

Periksa metrik `os.cpuUtilization.nice.avg` dalam Wawasan Performa. Jika nilai ini jauh lebih kecil daripada penggunaan CPU, proses non-basis data adalah kontributor utama ke CPU.

### Tentukan apakah jumlah koneksi meningkat
<a name="wait-event.cpu.actions.connections"></a>

Periksa `DatabaseConnections` metrik di Amazon CloudWatch. Tindakan Anda bergantung pada apakah jumlahnya meningkat atau menurun selama periode peningkatan peristiwa tunggu CPU.

#### Koneksi meningkat
<a name="wait-event.cpu.actions.connections.increased"></a>

Jika jumlah koneksi naik, bandingkan jumlah proses backend yang mengkonsumsi CPU dengan jumlah v. CPUs Skenario berikut dimungkinkan:
+ Jumlah proses backend yang mengkonsumsi CPU kurang dari jumlah v. CPUs

  Dalam hal ini, jumlah koneksi tidak menjadi masalah. Namun, Anda masih dapat mencoba mengurangi pemanfaatan CPU.
+ Jumlah proses backend yang mengkonsumsi CPU lebih besar dari jumlah v. CPUs

  Jika demikian, pertimbangkan opsi berikut:
  + Kurangi jumlah proses backend yang terhubung ke basis data Anda. Misalnya, terapkan solusi pooling koneksi seperti Proksi RDS. Untuk mempelajari selengkapnya, lihat [Proksi Amazon RDS Aurora](rds-proxy.md).
  + Tingkatkan ukuran instans Anda untuk mendapatkan jumlah v yang lebih tinggiCPUs.
  + Jika berlaku, arahkan ulang beberapa beban kerja hanya-baca ke simpul pembaca.

#### Koneksi tidak meningkat
<a name="wait-event.cpu.actions.connections.decreased"></a>

Periksa metrik `blks_hit` dalam Wawasan Performa. Cari korelasi antara peningkatan `blks_hit` dan penggunaan CPU. Skenario berikut mungkin terjadi:
+ Penggunaan CPU dan `blks_hit` berkorelasi.

  Dalam hal ini, temukan pernyataan SQL teratas yang terkait dengan penggunaan CPU, lalu cari perubahan rencana. Anda dapat menggunakan salah satu teknik berikut:
  + Jelaskan rencana secara manual, lalu bandingkan dengan rencana eksekusi yang diperkirakan.
  + Cari peningkatan hit blok per detik dan hit blok lokal per detik. Di bagian **SQL Teratas** pada dasbor Wawasan Performa, pilih **Preferensi**.
+ Penggunaan CPU dan `blks_hit` tidak berkorelasi.

  Jika demikian, ketahui apakah salah satu hal berikut terjadi:
  + Aplikasi dengan cepat terhubung ke dan terputus dari basis data. 

    Jalankan diagnosis perilaku ini dengan mengaktifkan `log_connections` dan `log_disconnections`, lalu menganalisis log PostgreSQL. Pertimbangkan untuk menggunakan penganalisis log `pgbadger`. Untuk informasi selengkapnya, lihat [https://github.com/darold/pgbadger](https://github.com/darold/pgbadger).
  + OS kelebihan beban.

    Dalam hal ini, Wawasan Performa menunjukkan bahwa proses backend menggunakan CPU untuk waktu yang lebih lama dari biasanya. Cari bukti di metrik Performance Insights atau `os.cpuUtilization` metrik. CloudWatch `CPUUtilization` Jika sistem operasi kelebihan beban, lihat metrik Pemantauan yang Ditingkatkan untuk mendiagnosis lebih lanjut. Secara khusus, lihat daftar proses dan persentase CPU yang dikonsumsi oleh setiap proses.
  + Pernyataan SQL teratas mengonsumsi terlalu banyak CPU.

    Periksa pernyataan yang terkait dengan penggunaan CPU untuk melihat apakah pernyataan tersebut dapat menggunakan lebih sedikit CPU. Jalankan perintah `EXPLAIN`, lalu fokus pada simpul rencana yang memiliki dampak terbesar. Pertimbangkan untuk menggunakan pemvisualisasi rencana eksekusi PostgreSQL. Untuk mencoba alat ini, lihat [http://explain.dalibo.com/](http://explain.dalibo.com/).

### Tanggapi perubahan beban kerja
<a name="wait-event.cpu.actions.workload"></a>

Jika beban kerja Anda telah berubah, cari jenis perubahan berikut:

Kueri baru  
Periksa apakah kueri baru memang diharapkan. Jika demikian, pastikan bahwa rencana eksekusinya dan jumlah eksekusi per detik memang diharapkan.

Peningkatan ukuran set data  
Ketahui apakah pemartisian, jika belum diterapkan, dapat membantu. Strategi ini dapat mengurangi jumlah halaman yang perlu diambil kueri.

Pemeliharaan atau pembuatan indeks  
Periksa apakah jadwal pemeliharaan memang diharapkan. Praktik terbaiknya adalah menjadwalkan aktivitas pemeliharaan di luar aktivitas puncak.

Fungsi baru  
Periksa apakah fungsi-fungsi ini berfungsi seperti yang diharapkan selama pengujian. Secara khusus, periksa apakah jumlah eksekusi per detik memang diharapkan.

Operator baru  
Periksa apakah operator baru berfungsi seperti yang diharapkan selama pengujian.

Peningkatan dalam menjalankan kueri paralel  
Ketahui apakah salah satu situasi berikut telah terjadi:  
+ Relasi atau indeks yang terkait tiba-tiba bertambah ukurannya sehingga sangat berbeda dari `min_parallel_table_scan_size` atau `min_parallel_index_scan_size`.
+ Perubahan terkini telah dilakukan pada `parallel_setup_cost` atau `parallel_tuple_cost`.
+ Perubahan terkini telah dilakukan pada `max_parallel_workers` atau `max_parallel_workers_per_gather`.

# IO: BufFileRead dan IO: BufFileWrite
<a name="wait-event.iobuffile"></a>

Peristiwa `IO:BufFileRead` dan `IO:BufFileWrite` terjadi ketika RDS for PostgreSQL membuat file sementara. Saat operasi membutuhkan lebih banyak memori daripada yang saat ini ditentukan oleh parameter memori kerja, operasi ini akan menulis data sementara ke penyimpanan persisten. Operasi ini kadang-kadang disebut *tumpah ke disk*. Untuk informasi selengkapnya tentang file sementara dan penggunaannya, lihat[Mengelola file sementara dengan PostgreSQL](PostgreSQL.ManagingTempFiles.md).

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.iobuffile.context.supported)
+ [

## Konteks
](#wait-event.iobuffile.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.iobuffile.causes)
+ [

## Tindakan
](#wait-event.iobuffile.actions)

## Versi mesin yang didukung
<a name="wait-event.iobuffile.context.supported"></a>

Informasi peristiwa tunggu ini didukung untuk semua versi RDS for PostgreSQL.

## Konteks
<a name="wait-event.iobuffile.context"></a>

`IO:BufFileRead` dan `IO:BufFileWrite` berkaitan dengan area memori kerja dan area memori kerja pemeliharaan. Untuk informasi selengkapnya tentang penyetelan memori, lihat [Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html) dalam dokumentasi PostgreSQL.

Nilai default untuk `work_mem` adalah 4 MB. Jika satu sesi melakukan operasi secara paralel, setiap pekerja yang menangani paralelisme ini akan menggunakan memori 4 MB. Untuk alasan ini, atur `work_mem` dengan hati-hati. Jika Anda meningkatkan nilai ini terlalu banyak, basis data yang menjalankan banyak sesi mungkin akan mengonsumsi terlalu banyak memori. Jika Anda menetapkan nilai terlalu rendah, Aurora PostgreSQL akan membuat file sementara di penyimpanan lokal. Disk I/O untuk file-file sementara ini dapat mengurangi kinerja.

Jika Anda mengamati urutan peristiwa berikut, basis data mungkin menghasilkan file sementara:

1. Penurunan ketersediaan secara tiba-tiba dan drastis

1. Pemulihan cepat untuk ruang kosong

Anda mungkin juga melihat pola "gergaji". Pola ini dapat menunjukkan bahwa basis data Anda membuat file kecil terus-menerus.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.iobuffile.causes"></a>

Secara umum, peristiwa tunggu ini disebabkan oleh operasi yang mengonsumsi lebih banyak memori daripada yang dialokasikan oleh parameter `work_mem` atau `maintenance_work_mem`. Untuk mengompensasi, operasi menulis ke file sementara. Penyebab umum peristiwa `IO:BufFileRead` dan `IO:BufFileWrite` mencakup hal berikut:

**Kueri yang membutuhkan lebih banyak memori daripada yang ada di area memori kerja**  
Kueri dengan karakteristik berikut menggunakan area memori kerja:  
+ Hash join
+ Klausa `ORDER BY`
+ Klausa `GROUP BY`
+ `DISTINCT`
+ Fungsi jendela
+ `CREATE TABLE AS SELECT`
+ Penyegaran tampilan terwujud

**Pernyataan yang membutuhkan lebih banyak memori daripada yang ada di area memori kerja pemeliharaan**  
Pernyataan berikut menggunakan area memori kerja pemeliharaan:  
+ `CREATE INDEX`
+ `CLUSTER`

## Tindakan
<a name="wait-event.iobuffile.actions"></a>

Kami merekomendasikan berbagai tindakan, tergantung pada penyebab peristiwa tunggu Anda.

**Topics**
+ [

### Identifikasi masalah
](#wait-event.iobuffile.actions.problem)
+ [

### Periksa kueri join
](#wait-event.iobuffile.actions.joins)
+ [

### Periksa kueri ORDER BY dan GROUP BY
](#wait-event.iobuffile.actions.order-by)
+ [

### Hindari menggunakan operasi DISTINCT
](#wait-event.iobuffile.actions.distinct)
+ [

### Mempertimbangkan untuk menggunakan fungsi jendela alih-alih fungsi GROUP BY
](#wait-event.iobuffile.actions.window)
+ [

### Selidiki tampilan terwujud dan pernyataan CTAS
](#wait-event.iobuffile.actions.mv-refresh)
+ [

### Gunakan pg\$1repack saat Anda membuat kembali indeks
](#wait-event.iobuffile.actions.pg_repack)
+ [

### Tingkatkan maintenance\$1work\$1mem saat Anda membuat klaster tabel
](#wait-event.iobuffile.actions.cluster)
+ [

### Tune memori untuk mencegah IO: BufFileRead dan IO: BufFileWrite
](#wait-event.iobuffile.actions.tuning-memory)

### Identifikasi masalah
<a name="wait-event.iobuffile.actions.problem"></a>

Anda dapat melihat penggunaan file sementara secara langsung di Performance Insights. Untuk informasi selengkapnya, lihat [Melihat penggunaan file sementara dengan Performance Insights](PostgreSQL.ManagingTempFiles.Example.md). Jika Performance Insights dinonaktifkan, Anda mungkin melihat peningkatan `IO:BufFileRead` dan `IO:BufFileWrite` operasi.

Untuk mengidentifikasi sumber masalahnya, Anda dapat mengatur parameter `log_temp_files` untuk mencatat log semua kueri yang menghasilkan file sementara lebih dari ambang batas KB yang Anda tentukan. Secara default, `log_temp_files` diatur ke `-1`, yang menonaktifkan fitur pencatatan log ini. Jika Anda mengatur parameter ini ke `0`, RDS for PostgreSQL mencatat log semua file sementara. Jika nilainya `1024`, Aurora PostgreSQL mencatat semua kueri yang menghasilkan file sementara yang berukuran lebih besar dari 1 MB. Untuk informasi selengkapnya tentang `log_temp_files`, lihat [Error Reporting and Logging](https://www.postgresql.org/docs/current/runtime-config-logging.html) dalam dokumentasi PostgreSQL.

### Periksa kueri join
<a name="wait-event.iobuffile.actions.joins"></a>

Kemungkinan kueri Anda menggunakan join. Misalnya, kueri berikut menggabungkan empat tabel.

```
SELECT * 
       FROM "order" 
 INNER JOIN order_item 
       ON (order.id = order_item.order_id)
 INNER JOIN customer 
       ON (customer.id = order.customer_id)
 INNER JOIN customer_address 
       ON (customer_address.customer_id = customer.id AND 
           order.customer_address_id = customer_address.id)
 WHERE customer.id = 1234567890;
```

Kemungkinan penyebab lonjakan penggunaan file sementara adalah masalah dalam kueri itu sendiri. Misalnya, klausa yang rusak mungkin tidak memfilter join dengan benar. Pertimbangkan inner join kedua dalam contoh berikut.

```
SELECT * 
       FROM "order"
 INNER JOIN order_item 
       ON (order.id = order_item.order_id)
 INNER JOIN customer 
       ON (customer.id = customer.id)
 INNER JOIN customer_address 
       ON (customer_address.customer_id = customer.id AND 
           order.customer_address_id = customer_address.id)
 WHERE customer.id = 1234567890;
```

Kueri sebelumnya secara keliru menggabungkan `customer.id` ke `customer.id`, sehingga memberikan hasil perkalian Cartesian antara setiap pelanggan dan setiap pesanan. Jenis join yang tak terduga ini menghasilkan file sementara yang besar. Tergantung pada ukuran tabel, kueri Cartesian bahkan dapat memenuhi penyimpanan. Aplikasi Anda dapat memiliki join Cartesian jika kondisi berikut terpenuhi:
+ Anda melihat penurunan besar dan drastis dalam ketersediaan penyimpanan, yang diikuti oleh pemulihan cepat.
+ Tidak ada indeks yang dibuat.
+ Tidak ada pernyataan `CREATE TABLE FROM SELECT` yang dikeluarkan.
+ Tidak ada tampilan terwujud yang disegarkan.

Untuk melihat apakah tabel sedang digabungkan menggunakan kunci yang tepat, periksa kueri dan petunjuk pemetaan relasional objek Anda. Perlu diperhatikan bahwa kueri tertentu dari aplikasi Anda tidak dipanggil sepanjang waktu, dan beberapa kueri dihasilkan secara dinamis.

### Periksa kueri ORDER BY dan GROUP BY
<a name="wait-event.iobuffile.actions.order-by"></a>

Dalam beberapa kasus, klausa `ORDER BY` dapat menghasilkan file sementara yang berlebihan. Pertimbangkan panduan berikut ini:
+ Hanya sertakan kolom dalam klausa `ORDER BY` saat kolom tersebut perlu diurutkan. Pedoman ini sangat penting untuk kueri yang menampilkan ribuan baris dan menentukan banyak kolom dalam klausa `ORDER BY`.
+ Pertimbangkan untuk membuat indeks guna mempercepat klausa `ORDER BY` saat klausa cocok dengan kolom yang memiliki urutan naik atau turun yang sama. Indeks sebagian lebih direkomendasikan karena lebih kecil. Indeks yang lebih kecil lebih cepat untuk dibaca dan di-traverse.
+ Jika Anda membuat indeks untuk kolom yang dapat menerima nilai kosong, pertimbangkan apakah Anda ingin nilai kosong disimpan di akhir atau di awal indeks.

  Jika memungkinkan, kurangi jumlah baris yang perlu diurutkan dengan memfilter set hasil. Jika Anda menggunakan pernyataan klausa atau subkueri `WITH`, perlu diperhatikan bahwa kueri dalam menghasilkan set hasil, lalu meneruskannya ke kueri luar. Semakin banyak baris yang dapat difilter kueri, semakin sedikit pengurutan yang perlu dilakukan kueri.
+ Jika Anda tidak perlu mendapatkan set hasil lengkap, gunakan klausa `LIMIT`. Misalnya, jika Anda hanya menginginkan lima baris teratas, kueri yang menggunakan klausa `LIMIT` tidak akan terus memberikan hasil. Dengan cara ini, kueri membutuhkan lebih sedikit memori dan file sementara.

Kueri yang menggunakan klausa `GROUP BY` juga dapat memerlukan file sementara. Kueri `GROUP BY` meringkas nilai dengan menggunakan fungsi seperti berikut:
+ `COUNT`
+ `AVG`
+ `MIN`
+ `MAX`
+ `SUM`
+ `STDDEV`

Untuk menyetel kueri `GROUP BY`, ikuti rekomendasi untuk kueri `ORDER BY`.

### Hindari menggunakan operasi DISTINCT
<a name="wait-event.iobuffile.actions.distinct"></a>

Jika memungkinkan, jangan gunakan operasi `DISTINCT` untuk menghapus baris duplikat. Semakin banyak baris duplikat yang tidak perlu, yang ditampilkan oleh kueri Anda, operasi `DISTINCT` menjadi semakin mahal. Jika memungkinkan, tambahkan filter dalam klausa `WHERE` meskipun Anda menggunakan filter yang sama untuk tabel yang berbeda. Memfilter kueri dan melakukan join dengan benar akan meningkatkan performa Anda serta mengurangi penggunaan sumber daya. Hal tersebut juga mencegah laporan dan hasil yang salah.

Jika Anda perlu menggunakan `DISTINCT` untuk beberapa baris dari tabel yang sama, pertimbangkan untuk membuat indeks komposit. Mengelompokkan beberapa kolom dalam indeks dapat meningkatkan waktu untuk mengevaluasi baris yang berbeda. Selain itu, jika Anda menggunakan RDS for PostgreSQL versi 10 atau lebih tinggi, Anda dapat mengorelasikan statistik di antara beberapa kolom dengan menggunakan perintah `CREATE STATISTICS`.

### Mempertimbangkan untuk menggunakan fungsi jendela alih-alih fungsi GROUP BY
<a name="wait-event.iobuffile.actions.window"></a>

Dengan menggunakan `GROUP BY`, Anda mengubah set hasil, lalu mengambil hasil agregat. Dengan menggunakan fungsi jendela, Anda mengumpulkan data tanpa mengubah set hasil. Fungsi jendela menggunakan klausa `OVER` untuk melakukan penghitungan di seluruh set yang ditentukan oleh kueri, dengan mengorelasikan satu baris dengan yang lain. Anda dapat menggunakan semua fungsi `GROUP BY` dalam fungsi jendela, tetapi juga menggunakan fungsi seperti berikut:
+ `RANK`
+ `ARRAY_AGG`
+ `ROW_NUMBER`
+ `LAG`
+ `LEAD`

Untuk meminimalkan jumlah file sementara yang dihasilkan oleh fungsi jendela, hapus duplikasi untuk set hasil yang sama saat Anda membutuhkan dua agregasi yang berbeda. Pertimbangkan kueri berikut.

```
SELECT sum(salary) OVER (PARTITION BY dept ORDER BY salary DESC) as sum_salary
     , avg(salary) OVER (PARTITION BY dept ORDER BY salary ASC) as avg_salary
  FROM empsalary;
```

Anda dapat menulis ulang kueri dengan klausa `WINDOW` sebagai berikut:

```
SELECT sum(salary) OVER w as sum_salary
         , avg(salary) OVER w as_avg_salary
    FROM empsalary
  WINDOW w AS (PARTITION BY dept ORDER BY salary DESC);
```

Secara default, perencana eksekusi Aurora PostgreSQL menggabungkan simpul yang serupa, sehingga tidak menggandakan operasi. Namun, dengan menggunakan deklarasi eksplisit untuk blok jendela, Anda dapat mengelola kueri dengan lebih mudah. Anda juga dapat meningkatkan performa dengan mencegah duplikasi.

### Selidiki tampilan terwujud dan pernyataan CTAS
<a name="wait-event.iobuffile.actions.mv-refresh"></a>

Saat tampilan terwujud disegarkan, kueri akan dijalankan. Kueri ini dapat berisi operasi seperti `GROUP BY`, `ORDER BY`, atau `DISTINCT`. Selama penyegaran, Anda mungkin mengamati sejumlah besar file sementara serta peristiwa tunggu `IO:BufFileWrite` dan `IO:BufFileRead`. Demikian pula, saat Anda membuat tabel berdasarkan pernyataan `SELECT`, pernyataan `CREATE TABLE` tersebut menjalankan kueri. Untuk mengurangi file sementara yang dibutuhkan, optimalkan kueri.

### Gunakan pg\$1repack saat Anda membuat kembali indeks
<a name="wait-event.iobuffile.actions.pg_repack"></a>

Saat Anda membuat indeks, mesin mengurutkan set hasil. Seiring tabel bertambah besar, dan seiring nilai di kolom yang diindeks menjadi lebih beragam, file sementara membutuhkan lebih banyak ruang. Dalam kebanyakan kasus, Anda tidak dapat mencegah pembuatan file sementara untuk tabel besar tanpa memodifikasi area memori kerja pemeliharaan. Untuk informasi selengkapnya tentang `maintenance_work_mem`, lihat [https://www.postgresql.org/docs/current/runtime-config-resource.html](https://www.postgresql.org/docs/current/runtime-config-resource.html) dalam dokumentasi PostgreSQL. 

Solusi yang mungkin saat membuat ulang indeks besar adalah dengan menggunakan ekstensi pg\$1repack. Untuk informasi selengkapnya, lihat [Reorganize tables in PostgreSQL databases with minimal locks](https://reorg.github.io/pg_repack/) dalam dokumentasi pg\$1repack. Untuk informasi tentang menyiapkan ekstensi di instans DB RDS for PostgreSQL Anda, lihat [Mengurangi bloat dalam tabel dan indeks dengan ekstensi pg\$1repack](Appendix.PostgreSQL.CommonDBATasks.pg_repack.md). 

### Tingkatkan maintenance\$1work\$1mem saat Anda membuat klaster tabel
<a name="wait-event.iobuffile.actions.cluster"></a>

Perintah `CLUSTER` membuat klaster tabel yang ditentukan menurut *table\$1name* berdasarkan indeks yang ada yang ditentukan menurut *index\$1name*. RDS for PostgreSQL secara fisik membuat ulang tabel agar sesuai dengan urutan indeks yang diberikan.

Saat penyimpanan magnetik lazim digunakan, pembuatan klaster menjadi umum dilakukan karena throughput penyimpanan terbatas. Sekarang penyimpanan berbasis SSD sudah umum, sehingga pembuatan klaster menjadi kurang populer. Namun, jika Anda membuat klaster tabel, Anda masih dapat sedikit meningkatkan performa tergantung pada ukuran tabel, indeks, kueri, dan banyak lagi. 

Jika Anda menjalankan perintah `CLUSTER` dan mengamati peristiwa tunggu `IO:BufFileWrite` dan `IO:BufFileRead`, setel `maintenance_work_mem`. Tingkatkan ukuran memori ke jumlah yang cukup besar. Nilai tinggi berarti mesin dapat menggunakan lebih banyak memori untuk operasi klaster.

### Tune memori untuk mencegah IO: BufFileRead dan IO: BufFileWrite
<a name="wait-event.iobuffile.actions.tuning-memory"></a>

Dalam beberapa situasi, Anda perlu menyetel memori. Tujuan Anda adalah menyeimbangkan memori di seluruh area konsumsi berikut menggunakan parameter yang sesuai, sebagai berikut.
+ Nilai `work_mem` 
+ Memori yang tersisa setelah mengecualikan nilai `shared_buffers`
+ Koneksi maksimum yang dibuka dan digunakan, yang dibatasi oleh `max_connections`

Untuk informasi selengkapnya tentang penyetelan memori, lihat [Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html) dalam dokumentasi PostgreSQL. 

#### Tingkatkan ukuran area memori kerja
<a name="wait-event.iobuffile.actions.tuning-memory.work-mem"></a>

Dalam beberapa situasi, satu-satunya pilihan adalah menambah memori yang digunakan oleh sesi Anda. Jika kueri Anda ditulis dengan benar dan menggunakan kunci yang benar untuk join, pertimbangkan untuk meningkatkan nilai `work_mem`. 

Untuk mengetahui jumlah file sementara yang dihasilkan kueri, atur `log_temp_files` ke `0`. Jika meningkatkan nilai `work_mem` ke nilai maksimum yang diidentifikasi dalam log, Anda mencegah kueri menghasilkan file sementara. Namun, `work_mem` menetapkan nilai maksimum per simpul rencana untuk setiap koneksi atau pekerja paralel. Jika basis data memiliki 5.000 koneksi, dan jika masing-masing menggunakan memori 256 MiB, mesin akan membutuhkan RAM 1,2 TiB. Oleh karena itu, instans Anda dapat kehabisan memori.

#### Cadangkan memori yang cukup untuk pool buffer bersama
<a name="wait-event.iobuffile.actions.tuning-memory.shared-pool"></a>

Basis data Anda menggunakan area memori seperti pool buffer bersama, bukan hanya area memori kerja. Pertimbangkan persyaratan area memori tambahan ini sebelum Anda meningkatkan `work_mem`.

Misalnya, anggaplah kelas instans Aurora PostgreSQL Anda adalah db.r5.2xlarge. Kelas ini memiliki memori 64 GiB. Secara default, 25 persen memori dicadangkan untuk pool buffer bersama. Setelah Anda mengurangi jumlah yang dialokasikan ke area memori bersama, 16.384 MB tetap ada. Jangan mengalokasikan memori yang tersisa hanya ke area memori kerja karena sistem operasi dan mesin juga memerlukan memori.

Memori yang dapat Anda alokasikan ke `work_mem` tergantung pada kelas instans. Jika Anda menggunakan kelas instans yang lebih besar, memori yang tersedia akan lebih banyak. Namun, dalam contoh sebelumnya, Anda tidak dapat menggunakan lebih dari 16 GiB. Jika melakukannya, instans Anda menjadi tidak tersedia saat kehabisan memori. Untuk memulihkan instans dari status tidak tersedia, layanan otomatisasi PostgreSQL Aurora secara otomatis dimulai ulang.

#### Kelola jumlah koneksi
<a name="wait-event.iobuffile.actions.tuning-memory.connections"></a>

Misalnya, instans basis data Anda memiliki 5.000 koneksi simultan. Setiap koneksi menggunakan setidaknya 4 MiB `work_mem`. Konsumsi memori yang tinggi dari koneksi cenderung menurunkan performa. Untuk mengatasinya, Anda memiliki opsi berikut:
+ Tingkatkan ke kelas instans yang lebih besar.
+ Kurangi jumlah koneksi basis data simultan dengan menggunakan proksi atau pooler koneksi.

Untuk proksi, pertimbangkan Proksi Amazon RDS, pgBouncer, atau pooler koneksi berdasarkan aplikasi Anda. Solusi ini mengurangi beban CPU. Solusi ini juga mengurangi risiko saat semua koneksi memerlukan area memori kerja. Saat koneksi basis data lebih sedikit, Anda dapat meningkatkan nilai `work_mem`. Dengan cara ini, Anda mengurangi munculnya peristiwa tunggu `IO:BufFileRead` dan `IO:BufFileWrite`. Selain itu, kueri yang menunggu area memori kerja akan dipercepat secara signifikan.

# IO: DataFileRead
<a name="wait-event.iodatafileread"></a>

Peristiwa `IO:DataFileRead` terjadi saat koneksi menunggu proses backend untuk membaca halaman yang diperlukan dari penyimpanan karena halaman tidak tersedia dalam memori bersama.

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.iodatafileread.context.supported)
+ [

## Konteks
](#wait-event.iodatafileread.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.iodatafileread.causes)
+ [

## Tindakan
](#wait-event.iodatafileread.actions)

## Versi mesin yang didukung
<a name="wait-event.iodatafileread.context.supported"></a>

Informasi peristiwa tunggu ini didukung untuk semua versi RDS for PostgreSQL.

## Konteks
<a name="wait-event.iodatafileread.context"></a>

Semua kueri dan operasi manipulasi data (DML) mengakses halaman di pool buffer. Pernyataan yang dapat menimbulkan pembacaan mencakup `SELECT`, `UPDATE`, dan `DELETE`. Misalnya, `UPDATE` dapat membaca halaman dari tabel atau indeks. Jika halaman yang diminta atau diperbarui tidak berada dalam pool buffer bersama, pembacaan ini dapat mengarah ke peristiwa `IO:DataFileRead`.

Karena bersifat terbatas, pool buffer bersama dapat diisi. Dalam hal ini, permintaan untuk halaman yang tidak berada dalam memori memaksa basis data untuk membaca blok dari disk. Jika peristiwa `IO:DataFileRead` sering terjadi, pool buffer bersama mungkin terlalu kecil untuk mengakomodasi beban kerja Anda. Masalah ini bersifat akut untuk kueri `SELECT` yang membaca sejumlah besar baris yang tidak dapat ditampung pool buffer. Untuk informasi selengkapnya tentang pool buffer, lihat [Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html) dalam dokumentasi PostgreSQL.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.iodatafileread.causes"></a>

Penyebab umum peristiwa `IO:DataFileRead` tersebut mencakup:

**Lonjakan koneksi**  
Anda mungkin menemukan beberapa koneksi yang menghasilkan jumlah acara IO: DataFileRead wait yang sama. Dalam hal ini, lonjakan (peningkatan tiba-tiba dan besar) dalam peristiwa `IO:DataFileRead` dapat terjadi. 

**Pernyataan SELECT dan DML yang melakukan pemindaian berurutan**  
Aplikasi Anda mungkin melakukan operasi baru. Operasi yang ada mungkin juga berubah karena rencana eksekusi baru. Dalam kasus ini, cari tabel (terutama tabel besar) yang memiliki nilai `seq_scan` yang lebih besar. Temukan tabel dengan membuat kueri `pg_stat_user_tables`. Untuk melacak kueri yang menghasilkan lebih banyak operasi baca, gunakan ekstensi `pg_stat_statements`.

**CTAS dan CREATE INDEX untuk set data besar**  
*CTAS* adalah sebuah pernyataan `CREATE TABLE AS SELECT`. Jika Anda menjalankan CTAS menggunakan set data besar sebagai sumber, atau membuat indeks pada tabel besar, maka peristiwa `IO:DataFileRead` dapat terjadi. Saat Anda membuat indeks, basis data mungkin perlu membaca seluruh objek menggunakan pemindaian berurutan. CTAS menghasilkan pembacaan `IO:DataFile` saat halaman tidak ada dalam memori.

**Beberapa pekerja vakum berjalan pada waktu yang sama**  
Pekerja vakum dapat dipicu secara manual atau otomatis. Sebaiknya adopsi strategi vakum yang agresif. Namun, saat tabel memiliki banyak baris yang diperbarui atau dihapus, peristiwa tunggu `IO:DataFileRead` bertambah. Setelah ruang direklamasi, waktu vakum yang dihabiskan untuk `IO:DataFileRead` akan berkurang.

**Menyerap data dalam jumlah besar**  
Saat aplikasi Anda menyerap data dalam jumlah besar, operasi `ANALYZE` mungkin terjadi lebih sering. Proses `ANALYZE` dapat dipicu oleh peluncur autovacuum atau diinvokasi secara manual.  
Operasi `ANALYZE` membaca subset dari tabel. Jumlah halaman yang harus dipindai dihitung menggunakan perkalian 30 dengan nilai `default_statistics_target`. Untuk informasi selengkapnya, lihat [Dokumentasi PostgreSQL](https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET). Parameter `default_statistics_target` menerima nilai antara 1 hingga 10.000, dengan nilai default adalah 100.

**Kekurangan sumber daya**  
Jika bandwidth jaringan instans atau CPU dikonsumsi, peristiwa `IO:DataFileRead` mungkin terjadi lebih sering.

## Tindakan
<a name="wait-event.iodatafileread.actions"></a>

Kami merekomendasikan berbagai tindakan, tergantung pada penyebab peristiwa tunggu Anda.

**Topics**
+ [

### Memeriksa filter predikat untuk kueri yang menghasilkan peristiwa tunggu
](#wait-event.iodatafileread.actions.filters)
+ [

### Meminimalkan efek operasi pemeliharaan
](#wait-event.iodatafileread.actions.maintenance)
+ [

### Merespons jumlah koneksi yang tinggi
](#wait-event.iodatafileread.actions.connections)

### Memeriksa filter predikat untuk kueri yang menghasilkan peristiwa tunggu
<a name="wait-event.iodatafileread.actions.filters"></a>

Asumsikan bahwa Anda mengidentifikasi kueri spesifik yang menghasilkan peristiwa tunggu `IO:DataFileRead`. Anda dapat mengidentifikasinya menggunakan teknik berikut:
+ Wawasan Performa
+ Tampilan katalog seperti yang disediakan oleh ekstensi `pg_stat_statements`
+ Tampilan katalog `pg_stat_all_tables`, jika secara berkala menunjukkan peningkatan jumlah pembacaan fisik
+ Tampilan `pg_statio_all_tables`, jika menunjukkan bahwa penghitung `_read` meningkat

Sebaiknya Anda menentukan filter yang akan digunakan dalam predikat (klausa `WHERE`) kueri ini. Ikuti pedoman berikut:
+ Jalankan perintah `EXPLAIN`. Pada output, identifikasi jenis pemindaian yang digunakan. Pemindaian berurutan tidak selalu menunjukkan adanya masalah. Kueri yang menggunakan pemindaian berurutan secara alami menghasilkan lebih banyak peristiwa `IO:DataFileRead` jika dibandingkan dengan kueri yang menggunakan filter.

  Cari tahu apakah kolom yang tercantum dalam klausa `WHERE` telah diindeks. Jika tidak, coba buat indeks untuk kolom ini. Pendekatan ini mencegah pemindaian berurutan dan mengurangi peristiwa `IO:DataFileRead`. Jika kueri memiliki filter yang ketat dan masih menghasilkan pemindaian berurutan, evaluasi apakah indeks yang tepat sedang digunakan.
+ Cari tahu apakah kueri mengakses tabel yang sangat besar. Dalam beberapa kasus, partisi tabel dapat meningkatkan performa, dengan memungkinkan kueri hanya membaca partisi yang diperlukan.
+ Periksa kardinalitas (jumlah total baris) dari operasi gabungan Anda. Perhatikan seberapa ketat nilai yang Anda teruskan di filter untuk klausa `WHERE` Anda. Jika memungkinkan, setel kueri Anda untuk mengurangi jumlah baris yang diteruskan di setiap langkah rencana.

### Meminimalkan efek operasi pemeliharaan
<a name="wait-event.iodatafileread.actions.maintenance"></a>

Operasi pemeliharaan seperti `VACUUM` dan `ANALYZE` bersifat penting. Sebaiknya jangan dinonaktifkan karena peristiwa tunggu `IO:DataFileRead` berkaitan dengan operasi pemeliharaan ini. Pendekatan berikut dapat meminimalkan efek operasi ini:
+ Jalankan operasi pemeliharaan secara manual selama di luar jam sibuk. Teknik ini mencegah basis data mencapai ambang batas untuk operasi otomatis.
+ Untuk tabel yang sangat besar, pertimbangkan untuk mempartisi tabel. Teknik ini mengurangi overhead operasi pemeliharaan. Basis data hanya mengakses partisi yang membutuhkan pemeliharaan.
+ Saat Anda menyerap data dalam jumlah besar, coba nonaktifkan fitur analisis otomatis.

Fitur autovacuum secara otomatis dipicu untuk tabel saat rumus berikut benar.

```
pg_stat_user_tables.n_dead_tup > (pg_class.reltuples x autovacuum_vacuum_scale_factor) + autovacuum_vacuum_threshold
```

Tampilan `pg_stat_user_tables` dan katalog `pg_class` berisi beberapa baris. Satu baris dapat sesuai dengan satu baris di tabel Anda. Rumus ini mengasumsikan bahwa `reltuples` adalah untuk tabel tertentu. Parameter `autovacuum_vacuum_scale_factor` (0,20 secara default) dan `autovacuum_vacuum_threshold` (50 tuple secara default) biasanya diatur secara global untuk seluruh instans. Namun, Anda dapat mengatur nilai yang berbeda untuk tabel tertentu.

**Topics**
+ [

#### Temukan tabel yang mengonsumsi ruang secara tidak perlu
](#wait-event.iodatafileread.actions.maintenance.tables)
+ [

#### Temukan tabel yang mengonsumsi ruang secara tidak perlu
](#wait-event.iodatafileread.actions.maintenance.indexes)
+ [

#### Temukan tabel yang memenuhi syarat untuk di-autovacuum
](#wait-event.iodatafileread.actions.maintenance.autovacuumed)

#### Temukan tabel yang mengonsumsi ruang secara tidak perlu
<a name="wait-event.iodatafileread.actions.maintenance.tables"></a>

Untuk menemukan tabel yang menghabiskan ruang secara tidak perlu, Anda dapat menggunakan fungsi dari ekstensi `pgstattuple` PostgreSQL. Ekstensi (modul) ini tersedia secara default di semua instans DB RDS for PostgreSQL dan dapat diinstansiasi pada instans dengan perintah berikut.

```
CREATE EXTENSION pgstattuple;
```

Untuk informasi selengkapnya tentang ekstensi ini, lihat [pgstattuple](https://www.postgresql.org/docs/current/pgstattuple.html) dalam dokumentasi PostgreSQL.

Anda dapat memeriksa bloat tabel dan indeks di aplikasi Anda. Untuk informasi selengkapnya, lihat [Mendiagnosis bloat tabel dan indeks](https://docs.aws.amazon.com//AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html).

#### Temukan tabel yang mengonsumsi ruang secara tidak perlu
<a name="wait-event.iodatafileread.actions.maintenance.indexes"></a>

Untuk menemukan indeks yang mengalami bloat dan memperkirakan jumlah ruang yang dikonsumsi secara tidak perlu pada tabel yang hak akses bacanya Anda miliki, Anda dapat menjalankan kueri berikut.

```
-- WARNING: rows with is_na = 't' are known to have bad statistics ("name" type is not supported).
-- This query is compatible with PostgreSQL 8.2 and later.

SELECT current_database(), nspname AS schemaname, tblname, idxname, bs*(relpages)::bigint AS real_size,
  bs*(relpages-est_pages)::bigint AS extra_size,
  100 * (relpages-est_pages)::float / relpages AS extra_ratio,
  fillfactor, bs*(relpages-est_pages_ff) AS bloat_size,
  100 * (relpages-est_pages_ff)::float / relpages AS bloat_ratio,
  is_na
  -- , 100-(sub.pst).avg_leaf_density, est_pages, index_tuple_hdr_bm, 
  -- maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, sub.reltuples, sub.relpages 
  -- (DEBUG INFO)
FROM (
  SELECT coalesce(1 +
       ceil(reltuples/floor((bs-pageopqdata-pagehdr)/(4+nulldatahdrwidth)::float)), 0 
       -- ItemIdData size + computed avg size of a tuple (nulldatahdrwidth)
    ) AS est_pages,
    coalesce(1 +
       ceil(reltuples/floor((bs-pageopqdata-pagehdr)*fillfactor/(100*(4+nulldatahdrwidth)::float))), 0
    ) AS est_pages_ff,
    bs, nspname, table_oid, tblname, idxname, relpages, fillfactor, is_na
    -- , stattuple.pgstatindex(quote_ident(nspname)||'.'||quote_ident(idxname)) AS pst, 
    -- index_tuple_hdr_bm, maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, reltuples 
    -- (DEBUG INFO)
  FROM (
    SELECT maxalign, bs, nspname, tblname, idxname, reltuples, relpages, relam, table_oid, fillfactor,
      ( index_tuple_hdr_bm +
          maxalign - CASE -- Add padding to the index tuple header to align on MAXALIGN
            WHEN index_tuple_hdr_bm%maxalign = 0 THEN maxalign
            ELSE index_tuple_hdr_bm%maxalign
          END
        + nulldatawidth + maxalign - CASE -- Add padding to the data to align on MAXALIGN
            WHEN nulldatawidth = 0 THEN 0
            WHEN nulldatawidth::integer%maxalign = 0 THEN maxalign
            ELSE nulldatawidth::integer%maxalign
          END
      )::numeric AS nulldatahdrwidth, pagehdr, pageopqdata, is_na
      -- , index_tuple_hdr_bm, nulldatawidth -- (DEBUG INFO)
    FROM (
      SELECT
        i.nspname, i.tblname, i.idxname, i.reltuples, i.relpages, i.relam, a.attrelid AS table_oid,
        current_setting('block_size')::numeric AS bs, fillfactor,
        CASE -- MAXALIGN: 4 on 32bits, 8 on 64bits (and mingw32 ?)
          WHEN version() ~ 'mingw32' OR version() ~ '64-bit|x86_64|ppc64|ia64|amd64' THEN 8
          ELSE 4
        END AS maxalign,
        /* per page header, fixed size: 20 for 7.X, 24 for others */
        24 AS pagehdr,
        /* per page btree opaque data */
        16 AS pageopqdata,
        /* per tuple header: add IndexAttributeBitMapData if some cols are null-able */
        CASE WHEN max(coalesce(s.null_frac,0)) = 0
          THEN 2 -- IndexTupleData size
          ELSE 2 + (( 32 + 8 - 1 ) / 8) 
          -- IndexTupleData size + IndexAttributeBitMapData size ( max num filed per index + 8 - 1 /8)
        END AS index_tuple_hdr_bm,
        /* data len: we remove null values save space using it fractionnal part from stats */
        sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 1024)) AS nulldatawidth,
        max( CASE WHEN a.atttypid = 'pg_catalog.name'::regtype THEN 1 ELSE 0 END ) > 0 AS is_na
      FROM pg_attribute AS a
        JOIN (
          SELECT nspname, tbl.relname AS tblname, idx.relname AS idxname, 
            idx.reltuples, idx.relpages, idx.relam,
            indrelid, indexrelid, indkey::smallint[] AS attnum,
            coalesce(substring(
              array_to_string(idx.reloptions, ' ')
               from 'fillfactor=([0-9]+)')::smallint, 90) AS fillfactor
          FROM pg_index
            JOIN pg_class idx ON idx.oid=pg_index.indexrelid
            JOIN pg_class tbl ON tbl.oid=pg_index.indrelid
            JOIN pg_namespace ON pg_namespace.oid = idx.relnamespace
          WHERE pg_index.indisvalid AND tbl.relkind = 'r' AND idx.relpages > 0
        ) AS i ON a.attrelid = i.indexrelid
        JOIN pg_stats AS s ON s.schemaname = i.nspname
          AND ((s.tablename = i.tblname AND s.attname = pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE)) 
          -- stats from tbl
          OR  (s.tablename = i.idxname AND s.attname = a.attname))
          -- stats from functional cols
        JOIN pg_type AS t ON a.atttypid = t.oid
      WHERE a.attnum > 0
      GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9
    ) AS s1
  ) AS s2
    JOIN pg_am am ON s2.relam = am.oid WHERE am.amname = 'btree'
) AS sub
-- WHERE NOT is_na
ORDER BY 2,3,4;
```

#### Temukan tabel yang memenuhi syarat untuk di-autovacuum
<a name="wait-event.iodatafileread.actions.maintenance.autovacuumed"></a>

Untuk menemukan tabel yang memenuhi syarat untuk autovacuum, jalankan kueri berikut.

```
--This query shows tables that need vacuuming and are eligible candidates.
--The following query lists all tables that are due to be processed by autovacuum. 
-- During normal operation, this query should return very little.
WITH  vbt AS (SELECT setting AS autovacuum_vacuum_threshold 
              FROM pg_settings WHERE name = 'autovacuum_vacuum_threshold')
    , vsf AS (SELECT setting AS autovacuum_vacuum_scale_factor 
              FROM pg_settings WHERE name = 'autovacuum_vacuum_scale_factor')
    , fma AS (SELECT setting AS autovacuum_freeze_max_age 
              FROM pg_settings WHERE name = 'autovacuum_freeze_max_age')
    , sto AS (SELECT opt_oid, split_part(setting, '=', 1) as param, 
                split_part(setting, '=', 2) as value 
              FROM (SELECT oid opt_oid, unnest(reloptions) setting FROM pg_class) opt)
SELECT
    '"'||ns.nspname||'"."'||c.relname||'"' as relation
    , pg_size_pretty(pg_table_size(c.oid)) as table_size
    , age(relfrozenxid) as xid_age
    , coalesce(cfma.value::float, autovacuum_freeze_max_age::float) autovacuum_freeze_max_age
    , (coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + 
         coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples) 
         as autovacuum_vacuum_tuples
    , n_dead_tup as dead_tuples
FROM pg_class c 
JOIN pg_namespace ns ON ns.oid = c.relnamespace
JOIN pg_stat_all_tables stat ON stat.relid = c.oid
JOIN vbt on (1=1) 
JOIN vsf ON (1=1) 
JOIN fma on (1=1)
LEFT JOIN sto cvbt ON cvbt.param = 'autovacuum_vacuum_threshold' AND c.oid = cvbt.opt_oid
LEFT JOIN sto cvsf ON cvsf.param = 'autovacuum_vacuum_scale_factor' AND c.oid = cvsf.opt_oid
LEFT JOIN sto cfma ON cfma.param = 'autovacuum_freeze_max_age' AND c.oid = cfma.opt_oid
WHERE c.relkind = 'r' 
AND nspname <> 'pg_catalog'
AND (
    age(relfrozenxid) >= coalesce(cfma.value::float, autovacuum_freeze_max_age::float)
    or
    coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + 
      coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples <= n_dead_tup
    -- or 1 = 1
)
ORDER BY age(relfrozenxid) DESC;
```

### Merespons jumlah koneksi yang tinggi
<a name="wait-event.iodatafileread.actions.connections"></a>

Saat Anda memantau Amazon CloudWatch, Anda mungkin menemukan bahwa `DatabaseConnections` metrik melonjak. Peningkatan ini menunjukkan bertambahnya jumlah koneksi ke basis data Anda. Sebaiknya lakukan pendekatan berikut:
+ Membatasi jumlah koneksi yang dapat dibuka aplikasi dengan setiap instans. Jika aplikasi Anda memiliki fitur kumpulan koneksi tertanam, tetapkan jumlah koneksi yang wajar. Dasarkan angka pada apa yang dapat diparalelkan oleh v CPUs dalam instance Anda secara efektif.

  Jika aplikasi Anda tidak menggunakan fitur kumpulan koneksi, coba gunakan Proksi Amazon RDS atau alternatifnya. Pendekatan ini memungkinkan aplikasi Anda membuka beberapa koneksi dengan penyeimbang beban. Penyeimbang selanjutnya dapat membuka sejumlah koneksi terbatas dengan basis data. Karena lebih sedikit koneksi yang berjalan secara paralel, instans DB Anda melakukan lebih sedikit peralihan konteks di kernel. Kueri harus berkembang lebih cepat, yang mengarah ke lebih sedikit peristiwa tunggu. Untuk informasi selengkapnya, lihat [Proksi Amazon RDS Aurora](rds-proxy.md).
+ Jika memungkinkan, manfaatkan replika baca RDS for PostgreSQL. Saat aplikasi Anda menjalankan operasi hanya-baca, kirim permintaan ini ke replika pembaca. Teknik ini mengurangi I/O tekanan pada simpul primer (penulis).
+ Coba naikkan skala instans DB Anda. Kelas instans berkapasitas lebih tinggi memberikan memori lebih banyak, yang memberi RDS for PostgreSQL pool buffer bersama yang lebih besar untuk menampung halaman. Ukuran yang lebih besar juga memberi instans DB lebih banyak v CPUs untuk menangani koneksi. Lebih CPUs banyak v sangat membantu ketika operasi yang menghasilkan peristiwa `IO:DataFileRead` tunggu ditulis.

# IO: WALWrite
<a name="wait-event.iowalwrite"></a>



**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.iowalwrite.context.supported)
+ [

## Konteks
](#wait-event.iowalwrite.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.iowalwrite.causes)
+ [

## Tindakan
](#wait-event.iowalwrite.actions)

## Versi mesin yang didukung
<a name="wait-event.iowalwrite.context.supported"></a>

Informasi peristiwa tunggu ini didukung untuk semua RDS for PostgreSQL versi 10 dan yang lebih tinggi.

## Konteks
<a name="wait-event.iowalwrite.context"></a>

Aktivitas dalam basis data yang menghasilkan data log write-ahead mengisi akan buffer WAL terlebih dahulu lalu menulis ke disk, secara asinkron. Peristiwa tunggu `IO:WALWrite` dihasilkan ketika sesi SQL menunggu data WAL selesai ditulis ke disk sehingga dapat melepaskan panggilan COMMIT transaksi. 

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.iowalwrite.causes"></a>

Jika peristiwa tunggu ini sering terjadi, Anda harus meninjau beban kerja Anda dan jenis pembaruan yang dilakukan beban kerja Anda serta frekuensinya. Secara khusus, cari jenis aktivitas berikut.

**Aktivitas DML yang berat**  
Perubahan data pada tabel basis data tidak terjadi secara instan. Penyisipan ke satu tabel mungkin perlu menunggu penyisipan atau pembaruan ke tabel yang sama dari klien lain. Pernyataan bahasa manipulasi data (DML) untuk mengubah nilai data (INSERT, UPDATE, DELETE, COMMIT, ROLLBACK TRANSACTION) dapat mengakibatkan pertentangan sehingga file log write-ahead yang menunggu buffer di-flushing. Situasi ini dicatat dalam metrik Wawasan Performa Amazon RDS berikut yang menunjukkan aktivitas DML yang berat.  
+  `tup_inserted`
+ `tup_updated`
+ `tup_deleted`
+ `xact_rollback`
+ `xact_commit`
Untuk informasi selengkapnya tentang metrik ini, lihat [Penghitung Wawasan Performa untuk Amazon RDS for PostgreSQL](USER_PerfInsights_Counters.md#USER_PerfInsights_Counters.PostgreSQL).

**Aktivitas checkpoint yang sering**  
Pos pemeriksaan yang sering berkontribusi pada jumlah file WAL yang lebih tinggi. Di RDS for PostgreSQL, penulisan halaman lengkap selalu "aktif". Penulisan halaman penuh membantu melindungi dari kehilangan data. Namun, jika pembuatan checkpoint terjadi terlalu sering, sistem dapat mengalami masalah performa secara keseluruhan. Hal ini terutama berlaku pada sistem dengan aktivitas DML yang berat. Dalam beberapa kasus, Anda mungkin menemukan pesan kesalahan di `postgresql.log` Anda yang menyatakan bahwa “checkpoint terjadi terlalu sering".   
Saat menyetel checkpoint, sebaiknya Anda menyeimbangkan performa dengan hati-hati berdasarkan perkiraan waktu pemulihan jika terjadi penonaktifan yang tidak normal. 

## Tindakan
<a name="wait-event.iowalwrite.actions"></a>

Kami merekomendasikan tindakan berikut untuk mengurangi jumlah peristiwa tunggu ini.

**Topics**
+ [

### Kurangi jumlah commit
](#wait-event.iowalwrite.actions.problem)
+ [

### Pantau checkpoint Anda
](#wait-event.iowalwrite.actions.monitor)
+ [

### Naikkan skala IO
](#wait-event.iowalwrite.actions.scale-io)
+ [

### Volume log khusus (DLV)
](#wait-event.iowalwrite.actions.dlv)

### Kurangi jumlah commit
<a name="wait-event.iowalwrite.actions.problem"></a>

Untuk mengurangi jumlah commit, gabungkan pernyataan ke dalam blok transaksi. Gunakan Wawasan Performa Amazon RDS untuk memeriksa jenis kueri yang dijalankan. Anda juga dapat memindahkan operasi pemeliharaan besar ke waktu di luar jam sibuk. Misalnya, buat indeks atau gunakan operasi `pg_repack` selama jam non-produksi.

### Pantau checkpoint Anda
<a name="wait-event.iowalwrite.actions.monitor"></a>

Ada dua parameter yang dapat Anda pantau untuk melihat seberapa sering instans DB RDS for PostgreSQL Anda menulis ke file WAL untuk checkpoint. 
+ `log_checkpoints` – Parameter ini diatur ke "aktif" secara default. Hal ini menyebabkan pesan dikirim ke log PostgreSQL untuk setiap checkpoint. Pesan log ini mencakup jumlah buffer yang ditulis, waktu yang dihabiskan untuk menulisnya, dan jumlah file WAL yang ditambahkan, dihapus, atau didaur ulang untuk checkpoint tertentu. 

  Untuk informasi selengkapnya tentang parameter ini, lihat [Error Reporting and Logging](https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-CHECKPOINTS) dalam dokumentasi PostgreSQL. 
+ `checkpoint_warning` – Parameter ini menetapkan nilai ambang batas (dalam detik) untuk frekuensi checkpoint yang jika terlampaui, akan menghasilkan peringatan. Secara default, parameter ini tidak diatur di RDS for PostgreSQL. Anda dapat mengatur nilai parameter ini untuk mendapatkan peringatan ketika perubahan basis data di instans DB RDS for PostgreSQL Anda ditulis pada laju yang tidak dapat ditangani oleh ukuran file WAL. Misalnya, Anda mengatur parameter ini ke 30. Jika instans RDS for PostgreSQL Anda perlu menulis perubahan lebih sering daripada setiap 30 detik, peringatan bahwa "checkpoint terjadi terlalu sering" akan dikirim ke log PostgreSQL. Hal ini dapat menunjukkan bahwa nilai `max_wal_size` Anda harus ditingkatkan. 

  Untuk informasi selengkapnya, lihat [Write Ahead Log](https://www.postgresql.org/docs/current/runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS) dalam dokumentasi PostgreSQL. 

### Naikkan skala IO
<a name="wait-event.iowalwrite.actions.scale-io"></a>

Jenis input/output (IO) wait event can remediated by scaling the input/output operasi per detik (IOPs) untuk menyediakan IO lebih cepat. Penskalaan IO lebih direkomendasikan daripada penskalaan CPU karena penskalaan CPU dapat menghasilkan lebih banyak pertentangan IO. Hal ini terjadi karena CPU yang ditingkatkan dapat menangani lebih banyak pekerjaan dan dengan demikian membuat bottleneck IO semakin buruk. Secara umum, kami menyarankan Anda mempertimbangkan untuk menyetel beban kerja Anda sebelum melakukan operasi penskalaan.

### Volume log khusus (DLV)
<a name="wait-event.iowalwrite.actions.dlv"></a>

Anda dapat menggunakan volume log khusus (DLV) untuk instans DB yang menggunakan penyimpanan IOPS yang Tersedia (PIOPS) dengan menggunakan konsol Amazon RDS, AWS CLI, atau API Amazon RDS. DLV memindahkan log transaksi database PostgreSQL ke volume penyimpanan yang terpisah dari volume yang berisi tabel database. Untuk informasi selengkapnya, lihat [Volume log khusus (DLV)](CHAP_Storage.md#CHAP_Storage.dlv).

# IPC: Acara tunggu paralel
<a name="rpg-ipc-parallel"></a>

Berikut ini `IPC:parallel wait events` menunjukkan bahwa sesi sedang menunggu komunikasi antar-proses yang terkait dengan operasi eksekusi query paralel.
+ `IPC:BgWorkerStartup`- Sebuah proses sedang menunggu proses parallel worker untuk menyelesaikan urutan startupnya. Ini terjadi ketika menginisialisasi pekerja untuk eksekusi kueri paralel.
+ `IPC:BgWorkerShutdown`- Sebuah proses sedang menunggu proses parallel worker untuk menyelesaikan urutan shutdown-nya. Ini terjadi selama fase pembersihan eksekusi query paralel.
+ `IPC:ExecuteGather`- Sebuah proses menunggu untuk menerima data dari proses pekerja paralel selama eksekusi kueri. Ini terjadi ketika proses pemimpin perlu mengumpulkan hasil dari pekerjanya.
+ `IPC:ParallelFinish`- Sebuah proses sedang menunggu pekerja paralel untuk menyelesaikan eksekusi mereka dan melaporkan hasil akhir mereka. Ini terjadi selama fase penyelesaian eksekusi query paralel.

**Topics**
+ [

## Versi mesin yang didukung
](#rpg-ipc-parallel-context-supported)
+ [

## Konteks
](#rpg-ipc-parallel-context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#rpg-ipc-parallel-causes)
+ [

## Tindakan
](#rpg-ipc-parallel-actions)

## Versi mesin yang didukung
<a name="rpg-ipc-parallel-context-supported"></a>

Informasi peristiwa tunggu ini didukung untuk semua versi Aurora PostgreSQL.

## Konteks
<a name="rpg-ipc-parallel-context"></a>

Eksekusi query paralel di PostgreSQL melibatkan beberapa proses yang bekerja sama untuk memproses satu query. Ketika kueri ditentukan cocok untuk paralelisasi, proses pemimpin berkoordinasi dengan satu atau lebih proses pekerja paralel berdasarkan pengaturan parameter. `max_parallel_workers_per_gather` Proses pemimpin membagi pekerjaan di antara pekerja, setiap pekerja memproses porsi datanya secara independen, dan hasilnya dikumpulkan kembali ke proses pemimpin.

**catatan**  
Setiap pekerja paralel beroperasi sebagai proses terpisah dengan persyaratan sumber daya yang mirip dengan sesi pengguna penuh. Ini berarti query paralel dengan 4 pekerja dapat mengkonsumsi hingga 5 kali sumber daya (CPU, memori, I/O bandwidth) dibandingkan dengan kueri non-paralel, karena proses pemimpin dan setiap proses pekerja mempertahankan alokasi sumber daya mereka sendiri. Misalnya, pengaturan seperti diterapkan `work_mem` secara individual ke setiap pekerja, berpotensi mengalikan total penggunaan memori di semua proses.

Arsitektur query paralel terdiri dari tiga komponen utama:
+ Proses pemimpin: Proses utama yang memulai operasi paralel, membagi beban kerja, dan berkoordinasi dengan proses pekerja.
+ Proses pekerja: Proses latar belakang yang mengeksekusi bagian kueri secara paralel.
+ Gather/Gathering merge: Operasi yang menggabungkan hasil dari beberapa proses pekerja kembali ke pemimpin

Selama eksekusi paralel, proses perlu berkomunikasi satu sama lain melalui mekanisme Inter-Process Communication (IPC). Peristiwa tunggu IPC ini terjadi selama fase yang berbeda:
+ Startup pekerja: Saat pekerja paralel diinisialisasi
+ Pertukaran data: Ketika pekerja memproses data dan mengirimkan hasil kepada pemimpin
+ Worker shutdown: Ketika eksekusi paralel selesai dan pekerja dihentikan
+ Titik sinkronisasi: Ketika proses perlu mengoordinasikan atau menunggu proses lain untuk menyelesaikan tugasnya

Memahami peristiwa tunggu ini sangat penting untuk mendiagnosis masalah kinerja yang terkait dengan eksekusi kueri paralel, terutama di lingkungan konkurensi tinggi di mana beberapa kueri paralel dapat dijalankan secara bersamaan.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="rpg-ipc-parallel-causes"></a>

Beberapa faktor dapat berkontribusi pada peningkatan acara tunggu IPC terkait paralel:

**Konkurensi tinggi dari query paralel**  
Ketika banyak query paralel berjalan secara bersamaan, hal itu dapat menyebabkan pertentangan sumber daya dan peningkatan waktu tunggu untuk operasi IPC. Ini sangat umum dalam sistem dengan volume transaksi tinggi atau beban kerja analitis.

**Rencana kueri paralel suboptimal**  
Jika perencana kueri memilih rencana paralel yang tidak efisien, hal itu dapat mengakibatkan paralelisasi yang tidak perlu atau distribusi kerja yang buruk di antara pekerja. Hal ini dapat menyebabkan peningkatan penantian IPC, terutama untuk `IPC:ExecuteGather` dan `IPC:ParallelFinish` acara. Masalah perencanaan ini sering berasal dari statistik yang sudah ketinggalan zaman dan table/index kembung.

**Sering startup dan shutdown pekerja paralel**  
Pertanyaan berumur pendek yang sering memulai dan menghentikan pekerja paralel dapat menyebabkan peningkatan dan peristiwa. `IPC:BgWorkerStartup` `IPC:BgWorkerShutdown` Ini sering terlihat pada beban kerja OLTP dengan banyak kueri kecil yang dapat diparalelkan.

**Kendala sumber daya**  
CPU, memori, atau I/O kapasitas yang terbatas dapat menyebabkan kemacetan dalam eksekusi paralel, yang menyebabkan peningkatan waktu tunggu di semua peristiwa IPC. Misalnya, jika CPU jenuh, proses pekerja mungkin membutuhkan waktu lebih lama untuk memulai atau memproses bagian pekerjaan mereka.

**Struktur kueri yang kompleks**  
Kueri dengan beberapa tingkat paralelisme (misalnya, gabungan paralel diikuti oleh agregasi paralel) dapat menyebabkan pola IPC yang lebih kompleks dan berpotensi meningkatkan waktu tunggu, terutama untuk acara. `IPC:ExecuteGather`

**Set hasil besar**  
Kueri yang menghasilkan kumpulan hasil yang besar dapat menyebabkan peningkatan waktu `IPC:ExecuteGather` tunggu karena proses pemimpin menghabiskan lebih banyak waktu untuk mengumpulkan dan memproses hasil dari proses pekerja.

Memahami faktor-faktor ini dapat membantu dalam mendiagnosis dan mengatasi masalah kinerja yang terkait dengan eksekusi kueri paralel di Aurora PostgreSQL.

## Tindakan
<a name="rpg-ipc-parallel-actions"></a>

Ketika Anda melihat waits terkait dengan query paralel, biasanya berarti bahwa proses backend sedang mengkoordinasikan atau menunggu proses parallel worker. Penantian ini biasa terjadi selama pelaksanaan rencana paralel. Anda dapat menyelidiki dan mengurangi dampak menunggu ini dengan memantau penggunaan pekerja paralel, meninjau pengaturan parameter, dan menyetel eksekusi kueri dan alokasi sumber daya.

**Topics**
+ [

### Menganalisis rencana kueri untuk paralelisme yang tidak efisien
](#rpg-ipc-parallel-analyze-plans)
+ [

### Pantau penggunaan query parallel
](#rpg-ipc-parallel-monitor)
+ [

### Tinjau dan sesuaikan pengaturan query parallel
](#rpg-ipc-parallel-adjust-settings)
+ [

### Optimalkan alokasi sumber daya
](#rpg-ipc-parallel-optimize-resources)
+ [

### Selidiki manajemen koneksi
](#rpg-ipc-parallel-connection-management)
+ [

### Meninjau dan mengoptimalkan operasi pemeliharaan
](#rpg-ipc-parallel-maintenance)

### Menganalisis rencana kueri untuk paralelisme yang tidak efisien
<a name="rpg-ipc-parallel-analyze-plans"></a>

Eksekusi kueri paralel seringkali dapat menyebabkan ketidakstabilan sistem, lonjakan CPU, dan varians kinerja kueri yang tidak dapat diprediksi. Sangat penting untuk menganalisis secara menyeluruh apakah paralelisme benar-benar meningkatkan beban kerja spesifik Anda. Gunakan EXPLORE ANALYZE untuk meninjau rencana eksekusi query paralel.

Nonaktifkan paralelisme sementara di tingkat sesi untuk membandingkan efisiensi rencana:

```
SET max_parallel_workers_per_gather = 0;
EXPLAIN ANALYZE <your_query>;
```

Aktifkan kembali paralelisme dan bandingkan:

```
RESET max_parallel_workers_per_gather;
EXPLAIN ANALYZE <your_query>;
```

Jika menonaktifkan paralelisme menghasilkan hasil yang lebih baik atau lebih konsisten, pertimbangkan untuk menonaktifkannya untuk kueri tertentu di tingkat sesi menggunakan perintah SET. Untuk dampak yang lebih luas, Anda mungkin ingin menonaktifkan paralelisme pada tingkat instans dengan menyesuaikan parameter yang relevan dalam grup parameter DB Anda. Untuk informasi selengkapnya, lihat [](USER_WorkingWithParamGroups.Modifying.md).

### Pantau penggunaan query parallel
<a name="rpg-ipc-parallel-monitor"></a>

Gunakan kueri berikut untuk mendapatkan visibilitas ke aktivitas dan kapasitas query paralel:

Periksa proses pekerja paralel aktif:

```
SELECT
    COUNT(*)
FROM
    pg_stat_activity
WHERE
    backend_type = 'parallel worker';
```

Kueri ini menunjukkan jumlah proses pekerja paralel aktif. Nilai tinggi mungkin menunjukkan bahwa `max\$1parallel\$1workers` Anda dikonfigurasi dengan nilai tinggi dan Anda mungkin ingin mempertimbangkan untuk menguranginya.

Periksa query paralel bersamaan:

```
SELECT
    COUNT(DISTINCT leader_pid)
FROM
    pg_stat_activity
WHERE
    leader_pid IS NOT NULL;
```

Kueri ini mengembalikan jumlah proses pemimpin berbeda yang telah meluncurkan query paralel. Angka yang tinggi di sini menunjukkan bahwa beberapa sesi menjalankan query paralel secara bersamaan, yang dapat meningkatkan permintaan pada CPU dan memori.

### Tinjau dan sesuaikan pengaturan query parallel
<a name="rpg-ipc-parallel-adjust-settings"></a>

Tinjau parameter berikut untuk memastikan parameter tersebut selaras dengan beban kerja Anda:
+ `max_parallel_workers`: Jumlah total pekerja paralel di semua sesi.
+ `max_parallel_workers_per_gather`: Pekerja maks per kueri.

Untuk beban kerja OLAP, meningkatkan nilai-nilai ini dapat meningkatkan kinerja. Untuk beban kerja OLTP, nilai yang lebih rendah umumnya lebih disukai.

```
SHOW max_parallel_workers;
SHOW max_parallel_workers_per_gather;
```

### Optimalkan alokasi sumber daya
<a name="rpg-ipc-parallel-optimize-resources"></a>

Pantau pemanfaatan CPU dan pertimbangkan untuk menyesuaikan jumlah v CPUs jika secara konsisten tinggi dan jika aplikasi Anda mendapat manfaat dari query paralel. Pastikan memori yang memadai tersedia untuk operasi paralel.
+ Gunakan metrik Performance Insights untuk menentukan apakah sistem terikat CPU.
+ Setiap pekerja paralel menggunakan miliknya sendiri`work_mem`. Pastikan penggunaan memori total berada dalam batas instans.

Query paralel dapat mengkonsumsi sumber daya yang jauh lebih banyak daripada query non-paralel, karena setiap proses pekerja adalah proses yang benar-benar terpisah yang memiliki dampak yang kira-kira sama pada sistem sebagai sesi pengguna tambahan. Ini harus diperhitungkan saat memilih nilai untuk pengaturan ini, serta saat mengonfigurasi pengaturan lain yang mengontrol pemanfaatan sumber daya, seperti. `work_mem` Untuk informasi selengkapnya, lihat [Dokumentasi PostgreSQL](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM). Batas sumber daya seperti `work_mem` diterapkan secara individual untuk setiap pekerja, yang berarti total pemanfaatan mungkin jauh lebih tinggi di semua proses daripada biasanya untuk setiap proses tunggal.

Pertimbangkan untuk meningkatkan v CPUs atau menyetel parameter memori jika beban kerja Anda sangat paralel.

### Selidiki manajemen koneksi
<a name="rpg-ipc-parallel-connection-management"></a>

Jika mengalami kelelahan koneksi, tinjau strategi penyatuan koneksi aplikasi. Pertimbangkan untuk menerapkan penyatuan koneksi di tingkat aplikasi jika belum digunakan.

### Meninjau dan mengoptimalkan operasi pemeliharaan
<a name="rpg-ipc-parallel-maintenance"></a>

Mengkoordinasikan pembuatan indeks dan tugas pemeliharaan lainnya untuk mencegah pertentangan sumber daya. Pertimbangkan untuk menjadwalkan operasi ini selama jam-jam di luar sibuk. Hindari penjadwalan pemeliharaan berat (misalnya, pembuatan indeks paralel) selama periode beban kueri pengguna yang tinggi. Operasi ini dapat mengkonsumsi pekerja paralel dan memengaruhi kinerja untuk kueri reguler.

# IPC: ProcArrayGroupUpdate
<a name="apg-rpg-ipcprocarraygroup"></a>

`IPC:ProcArrayGroupUpdate`Peristiwa terjadi ketika sesi menunggu pemimpin grup untuk memperbarui status transaksi di akhir operasi itu. Sementara PostgreSQL umumnya mengaitkan peristiwa tunggu tipe IPC dengan operasi query paralel, acara tunggu khusus ini tidak spesifik untuk query paralel.

**Topics**
+ [

## Versi mesin yang didukung
](#apg-rpg-ipcprocarraygroup.supported)
+ [

## Konteks
](#apg-rpg-ipcprocarraygroup.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#apg-rpg-ipcprocarraygroup.causes)
+ [

## Tindakan
](#apg-rpg-ipcprocarraygroup.actions)

## Versi mesin yang didukung
<a name="apg-rpg-ipcprocarraygroup.supported"></a>



## Konteks
<a name="apg-rpg-ipcprocarraygroup.context"></a>

**Memahami array proses - Array** process (proc) adalah struktur memori bersama di PostgreSQL. Ini menyimpan informasi tentang semua proses yang berjalan, termasuk rincian transaksi. Selama penyelesaian transaksi (`COMMIT`atau`ROLLBACK`), ProcArray perlu diperbarui untuk mencerminkan perubahan dan menghapus TransactionId dari array. Sesi yang mencoba menyelesaikan transaksinya harus memperoleh kunci eksklusif pada. ProcArray Ini mencegah proses lain mendapatkan kunci bersama atau eksklusif di atasnya.

**Mekanisme pembaruan grup** — Saat melakukan COMMIT atau ROLLBACK, jika proses backend tidak dapat memperoleh mode eksklusif, ia memperbarui ProcArrayLock bidang khusus yang disebut. ProcArrayGroupMember Ini menambahkan transaksi ke daftar sesi yang berniat untuk berakhir. Proses backend ini kemudian tidur dan waktu tidurnya diinstrumentasi sebagai acara tunggu. ProcArrayGroupUpdate Proses pertama dalam ProcArray dengan procArrayGroup Anggota, yang disebut sebagai proses pemimpin, memperoleh ProcArrayLock mode eksklusif. Kemudian membersihkan daftar proses yang menunggu kliring TransactionId grup. Setelah ini selesai, pemimpin melepaskan ProcArrayLock dan kemudian membangunkan semua proses dalam daftar ini, memberi tahu mereka bahwa transaksi mereka selesai.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="apg-rpg-ipcprocarraygroup.causes"></a>

Semakin banyak proses yang berjalan, semakin lama seorang pemimpin akan berpegang pada mode eksklusif. procArrayLock Akibatnya, semakin banyak transaksi tulis berakhir dalam skenario pembaruan grup yang menyebabkan potensi tumpukan proses menunggu acara `ProcArrayGroupUpdate` tunggu. Dalam tampilan SQL Top Database Insights, Anda akan melihat bahwa COMMIT adalah pernyataan dengan sebagian besar acara tunggu ini. Ini diharapkan tetapi akan membutuhkan penyelidikan lebih dalam ke SQL tulis spesifik yang dijalankan untuk menentukan tindakan apa yang tepat untuk diambil.

## Tindakan
<a name="apg-rpg-ipcprocarraygroup.actions"></a>

Kami merekomendasikan berbagai tindakan, tergantung pada penyebab peristiwa tunggu Anda. Identifikasi `IPC:ProcArrayGroupUpdate` peristiwa menggunakan Amazon RDS Performance Insights atau dengan menanyakan tampilan sistem PostgreSQL. `pg_stat_activity`

**Topics**
+ [

### Memantau transaksi komit dan operasi rollback
](#apg-rpg-ipcprocarraygroup.actions.monitor)
+ [

### Mengurangi konkurensi
](#apg-rpg-ipcprocarraygroup.actions.concurrency)
+ [

### Menerapkan penyatuan koneksi
](#apg-rpg-ipcprocarraygroup.actions.pooling)
+ [

### Menggunakan penyimpanan yang lebih cepat
](#apg-rpg-ipcprocarraygroup.actions.storage)

### Memantau transaksi komit dan operasi rollback
<a name="apg-rpg-ipcprocarraygroup.actions.monitor"></a>

**Monitor commit dan rollback** — Peningkatan jumlah commit dan rollback dapat menyebabkan peningkatan tekanan pada. ProcArray Misalnya, jika pernyataan SQL mulai gagal karena meningkatnya pelanggaran kunci duplikat, Anda mungkin melihat peningkatan rollback yang dapat meningkatkan ProcArray pertengkaran dan kembung tabel.

Amazon RDS Database Insights menyediakan metrik PostgreSQL dan melaporkan jumlah commit `xact_commit` dan rollback `xact_rollback` per detik.

### Mengurangi konkurensi
<a name="apg-rpg-ipcprocarraygroup.actions.concurrency"></a>

**Transaksi batching** — Jika memungkinkan, operasi batch dalam transaksi tunggal untuk mengurangi commit/rollback operasi.

**Batasi konkurensi** — Kurangi jumlah transaksi yang aktif secara bersamaan untuk mengurangi perselisihan kunci pada. ProcArray Meskipun akan memerlukan beberapa pengujian, mengurangi jumlah total koneksi bersamaan dapat mengurangi pertengkaran dan mempertahankan throughput.

### Menerapkan penyatuan koneksi
<a name="apg-rpg-ipcprocarraygroup.actions.pooling"></a>

**Solusi pengumpulan koneksi** - Gunakan penyatuan koneksi untuk mengelola koneksi database secara efisien, mengurangi jumlah total backend dan karenanya beban kerja pada file. ProcArray Meskipun akan memerlukan beberapa pengujian, mengurangi jumlah total koneksi bersamaan dapat mengurangi pertengkaran dan mempertahankan throughput.

**Mengurangi badai koneksi** — Demikian pula, pola sering membuat dan mengakhiri koneksi menyebabkan tekanan tambahan pada koneksi. ProcArray Dengan mengurangi pola ini, perselisihan keseluruhan berkurang.

### Menggunakan penyimpanan yang lebih cepat
<a name="apg-rpg-ipcprocarraygroup.actions.storage"></a>

**Volume log khusus** - Jika acara `IPC:ProcArrayGroupUpdate` tunggu disertai dengan peristiwa `IO:WALWrite` tunggu yang tinggi, menyiapkan volume log khusus dapat mengurangi penulisan bottleneck ke WAL. Pada gilirannya, ini meningkatkan kinerja komitmen.

Untuk informasi selengkapnya, lihat [Volume log khusus](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PIOPS.dlv.html).

# Lock:advisory
<a name="wait-event.lockadvisory"></a>

Peristiwa `Lock:advisory` terjadi saat aplikasi PostgreSQL menggunakan kunci untuk mengoordinasi aktivitas di beberapa sesi.

**Topics**
+ [

## Versi mesin yang relevan
](#wait-event.lockadvisory.context.supported)
+ [

## Konteks
](#wait-event.lockadvisory.context)
+ [

## Penyebab
](#wait-event.lockadvisory.causes)
+ [

## Tindakan
](#wait-event.lockadvisory.actions)

## Versi mesin yang relevan
<a name="wait-event.lockadvisory.context.supported"></a>

Informasi peristiwa tunggu ini relevan untuk RDS for PostgreSQL versi 9.6 dan lebih tinggi.

## Konteks
<a name="wait-event.lockadvisory.context"></a>

Kunci advisory PostgreSQL adalah kunci kooperatif tingkat aplikasi yang secara eksplisit dikunci dan dibuka oleh kode aplikasi pengguna. Aplikasi dapat menggunakan kunci advisory PostgreSQL untuk mengoordinasi aktivitas di beberapa sesi. Tidak seperti kunci biasa tingkat objek atau baris, aplikasi memiliki kontrol penuh atas masa pakai kunci. Untuk informasi selengkapnya, lihat [Advisory Locks](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS) dalam dokumentasi PostgreSQL.

Kunci advisory dapat dilepaskan sebelum transaksi berakhir atau disimpan oleh sesi di seluruh transaksi. Hal ini tidak berlaku untuk kunci implisit yang diberlakukan sistem, seperti kunci eksklusif akses pada tabel yang diperoleh oleh pernyataan `CREATE INDEX`.

Untuk deskripsi fungsi yang digunakan untuk memperoleh (mengunci) dan melepaskan (membuka kunci) kunci advisory, lihat [Advisory Lock Functions](https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS) dalam dokumentasi PostgreSQL.

Kunci advisory diimplementasikan di atas sistem penguncian PostgreSQL biasa dan terlihat dalam tampilan sistem `pg_locks`.

## Penyebab
<a name="wait-event.lockadvisory.causes"></a>

Jenis kunci ini secara khusus dikendalikan oleh aplikasi yang secara eksplisit menggunakannya. Kunci advisory yang diperoleh untuk setiap baris sebagai bagian dari kueri dapat menyebabkan lonjakan kunci atau penumpukan jangka panjang.

Efek ini terjadi saat kueri dijalankan dengan cara yang memperoleh kunci pada lebih banyak baris daripada yang ditampilkan oleh kueri. Aplikasi pada akhirnya harus melepaskan setiap kunci, tetapi jika kunci diperoleh pada baris yang tidak ditampilkan, maka aplikasi tidak dapat menemukan semua kunci.

Contoh berikut berasal dari [Advisory Locks](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS) dalam dokumentasi PostgreSQL.

```
SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100;
```

Dalam contoh ini, klausa `LIMIT` hanya dapat menghentikan output kueri setelah baris dipilih secara internal dan nilai ID-nya dikunci. Hal ini dapat terjadi secara tiba-tiba saat volume data yang bertambah menyebabkan perencana memilih rencana eksekusi lain yang tidak diuji selama pengembangan. Penumpukan dalam kasus ini terjadi karena aplikasi secara eksplisit memanggil `pg_advisory_unlock` untuk setiap nilai ID yang terkunci. Namun, dalam kasus ini, aplikasi tidak dapat menemukan set kunci yang diperoleh pada baris yang tidak ditampilkan. Karena diperoleh pada tingkat sesi, kunci tidak dilepaskan secara otomatis pada akhir transaksi.

Kemungkinan penyebab lain untuk lonjakan upaya kunci yang diblokir adalah konflik yang tidak diinginkan. Dalam konflik ini, bagian aplikasi yang tidak terkait berbagi ruang ID kunci yang sama secara tidak sengaja.

## Tindakan
<a name="wait-event.lockadvisory.actions"></a>

Tinjau penggunaan kunci advisory oleh aplikasi dan cari tahu secara mendetail di mana dan kapan dalam alur aplikasi setiap jenis kunci advisory diperoleh dan dilepaskan.

Ketahui apakah sesi memperoleh terlalu banyak kunci atau sesi yang berjalan lama tidak melepaskan kunci cukup awal, sehingga mengakibatkan penumpukan kunci yang lambat. Anda dapat memperbaiki penumpukan kunci tingkat sesi yang lambat dengan mengakhiri sesi menggunakan `pg_terminate_backend(pid)`. 

Klien yang menunggu kunci advisory muncul dalam `pg_stat_activity` dengan `wait_event_type=Lock` dan `wait_event=advisory`. Anda dapat memperoleh nilai kunci tertentu dengan mengkueri tampilan sistem `pg_locks` untuk `pid` yang sama, dengan mencari `locktype=advisory` dan `granted=f`.

Anda kemudian dapat mengidentifikasi sesi yang memblokir dengan mengkueri `pg_locks` untuk kunci advisory serupa yang memiliki `granted=t`, seperti ditunjukkan dalam contoh berikut.

```
SELECT blocked_locks.pid AS blocked_pid,
         blocking_locks.pid AS blocking_pid,
         blocked_activity.usename AS blocked_user,
         blocking_activity.usename AS blocking_user,
         now() - blocked_activity.xact_start AS blocked_transaction_duration,
         now() - blocking_activity.xact_start AS blocking_transaction_duration,
         concat(blocked_activity.wait_event_type,':',blocked_activity.wait_event) AS blocked_wait_event,
         concat(blocking_activity.wait_event_type,':',blocking_activity.wait_event) AS blocking_wait_event,
         blocked_activity.state AS blocked_state,
         blocking_activity.state AS blocking_state,
         blocked_locks.locktype AS blocked_locktype,
         blocking_locks.locktype AS blocking_locktype,
         blocked_activity.query AS blocked_statement,
         blocking_activity.query AS blocking_statement
    FROM pg_catalog.pg_locks blocked_locks
    JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
    JOIN pg_catalog.pg_locks blocking_locks
        ON blocking_locks.locktype = blocked_locks.locktype
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
        AND blocking_locks.pid != blocked_locks.pid
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
    WHERE NOT blocked_locks.GRANTED;
```

Semua fungsi API kunci advisory memiliki dua set argumen, baik satu argumen `bigint` maupun dua argumen `integer`:
+ Untuk fungsi API dengan satu argumen `bigint`, 32 bit atas berada dalam `pg_locks.classid` dan 32 bit bawah berada dalam `pg_locks.objid`.
+ Untuk fungsi API dengan dua argumen `integer`, argumen pertama adalah `pg_locks.classid` dan argumen kedua adalah `pg_locks.objid`.

Nilai `pg_locks.objsubid` menunjukkan form API yang digunakan: `1` berarti satu argumen `bigint`; `2` berarti dua argumen `integer`.

# Lock:extend
<a name="wait-event.lockextend"></a>

Peristiwa `Lock:extend` terjadi saat sebuah proses backend menunggu untuk mengunci relasi agar dapat diperluas, sementara proses lain mengunci relasi tersebut untuk tujuan yang sama.

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.lockextend.context.supported)
+ [

## Konteks
](#wait-event.lockextend.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.lockextend.causes)
+ [

## Tindakan
](#wait-event.lockextend.actions)

## Versi mesin yang didukung
<a name="wait-event.lockextend.context.supported"></a>

Informasi peristiwa tunggu ini didukung untuk semua versi RDS for PostgreSQL.

## Konteks
<a name="wait-event.lockextend.context"></a>

Peristiwa `Lock:extend` menunjukkan bahwa proses backend menunggu untuk memperluas relasi yang dikunci oleh proses backend lain saat proses backend lain ini memperluas relasi tersebut. Karena hanya satu proses pada satu waktu yang dapat memperluas relasi, sistem membuat peristiwa tunggu `Lock:extend`. Operasi `INSERT`, `COPY`, dan `UPDATE` dapat menghasilkan peristiwa ini.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.lockextend.causes"></a>

Saat peristiwa `Lock:extend` muncul lebih dari biasanya, yang mungkin menunjukkan adanya masalah performa, berikut adalah penyebab umumnya:

**Lonjakan penyisipan atau pembaruan konkuren ke tabel yang sama **  
Mungkin terdapat peningkatan jumlah sesi konkuren dengan kueri yang melakukan penyisipan atau pembaruan pada tabel yang sama.

**Bandwidth jaringan tidak cukup**  
Bandwidth jaringan pada instans DB mungkin tidak cukup untuk kebutuhan komunikasi penyimpanan dari beban kerja saat ini. Hal ini dapat berkontribusi pada latensi penyimpanan yang menyebabkan peningkatan peristiwa `Lock:extend`.

## Tindakan
<a name="wait-event.lockextend.actions"></a>

Kami merekomendasikan berbagai tindakan, tergantung pada penyebab peristiwa tunggu Anda.

**Topics**
+ [

### Kurangi penyisipan dan pembaruan konkuren ke relasi yang sama
](#wait-event.lockextend.actions.action1)
+ [

### Tingkatkan bandwidth jaringan
](#wait-event.lockextend.actions.increase-network-bandwidth)

### Kurangi penyisipan dan pembaruan konkuren ke relasi yang sama
<a name="wait-event.lockextend.actions.action1"></a>

Pertama, ketahui apakah terdapat peningkatan pada metrik `tup_inserted` dan `tup_updated` dengan disertai peningkatan pada peristiwa tunggu ini. Jika demikian, periksa relasi yang memiliki pertentangan tinggi untuk operasi penyisipan dan pembaruan. Untuk menentukan hal ini, jalankan kueri tampilan `pg_stat_all_tables` untuk nilai pada bidang `n_tup_ins` dan `n_tup_upd`. Untuk informasi tentang tampilan `pg_stat_all_tables`, lihat [pg\$1stat\$1all\$1tables](https://www.postgresql.org/docs/13/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW) dalam dokumentasi PostgreSQL. 

Untuk mendapatkan informasi selengkapnya tentang pemblokiran dan kueri yang diblokir, jalankan kueri `pg_stat_activity` seperti contoh berikut:

```
SELECT
    blocked.pid,
    blocked.usename,
    blocked.query,
    blocking.pid AS blocking_id,
    blocking.query AS blocking_query,
    blocking.wait_event AS blocking_wait_event,
    blocking.wait_event_type AS blocking_wait_event_type
FROM pg_stat_activity AS blocked
JOIN pg_stat_activity AS blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid))
where
blocked.wait_event = 'extend'
and blocked.wait_event_type = 'Lock';
 
   pid  | usename  |            query             | blocking_id |                         blocking_query                           | blocking_wait_event | blocking_wait_event_type
  ------+----------+------------------------------+-------------+------------------------------------------------------------------+---------------------+--------------------------
   7143 |  myuser  | insert into tab1 values (1); |        4600 | INSERT INTO tab1 (a) SELECT s FROM generate_series(1,1000000) s; | DataFileExtend      | IO
```

Setelah Anda mengidentifikasi relasi yang berkontribusi pada peningkatan peristiwa `Lock:extend`, gunakan teknik berikut untuk mengurangi pertentangan:
+ Cari tahu apakah Anda dapat menggunakan pemartisian untuk mengurangi pertentangan pada tabel yang sama. Memisahkan tuple yang disisipkan atau diperbarui ke dalam partisi yang berbeda dapat mengurangi pertentangan. Untuk informasi tentang partisi, lihat [Mengelola partisi PostgreSQL dengan ekstensi pg\$1partman](PostgreSQL_Partitions.md).
+ Jika peristiwa tunggu terutama disebabkan oleh aktivitas pembaruan, pertimbangkan untuk mengurangi nilai faktor pengisian relasi. Hal ini dapat mengurangi permintaan untuk blok baru selama pembaruan. Faktor pengisian adalah parameter penyimpanan untuk tabel yang menentukan jumlah maksimum ruang untuk melakukan packing halaman tabel. Hal ini dinyatakan sebagai persentase dari total ruang untuk sebuah halaman. Untuk informasi selengkapnya tentang parameter fillfactor, lihat [CREATE TABLE](https://www.postgresql.org/docs/13/sql-createtable.html) dalam dokumentasi PostgreSQL. 
**penting**  
Kami sangat merekomendasikan untuk menguji sistem jika Anda mengubah faktor pengisian karena mengubah nilai ini dapat berdampak negatif pada performa, tergantung pada beban kerja Anda.

### Tingkatkan bandwidth jaringan
<a name="wait-event.lockextend.actions.increase-network-bandwidth"></a>

Untuk melihat apakah terdapat peningkatan latensi tulis, periksa metrik `WriteLatency` di CloudWatch. Jika ada, gunakan metrik `WriteThroughput` dan `ReadThroughput` Amazon CloudWatch untuk memantau lalu lintas terkait penyimpanan pada klaster DB. Metrik ini dapat membantu Anda menentukan apakah bandwidth jaringan cukup untuk aktivitas penyimpanan beban kerja Anda.

Jika bandwidth jaringan Anda tidak cukup, tingkatkan. Jika instans DB Anda mencapai batas bandwidth jaringan, satu-satunya cara untuk meningkatkan bandwidth adalah meningkatkan ukuran instans DB Anda.

Untuk informasi selengkapnya tentang metrik CloudWatch, lihat [Metrik CloudWatch tingkat instans Amazon untuk Amazon RDS](rds-metrics.md#rds-cw-metrics-instance). Untuk informasi tentang performa jaringan untuk setiap kelas instans DB, lihat [Metrik CloudWatch tingkat instans Amazon untuk Amazon RDS](rds-metrics.md#rds-cw-metrics-instance). 

# Lock:Relation
<a name="wait-event.lockrelation"></a>

Peristiwa `Lock:Relation` terjadi saat kueri menunggu untuk memperoleh kunci pada tabel atau tampilan (relasi) yang saat ini dikunci oleh transaksi lain.

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.lockrelation.context.supported)
+ [

## Konteks
](#wait-event.lockrelation.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.lockrelation.causes)
+ [

## Tindakan
](#wait-event.lockrelation.actions)

## Versi mesin yang didukung
<a name="wait-event.lockrelation.context.supported"></a>

Informasi peristiwa tunggu ini didukung untuk semua versi RDS for PostgreSQL.

## Konteks
<a name="wait-event.lockrelation.context"></a>

Sebagian besar perintah PostgreSQL secara implisit menggunakan kunci untuk mengontrol akses konkuren ke data dalam tabel. Anda juga dapat menggunakan kunci ini secara eksplisit dalam kode aplikasi Anda dengan perintah `LOCK`. Banyak mode kunci yang tidak kompatibel satu sama lain, dan mode ini dapat memblokir transaksi saat mencoba mengakses objek yang sama. Ketika ini terjadi, RDS for PostgreSQL akan menghasilkan peristiwa `Lock:Relation`. Berikut adalah beberapa contoh umum:
+ Kunci eksklusif seperti `ACCESS EXCLUSIVE` dapat memblokir semua akses konkuren. Operasi bahasa definisi data (DDL) seperti `DROP TABLE`, `TRUNCATE`, `VACUUM FULL`, dan `CLUSTER` memperoleh kunci `ACCESS EXCLUSIVE` secara implisit. `ACCESS EXCLUSIVE` juga merupakan mode kunci default untuk pernyataan `LOCK TABLE` yang tidak menentukan mode secara eksplisit.
+ Menggunakan `CREATE INDEX (without CONCURRENT)` pada tabel akan bertentangan dengan pernyataan bahasa manipulasi data (DML) `UPDATE`, `DELETE`, dan `INSERT`, yang memperoleh kunci `ROW EXCLUSIVE`.

Untuk informasi selengkapnya tentang kunci tingkat tabel dan mode kunci yang bertentangan, lihat [Explicit Locking](https://www.postgresql.org/docs/13/explicit-locking.html) dalam dokumentasi PostgreSQL.

Kueri dan transaksi yang memblokir biasanya dapat dibuka blokirnya dengan salah satu cara berikut:
+ Kueri yang memblokir – Aplikasi dapat membatalkan kueri atau pengguna dapat mengakhiri proses. Mesin juga dapat memaksa kueri untuk berakhir karena batas waktu pernyataan sesi atau mekanisme deteksi deadlock.
+ Transaksi yang memblokir – Transaksi berhenti memblokir saat menjalankan pernyataan `ROLLBACK` atau `COMMIT`. Rollback juga terjadi secara otomatis saat sesi diputus oleh klien atau masalah jaringan, atau diakhiri. Sesi dapat berakhir saat mesin basis data dimatikan, sistem kehabisan memori, dan sebagainya.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.lockrelation.causes"></a>

Saat peristiwa `Lock:Relation` terjadi lebih sering dari biasanya, hal tersebut dapat menunjukkan masalah performa. Penyebab umumnya meliputi yang berikut:

**Peningkatan sesi konkuren dengan kunci tabel yang bertentangan**  
Mungkin ada peningkatan jumlah sesi konkuren dengan kueri yang mengunci tabel yang sama dengan mode kunci yang bertentangan.

**Operasi pemeliharaan**  
Operasi pemeliharaan kondisi seperti `VACUUM` dan `ANALYZE` dapat secara signifikan meningkatkan jumlah kunci yang bertentangan. `VACUUM FULL` memperoleh kunci `ACCESS EXCLUSIVE`, dan `ANALYSE` memperoleh kunci `SHARE UPDATE EXCLUSIVE`. Kedua jenis kunci tersebut dapat menyebabkan peristiwa tunggu `Lock:Relation`. Operasi pemeliharaan data aplikasi seperti menyegarkan tampilan terwujud juga dapat meningkatkan kueri dan transaksi yang diblokir.

**Kunci pada instans pembaca**  
Mungkin ada pertentangan antara kunci relasi yang dipegang oleh penulis dan pembaca. Saat ini, hanya kunci relasi `ACCESS EXCLUSIVE` yang direplikasi ke instans pembaca. Namun, kunci relasi `ACCESS EXCLUSIVE` akan bertentangan dengan kunci relasi `ACCESS SHARE` yang dipegang oleh pembaca. Hal ini dapat menyebabkan peningkatan peristiwa tunggu relasi kunci pada pembaca. 

## Tindakan
<a name="wait-event.lockrelation.actions"></a>

Kami merekomendasikan berbagai tindakan, tergantung pada penyebab peristiwa tunggu Anda.

**Topics**
+ [

### Kurangi dampak pemblokiran pernyataan SQL
](#wait-event.lockrelation.actions.reduce-blocks)
+ [

### Minimalkan efek operasi pemeliharaan
](#wait-event.lockrelation.actions.maintenance)

### Kurangi dampak pemblokiran pernyataan SQL
<a name="wait-event.lockrelation.actions.reduce-blocks"></a>

Untuk mengurangi dampak pemblokiran pernyataan SQL, ubah kode aplikasi Anda jika memungkinkan. Berikut adalah dua teknik umum untuk mengurangi pemblokiran:
+ Gunakan opsi `NOWAIT` – Beberapa perintah SQL, seperti pernyataan `SELECT` dan `LOCK`, mendukung opsi ini. Arahan `NOWAIT` membatalkan kueri permintaan kunci jika kunci tidak dapat segera diperoleh. Teknik ini dapat membantu mencegah sesi yang memblokir menyebabkan penumpukan sesi yang diblokir di belakangnya.

  Misalnya: Transaksi A sedang menunggu kunci yang dipegang oleh transaksi B. Jika B meminta kunci pada tabel yang dikunci oleh transaksi C, transaksi A mungkin diblokir hingga transaksi C selesai. Namun, jika transaksi B menggunakan `NOWAIT` saat meminta kunci pada C, transaksi ini dapat gagal cepat (fail fast) dan memastikan bahwa transaksi A tidak harus menunggu tanpa batas waktu.
+ Gunakan `SET lock_timeout` – Tetapkan nilai `lock_timeout` untuk membatasi waktu tunggu pernyataan SQL dalam memperoleh kunci pada relasi. Jika kunci tidak diperoleh dalam batas waktu yang ditentukan, transaksi yang meminta kunci akan dibatalkan. Tetapkan nilai ini pada tingkat sesi.

### Minimalkan efek operasi pemeliharaan
<a name="wait-event.lockrelation.actions.maintenance"></a>

Operasi pemeliharaan seperti `VACUUM` dan `ANALYZE` bersifat penting. Sebaiknya jangan dinonaktifkan karena peristiwa tunggu `Lock:Relation` berkaitan dengan operasi pemeliharaan ini. Pendekatan berikut dapat meminimalkan efek operasi ini:
+ Jalankan operasi pemeliharaan secara manual di luar jam sibuk.
+ Untuk mengurangi peristiwa tunggu `Lock:Relation` yang disebabkan oleh tugas autovacuum, lakukan penyetelan autovacuum yang diperlukan. Untuk informasi tentang menyetel autovacuum, lihat [Menggunakan autovacuum PostgreSQL di Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html) dalam *Panduan Pengguna Amazon RDS*.

# Lock:transactionid
<a name="wait-event.locktransactionid"></a>

Peristiwa `Lock:transactionid` terjadi saat transaksi sedang menunggu kunci tingkat baris.

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.locktransactionid.context.supported)
+ [

## Konteks
](#wait-event.locktransactionid.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.locktransactionid.causes)
+ [

## Tindakan
](#wait-event.locktransactionid.actions)

## Versi mesin yang didukung
<a name="wait-event.locktransactionid.context.supported"></a>

Informasi peristiwa tunggu ini didukung untuk semua versi RDS for PostgreSQL.

## Konteks
<a name="wait-event.locktransactionid.context"></a>

Peristiwa `Lock:transactionid` terjadi saat transaksi mencoba memperoleh kunci tingkat baris yang telah diberikan untuk transaksi yang sedang berlangsung pada saat bersamaan. Sesi yang menunjukkan peristiwa tunggu `Lock:transactionid` diblokir karena kunci ini. Setelah transaksi yang memblokir berakhir dengan pernyataan `COMMIT` atau `ROLLBACK`, transaksi yang diblokir dapat dilanjutkan.

Semantik kontrol konkurensi multiversi dari RDS for PostgreSQL menjamin bahwa pembaca tidak memblokir penulis dan penulis tidak memblokir pembaca. Agar pertentangan tingkat baris terjadi, transaksi yang memblokir dan diblokir harus mengeluarkan pernyataan yang bertentangan dari jenis berikut:
+ `UPDATE`
+ `SELECT … FOR UPDATE`
+ `SELECT … FOR KEY SHARE`

Pernyataan `SELECT … FOR KEY SHARE` adalah kasus khusus. Basis data menggunakan klausa `FOR KEY SHARE` untuk mengoptimalkan performa integritas referensial. Kunci tingkat baris pada baris dapat memblokintah `INSERT`, `UPDATE`, dan `DELETE` pada tabel lain yang mereferensikan baris tersebut.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.locktransactionid.causes"></a>

Saat peristiwa ini ditampilkan lebih dari biasanya, penyebabnya biasanya adalah pernyataan `UPDATE`, `SELECT … FOR UPDATE`, atau `SELECT … FOR KEY SHARE` yang dikombinasikan dengan kondisi berikut.

**Topics**
+ [

### Konkurensi tinggi
](#wait-event.locktransactionid.concurrency)
+ [

### Idle pada transaksi
](#wait-event.locktransactionid.idle)
+ [

### Transaksi yang berjalan lama
](#wait-event.locktransactionid.long-running)

### Konkurensi tinggi
<a name="wait-event.locktransactionid.concurrency"></a>

Aurora PostgreSQL dapat menggunakan semantik penguncian tingkat baris terperinci. Probabilitas pertentangan tingkat baris meningkat saat kondisi berikut terpenuhi:
+ Beberapa beban kerja yang sangat konkuren bersaing untuk baris yang sama.
+ Konkurensi meningkat.

### Idle pada transaksi
<a name="wait-event.locktransactionid.idle"></a>

Terkadang kolom `pg_stat_activity.state` menunjukkan nilai `idle in transaction`. Nilai ini ditampilkan untuk sesi yang telah memulai transaksi, tetapi belum mengeluarkan `COMMIT` atau `ROLLBACK`. Jika nilai `pg_stat_activity.state` bukan `active`, kueri yang ditampilkan pada `pg_stat_activity` adalah yang paling baru diselesaikan. Sesi yang memblokir tidak secara aktif memproses kueri karena transaksi yang terbuka menahan kunci.

Jika transaksi yang idle memperoleh kunci tingkat baris, transaksi tersebut mungkin mencegah sesi lain memperolehnya. Kondisi ini menyebabkan peristiwa tunggu `Lock:transactionid` sering terjadi. Untuk mendiagnosis masalah, periksa output dari `pg_stat_activity` dan `pg_locks`.

### Transaksi yang berjalan lama
<a name="wait-event.locktransactionid.long-running"></a>

Transaksi yang berjalan dalam waktu lama akan mendapatkan kunci untuk waktu lama. Kunci yang lama dipegang ini dapat memblokir transaksi lain sehingga tidak berjalan.

## Tindakan
<a name="wait-event.locktransactionid.actions"></a>

Penguncian baris adalah pertentangan antara pernyataan `UPDATE`, `SELECT … FOR UPDATE`, atau `SELECT … FOR KEY SHARE`. Sebelum mencoba solusi, cari tahu kapan pernyataan ini berjalan pada baris yang sama. Gunakan informasi ini untuk memilih strategi yang dijelaskan pada bagian berikut.

**Topics**
+ [

### Tangani konkurensi tinggi
](#wait-event.locktransactionid.actions.problem)
+ [

### Tangani transaksi idle
](#wait-event.locktransactionid.actions.find-blocker)
+ [

### Tangani transaksi yang berjalan lama
](#wait-event.locktransactionid.actions.concurrency)

### Tangani konkurensi tinggi
<a name="wait-event.locktransactionid.actions.problem"></a>

Jika masalahnya adalah konkurensi, coba salah satu teknik berikut:
+ Turunkan konkurensi pada aplikasi. Misalnya, kurangi jumlah sesi aktif.
+ Terapkan pool koneksi. Untuk mempelajari cara melakukan pooling koneksi dengan Proksi RDS, lihat [Proksi Amazon RDS Aurora](rds-proxy.md).
+ Desain aplikasi atau model data untuk menghindari pertentangan pernyataan `UPDATE` dan `SELECT … FOR UPDATE`. Anda juga dapat mengurangi jumlah kunci asing yang diakses oleh pernyataan `SELECT … FOR KEY SHARE`.

### Tangani transaksi idle
<a name="wait-event.locktransactionid.actions.find-blocker"></a>

Jika `pg_stat_activity.state` menampilkan `idle in transaction`, gunakan strategi berikut:
+ Aktifkan autocommit saat memungkinkan. Pendekatan ini mencegah transaksi memblokir transaksi lain sambil menunggu `COMMIT` atau `ROLLBACK`.
+ Cari jalur kode yang tidak memiliki `COMMIT`, `ROLLBACK`, atau `END`.
+ Pastikan logika penanganan pengecualian pada aplikasi Anda selalu memiliki jalur ke `end of transaction` yang valid.
+ Pastikan bahwa aplikasi Anda memproses hasil kueri setelah mengakhiri transaksi dengan `COMMIT` atau `ROLLBACK`.

### Tangani transaksi yang berjalan lama
<a name="wait-event.locktransactionid.actions.concurrency"></a>

Jika transaksi yang berjalan lama menyebabkan `Lock:transactionid` sering terjadi, coba strategi berikut:
+ Cegah kunci baris dari transaksi jangka panjang.
+ Batasi panjang kueri dengan menerapkan autocommit jika memungkinkan.

# Lock:tuple
<a name="wait-event.locktuple"></a>

Peristiwa `Lock:tuple` terjadi saat proses backend menunggu untuk memperoleh kunci pada tuple.

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.locktuple.context.supported)
+ [

## Konteks
](#wait-event.locktuple.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.locktuple.causes)
+ [

## Tindakan
](#wait-event.locktuple.actions)

## Versi mesin yang didukung
<a name="wait-event.locktuple.context.supported"></a>

Informasi peristiwa tunggu ini didukung untuk semua versi RDS for PostgreSQL.

## Konteks
<a name="wait-event.locktuple.context"></a>

Peristiwa `Lock:tuple` menunjukkan bahwa backend menunggu untuk memperoleh kunci pada tuple, sementara backend lain memegang kunci yang bertentangan pada tuple yang sama. Tabel berikut menggambarkan skenario saat sesi membuat peristiwa `Lock:tuple`.


|  Waktu  |  Sesi 1  |  Sesi 2  |  Sesi 3  | 
| --- | --- | --- | --- | 
|  t1  |  Memulai transaksi.  |    |    | 
|  t2  |  Memperbarui baris 1.  |    |    | 
|  t3  |    |  Memperbarui baris 1. Sesi ini mendapatkan kunci eksklusif pada tuple, lalu menunggu sesi 1 untuk melepaskan kunci dengan melakukan komit atau rollback.  |    | 
|  t4  |    |    |  Memperbarui baris 1. Sesi ini menunggu sesi 2 untuk melepaskan kunci eksklusif pada tuple.  | 

Atau Anda dapat mensimulasikan peristiwa tunggu ini dengan menggunakan alat tolok ukur `pgbench`. Konfigurasikan jumlah sesi konkuren yang tinggi untuk memperbarui baris yang sama pada tabel dengan file SQL kustom.

Untuk mempelajari selengkapnya tentang mode kunci yang bertentangan, lihat [Explicit Locking](https://www.postgresql.org/docs/current/explicit-locking.html) dalam dokumentasi PostgreSQL. Untuk mempelajari selengkapnya tentang `pgbench`, lihat [pgbench](https://www.postgresql.org/docs/current/pgbench.html) dalam dokumentasi PostgreSQL.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.locktuple.causes"></a>

Saat peristiwa ini muncul lebih dari biasanya, yang mungkin menunjukkan adanya masalah performa, berikut adalah penyebab umumnya:
+ Sejumlah besar sesi konkuren mencoba mendapatkan kunci yang bertentangan untuk tuple yang sama dengan menjalankan pernyataan `UPDATE` atau `DELETE`.
+ Beberapa sesi yang sangat konkuren menjalankan pernyataan `SELECT` menggunakan mode kunci `FOR UPDATE` atau `FOR NO KEY UPDATE`.
+ Berbagai faktor mendorong aplikasi atau pool koneksi untuk membuka lebih banyak sesi agar menjalankan operasi yang sama. Saat sesi baru mencoba memodifikasi baris yang sama, beban DB dapat melonjak, dan `Lock:tuple` dapat ditampilkan.

Untuk informasi selengkapnya, lihat [Row-Level Locks](https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS) dalam dokumentasi PostgreSQL.

## Tindakan
<a name="wait-event.locktuple.actions"></a>

Kami merekomendasikan berbagai tindakan, tergantung pada penyebab peristiwa tunggu Anda.

**Topics**
+ [

### Selidiki logika aplikasi
](#wait-event.locktuple.actions.problem)
+ [

### Temukan sesi pemblokir
](#wait-event.locktuple.actions.find-blocker)
+ [

### Kurangi konkurensi saat tinggi
](#wait-event.locktuple.actions.concurrency)
+ [

### Pecahkan masalah bottleneck
](#wait-event.locktuple.actions.bottlenecks)

### Selidiki logika aplikasi
<a name="wait-event.locktuple.actions.problem"></a>

Cari tahu apakah sesi pemblokir telah berada pada status `idle in transaction` dalam waktu yang lama. Jika demikian, coba akhiri sesi pemblokir sebagai solusi jangka pendek. Anda dapat menggunakan fungsi `pg_terminate_backend`. Untuk informasi selengkapnya tentang fungsi ini, lihat [Server Signaling Functions](https://www.postgresql.org/docs/13/functions-admin.html#FUNCTIONS-ADMIN-SIGNAL) dalam dokumentasi PostgreSQL.

Untuk solusi jangka panjang, lakukan hal berikut:
+ Sesuaikan logika aplikasi.
+ Gunakan parameter `idle_in_transaction_session_timeout`. Parameter ini mengakhiri sesi apa pun dengan transaksi terbuka yang telah idle lebih lama dari jumlah waktu yang ditentukan. Untuk informasi selengkapnya, lihat [Client Connection Defaults](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-IDLE-IN-TRANSACTION-SESSION-TIMEOUT) dalam dokumentasi PostgreSQL.
+ Gunakan autocommit sebanyak mungkin. Untuk informasi selengkapnya, lihat [SET AUTOCOMMIT](https://www.postgresql.org/docs/current/ecpg-sql-set-autocommit.html) dalam dokumentasi PostgreSQL.

### Temukan sesi pemblokir
<a name="wait-event.locktuple.actions.find-blocker"></a>

Saat peristiwa tunggu `Lock:tuple` terjadi, identifikasi pemblokir dan sesi yang diblokir dengan mencari tahu kunci mana yang bergantung satu sama lain. Untuk informasi selengkapnya, lihat [Lock dependency information](https://wiki.postgresql.org/wiki/Lock_dependency_information) dalam wiki PostgreSQL. 

Contoh berikut mengkueri semua sesi, memfilter `tuple`, dan mengurutkan berdasarkan `wait_time`.

```
SELECT blocked_locks.pid AS blocked_pid,
         blocking_locks.pid AS blocking_pid,
         blocked_activity.usename AS blocked_user,
         blocking_activity.usename AS blocking_user,
         now() - blocked_activity.xact_start AS blocked_transaction_duration,
         now() - blocking_activity.xact_start AS blocking_transaction_duration,
         concat(blocked_activity.wait_event_type,':',blocked_activity.wait_event) AS blocked_wait_event,
         concat(blocking_activity.wait_event_type,':',blocking_activity.wait_event) AS blocking_wait_event,
         blocked_activity.state AS blocked_state,
         blocking_activity.state AS blocking_state,
         blocked_locks.locktype AS blocked_locktype,
         blocking_locks.locktype AS blocking_locktype,
         blocked_activity.query AS blocked_statement,
         blocking_activity.query AS blocking_statement
    FROM pg_catalog.pg_locks blocked_locks
    JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
    JOIN pg_catalog.pg_locks blocking_locks
        ON blocking_locks.locktype = blocked_locks.locktype
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
        AND blocking_locks.pid != blocked_locks.pid
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
    WHERE NOT blocked_locks.GRANTED;
```

### Kurangi konkurensi saat tinggi
<a name="wait-event.locktuple.actions.concurrency"></a>

Peristiwa `Lock:tuple` mungkin terjadi terus-menerus, terutama pada waktu beban kerja yang sibuk. Dalam situasi ini, pertimbangkan untuk mengurangi konkurensi tinggi untuk baris yang sangat sibuk. Sering kali, hanya beberapa baris mengontrol antrean atau logika Boolean, sehingga membuat baris ini sangat sibuk.

Anda dapat mengurangi konkurensi dengan menggunakan pendekatan yang berbeda berdasarkan kebutuhan bisnis, logika aplikasi, dan jenis beban kerja. Misalnya, Anda dapat melakukan hal berikut:
+ Desain ulang tabel dan logika data Anda untuk mengurangi konkurensi tinggi.
+ Ubah logika aplikasi untuk mengurangi konkurensi tinggi di tingkat baris.
+ Manfaatkan dan desain ulang kueri dengan kunci tingkat baris.
+ Gunakan klausa `NOWAIT` dengan operasi percobaan ulang.
+ Pertimbangkan untuk menggunakan kontrol konkurensi logika optimistis dan kontrol konkurensi logika penguncian hibrid.
+ Pertimbangkan untuk mengubah tingkat isolasi basis data.

### Pecahkan masalah bottleneck
<a name="wait-event.locktuple.actions.bottlenecks"></a>

`Lock:tuple` dapat terjadi dengan bottleneck seperti "CPU starvation" atau penggunaan maksimum bandwidth Amazon EBS. Untuk mengurangi bottleneck, pertimbangkan pendekatan berikut:
+ Naikkan skala jenis kelas instans Anda.
+ Optimalkan kueri sarat sumber daya.
+ Ubah logika aplikasi.
+ Arsipkan data yang jarang diakses.

# LWLock: BufferMapping (:buffer\$1mapping) LWLock
<a name="wait-event.lwl-buffer-mapping"></a>

Peristiwa ini terjadi saat sesi menunggu untuk mengaitkan blok data dengan buffer di pool buffer bersama.

**catatan**  
Peristiwa ini dinamai `LWLock:BufferMapping` untuk RDS for PostgreSQL versi 13 dan versi yang lebih tinggi. Untuk RDS for PostgreSQL versi 12 dan versi yang lebih lama, peristiwa ini dinamai `LWLock:buffer_mapping`. 

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.lwl-buffer-mapping.context.supported)
+ [

## Konteks
](#wait-event.lwl-buffer-mapping.context)
+ [

## Penyebab
](#wait-event.lwl-buffer-mapping.causes)
+ [

## Tindakan
](#wait-event.lwl-buffer-mapping.actions)

## Versi mesin yang didukung
<a name="wait-event.lwl-buffer-mapping.context.supported"></a>

Informasi peristiwa tunggu ini relevan untuk RDS for PostgreSQL versi 9.6 dan lebih tinggi.

## Konteks
<a name="wait-event.lwl-buffer-mapping.context"></a>

*Pool buffer bersama* adalah area memori PostgreSQL yang menampung semua halaman yang sedang atau telah digunakan oleh proses. Ketika suatu proses membutuhkan halaman, proses ini membacakan halaman tersebut ke dalam pool buffer bersama. Parameter `shared_buffers` menetapkan ukuran buffer bersama dan menyediakan area memori untuk menyimpan halaman tabel dan indeks. Jika Anda mengganti parameter ini, pastikan untuk mengaktifkan ulang basis data.

Peristiwa `LWLock:buffer_mapping` tunggu terjadi dalam skenario berikut:
+ Sebuah proses mencari tabel buffer untuk halaman dan memperoleh kunci pemetaan buffer bersama.
+ Sebuah proses memuat halaman ke dalam pool buffer dan memperoleh kunci pemetaan buffer eksklusif.
+ Sebuah proses menghapus halaman dari pool dan memperoleh kunci pemetaan buffer eksklusif.

## Penyebab
<a name="wait-event.lwl-buffer-mapping.causes"></a>

Ketika peristiwa ini muncul lebih sering dari biasanya, yang mungkin menunjukkan masalah performa, basis data akan melakukan paging masuk dan keluar pada pool buffer bersama. Penyebab umumnya meliputi yang berikut:
+ Kueri besar
+ Indeks dan tabel yang mengalami bloat
+ Pemindaian tabel lengkap
+ Ukuran pool bersama yang lebih kecil dari working set

## Tindakan
<a name="wait-event.lwl-buffer-mapping.actions"></a>

Kami merekomendasikan berbagai tindakan, tergantung pada penyebab peristiwa tunggu Anda.

**Topics**
+ [

### Pantau metrik terkait buffer
](#wait-event.lwl-buffer-mapping.actions.monitor-metrics)
+ [

### Evaluasi strategi pengindeksan Anda
](#wait-event.lwl-buffer-mapping.actions.indexes)
+ [

### Kurangi jumlah buffer yang harus dialokasikan dengan cepat
](#wait-event.lwl-buffer-mapping.actions.buffers)

### Pantau metrik terkait buffer
<a name="wait-event.lwl-buffer-mapping.actions.monitor-metrics"></a>

Saat `LWLock:buffer_mapping` menunggu lonjakan, selidiki rasio hit buffer. Anda dapat menggunakan metrik ini untuk mendapatkan pemahaman yang lebih baik tentang apa yang terjadi di cache buffer. Periksa metrik berikut:

`blks_hit`  
Metrik penghitung Wawasan Performa ini menunjukkan jumlah blok yang diambil dari pool buffer bersama. Setelah peristiwa tunggu `LWLock:buffer_mapping` muncul, Anda mungkin melihat lonjakan `blks_hit`.

`blks_read`  
Metrik penghitung Performance Insights ini menunjukkan jumlah blok yang perlu dibaca I/O ke dalam kumpulan buffer bersama. Anda mungkin melihat lonjakan `blks_read` menjelang peristiwa tunggu `LWLock:buffer_mapping`.

### Evaluasi strategi pengindeksan Anda
<a name="wait-event.lwl-buffer-mapping.actions.indexes"></a>

Untuk mengonfirmasi bahwa strategi pengindeksan Anda tidak menurunkan performa, periksa hal berikut:

Bloat indeks  
Pastikan bloat indeks dan tabel tidak menyebabkan halaman yang tidak perlu dibacakan ke buffer bersama. Jika tabel Anda berisi baris yang tidak digunakan, pertimbangkan untuk mengarsipkan datanya dan menghapus baris tersebut dari tabel. Anda kemudian dapat membuat kembali indeks untuk tabel yang diubah ukurannya.

Indeks untuk kueri yang sering digunakan  
Untuk menentukan apakah Anda memiliki indeks optimal, pantau metrik mesin DB di Wawasan Performa. Metrik `tup_returned` menunjukkan jumlah baris yang dibaca. Metrik `tup_fetched` menunjukkan jumlah baris yang dikembalikan ke klien. Jika `tup_returned` secara signifikan lebih besar dari `tup_fetched`, data mungkin tidak diindeks dengan benar. Selain itu, statistik tabel Anda mungkin tidak terkini.

### Kurangi jumlah buffer yang harus dialokasikan dengan cepat
<a name="wait-event.lwl-buffer-mapping.actions.buffers"></a>

Untuk mengurangi peristiwa tunggu `LWLock:buffer_mapping`, coba kurangi jumlah buffer yang harus dialokasikan dengan cepat. Salah satu strateginya adalah dengan melakukan operasi batch yang lebih kecil. Anda mungkin dapat memiliki batch yang lebih kecil dengan mempartisi tabel Anda.

# LWLock:Bufferio (IPC: Bufferio)
<a name="wait-event.lwlockbufferio"></a>

`LWLock:BufferIO`Peristiwa ini terjadi ketika RDS untuk PostgreSQL sedang menunggu proses lain untuk menyelesaikan operasi (I/O) input/output mereka ketika secara bersamaan mencoba mengakses halaman. Tujuannya adalah agar halaman yang sama dibacakan ke buffer bersama.

**Topics**
+ [

## Versi mesin yang relevan
](#wait-event.lwlockbufferio.context.supported)
+ [

## Konteks
](#wait-event.lwlockbufferio.context)
+ [

## Penyebab
](#wait-event.lwlockbufferio.causes)
+ [

## Tindakan
](#wait-event.lwlockbufferio.actions)

## Versi mesin yang relevan
<a name="wait-event.lwlockbufferio.context.supported"></a>

Informasi peristiwa tunggu ini relevan untuk semua versi RDS for PostgreSQL. Untuk RDS for PostgreSQL 12 dan versi sebelumnya peristiwa tunggu ini dinamai lwlock:buffer\$1io sedangkan di RDS for PostgreSQL versi 13 dinamai lwlock:bufferio. Mulai dari RDS for PostgreSQL versi 14, peristiwa tunggu BufferIO dipindahkan dari jenis peristiwa tunggu `LWLock` ke `IPC` (IPC:BufferIO). 

## Konteks
<a name="wait-event.lwlockbufferio.context"></a>

Setiap buffer bersama memiliki I/O kunci yang terkait dengan peristiwa `LWLock:BufferIO` tunggu, setiap kali blok (atau halaman) harus diambil di luar kumpulan buffer bersama.

Kunci ini digunakan untuk menangani beberapa sesi yang semuanya memerlukan akses ke blok yang sama. Blok ini harus dibaca dari luar pool buffer bersama, yang ditentukan oleh parameter `shared_buffers`.

Segera setelah halaman dibaca di dalam kumpulan buffer bersama, kunci `LWLock:BufferIO` akan dilepaskan.

**catatan**  
Peristiwa tunggu `LWLock:BufferIO` mendahului peristiwa tunggu [IO: DataFileRead](wait-event.iodatafileread.md). Peristiwa tunggu `IO:DataFileRead` terjadi saat data sedang dibaca dari penyimpanan.

Untuk informasi selengkapnya tentang kunci ringan, lihat [Gambaran Umum Penguncian](https://github.com/postgres/postgres/blob/65dc30ced64cd17f3800ff1b73ab1d358e92efd8/src/backend/storage/lmgr/README#L20).

## Penyebab
<a name="wait-event.lwlockbufferio.causes"></a>

Penyebab umum peristiwa `LWLock:BufferIO` muncul dalam peristiwa tunggu teratas mencakup yang berikut:
+ Beberapa backend atau koneksi mencoba mengakses halaman yang sama yang juga menunggu operasi I/O 
+ Rasio antara ukuran pool buffer bersama (ditentukan oleh parameter `shared_buffers`) dan jumlah buffer yang dibutuhkan oleh beban kerja saat ini
+ Ukuran pool buffer bersama tidak seimbang dengan jumlah halaman yang dikosongkan oleh operasi lain
+ Indeks besar atau bloat yang mengharuskan mesin membacakan lebih banyak halaman daripada yang diperlukan ke dalam pool buffer bersama
+ Kurangnya indeks yang memaksa mesin DB untuk membaca lebih banyak halaman dari tabel daripada yang diperlukan
+ Checkpoint terjadi terlalu sering atau perlu melakukan flushing terlalu banyak halaman yang dimodifikasi
+ Lonjakan tiba-tiba untuk koneksi basis data yang mencoba melakukan operasi pada halaman yang sama

## Tindakan
<a name="wait-event.lwlockbufferio.actions"></a>

Kami merekomendasikan berbagai tindakan tergantung pada penyebab peristiwa tunggu Anda:
+ Setel `max_wal_size` dan `checkpoint_timeout` berdasarkan waktu puncak beban kerja Anda jika Anda melihat `LWLock:BufferIO` bertepatan dengan penurunan metrik `BufferCacheHitRatio`. Kemudian, identifikasi kueri mana yang mungkin menyebabkannya.
+ Verifikasi apakah Anda memiliki indeks yang tidak digunakan, lalu hapus.
+ Gunakan tabel yang dipartisi (yang juga memiliki indeks yang dipartisi). Dengan melakukan hal ini, Anda dapat menjaga penyusunan ulang indeks tetap rendah dan mengurangi dampaknya.
+ Hindari kolom pengindeksan yang tidak perlu.
+ Cegah lonjakan koneksi basis data yang tiba-tiba dengan menggunakan pool koneksi.
+ Batasi jumlah maksimum koneksi ke basis data sebagai praktik terbaik.

# LWLock:buffer\$1content (BufferContent)
<a name="wait-event.lwlockbuffercontent"></a>

Peristiwa `LWLock:buffer_content` terjadi saat suatu sesi menunggu untuk membaca atau menulis halaman data di memori sementara sesi lain mengunci halaman tersebut untuk penulisan. Di RDS for PostgreSQL 13 dan yang lebih tinggi, peristiwa tunggu ini disebut `BufferContent`.

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.lwlockbuffercontent.context.supported)
+ [

## Konteks
](#wait-event.lwlockbuffercontent.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.lwlockbuffercontent.causes)
+ [

## Tindakan
](#wait-event.lwlockbuffercontent.actions)

## Versi mesin yang didukung
<a name="wait-event.lwlockbuffercontent.context.supported"></a>

Informasi peristiwa tunggu ini didukung untuk semua versi RDS for PostgreSQL.

## Konteks
<a name="wait-event.lwlockbuffercontent.context"></a>

Untuk membaca atau memanipulasi data, PostgreSQL mengaksesnya melalui buffer memori bersama. Untuk membaca dari buffer, proses mendapatkan kunci ringan (LWLock) pada konten buffer dalam mode bersama. Untuk menulis ke buffer, proses ini mendapatkan kunci tersebut dalam mode eksklusif. Kunci bersama memungkinkan proses lain untuk secara konkuren memperoleh kunci bersama pada konten tersebut. Kunci eksklusif mencegah proses lain mendapatkan jenis kunci apa pun.

Peristiwa `LWLock:buffer_content` (`BufferContent`) menunjukkan bahwa beberapa proses mencoba mendapatkan kunci pada konten buffer tertentu.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.lwlockbuffercontent.causes"></a>

Saat peristiwa `LWLock:buffer_content` (`BufferContent`) muncul lebih dari biasanya, yang mungkin menunjukkan adanya masalah performa, berikut adalah penyebab umumnya:

**Peningkatan pembaruan konkuren ke data yang sama**  
Mungkin ada peningkatan jumlah sesi konkuren dengan kueri yang memperbarui konten buffer yang sama. Pertentangan ini bisa lebih terlihat pada tabel dengan banyak indeks.

**Data beban kerja tidak ada dalam memori**  
Saat data yang diproses oleh beban kerja aktif tidak ada dalam memori, peristiwa tunggu ini dapat meningkat. Efek ini terjadi karena proses yang memegang kunci dapat mempertahankannya lebih lama saat melakukan operasi I/O disk.

**Penggunaan batasan kunci asing yang berlebihan**  
Batasan kunci asing dapat meningkatkan jumlah waktu saat sebuah proses memegang kunci konten buffer. Efek ini terjadi karena operasi baca memerlukan kunci konten buffer bersama pada kunci yang direferensikan saat kunci tersebut diperbarui.

## Tindakan
<a name="wait-event.lwlockbuffercontent.actions"></a>

Kami merekomendasikan berbagai tindakan, tergantung pada penyebab peristiwa tunggu Anda. Anda dapat mengidentifikasi peristiwa `LWLock:buffer_content` (`BufferContent`) dengan menggunakan Wawasan Performa Amazon RDS atau dengan mengkueri tampilan `pg_stat_activity`.

**Topics**
+ [

### Meningkatkan efisiensi dalam memori
](#wait-event.lwlockbuffercontent.actions.in-memory)
+ [

### Kurangi penggunaan batasan kunci asing
](#wait-event.lwlockbuffercontent.actions.foreignkey)
+ [

### Hapus indeks yang tidak digunakan
](#wait-event.lwlockbuffercontent.actions.indexes)
+ [

### Tingkatkan ukuran cache saat menggunakan urutan
](#wait-event.lwlockbuffercontent.actions.sequences)

### Meningkatkan efisiensi dalam memori
<a name="wait-event.lwlockbuffercontent.actions.in-memory"></a>

Untuk meningkatkan kemungkinan data beban kerja aktif ada di memori, partisi tabel atau naikkan skala kelas instans Anda. Untuk informasi tentang kelas instans DB, lihat [ DB](Concepts.DBInstanceClass.md).

### Kurangi penggunaan batasan kunci asing
<a name="wait-event.lwlockbuffercontent.actions.foreignkey"></a>

Selidiki beban kerja yang mengalami jumlah peristiwa tunggu `LWLock:buffer_content` (`BufferContent`) yang tinggi untuk penggunaan batasan kunci asing. Hapus batasan kunci asing yang tidak perlu.

### Hapus indeks yang tidak digunakan
<a name="wait-event.lwlockbuffercontent.actions.indexes"></a>

Untuk beban kerja yang mengalami jumlah peristiwa tunggu `LWLock:buffer_content` (`BufferContent`) yang tinggi, identifikasi indeks yang tidak digunakan, lalu hapus.

### Tingkatkan ukuran cache saat menggunakan urutan
<a name="wait-event.lwlockbuffercontent.actions.sequences"></a>

Jika tabel Anda menggunakan urutan, tingkatkan ukuran cache untuk menghapus pertentangan pada halaman urutan dan halaman indeks. Setiap urutan adalah satu halaman dalam memori bersama. Cache yang telah ditentukan adalah per koneksi. Ini mungkin tidak cukup untuk menangani beban kerja ketika banyak sesi konkuren mendapatkan nilai urutan. 

# LWLock:lock\$1manager (manajer kunci) LWLock
<a name="wait-event.lw-lock-manager"></a>

Peristiwa ini terjadi saat mesin RDS for PostgreSQL mempertahankan area memori kunci bersama untuk mengalokasikan, memeriksa, dan mendealokasikan kunci saat kunci jalur cepat tidak memungkinkan.

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.lw-lock-manager.context.supported)
+ [

## Konteks
](#wait-event.lw-lock-manager.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.lw-lock-manager.causes)
+ [

## Tindakan
](#wait-event.lw-lock-manager.actions)

## Versi mesin yang didukung
<a name="wait-event.lw-lock-manager.context.supported"></a>

Informasi peristiwa tunggu ini relevan untuk RDS for PostgreSQL versi 9.6 dan lebih tinggi. Untuk rilis RDS for PostgreSQL yang lebih lama dari versi 13, nama peristiwa tunggu ini adalah `LWLock:lock_manager`. Untuk RDS for PostgreSQL versi 13 dan yang lebih tinggi, nama peristiwa tunggu ini adalah `LWLock:lockmanager`. 

## Konteks
<a name="wait-event.lw-lock-manager.context"></a>

Saat Anda mengeluarkan pernyataan SQL, RDS for PostgreSQL mencatat kunci untuk melindungi struktur, data, dan integritas basis data Anda selama operasi konkuren. Mesin dapat mencapai tujuan ini menggunakan kunci jalur cepat atau kunci jalur yang tidak cepat. Kunci jalur yang tidak cepat lebih mahal dan menghasilkan lebih banyak overhead daripada kunci jalur cepat.

### Penguncian jalur cepat
<a name="wait-event.lw-lock-manager.context.fast-path"></a>

Untuk mengurangi overhead kunci yang sering diambil dan dilepaskan, tetapi jarang bertentangan, proses backend dapat menggunakan penguncian jalur cepat. Basis data menggunakan mekanisme ini untuk kunci yang memenuhi kriteria berikut:
+ Kunci tersebut menggunakan metode kunci DEFAULT.
+ Kunci tersebut merepresentasikan kunci pada relasi basis data, bukan relasi bersama.
+ Kunci tersebut adalah kunci lemah yang tidak mungkin bertentangan.
+ Mesin dapat dengan cepat memverifikasi bahwa tidak ada kunci yang mungkin dapat bertentangan.

Mesin tidak dapat menggunakan penguncian jalur cepat jika salah satu kondisi berikut ini berlaku:
+ Kunci tidak memenuhi kriteria di atas.
+ Tidak ada lagi slot yang tersedia untuk proses backend.

Untuk menyetel kueri Anda untuk penguncian jalur cepat, Anda dapat menggunakan kueri berikut.

```
SELECT count(*), pid, mode, fastpath
  FROM pg_locks
 WHERE fastpath IS NOT NULL
 GROUP BY 4,3,2
 ORDER BY pid, mode;
 count | pid  |      mode       | fastpath
-------+------+-----------------+----------
16 | 9185 | AccessShareLock | t
336 | 9185 | AccessShareLock | f
1 | 9185 | ExclusiveLock   | t
```

Kueri berikut hanya menunjukkan total di seluruh basis data.

```
SELECT count(*), mode, fastpath
  FROM pg_locks
 WHERE fastpath IS NOT NULL
 GROUP BY 3,2
 ORDER BY mode,1;
count |      mode       | fastpath
-------+-----------------+----------
16 | AccessShareLock | t
337 | AccessShareLock | f
1 | ExclusiveLock   | t
(3 rows)
```

Untuk informasi selengkapnya tentang penguncian jalur cepat, lihat [fast path](https://github.com/postgres/postgres/blob/master/src/backend/storage/lmgr/README#L70-L76) dalam README pengelola kunci PostgreSQL dan [pg-locks](https://www.postgresql.org/docs/9.3/view-pg-locks.html#AEN98195) dalam dokumentasi PostgreSQL. 

### Contoh masalah penskalaan untuk pengelola kunci
<a name="wait-event.lw-lock-manager.context.lock-manager"></a>

Dalam contoh ini, tabel bernama `purchases` menyimpan data dari rentang waktu lima tahun, yang dipartisi berdasarkan hari. Setiap partisi memiliki dua indeks. Urutan peristiwa berikut terjadi:

1. Anda mengueri data dari rentang waktu beberapa hari, yang mengharuskan basis data untuk membaca banyak partisi.

1. Basis data membuat entri kunci untuk setiap partisi. Jika indeks partisi adalah bagian dari jalur akses pengoptimisasi, basis data juga akan membuat entri kunci untuk indeks tersebut.

1. Saat jumlah entri kunci yang diminta untuk proses backend yang sama lebih tinggi dari 16, yang merupakan nilai `FP_LOCK_SLOTS_PER_BACKEND`, pengelola kunci menggunakan metode kunci jalur yang tidak cepat.

Aplikasi modern mungkin memiliki ratusan sesi. Jika sesi konkuren mengueri induk tanpa pemangkasan partisi yang tepat, basis data mungkin membuat ratusan atau bahkan ribuan kunci jalur yang tidak cepat. Biasanya, ketika konkurensi ini lebih tinggi dari jumlah vCPUs, acara `LWLock:lock_manager` tunggu muncul.

**catatan**  
Peristiwa tunggu `LWLock:lock_manager` tidak terkait dengan jumlah partisi atau indeks dalam skema basis data. Sebagai gantinya, hal ini terkait dengan jumlah kunci jalur yang tidak cepat yang harus dikontrol oleh basis data.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.lw-lock-manager.causes"></a>

Saat peristiwa tunggu `LWLock:lock_manager` terjadi lebih sering dari biasanya, yang mungkin menunjukkan masalah performa, kemungkinan penyebab lonjakan yang mendadak ini adalah sebagai berikut:
+ Sesi aktif konkuren menjalankan kueri yang tidak menggunakan kunci jalur cepat. Sesi ini juga melebihi vCPU maksimum.
+ Sejumlah besar sesi aktif konkuren mengakses tabel yang memiliki banyak partisi. Setiap partisi memiliki beberapa indeks.
+ Basis data mengalami badai koneksi. Secara default, beberapa aplikasi dan perangkat lunak pool koneksi akan membuat lebih banyak koneksi ketika basis data lambat. Praktik ini memperburuk masalahnya. Setel perangkat lunak pool koneksi Anda sehingga badai koneksi tidak terjadi.
+ Sejumlah besar sesi mengueri tabel induk tanpa memangkas partisi.
+ Bahasa definisi data (DL), bahasa manipulasi data (DL), atau perintah pemeliharaan secara khusus mengunci relasi sibuk atau tuple yang sering diakses atau dimodifikasi.

## Tindakan
<a name="wait-event.lw-lock-manager.actions"></a>

Jika peristiwa tunggu `CPU` terjadi, hal ini tidak selalu menunjukkan masalah performa. Tanggapi peristiwa ini hanya ketika performa menurun dan peristiwa tunggu ini mendominasi beban DB.

**Topics**
+ [

### Gunakan pemangkasan partisi
](#wait-event.lw-lock-manager.actions.pruning)
+ [

### Hapus indeks yang tidak perlu
](#wait-event.lw-lock-manager.actions.indexes)
+ [

### Setel kueri Anda untuk penguncian jalur cepat
](#wait-event.lw-lock-manager.actions.tuning)
+ [

### Setel peristiwa tunggu lainnya
](#wait-event.lw-lock-manager.actions.other-waits)
+ [

### Kurangi bottleneck perangkat keras
](#wait-event.lw-lock-manager.actions.hw-bottlenecks)
+ [

### Gunakan pooler koneksi
](#wait-event.lw-lock-manager.actions.pooler)
+ [

### Tingkatkan versi RDS for PostgreSQL Anda
](#wait-event.lw-lock-manager.actions.pg-version)

### Gunakan pemangkasan partisi
<a name="wait-event.lw-lock-manager.actions.pruning"></a>

*Pemangkasan partisi* adalah strategi optimisasi kueri untuk tabel yang dipartisi secara deklaratif yang mengecualikan partisi yang tidak dibutuhkan dari pemindaian tabel, sehingga meningkatkan performa. Pemangkasan partisi diaktifkan secara default. Jika dinonaktifkan, aktifkan sebagai berikut.

```
SET enable_partition_pruning = on;
```

Kueri dapat memanfaatkan pemangkasan partisi ketika klausa `WHERE`-nya berisi kolom yang digunakan untuk pembuatan partisi. Untuk informasi selengkapnya, lihat [Partition Pruning](https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITION-PRUNING) dalam dokumentasi PostgreSQL.

### Hapus indeks yang tidak perlu
<a name="wait-event.lw-lock-manager.actions.indexes"></a>

Basis data Anda mungkin berisi indeks yang tidak digunakan atau jarang digunakan. Jika demikian, pertimbangkan untuk menghapusnya. Lakukan salah satu dari langkah berikut:
+ Pelajari cara menemukan indeks yang tidak perlu dengan membaca [Indeks yang Tidak Digunakan](https://wiki.postgresql.org/wiki/Index_Maintenance#Unused_Indexes) di wiki PostgreSQL.
+ Jalankan PG Collector. Skrip SQL ini mengumpulkan informasi basis data dan menyajikannya dalam laporan HTML terkonsolidasi. Periksa bagian “Indeks yang tidak digunakan”. Untuk informasi selengkapnya, lihat [pg-collector di repositori](https://github.com/awslabs/pg-collector) AWS Labs GitHub .

### Setel kueri Anda untuk penguncian jalur cepat
<a name="wait-event.lw-lock-manager.actions.tuning"></a>

Untuk mengetahui apakah kueri Anda menggunakan penguncian jalur cepat, buat kueri pada kolom `fastpath` dalam tabel `pg_locks`. Jika kueri Anda tidak menggunakan penguncian jalur cepat, coba kurangi jumlah relasi per kueri menjadi kurang dari 16.

### Setel peristiwa tunggu lainnya
<a name="wait-event.lw-lock-manager.actions.other-waits"></a>

Jika `LWLock:lock_manager` adalah yang pertama atau kedua dalam daftar peristiwa tunggu teratas, periksa apakah peristiwa tunggu berikut juga ditampilkan pada daftar ini:
+ `Lock:Relation`
+ `Lock:transactionid`
+ `Lock:tuple`

Jika peristiwa di atas ditampilkan pada posisi tinggi dalam daftar, pertimbangkan untuk menyetel peristiwa tunggu ini terlebih dahulu. Peristiwa ini dapat menjadi pendorong untuk `LWLock:lock_manager`.

### Kurangi bottleneck perangkat keras
<a name="wait-event.lw-lock-manager.actions.hw-bottlenecks"></a>

Anda mungkin memiliki bottleneck perangkat keras, seperti kelaparan CPU atau penggunaan maksimum bandwidth Amazon EBS Anda. Jika demikian, maka pertimbangkan untuk mengurangi bottleneck perangkat keras. Pertimbangkan tindakan berikut:
+ Naikkan kelas instans Anda.
+ Optimalkan kueri yang mengonsumsi CPU dan memori dalam jumlah besar.
+ Ubah logika aplikasi Anda.
+ Arsipkan data Anda.

Untuk informasi selengkapnya tentang CPU, memori, dan bandwidth jaringan EBS, lihat [Jenis Instans Amazon RDS](https://aws.amazon.com/rds/instance-types/).

### Gunakan pooler koneksi
<a name="wait-event.lw-lock-manager.actions.pooler"></a>

Jika jumlah total koneksi aktif Anda melebihi vCPU maksimum, lebih banyak proses OS akan memerlukan CPU yang melampaui kapasitas yang dapat didukung oleh jenis instans Anda. Jika demikian, pertimbangkan untuk menggunakan atau menyetel pool koneksi. Untuk informasi selengkapnya tentang v CPUs untuk jenis instans Anda, lihat [Jenis Instans Amazon RDS](https://aws.amazon.com/rds/instance-types/).

Untuk informasi selengkapnya tentang pooling koneksi, lihat sumber daya berikut:
+ [Proksi Amazon RDS Aurora](rds-proxy.md)
+ [pgbouncer](http://www.pgbouncer.org/usage.html)
+ [Connection Pools and Data Sources](https://www.postgresql.org/docs/7.4/jdbc-datasource.html) dalam *dokumentasi PostgreSQL*

### Tingkatkan versi RDS for PostgreSQL Anda
<a name="wait-event.lw-lock-manager.actions.pg-version"></a>

Jika versi RDS for PostgreSQL Anda saat ini lebih rendah dari 12, tingkatkan ke versi 12 atau lebih tinggi. PostgreSQL versi 12 dan yang lebih baru memiliki mekanisme partisi yang ditingkatkan. Untuk informasi selengkapnya tentang versi 12, lihat [Catatan Rilis PostgreSQL 12.0]( https://www.postgresql.org/docs/release/12.0/). Untuk informasi selengkapnya tentang meningkatkan RDS for PostgreSQL, lihat [Upgrade RDS untuk mesin PostgreSQL DB](USER_UpgradeDBInstance.PostgreSQL.md).

# LWLock:pg\$1stat\$1statement
<a name="apg-rpg-lwlockpgstat"></a>

Peristiwa LWLock tunggu: PG\$1STAT\$1Statements terjadi ketika ekstensi `pg_stat_statements` mengambil kunci eksklusif pada tabel hash yang melacak pernyataan SQL. Ini terjadi dalam skenario berikut:
+ Ketika jumlah pernyataan yang dilacak mencapai nilai `pg_stat_statements.max` parameter yang dikonfigurasi dan ada kebutuhan untuk memberi ruang untuk lebih banyak entri, ekstensi melakukan pengurutan pada jumlah panggilan, menghapus 5% dari pernyataan yang paling tidak dieksekusi, dan mengisi ulang hash dengan entri yang tersisa.
+ Ketika `pg_stat_statements` melakukan `garbage collection` operasi ke `pgss_query_texts.stat` file pada disk dan menulis ulang file.

**Topics**
+ [

## Versi mesin yang didukung
](#apg-rpg-lwlockpgstat.supported)
+ [

## Konteks
](#apg-rpg-lwlockpgstat.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#apg-rpg-lwlockpgstat.causes)
+ [

## Tindakan
](#apg-rpg-lwlockpgstat.actions)

## Versi mesin yang didukung
<a name="apg-rpg-lwlockpgstat.supported"></a>

 

## Konteks
<a name="apg-rpg-lwlockpgstat.context"></a>

**Memahami ekstensi pg\$1stat\$1statement - Ekstensi** pg\$1stat\$1statement melacak statistik eksekusi pernyataan SQL dalam tabel hash. Ekstensi melacak pernyataan SQL hingga batas yang ditentukan oleh `pg_stat_statements.max` parameter. Parameter ini menentukan jumlah maksimum pernyataan yang dapat dilacak yang sesuai dengan jumlah maksimum baris dalam tampilan pg\$1stat\$1statement.

**Persistensi statistik pernyataan** — Ekstensi mempertahankan statistik pernyataan di seluruh instans dimulai ulang dengan:
+ Menulis data ke file bernama pg\$1stat\$1statements.stat
+ Menggunakan parameter pg\$1stat\$1statements.save untuk mengontrol perilaku persistensi

Ketika pg\$1stat\$1statements.save diatur ke:
+ aktif (default): Statistik disimpan saat shutdown dan dimuat ulang saat server dimulai
+ off: Statistik tidak disimpan saat shutdown atau dimuat ulang saat server dimulai

**Penyimpanan teks kueri** — Ekstensi menyimpan teks kueri yang dilacak dalam file bernama. `pgss_query_texts.stat` File ini dapat tumbuh menjadi dua kali lipat ukuran rata-rata semua pernyataan SQL yang dilacak sebelum pengumpulan sampah terjadi. Ekstensi memerlukan kunci eksklusif pada tabel hash selama operasi pembersihan dan menulis ulang `pgss_query_texts.stat` file.

**Proses deallocation pernyataan** — Ketika jumlah pernyataan yang dilacak mencapai `pg_stat_statements.max` batas dan pernyataan baru perlu dilacak, ekstensi:
+ Mengambil kunci eksklusif: pg\$1stat\$1statement) LWLock pada tabel hash.
+ Memuat data yang ada ke dalam memori lokal.
+ Melakukan quicksort berdasarkan jumlah panggilan.
+ Menghapus pernyataan yang paling tidak disebut (5% bawah).
+ Mengisi ulang tabel hash dengan entri yang tersisa.

**Monitoring statement deallocation** — Di PostgreSQL 14 dan yang lebih baru, Anda dapat memantau deallocation pernyataan menggunakan tampilan pg\$1stat\$1statements\$1info. Tampilan ini mencakup kolom dealloc yang menunjukkan berapa kali pernyataan dialokasikan untuk memberi ruang bagi yang baru

Jika deallocation pernyataan sering terjadi, itu akan menyebabkan pengumpulan sampah `pgss_query_texts.stat` file yang lebih sering pada disk.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="apg-rpg-lwlockpgstat.causes"></a>

Penyebab khas peningkatan `LWLock:pg_stat_statements` menunggu meliputi:
+ Peningkatan jumlah kueri unik yang digunakan oleh aplikasi.
+ Nilai `pg_stat_statements.max` parameter menjadi kecil dibandingkan dengan jumlah query unik yang digunakan.

## Tindakan
<a name="apg-rpg-lwlockpgstat.actions"></a>

Kami merekomendasikan berbagai tindakan, tergantung pada penyebab peristiwa tunggu Anda. Anda dapat mengidentifikasi `LWLock:pg_stat_statements` peristiwa dengan menggunakan Amazon RDS Performance Insights atau dengan menanyakan tampilan. `pg_stat_activity`

Sesuaikan `pg_stat_statements` parameter berikut untuk mengontrol perilaku pelacakan dan kurangi: LWLock pg\$1stat\$1 statement wait events.

**Topics**
+ [

### Nonaktifkan parameter pg\$1stat\$1statements.track
](#apg-rpg-lwlockpgstat.actions.disabletrack)
+ [

### Meningkatkan parameter pg\$1stat\$1statements.max
](#apg-rpg-lwlockpgstat.actions.increasemax)
+ [

### Nonaktifkan parameter pg\$1stat\$1statements.track\$1utility
](#apg-rpg-lwlockpgstat.actions.disableutility)

### Nonaktifkan parameter pg\$1stat\$1statements.track
<a name="apg-rpg-lwlockpgstat.actions.disabletrack"></a>

Jika peristiwa:pg\$1stat\$1statement LWLock wait berdampak buruk pada kinerja database, dan solusi cepat diperlukan sebelum analisis lebih lanjut dari tampilan `pg_stat_statements` untuk mengidentifikasi akar penyebab, parameter dapat dinonaktifkan dengan menyetelnya ke. `pg_stat_statements.track` `none` Ini akan menonaktifkan pengumpulan statistik pernyataan.

### Meningkatkan parameter pg\$1stat\$1statements.max
<a name="apg-rpg-lwlockpgstat.actions.increasemax"></a>

Untuk mengurangi deallocation dan meminimalkan pengumpulan sampah `pgss_query_texts.stat` file pada disk, tingkatkan nilai `pg_stat_statements.max` parameter. Nilai default-nya adalah `5,000`.

**catatan**  
`pg_stat_statements.max`Parameternya statis. Anda harus memulai ulang instans DB Anda untuk menerapkan perubahan apa pun pada parameter ini. 

### Nonaktifkan parameter pg\$1stat\$1statements.track\$1utility
<a name="apg-rpg-lwlockpgstat.actions.disableutility"></a>

Anda dapat menganalisis tampilan pg\$1stat\$1statement untuk menentukan perintah utilitas mana yang paling banyak menggunakan sumber daya yang dilacak. `pg_stat_statements`

`pg_stat_statements.track_utility`Parameter mengontrol apakah modul melacak perintah utilitas, yang mencakup semua perintah kecuali SELECT, INSERT, UPDATE, DELETE, dan MERGE. Secara default, parameter ini diatur ke`on`.

Misalnya, ketika aplikasi Anda menggunakan banyak kueri savepoint, yang secara inheren unik, itu dapat meningkatkan deallocation pernyataan. Untuk mengatasinya, Anda dapat menonaktifkan `pg_stat_statements.track_utility` parameter untuk berhenti melacak `pg_stat_statements` kueri savepoint.

**catatan**  
`pg_stat_statements.track_utility`Parameternya adalah parameter dinamis. Anda dapat mengubah nilainya tanpa memulai ulang instance database Anda.

**Example Contoh kueri titik simpan unik di pg\$1stat\$1statement**  <a name="savepoint-queries"></a>

```
                     query                       |       queryid       
-------------------------------------------------+---------------------
 SAVEPOINT JDBC_SAVEPOINT_495701                 | -7249565344517699703
 SAVEPOINT JDBC_SAVEPOINT_1320                   | -1572997038849006629
 SAVEPOINT JDBC_SAVEPOINT_26739                  |  54791337410474486
 SAVEPOINT JDBC_SAVEPOINT_1294466                |  8170064357463507593
 ROLLBACK TO SAVEPOINT JDBC_SAVEPOINT_65016      | -33608214779996400
 SAVEPOINT JDBC_SAVEPOINT_14185                  | -2175035613806809562
 SAVEPOINT JDBC_SAVEPOINT_45837                  | -6201592986750645383
 SAVEPOINT JDBC_SAVEPOINT_1324                   |  6388797791882029332
```

PostgreSQL 17 memperkenalkan beberapa penyempurnaan untuk pelacakan perintah utilitas:
+ Nama Savepoint sekarang ditampilkan sebagai konstanta.
+ Global Transaction IDs (GIDs) dari perintah komit dua fase sekarang ditampilkan sebagai konstanta.
+ Nama pernyataan DEALLOCATE ditampilkan sebagai konstanta.
+ Parameter CALL sekarang ditampilkan sebagai konstanta.

# LWLock:subtransslru (:) LWLock SubtransControlLock
<a name="wait-event.lwlocksubtransslru"></a>

Peristiwa `LWLock:SubtransSLRU` dan `LWLock:SubtransBuffer` tunggu menunjukkan bahwa sesi sedang menunggu untuk mengakses cache sederhana yang paling tidak baru digunakan (SLRU) untuk informasi subtransaksi. Ini terjadi ketika menentukan visibilitas transaksi dan hubungan orang tua-anak.
+ `LWLock:SubtransSLRU`: Sebuah proses sedang menunggu untuk mengakses cache sederhana yang paling tidak baru digunakan (SLRU) untuk subtransaksi. Dalam RDS untuk PostgreSQL sebelum versi 13, acara tunggu ini dipanggil. `SubtransControlLock`
+ `LWLock:SubtransBuffer`: Sebuah proses I/O sedang menunggu buffer sederhana yang paling tidak baru digunakan (SLRU) untuk subtransaksi. Dalam RDS untuk PostgreSQL sebelum versi 13, acara tunggu ini dipanggil. `subtrans`

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.lwlocksubtransslru.supported)
+ [

## Konteks
](#wait-event.lwlocksubtransslru.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.lwlocksubtransslru.causes)
+ [

## Tindakan
](#wait-event.lwlocksubtransslru.actions)

## Versi mesin yang didukung
<a name="wait-event.lwlocksubtransslru.supported"></a>

Informasi peristiwa tunggu ini didukung untuk semua versi RDS for PostgreSQL.

## Konteks
<a name="wait-event.lwlocksubtransslru.context"></a>

**Memahami subtransaksi** — Subtransaksi adalah transaksi dalam transaksi di PostgreSQL. Ini juga dikenal sebagai transaksi bersarang.

Subtransaksi biasanya dibuat saat Anda menggunakan:
+ `SAVEPOINT`perintah
+ Blok pengecualian (`BEGIN/EXCEPTION/END`)

Subtransaksi memungkinkan Anda memutar kembali bagian transaksi tanpa mempengaruhi seluruh transaksi. Ini memberi Anda kontrol halus atas manajemen transaksi.

**Detail implementasi** - PostgreSQL mengimplementasikan subtransaksi sebagai struktur bersarang dalam transaksi utama. Setiap subtransaksi mendapatkan ID transaksinya sendiri.

Aspek implementasi kunci:
+ Transaksi IDs dilacak di `pg_xact`
+ Hubungan orangtua-anak disimpan dalam subdirektori di bawah `pg_subtrans` `PGDATA`
+ Setiap sesi database dapat mempertahankan hingga `64` subtransaksi aktif
+ Melebihi batas ini menyebabkan luapan subtransaksi, yang mengharuskan mengakses cache sederhana yang paling tidak baru digunakan (SLRU) untuk informasi subtransaksi

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.lwlocksubtransslru.causes"></a>

Penyebab umum pertengkaran SLRU subtransaksi meliputi:
+ **Penggunaan berlebihan penanganan SAVEPOINT dan EXCEPTION** — PL/pgSQL prosedur dengan `EXCEPTION` handler secara otomatis membuat savepoint implisit, terlepas dari apakah pengecualian terjadi. Masing-masing `SAVEPOINT` memulai subtransaksi baru. Ketika satu transaksi mengakumulasi lebih dari 64 subtransaksi, itu memicu overflow SLRU subtransaksi.
+ **Konfigurasi driver dan ORM** — `SAVEPOINT` penggunaan dapat eksplisit dalam kode aplikasi atau implisit melalui konfigurasi driver. Banyak alat ORM dan kerangka kerja aplikasi yang umum digunakan mendukung transaksi bersarang secara native. Berikut adalah beberapa contoh umum:
  + Parameter driver JDBC`autosave`, jika disetel ke `always` atau`conservative`, menghasilkan savepoint sebelum setiap kueri.
  + Definisi transaksi Spring Framework saat disetel ke`propagation_nested`.
  + Rel saat `requires_new: true` diatur.
  + SQLAlchemy kapan `session.begin_nested` digunakan.
  + Django ketika `atomic()` blok bersarang digunakan.
  + GORM saat `Savepoint` digunakan.
  + psqlodbc ketika pengaturan tingkat rollback diatur ke rollback tingkat pernyataan (misalnya,). `PROTOCOL=7.4-2`
+ **Beban kerja bersamaan yang tinggi dengan transaksi dan subtransaksi yang berjalan lama — Ketika overflow SLRU subtransaksi terjadi selama beban kerja** bersamaan yang tinggi dan transaksi serta subtransaksi yang berjalan lama, PostgreSQL mengalami peningkatan pertengkaran. Ini bermanifestasi sebagai peristiwa menunggu `LWLock:SubtransBuffer` dan `LWLock:SubtransSLRU` mengunci yang tinggi.

## Tindakan
<a name="wait-event.lwlocksubtransslru.actions"></a>

Kami merekomendasikan berbagai tindakan, tergantung pada penyebab peristiwa tunggu Anda. Beberapa tindakan memberikan bantuan segera, sementara yang lain memerlukan penyelidikan dan koreksi jangka panjang.

**Topics**
+ [

### Memantau penggunaan subtransaksi
](#wait-event.lwlocksubtransslru.actions.monitor)
+ [

### Mengkonfigurasi parameter memori
](#wait-event.lwlocksubtransslru.actions.memory)
+ [

### Tindakan jangka panjang
](#wait-event.lwlocksubtransslru.actions.longterm)

### Memantau penggunaan subtransaksi
<a name="wait-event.lwlocksubtransslru.actions.monitor"></a>

Untuk PostgreSQL versi 16.1 dan yang lebih baru, gunakan kueri berikut untuk memantau jumlah subtransaksi dan status overflow per backend. Kueri ini menggabungkan statistik backend dengan informasi aktivitas untuk menunjukkan proses mana yang menggunakan subtransaksi:

```
SELECT a.pid, usename, query, state, wait_event_type,
       wait_event, subxact_count, subxact_overflowed
FROM (SELECT id, pg_stat_get_backend_pid(id) pid, subxact_count, subxact_overflowed
      FROM pg_stat_get_backend_idset() id
           JOIN LATERAL pg_stat_get_backend_subxact(id) AS s ON true
     ) a
JOIN pg_stat_activity b ON a.pid = b.pid;
```

Untuk PostgreSQL versi 13.3 dan yang lebih baru, pantau `pg_stat_slru` tampilan untuk tekanan cache subtransaction. Kueri SQL berikut mengambil statistik cache SLRU untuk komponen Subtrans:

```
SELECT * FROM pg_stat_slru WHERE name = 'Subtrans';
```

`blks_read`Nilai yang meningkat secara konsisten menunjukkan akses disk yang sering untuk subtransaksi yang tidak di-cache, menandakan potensi tekanan cache SLRU.

### Mengkonfigurasi parameter memori
<a name="wait-event.lwlocksubtransslru.actions.memory"></a>

Untuk PostgreSQL 17.1 dan yang lebih baru, Anda dapat mengonfigurasi ukuran cache SLRU subtransaksi menggunakan parameter. `subtransaction_buffers` Contoh konfigurasi berikut menunjukkan cara mengatur parameter buffer subtransaction:

```
subtransaction_buffers = 128
```

Parameter ini menentukan jumlah memori bersama yang digunakan untuk cache konten subtransaksi ()`pg_subtrans`. Ketika ditentukan tanpa unit, nilai mewakili blok `BLCKSZ` byte, biasanya 8KB masing-masing. Misalnya, mengatur nilai ke 128 mengalokasikan 1MB (128 \$1 8kB) memori untuk cache subtransaksi.

**catatan**  
Anda dapat mengatur parameter ini di tingkat cluster sehingga semua instance tetap konsisten. Uji dan sesuaikan nilainya agar sesuai dengan persyaratan beban kerja spesifik dan kelas instance Anda. Anda harus me-reboot instance writer agar perubahan parameter diterapkan.

### Tindakan jangka panjang
<a name="wait-event.lwlocksubtransslru.actions.longterm"></a>
+ **Periksa kode dan konfigurasi aplikasi** — Tinjau kode aplikasi dan konfigurasi driver database Anda untuk penggunaan eksplisit dan implisit serta `SAVEPOINT` penggunaan subtransaksi secara umum. Identifikasi transaksi yang berpotensi menghasilkan lebih dari 64 subtransaksi.
+ **Kurangi penggunaan savepoint** — Minimalkan penggunaan savepoint dalam transaksi Anda:
  + Tinjau PL/pgSQL prosedur dan fungsi dengan blok EXCEPTION. Blok EXCEPTION secara otomatis membuat savepoint implisit, yang dapat berkontribusi pada overflow subtransaksi. Setiap klausa EXCEPTION membuat subtransaksi, terlepas dari apakah pengecualian benar-benar terjadi selama eksekusi.  
**Example**  

    Contoh 1: Penggunaan blok PENGECUALIAN yang bermasalah

    Contoh kode berikut menunjukkan penggunaan blok EXCEPTION bermasalah yang menciptakan beberapa subtransaksi:

    ```
    CREATE OR REPLACE FUNCTION process_user_data()
    RETURNS void AS $$
    DECLARE
        user_record RECORD;
    BEGIN
        FOR user_record IN SELECT * FROM users LOOP
            BEGIN
                -- This creates a subtransaction for each iteration
                INSERT INTO user_audit (user_id, action, timestamp)
                VALUES (user_record.id, 'processed', NOW());
                
                UPDATE users 
                SET last_processed = NOW() 
                WHERE id = user_record.id;
                
            EXCEPTION
                WHEN unique_violation THEN
                    -- Handle duplicate audit entries
                    UPDATE user_audit 
                    SET timestamp = NOW() 
                    WHERE user_id = user_record.id AND action = 'processed';
            END;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
    ```

    Contoh kode yang ditingkatkan berikut mengurangi penggunaan subtransaksi dengan menggunakan UPSERT alih-alih penanganan pengecualian:

    ```
    CREATE OR REPLACE FUNCTION process_user_data()
    RETURNS void AS $$
    DECLARE
        user_record RECORD;
    BEGIN
        FOR user_record IN SELECT * FROM users LOOP
            -- Use UPSERT to avoid exception handling
            INSERT INTO user_audit (user_id, action, timestamp)
            VALUES (user_record.id, 'processed', NOW())
            ON CONFLICT (user_id, action) 
            DO UPDATE SET timestamp = NOW();
            
            UPDATE users 
            SET last_processed = NOW() 
            WHERE id = user_record.id;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
    ```  
**Example**  

    Contoh 2: Penangan pengecualian KETAT

    Contoh kode berikut menunjukkan penanganan EXCEPTION bermasalah dengan NO\$1DATA\$1FOUND:

    ```
    CREATE OR REPLACE FUNCTION get_user_email(p_user_id INTEGER)
    RETURNS TEXT AS $$
    DECLARE
        user_email TEXT;
    BEGIN
        BEGIN
            -- STRICT causes an exception if no rows or multiple rows found
            SELECT email INTO STRICT user_email 
            FROM users 
            WHERE id = p_user_id;
            
            RETURN user_email;
            
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                RETURN 'Email not found';
        END;
    END;
    $$ LANGUAGE plpgsql;
    ```

    Contoh kode yang ditingkatkan berikut menghindari subtransaksi dengan menggunakan IF NOT FOUND alih-alih penanganan pengecualian:

    ```
    CREATE OR REPLACE FUNCTION get_user_email(p_user_id INTEGER)
    RETURNS TEXT AS $$
    DECLARE
        user_email TEXT;
    BEGIN
         SELECT email INTO user_email 
         FROM users 
         WHERE id = p_user_id;
            
         IF NOT FOUND THEN
             RETURN 'Email not found';
         ELSE
             RETURN user_email;
         END IF;
    END;
    $$ LANGUAGE plpgsql;
    ```
  + Driver JDBC — `autosave` Parameter, jika diatur ke `always` atau`conservative`, menghasilkan savepoint sebelum setiap kueri. Evaluasi apakah `never` pengaturan akan dapat diterima untuk aplikasi Anda.
  + Driver PostgreSQL ODBC (psqlodBC) - Pengaturan level rollback (untuk rollback tingkat pernyataan) menciptakan savepoint implisit untuk mengaktifkan fungsionalitas rollback pernyataan. Evaluasi apakah tingkat transaksi atau tidak ada rollback dapat diterima untuk aplikasi Anda. 
  + Periksa konfigurasi transaksi ORM
  + Pertimbangkan strategi penanganan kesalahan alternatif yang tidak memerlukan savepoint
+ **Optimalkan desain transaksi** — Merestrukturisasi transaksi untuk menghindari penyarangan yang berlebihan dan mengurangi kemungkinan kondisi overflow subtransaksi.
+ **Mengurangi transaksi jangka panjang — Transaksi** jangka panjang dapat memperburuk masalah subtransaksi dengan menahan informasi subtransaksi lebih lama. Pantau metrik Performance Insights dan konfigurasikan `idle_in_transaction_session_timeout` parameter untuk menghentikan transaksi idle secara otomatis.
+ Monitor Metrik Performance Insights — Melacak metrik termasuk `idle_in_transaction_count` (jumlah sesi dalam keadaan idle dalam keadaan transaksi) dan `idle_in_transaction_max_time` (durasi transaksi idle yang berjalan paling lama) untuk mendeteksi transaksi yang berjalan lama.
+ Konfigurasi `idle_in_transaction_session_timeout` - Tetapkan parameter ini di grup parameter Anda untuk secara otomatis menghentikan transaksi idle setelah durasi yang ditentukan.
+ Pemantauan proaktif — Memantau kejadian tinggi `LWLock:SubtransBuffer` dan `LWLock:SubtransSLRU` menunggu peristiwa untuk mendeteksi pertikaian terkait subtransaksi sebelum menjadi kritis.

# Timeout:PgSleep
<a name="wait-event.timeoutpgsleep"></a>

Peristiwa `Timeout:PgSleep` terjadi saat proses server telah memanggil fungsi `pg_sleep` dan menunggu batas waktu tidur berakhir.

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.timeoutpgsleep.context.supported)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.timeoutpgsleep.causes)
+ [

## Tindakan
](#wait-event.timeoutpgsleep.actions)

## Versi mesin yang didukung
<a name="wait-event.timeoutpgsleep.context.supported"></a>

Informasi peristiwa tunggu ini didukung untuk semua versi RDS for PostgreSQL.

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.timeoutpgsleep.causes"></a>

Peristiwa tunggu ini terjadi saat aplikasi, fungsi tersimpan, atau pengguna mengeluarkan pernyataan SQL yang memanggil salah satu fungsi berikut:
+ `pg_sleep`
+ `pg_sleep_for`
+ `pg_sleep_until`

Fungsi tersebut menunda eksekusi sampai jumlah detik yang ditentukan telah berlalu. Misalnya, `SELECT pg_sleep(1)` melakukan penundaan selama 1 detik. Untuk informasi selengkapnya, lihat [Delaying Execution](https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-DELAY) dalam dokumentasi PostgreSQL.

## Tindakan
<a name="wait-event.timeoutpgsleep.actions"></a>

Identifikasi pernyataan yang menjalankan fungsi `pg_sleep`. Tentukan apakah penggunaan fungsi tersebut sesuai.

# Timeout:VacuumDelay
<a name="wait-event.timeoutvacuumdelay"></a>

Peristiwa `Timeout:VacuumDelay` menunjukkan bahwa batas biaya untuk I/O vakum telah terlampaui dan bahwa proses vakum telah dibuat tidur. Operasi vakum berhenti selama durasi yang ditentukan dalam parameter penundaan biaya masing-masing lalu melanjutkan pekerjaannya. Untuk perintah vakum manual, penundaan ditentukan dalam parameter `vacuum_cost_delay`. Untuk daemon autovacuum, penundaan ditentukan dalam `autovacuum_vacuum_cost_delay parameter.` 

**Topics**
+ [

## Versi mesin yang didukung
](#wait-event.timeoutvacuumdelay.context.supported)
+ [

## Konteks
](#wait-event.timeoutvacuumdelay.context)
+ [

## Kemungkinan penyebab peningkatan peristiwa tunggu
](#wait-event.timeoutvacuumdelay.causes)
+ [

## Tindakan
](#wait-event.timeoutvacuumdelay.actions)

## Versi mesin yang didukung
<a name="wait-event.timeoutvacuumdelay.context.supported"></a>

Informasi peristiwa tunggu ini didukung untuk semua versi RDS for PostgreSQL.

## Konteks
<a name="wait-event.timeoutvacuumdelay.context"></a>

PostgreSQL memiliki daemon autovacuum dan perintah vakum manual. Proses autovacuum “aktif” secara default untuk instans DB RDS for PostgreSQL. Perintah vakum manual digunakan sesuai kebutuhan, misalnya, untuk melakukan purging tabel tuple mati atau menghasilkan statistik baru.

Saat pemvakuman sedang berlangsung, PostgreSQL menggunakan penghitung internal untuk melacak perkiraan biaya seiring sistem melakukan berbagai operasi I/O. Ketika penghitung mencapai nilai yang ditentukan oleh parameter batas biaya, proses yang melakukan operasi akan tidur selama durasi singkat yang ditentukan dalam parameter penundaan biaya. Kemudian, proses ini akan mengatur ulang penghitung dan melanjutkan operasi. 

Proses vakum memiliki parameter yang dapat digunakan untuk mengatur konsumsi sumber daya. Autovacuum dan perintah vakum manual memiliki parameter sendiri untuk menetapkan nilai batas biaya. Keduanya juga memiliki parameter sendiri untuk menentukan penundaan biaya, yaitu jumlah waktu untuk membuat proses vakum menjadi tidur ketika batasnya tercapai. Dengan cara ini, parameter penundaan biaya berfungsi sebagai mekanisme throttling untuk konsumsi sumber daya. Dalam daftar berikut, Anda dapat menemukan deskripsi parameter ini. 

**Parameter yang mempengaruhi throttling daemon autovacuum**
+ `[autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)` – Menentukan nilai batas biaya yang akan digunakan dalam operasi vakum otomatis. Jika pengaturan untuk parameter ini ditingkatkan, proses vakum dapat menggunakan lebih banyak sumber daya dan peristiwa tunggu `Timeout:VacuumDelay` akan berkurang. 
+ `[autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)` – Menentukan nilai penundaan biaya yang akan digunakan dalam operasi vakum otomatis. Nilai default adalah 2 milidetik. Mengatur parameter penundaan ke 0 akan menonaktifkan mekanisme throttling dan dengan demikian, peristiwa tunggu `Timeout:VacuumDelay` tidak akan muncul. 

Untuk informasi selengkapnya, lihat [Automatic Vacuuming](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY) dalam dokumentasi PostgreSQL.

**Parameter yang memengaruhi throttling proses vakum manual**
+ `vacuum_cost_limit` – Ambang batas yang membuat proses pemvakuman menjadi tidur. Secara default, batasnya adalah 200. Angka ini merepresentasikan perkiraan biaya terakumulasi untuk I/O tambahan yang dibutuhkan oleh berbagai sumber daya. Meningkatkan nilai ini akan mengurangi jumlah peristiwa tunggu `Timeout:VacuumDelay`. 
+ `vacuum_cost_delay` – Jumlah waktu proses vakum tidur ketika batas biaya vakum telah tercapai. Pengaturan default adalah 0, yang berarti fitur ini tidak aktif. Anda dapat mengaturnya ke nilai bilangan bulat untuk menentukan jumlah milidetik untuk mengaktifkan fitur ini, tetapi kami sarankan Anda membiarkannya di pengaturan default.

Untuk informasi selengkapnya tentang parameter `vacuum_cost_delay`, lihat [Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST) dalam dokumentasi PostgreSQL. 

Untuk mempelajari selengkapnya tentang cara mengonfigurasi dan menggunakan autovacuum dengan RDS for PostgreSQL, lihat [](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md). 

## Kemungkinan penyebab peningkatan peristiwa tunggu
<a name="wait-event.timeoutvacuumdelay.causes"></a>

`Timeout:VacuumDelay` dipengaruhi oleh keseimbangan antara pengaturan parameter batas biaya (`vacuum_cost_limit`, `autovacuum_vacuum_cost_limit`) dan parameter penundaan biaya (`vacuum_cost_delay`, `autovacuum_vacuum_cost_delay`) yang mengontrol durasi tidur vakum. Meningkatkan nilai parameter batas biaya akan memungkinkan lebih banyak sumber daya digunakan oleh vakum sebelum dibuat tidur. Tindakan ini akan menghasilkan lebih sedikit peristiwa tunggu `Timeout:VacuumDelay`. Meningkatkan salah satu parameter penundaan akan menyebabkan peristiwa tunggu `Timeout:VacuumDelay` terjadi lebih sering dan berlangsung lebih lama. 

Pengaturan parameter `autovacuum_max_workers` juga dapat meningkatkan jumlah `Timeout:VacuumDelay`. Setiap proses pekerja autovacuum tambahan berkontribusi pada mekanisme penghitung internal, dan dengan demikian batasnya dapat tercapai lebih cepat daripada dengan proses pekerja autovacuum tunggal. Karena batas biaya tercapai lebih cepat, penundaan biaya diberlakukan lebih sering, sehingga menghasilkan lebih banyak peristiwa tunggu `Timeout:VacuumDelay`. Untuk informasi selengkapnya, lihat [autovacuum\$1max\$1workers](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS) dalam dokumentasi PostgreSQL.

Objek besar, seperti 500 GB atau lebih, juga meningkatkan peristiwa tunggu ini karena vakum dapat menghabiskan waktu lama untuk menyelesaikan pemrosesan objek besar.

## Tindakan
<a name="wait-event.timeoutvacuumdelay.actions"></a>

Jika operasi vakum selesai seperti yang diharapkan, tidak diperlukan remediasi. Dengan kata lain, peristiwa tunggu ini belum tentu menunjukkan masalah. Ini menunjukkan bahwa vakum sedang dibuat tidur selama periode waktu yang ditentukan dalam parameter penundaan sehingga sumber daya dapat diterapkan pada proses lain yang perlu diselesaikan. 

Jika Anda ingin operasi vakum selesai lebih cepat, Anda dapat menurunkan parameter penundaan. Tindakan ini akan mempersingkat waktu tidur vakum. 