tl; dr: Proses pertama yang membaca data setelah dilakukan akan menetapkan bit petunjuk. Itu akan mengotori halaman, menciptakan aktivitas menulis. Hal lain VACUUM
(tetapi bukan perintah lain) yang dilakukan adalah menandai halaman sebagai semua-terlihat, jika sesuai. VACUUM
akhirnya harus menekan meja untuk membekukan tuple.
Pekerjaan yang perlu dilakukan setelah memasukkan tidak benar-benar pembersihan, setidaknya tidak dalam arti pekerjaan lain yang VACUUM
biasanya dilakukan. Sebelum saya masuk ke perinciannya, perhatikan bahwa jawaban ini didasarkan pada kode 9,6 saat ini (yang belum dirilis) dan saya mengabaikan efek replikasi streaming, meskipun itu dapat memengaruhi visibilitas.
Karena MVCC , setiap kali Postgres mengevaluasi apakah sebuah tuple harus dapat dilihat oleh permintaan, ia harus mempertimbangkan apakah transaksi yang membuat tuple (dicatat di bidang tersembunyi xmin) dilakukan, bersama dengan beberapa kriteria lainnya. Cek itu mahal, jadi segera setelah diketahui bahwa transaksi dapat dilihat oleh semua transaksi yang saat ini terbuka, "bit petunjuk" ditetapkan pada tuple header yang mengindikasikan hal itu. Pengaturan bit itu meruntuhkan halaman, yang berarti harus ditulis ke disk. Ini bisa sangat membingungkan jika perintah berikutnya untuk membaca data adalah SELECT
yang tiba-tiba menciptakan banyak lalu lintas tulis. Menjalankan aVACUUM
setelah memasukkan komitmen akan menghindarinya. Perbedaan penting lainnya adalah ituVACUUM
akan SELALU mengisyaratkan tupel pada halaman (selama itu mendapat kunci pembersihan pada halaman), tetapi sebagian besar perintah lain hanya akan mengisyaratkan jika transaksi memasukkan dilakukan sebelum perintah dimulai.
Poin penting tentang penulisan semua bit petunjuk ini adalah yang VACUUM
dapat dicekik (dan autovacuum dicekik secara default). Perintah lain tidak dibatasi dan akan menghasilkan data kotor secepat mungkin.
VACUUM
adalah satu-satunya metode untuk menandai halaman sebagai semua-terlihat, yang merupakan pertimbangan kinerja yang penting untuk beberapa operasi (terutama, hanya memindai indeks). Jika Anda melakukan penyisipan besar, sangat mungkin ada banyak halaman dengan tuple yang baru dimasukkan. VACUUM
dapat berpotensi menandai halaman-halaman itu sebagai semua-terlihat, tetapi hanya jika transaksi yang paling lama berjalan ketika VACUUM
dimulai lebih baru daripada transaksi yang memasukkan data .
Karena cara kerja MVCC, tupel yang dimasukkan lebih dari ~ 2 miliar transaksi yang lalu harus ditandai sebagai " beku ". Secara default autovacuum akan melakukan itu setiap 200 juta transaksi. Menjalankan vakum manual dengan vacuum_freeze_min_age diatur ke 0 setelah penyisipan massal dapat membantu mengurangi dampaknya. Lebih agresif, Anda bisa berlari VACUUM FREEZE
di atas meja setelah memasukkan. Itu akan "mengatur ulang jam" pada saat pemindaian pembekuan berikutnya akan terjadi.
Jika Anda ingin mengetahui detail spesifik, lihat HEAPTUPLE_LIVE
kasing setelah panggilan ke HeapTupleSatisfiesVacuum()
dalam lazy_scan_heap()
. Lihat juga HeapTupleSatisfiesVacuum()
sendiri, dan bandingkan HeapTupleSatisfiesMVCC()
.
Ada dua presentasi saya yang mungkin menarik. Video pertama tersedia dari http://www.pgcon.org/2015/schedule/events/829.en.html , sedangkan yang kedua (yang saya pikir sedikit lebih baik) di https://www.youtube. com / watch? v = L8nErzxPJjQ
EXPLAIN (ANALYZE, BUFFERS) outputs. But, if I understand things correctly, some of the hint bits (at least
* COMMITTED` dan*INVALID
) dapat (dapat) sudah diatur olehCOMMIT
atauROLLBACK
, kan?