

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

# 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.