Menurut dokumen:
CONCURRENTLY. Refresh tampilan terwujud tanpa mengunci pilihan bersamaan pada tampilan terwujud. (...)
... ISI LAINNYA ...
Bahkan dengan opsi ini hanya satu REFRESH pada satu waktu yang dapat berjalan melawan satu tampilan terwujud .
Saya memiliki fungsi yang memeriksa waktu refresh terakhir untuk tampilan MATERIALISASI dan, jika lebih dari 60 detik telah berlalu, itu akan menyegarkan kembali.
Namun, apa yang akan terjadi jika saya mencoba menyegarkan tampilan terwujud dari dua proses terpisah pada saat yang sama? apakah mereka akan mengantri atau mereka akan membuat kesalahan?
Apakah ada cara untuk mendeteksi ketika PANDANGAN MATERIALISASI sedang disegarkan dan karenanya tidak menyentuhnya?
Saat ini, saya terpaksa mengisi catatan tabel sebelum menyegarkan (mengatur refreshing
ke true
) dan kemudian mengaturnya false
ketika proses telah selesai.
EXECUTE 'INSERT INTO refresh_status (last_update, refreshing)
VALUES (clock_timestamp(), true) RETURNING id') INTO refresh_id;
EXECUTE 'REFRESH MATERIALIZED VIEW CONCURRENTLY my_mat_view';
EXECUTE 'UPDATE refresh_status SET refreshing=false WHERE id=$1' USING refresh_id;
Kemudian, setiap kali saya memanggil prosedur ini, saya memeriksa yang terbaru last_update
dan refreshing
nilainya. Jika refreshing
benar, maka jangan mencoba untuk menyegarkan tampilan terwujud.
EXECUTE 'SELECT
extract(epoch FROM now() - (last_update))::integer,
refreshing
FROM refresh_status
ORDER BY last_update DESC
LIMIT 1' INTO update_seconds_ago, refreshing;
IF(updated_seconds_ago > 60 AND refreshing = FALSE) THEN
-- the refresh block above
END IF;
Namun, saya tidak yakin bendera penyegaran diperbarui secara serempak (maksud saya, itu benar-benar menunggu penyegaran untuk benar-benar selesai)
Apakah pendekatan ini rasional atau saya melewatkan sesuatu di sini?
sumber
pg_locks
dan mulai menyegarkan Anda. Cara yang tepat untuk mengatasi konflik kunci adalah mengatur batas waktu dan menangani kesalahan.Seperti dicatat oleh mustaccio , pertanyaan ini tumpang tindih secara signifikan dengan Postgres Refresh Materialized View Locks .
Namun, sementara jawaban yang diterima untuk pertanyaan itu memiliki tautan yang menjawab yang ini, jawaban untuk pertanyaan ini tidak secara langsung termasuk di dalamnya.
Jadi, untuk lebih spesifik: Menurut halaman manual PostgreSQL tentang penguncian eksplisit (Tautan ke halaman versi saat ini, untuk PostGres 10),
REFRESH MATERIALIZED VIEW CONCURRENTLY
mengambilEXCLUSIVE
kunci. TheEXCLUSIVE
kunci muncul untuk memblokir semua kunci lainnya kecualiACCESS SHARE
- yang mencakup lainnyaEXCLUSIVE
kunci.Jadi
REFRESH MATERIALIZED VIEW CONCURRENTLY
permintaan kedua pada tampilan yang sama akan menunggu kunci yang diperoleh oleh yang pertama dirilis.sumber
Berkat jawaban oleh mustaccio dan RDFozz , saya akhirnya mengerti bahwa
REFRESH ... CONCURRENTLY
mengambil kunci eksklusif adalah alasan yang dikatakan oleh dokumentasi PostgreSQL :Saya takut bahwa ini berarti segala upaya untuk membuat penyegaran secara simultan akan membuat kesalahan , tetapi berdasarkan jawaban mereka, tidak ada kesalahan khusus yang terlibat. Ini hanya masalah kunci yang akan memungkinkan upaya simultan. Jadi, dokumentasi itu bisa diartikan sebagai:
sumber