

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

# Lock:tuple
<a name="apg-waits.locktuple"></a>

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

**Topics**
+ [Versi mesin yang didukung](#apg-waits.locktuple.context.supported)
+ [Konteks](#apg-waits.locktuple.context)
+ [Kemungkinan penyebab peningkatan peristiwa tunggu](#apg-waits.locktuple.causes)
+ [Tindakan](#apg-waits.locktuple.actions)

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

Informasi peristiwa tunggu ini didukung untuk semua versi Aurora PostgreSQL.

## Konteks
<a name="apg-waits.locktuple.context"></a>

Peristiwa `Lock:tuple` menunjukkan bahwa backend sedang 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 tersebut mendapatkan kunci eksklusif pada tuple, lalu menunggu sesi 1 untuk melepaskan kunci dengan metode commit atau rollback.  |    | 
|  t4  |    |    |  Memperbarui baris 1. Sesi tersebut menunggu sesi 2 untuk melepaskan kunci eksklusif pada tuple.  | 

Atau Anda dapat menyimulasikan peristiwa tunggu ini dengan menggunakan alat benchmarking `pgbench`. Konfigurasikan jumlah sesi bersamaan yang tinggi untuk memperbarui baris yang sama pada tabel dengan file SQL khusus.

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

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

Saat peristiwa ini ditampilkan lebih dari biasanya, mungkin menunjukkan masalah performa, penyebab umumnya terdiri dari berikut:
+ Sesi bersamaan dalam jumlah yang tinggi mencoba mendapatkan kunci yang bertentangan untuk tuple yang sama dengan menjalankan pernyataan `UPDATE` atau `DELETE`.
+ Sesi bersamaan yang tinggi 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 [Penguncian Tingkat Baris](https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS) pada dokumentasi PostgreSQL.

## Tindakan
<a name="apg-waits.locktuple.actions"></a>

Kami merekomendasikan berbagai tindakan tergantung pada penyebab peristiwa tunggu Anda.

**Topics**
+ [Menyelidiki logika aplikasi](#apg-waits.locktuple.actions.problem)
+ [Menemukan sesi pemblokir](#apg-waits.locktuple.actions.find-blocker)
+ [Mengurangi konkurensi saat tinggi](#apg-waits.locktuple.actions.concurrency)
+ [Memecahkan masalah](#apg-waits.locktuple.actions.bottlenecks)

### Menyelidiki logika aplikasi
<a name="apg-waits.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 [Fungsi Pemberi Sinyal Server](https://www.postgresql.org/docs/13/functions-admin.html#FUNCTIONS-ADMIN-SIGNAL) pada 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 [Default Koneksi Klien](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-IDLE-IN-TRANSACTION-SESSION-TIMEOUT) pada dokumentasi PostgreSQL.
+ Gunakan autocommit sebanyak mungkin. Untuk informasi selengkapnya, lihat [SET AUTOCOMMIT](https://www.postgresql.org/docs/current/ecpg-sql-set-autocommit.html) pada dokumentasi PostgreSQL.

### Menemukan sesi pemblokir
<a name="apg-waits.locktuple.actions.find-blocker"></a>

Saat peristiwa tunggu `Lock:tuple` terjadi, identifikasi pemblokir dan sesi yang diblokir dengan mencari tahu kunci yang bergantung satu sama lain. Untuk informasi selengkapnya, lihat [Informasi dependensi kunci](https://wiki.postgresql.org/wiki/Lock_dependency_information) pada wiki PostgreSQL. Untuk menganalisis peristiwa `Lock:tuple` yang lampau, gunakan fungsi Aurora `aurora_stat_backend_waits`. 

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

```
--AURORA_STAT_BACKEND_WAITS
      SELECT a.pid, 
             a.usename, 
             a.app_name, 
             a.current_query,
             a.current_wait_type, 
             a.current_wait_event, 
             a.current_state, 
             wt.type_name AS wait_type, 
             we.event_name AS wait_event, 
             a.waits, 
             a.wait_time
        FROM (SELECT pid, 
                     usename, 
                     left(application_name,16) AS app_name,
                     coalesce(wait_event_type,'CPU') AS current_wait_type,
                     coalesce(wait_event,'CPU') AS current_wait_event, 
                     state AS current_state,
                     left(query,80) as current_query,
                     (aurora_stat_backend_waits(pid)).* 
                FROM pg_stat_activity 
               WHERE pid <> pg_backend_pid()
                 AND usename<>'rdsadmin') a
NATURAL JOIN aurora_stat_wait_type() wt 
NATURAL JOIN aurora_stat_wait_event() we
WHERE we.event_name = 'tuple'
    ORDER BY a.wait_time;

  pid  | usename | app_name |                 current_query                  | current_wait_type | current_wait_event | current_state | wait_type | wait_event | waits | wait_time
-------+---------+----------+------------------------------------------------+-------------------+--------------------+---------------+-----------+------------+-------+-----------
 32136 | sys     | psql     | /*session3*/ update tab set col=1 where col=1; | Lock              | tuple              | active        | Lock      | tuple      |     1 |   1000018
 11999 | sys     | psql     | /*session4*/ update tab set col=1 where col=1; | Lock              | tuple              | active        | Lock      | tuple      |     1 |   1000024
```

### Mengurangi konkurensi saat tinggi
<a name="apg-waits.locktuple.actions.concurrency"></a>

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

Anda dapat mengurangi konkurensi dengan menggunakan pendekatan yang berbeda berdasarkan ketentuan bisnis, logika aplikasi, dan jenis beban kerja. Misalnya, Anda dapat melakukan hal berikut:
+ Mendesain ulang tabel dan logika data untuk mengurangi konkurensi tinggi.
+ Mengubah logika aplikasi untuk mengurangi konkurensi tinggi di tingkat baris.
+ Memanfaatkan dan mendesain ulang kueri dengan kunci tingkat baris.
+ Menggunakan klausa `NOWAIT` dengan operasi coba lagi.
+ Mempertimbangkan penggunaan kontrol konkurensi logika penguncian hibrid yang optimis.
+ Mempertimbangkan perubahan tingkat isolasi basis data.

### Memecahkan masalah
<a name="apg-waits.locktuple.actions.bottlenecks"></a>

`Lock:tuple` dapat terjadi dengan masalah seperti kekurangan CPU atau penggunaan maksimum bandwidth Amazon EBS. Untuk mengurangi masalah, pertimbangkan pendekatan berikut:
+ Menaikkan skala jenis kelas instans.
+ Mengoptimalkan kueri intensif sumber daya.
+ Mengubah logika aplikasi.
+ Mengarsipkan data yang jarang diakses.