PostgreSQL Antipatterns: memerangi gerombolan "orang mati"

Fitur-fitur dari mekanisme PostgreSQL internal memungkinkannya menjadi sangat cepat dalam beberapa situasi dan tidak begitu cepat dalam situasi lain. Hari ini kita akan membahas contoh klasik konflik antara cara kerja DBMS dan apa yang dilakukan pengembang - DBD vs vs MVCC .

Alur singkat dari artikel bagus :
Ketika sebuah baris dimodifikasi dengan perintah UPDATE, dua operasi sebenarnya dilakukan: HAPUS dan INSERT. Di versi baris saat ini , xmax diset sama dengan jumlah transaksi yang melakukan UPDATE. Kemudian versi baru dari baris yang sama dibuat; nilainya xmin cocok dengan nilai xmax dari versi sebelumnya.
Beberapa waktu setelah penyelesaian transaksi ini, versi lama atau baru, tergantung pada yang mana COMMIT/ROOLBACK, akan diakui sebagai "mati" (dead tuple) ketika melewati VACUUMmeja dan dibersihkan.



Tapi ini tidak akan terjadi segera, tetapi masalah dengan "mati" dapat diperoleh dengan sangat cepat - dengan beberapa atau pembaruan massal catatan dalam tabel besar, dan sedikit kemudian, dihadapkan pada situasi yang VACUUM tidak akan dapat membantu .

# 1: Saya Suka Memindahkannya


Misalkan metode Anda pada logika bisnis berfungsi dengan sendirinya, dan tiba-tiba menyadari bahwa perlu memperbarui bidang X dalam beberapa catatan:

UPDATE tbl SET X = <newX> WHERE pk = $1;

Kemudian, ketika itu berlanjut, ia menemukan bahwa bidang Y juga harus diperbarui:

UPDATE tbl SET Y = <newY> WHERE pk = $1;

... dan kemudian juga Z - mengapa agak sepele?

UPDATE tbl SET Z = <newZ> WHERE pk = $1;

Berapa banyak versi catatan ini sekarang di database? Ya, 4 buah! Dari jumlah tersebut, satu relevan, dan 3 harus mengambil VACUUM [otomatis] untuk Anda.

Jangan lakukan seperti ini! Gunakan pembaruan semua bidang dalam satu permintaan - hampir selalu logika metode dapat diubah seperti ini:

UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;

# 2: Gunakan IS DISTINCT FROM, Luke!


Jadi, Anda masih ingin memperbarui banyak, banyak catatan dalam tabel (misalnya, saat menggunakan skrip atau konverter). Dan sesuatu seperti ini terbang ke dalam skrip:

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2;

Dalam kira-kira formulir ini, permintaan sering ditemui dan hampir selalu tidak mengisi bidang baru yang kosong, tetapi untuk memperbaiki beberapa kesalahan dalam data. Selain itu, kebenaran data yang sudah ada tidak diperhitungkan sama sekali - tetapi sia-sia! Artinya, catatan sedang ditulis ulang, bahkan jika itu persis apa yang saya inginkan - mengapa? Benar:

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2 AND X IS DISTINCT FROM <newX>;

Banyak orang tidak menyadari keberadaan operator yang begitu hebat, jadi berikut ini adalah lembar contekan untuk IS DISTINCT FROMoperator logis lainnya untuk membantu:

... dan sedikit tentang operasi pada ROW()ekspresi kompleks :

# 3: Saya akan mengenali sayangku dengan ... memblokir


Jalankan dua proses paralel yang identik , yang masing-masing ditujukan untuk tanda rekaman, bahwa "dalam operasi":

UPDATE tbl SET processing = TRUE WHERE pk = $1;

Sekalipun proses-proses ini secara substantif melakukan hal-hal yang independen satu sama lain, tetapi dalam kerangka satu ID, pada permintaan ini klien kedua akan "mengunci" sampai transaksi pertama selesai.

Solusi # 1 : tugas dikurangi menjadi yang sebelumnya.

Cukup tambahkan lagi IS DISTINCT FROM:

UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;

Dalam formulir ini, permintaan kedua tidak akan mengubah apa pun dalam database, sudah ada "semuanya sudah sebagaimana mestinya" - karena itu, pemblokiran tidak akan terjadi. Selanjutnya, fakta "tidak adanya" catatan sudah diproses dalam algoritma yang diterapkan.

Keputusan nomor 2 : kunci penasihat

Topik besar untuk artikel terpisah di mana Anda dapat membaca tentang metode aplikasi dan "rake" dari kunci rekomendasi .

Solusi # 3 : tanpa panggilan pintar [d]

Tapi, tepatnya, tepatnya, Anda harus bekerja secara simultan dengan catatan yang sama ? Atau apakah Anda masih mengacaukan algoritma panggilan logika bisnis sisi klien, misalnya? Dan jika Anda memikirkannya?

All Articles