WAL di PostgreSQL: 1. Buffer cache

Seri sebelumnya dikhususkan untuk isolasi dan multi-versi PostgreSQL, dan hari ini kita akan memulai yang baru - tentang mekanisme logging write-ahead. Biarkan saya mengingatkan Anda bahwa materi ini didasarkan pada kursus pelatihan administrasi yang saya dan Pavel pluzanov lakukan , tetapi jangan ulangi kata demi kata dan dimaksudkan untuk membaca dengan penuh pertimbangan dan eksperimen independen.

Siklus ini akan terdiri dari empat bagian:

  • Cache penyangga (artikel ini);
  • Jurnal Prarekam - bagaimana ia diatur dan bagaimana ia digunakan selama pemulihan;
  • Rekaman pos pemeriksaan dan latar belakang - mengapa mereka dibutuhkan dan bagaimana cara mereka dikonfigurasi;
  • Penyesuaian log - level dan tugas yang harus diselesaikan, keandalan dan kinerja.

Mengapa jurnal itu perlu?


Dalam prosesnya, bagian dari data yang ditangani DBMS disimpan dalam RAM dan ditulis ke disk (atau media non-volatil lainnya) dengan cara yang ditangguhkan. Semakin jarang ini terjadi, semakin sedikit input-output dan semakin cepat sistem bekerja.

Tetapi apa yang terjadi jika terjadi kegagalan, misalnya, ketika daya dimatikan atau jika kesalahan terjadi dalam kode DBMS atau sistem operasi? Semua isi RAM akan hilang, dan hanya data yang ditulis ke disk akan tetap ada (dengan beberapa jenis kegagalan, disk juga akan menderita, tetapi dalam hal ini hanya salinan cadangan yang akan membantu). Pada prinsipnya, I / O dapat diatur sedemikian rupa sehingga data pada disk selalu dipertahankan dalam keadaan konsisten, tetapi ini sulit dan tidak terlalu efisien (sejauh yang saya tahu, hanya Firebird yang menggunakan cara ini).

Biasanya, termasuk PostgreSQL, data yang ditulis ke disk tidak konsisten, dan ketika memulihkan dari kegagalan, tindakan khusus diperlukan untuk mengembalikan konsistensi. Penjurnalan adalah mekanisme yang memungkinkan hal ini terjadi.

Cache penyangga


Anehnya, kita akan mulai berbicara tentang penjurnalan dengan cache buffer. Cache penyangga bukan satu-satunya struktur yang disimpan dalam RAM, tetapi salah satu yang paling penting dan kompleks. Memahami prinsip operasinya itu penting, apalagi, dalam contoh ini kita akan berkenalan dengan bagaimana data dipertukarkan antara RAM dan disk.

Caching digunakan di mana-mana dalam sistem komputasi modern, satu prosesor saja dapat menghitung tiga atau empat level cache. Secara umum, cache apa pun diperlukan untuk memuluskan perbedaan kinerja antara kedua jenis memori, yang salah satunya relatif cepat, tetapi tidak cukup untuk semua orang, dan yang lainnya relatif lambat, tetapi berlimpah. Jadi buffer cache memperhalus perbedaan antara waktu akses ke RAM (nanoseconds) dan ke disk (milidetik).

Perhatikan bahwa sistem operasi juga memiliki cache disk yang memecahkan masalah yang sama. Oleh karena itu, DBMS biasanya mencoba untuk menghindari caching ganda dengan mengakses disk secara langsung, melewati cache OS. Tetapi dalam kasus PostgreSQL, ini tidak demikian: semua data dibaca dan ditulis menggunakan operasi file biasa.

Selain itu, disk array, dan bahkan disk itu sendiri, juga memiliki cache sendiri. Fakta ini masih berguna bagi kita ketika kita sampai pada masalah keandalan.

Tetapi kembali ke cache buffer DBMS.

Disebut demikian karena merupakan susunan buffer . Setiap buffer adalah tempat untuk satu halaman data (blok), ditambah header. Judul, antara lain, berisi:

  • lokasi pada disk halaman di buffer (file dan nomor blok di dalamnya);
  • tanda bahwa data pada halaman telah berubah dan cepat atau lambat harus ditulis ke disk (buffer seperti itu disebut kotor );
  • jumlah panggilan ke buffer (jumlah penggunaan);
  • bendera menyematkan buffer (jumlah pin).

Cache buffer terletak di memori bersama server dan dapat diakses untuk semua proses. Untuk bekerja dengan data - baca atau modifikasi, - proses baca halaman dalam cache. Saat halaman dalam cache, kami bekerja dengannya dalam RAM dan menghemat akses disk.



Awalnya, cache berisi buffer kosong, dan semuanya terhubung ke daftar buffer gratis. Arti dari pointer ke "korban berikutnya" akan menjadi jelas nanti. Untuk menemukan halaman yang diinginkan dengan cepat di cache, digunakan tabel hash.

Cari halaman dalam cache


Ketika suatu proses perlu membaca halaman, itu pertama-tama mencoba menemukannya di cache buffer menggunakan tabel hash. Kunci hash adalah nomor file dan nomor halaman di dalam file. Dalam keranjang terkait tabel hash, proses menemukan nomor buffer dan memeriksa apakah itu benar-benar berisi halaman yang diinginkan. Seperti halnya tabel hash, tabrakan dimungkinkan di sini; dalam hal ini, proses harus memeriksa beberapa halaman.

Menggunakan tabel hash telah lama dikritik. Struktur ini memungkinkan Anda untuk dengan cepat menemukan buffer pada halaman, tetapi sama sekali tidak berguna jika, misalnya, Anda perlu menemukan semua buffer yang ditempati oleh tabel tertentu. Tapi belum ada yang mengusulkan pengganti yang baik.

Jika halaman yang diinginkan ditemukan dalam cache, proses harus "membekukan" buffer dengan meningkatkan jumlah pin (beberapa proses dapat melakukan ini secara bersamaan). Selama buffer diperbaiki (nilai counter lebih besar dari nol), dianggap bahwa buffer digunakan dan kontennya tidak boleh "diubah secara radikal". Misalnya, versi baru dari garis tersebut dapat muncul di halaman - ini tidak mengganggu siapa pun karena multi-versi dan aturan visibilitas. Tetapi halaman lain tidak dapat dibaca ke buffer yang disematkan.

Berkerumun keluar


Mungkin terjadi bahwa halaman yang diperlukan tidak ditemukan dalam cache. Dalam hal ini, itu harus dibaca dari disk ke beberapa buffer.

Jika masih ada buffer gratis di cache, yang gratis pertama dipilih. Tetapi cepat atau lambat mereka akan berakhir (biasanya ukuran database lebih besar dari memori yang dialokasikan untuk cache) dan kemudian Anda harus memilih salah satu buffer yang ditempati, memaksa keluar halaman di sana dan membaca yang baru di ruang kosong.

Mekanisme preemption didasarkan pada fakta bahwa setiap kali buffer diakses, proses meningkatkan jumlah penggunaan di header buffer. Dengan demikian, buffer yang digunakan lebih jarang daripada yang lain memiliki nilai counter yang lebih rendah dan merupakan kandidat yang baik untuk berkeliaran.

Algoritme clock-sweep loop melalui semua buffer (menggunakan pointer ke "korban berikutnya"), mengurangi jumlah akses mereka dengan satu. Untuk crowding out, buffer pertama dipilih, yang:

  1. memiliki hit counter nol (jumlah penggunaan),
  2. dan tidak diperbaiki (zero pin count).

Anda dapat melihat bahwa jika semua buffer memiliki hit counter non-nol, maka algoritma harus melakukan lebih dari satu lingkaran, mengatur ulang penghitung, sampai salah satu dari mereka akhirnya pergi ke nol. Untuk menghindari "lingkaran yang berliku" nilai maksimum hit counter dibatasi hingga 5. Tetapi tetap saja, dengan ukuran cache buffer yang besar, algoritma ini dapat menyebabkan overhead yang signifikan.

Setelah buffer ditemukan, hal berikut terjadi padanya.

Buffer disematkan untuk menunjukkan proses lain yang sedang digunakan. Selain memperbaiki, cara lain untuk memblokir juga digunakan, tetapi kita akan membicarakan lebih lanjut tentang ini secara terpisah.

Jika buffer ternyata kotor, artinya berisi data yang diubah, halaman tidak bisa dibuang begitu saja - pertama-tama perlu disimpan ke disk. Ini bukan situasi yang baik, karena proses yang akan membaca halaman harus menunggu rekaman data "asing", tetapi efek ini diperhalus oleh pos pemeriksaan dan proses perekaman latar belakang, yang akan dibahas nanti.

Selanjutnya, halaman baru dibaca dari disk ke buffer yang dipilih. Penghitung jumlah panggilan diatur ke satu. Selain itu, tautan ke halaman yang dimuat harus didaftarkan di tabel hash sehingga dapat ditemukan di masa mendatang.

Sekarang tautan ke "korban berikutnya" menunjuk ke buffer berikutnya, dan yang baru saja dimuat punya waktu untuk meningkatkan hit counter sampai pointer melewati seluruh cache buffer dan kembali lagi.

Dengan mataku sendiri


Seperti kebiasaan di PostgreSQL, ada ekstensi yang memungkinkan Anda untuk melihat ke dalam cache buffer.

=> CREATE EXTENSION pg_buffercache; 

Buat tabel dan masukkan satu baris ke dalamnya.

 => CREATE TABLE cacheme( id integer ) WITH (autovacuum_enabled = off); => INSERT INTO cacheme VALUES (1); 

Apa yang akan ada di cache buffer? Minimal, sebuah halaman akan muncul di dalamnya dengan satu baris ditambahkan. Kami akan memverifikasi ini dengan kueri berikut, di mana kami hanya memilih buffer yang termasuk dalam tabel kami (berdasarkan nomor file relfilenode), dan mendekodekan nomor layer (relforknumber):

 => SELECT bufferid, CASE relforknumber WHEN 0 THEN 'main' WHEN 1 THEN 'fsm' WHEN 2 THEN 'vm' END relfork, relblocknumber, isdirty, usagecount, pinning_backends FROM pg_buffercache WHERE relfilenode = pg_relation_filenode('cacheme'::regclass); 
  bufferid | relfork | relblocknumber | isdirty | usagecount | pinning_backends ----------+---------+----------------+---------+------------+------------------ 15735 | main | 0 | t | 1 | 0 (1 row) 

Begitulah - ada satu halaman di buffer. Itu kotor (isdirty), hit counter sama dengan satu (usagecount), dan itu tidak diperbaiki oleh proses apa pun (pinning_backends).

Sekarang tambahkan baris lain dan ulangi kueri. Untuk menyimpan surat, kami menyisipkan baris di sesi lain, dan ulangi permintaan panjang dengan perintah \g .

 | => INSERT INTO cacheme VALUES (2); 

 => \g 
  bufferid | relfork | relblocknumber | isdirty | usagecount | pinning_backends ----------+---------+----------------+---------+------------+------------------ 15735 | main | 0 | t | 2 | 0 (1 row) 

Tidak ada buffer baru yang ditambahkan - baris kedua pas di halaman yang sama. Harap perhatikan bahwa penghitung penggunaan telah meningkat.

 | => SELECT * FROM cacheme; 
 | id | ---- | 1 | 2 | (2 rows) 

 => \g 
  bufferid | relfork | relblocknumber | isdirty | usagecount | pinning_backends ----------+---------+----------------+---------+------------+------------------ 15735 | main | 0 | t | 3 | 0 (1 row) 

Dan setelah mengakses halaman untuk membaca, penghitung juga bertambah.

Dan jika Anda bersih?

 | => VACUUM cacheme; 

 => \g 
  bufferid | relfork | relblocknumber | isdirty | usagecount | pinning_backends ----------+---------+----------------+---------+------------+------------------ 15731 | fsm | 1 | t | 1 | 0 15732 | fsm | 0 | t | 1 | 0 15733 | fsm | 2 | t | 2 | 0 15734 | vm | 0 | t | 2 | 0 15735 | main | 0 | t | 3 | 0 (5 rows) 

Pembersihan membuat peta visibilitas (satu halaman) dan peta ruang kosong (tiga halaman - ukuran minimum peta ini).

Baik dan sebagainya.

Pengaturan ukuran


Ukuran cache ditetapkan oleh parameter shared_buffers . Nilai standarnya adalah 128 MB. Ini adalah salah satu parameter yang masuk akal untuk meningkat segera setelah menginstal PostgreSQL.

 => SELECT setting, unit FROM pg_settings WHERE name = 'shared_buffers'; 
  setting | unit ---------+------ 16384 | 8kB (1 row) 

Perlu diingat bahwa mengubah parameter memerlukan restart server, karena semua memori cache yang diperlukan dialokasikan pada startup server.

Untuk alasan apa memilih nilai yang sesuai?

Bahkan basis data terbesar memiliki kumpulan data "panas" yang terbatas, yang dengannya pekerjaan aktif dilakukan pada setiap saat. Idealnya, set ini harus ditempatkan dalam cache buffer (ditambah beberapa ruang untuk data "satu kali"). Jika ukuran cache lebih kecil, maka halaman yang digunakan secara aktif akan terus-menerus saling menekan, sehingga menghasilkan input-output yang berlebihan. Tapi meningkatkan cache tanpa berpikir juga salah. Dengan ukuran yang besar, biaya overhead untuk mempertahankannya akan meningkat, dan di samping itu, RAM juga diperlukan untuk kebutuhan lain.

Dengan demikian, ukuran cache buffer yang optimal akan berbeda di sistem yang berbeda: itu tergantung pada data, pada aplikasi, pada beban. Sayangnya, tidak ada makna magis yang akan cocok untuk semua orang sama baiknya.

Rekomendasi standar adalah untuk mengambil 1/4 dari RAM sebagai perkiraan pertama (untuk Windows sebelum PostgreSQL 10 disarankan untuk memilih ukuran yang lebih kecil).

Dan kemudian Anda perlu melihat situasinya. Yang terbaik adalah melakukan percobaan: menambah atau mengurangi ukuran cache dan membandingkan kinerja sistem. Tentu saja, untuk ini perlu memiliki bangku tes dan dapat mereproduksi beban khas - dalam lingkungan produksi, percobaan tersebut terlihat seperti kesenangan yang meragukan.

Pastikan untuk melihat laporan oleh Nikolay Samokhvalov di PgConf-2019: " Pendekatan Industri untuk Tuning PostgreSQL: Eksperimen Basis Data "

Tetapi beberapa informasi tentang apa yang terjadi dapat diperoleh secara langsung pada sistem langsung menggunakan ekstensi pg_buffercache yang sama - yang paling penting, lihat sudut kanan.

Misalnya, Anda dapat mempelajari distribusi buffer sesuai dengan tingkat penggunaannya:

 => SELECT usagecount, count(*) FROM pg_buffercache GROUP BY usagecount ORDER BY usagecount; 
  usagecount | count ------------+------- 1 | 221 2 | 869 3 | 29 4 | 12 5 | 564 | 14689 (6 rows) 

Dalam hal ini, banyak nilai penghitung kosong adalah buffer gratis. Tidak mengherankan untuk sistem di mana tidak ada yang terjadi.

Anda dapat melihat seberapa banyak tabel mana di dalam basis data kami di-cache dan seberapa aktif data ini digunakan (dengan penggunaan aktif dalam kueri ini yang kami maksudkan buffer dengan penghitung penggunaan lebih dari 3):

 => SELECT c.relname, count(*) blocks, round( 100.0 * 8192 * count(*) / pg_table_size(c.oid) ) "% of rel", round( 100.0 * 8192 * count(*) FILTER (WHERE b.usagecount > 3) / pg_table_size(c.oid) ) "% hot" FROM pg_buffercache b JOIN pg_class c ON pg_relation_filenode(c.oid) = b.relfilenode WHERE b.reldatabase IN ( 0, (SELECT oid FROM pg_database WHERE datname = current_database()) ) AND b.usagecount is not null GROUP BY c.relname, c.oid ORDER BY 2 DESC LIMIT 10; 
  relname | blocks | % of rel | % hot ---------------------------+--------+----------+------- vac | 833 | 100 | 0 pg_proc | 71 | 85 | 37 pg_depend | 57 | 98 | 19 pg_attribute | 55 | 100 | 64 vac_s | 32 | 4 | 0 pg_statistic | 27 | 71 | 63 autovac | 22 | 100 | 95 pg_depend_reference_index | 19 | 48 | 35 pg_rewrite | 17 | 23 | 8 pg_class | 16 | 100 | 100 (10 rows) 

Di sini, misalnya, dapat dilihat bahwa tabel vakum menempati sebagian besar tempat (kami menggunakannya dalam salah satu topik sebelumnya), tetapi belum ada yang membahasnya sejak lama dan belum diperas hanya karena buffer gratis belum habis.

Anda dapat membuat bagian lain yang akan memberikan informasi yang berguna untuk dipikirkan. Hanya perlu mempertimbangkan bahwa permintaan tersebut:

  • harus diulang beberapa kali: angkanya akan bervariasi dalam batas-batas tertentu;
  • tidak perlu untuk melakukannya terus-menerus (sebagai bagian dari pemantauan) karena fakta bahwa ekstensi memblokir operasi dengan cache buffer untuk waktu yang singkat.

Dan satu hal lagi. Kita tidak boleh lupa bahwa PostgreSQL bekerja dengan file melalui panggilan biasa ke sistem operasi dan, dengan demikian, ada caching ganda: halaman jatuh ke dalam buffer buffer DBMS dan cache OS. Dengan demikian, "miss" dalam cache buffer tidak selalu mengarah pada kebutuhan akan I / O nyata. Tetapi strategi crowding out OS berbeda dari strategi DBMS: sistem operasi tidak tahu apa-apa tentang makna data yang dibaca.

Pemindahan massal


Dalam operasi yang melakukan pembacaan massal atau penulisan data, ada bahaya dengan cepatnya memindahkan halaman berguna dari cache buffer dengan data "satu kali".

Untuk mencegah hal ini terjadi, yang disebut cincin buffer digunakan untuk operasi seperti itu - sebagian kecil dari cache buffer dialokasikan untuk setiap operasi. Ekstrusi hanya bekerja di dalam ring, sehingga data cache buffer lainnya tidak mengalami kerusakan.

Untuk pembacaan berurutan dari tabel besar (ukuran yang melebihi seperempat dari cache buffer) dialokasikan 32 halaman. Jika proses lain juga membutuhkan data ini saat membaca tabel, itu tidak mulai membaca tabel terlebih dahulu, tetapi terhubung ke cincin buffer yang ada. Setelah memindai, ia membaca awal tabel yang "tidak terjawab".

Mari kita periksa. Untuk melakukan ini, buat tabel agar satu baris menempati seluruh halaman - lebih mudah untuk dihitung. Ukuran cache buffer standar adalah 128 MB = 16384 halaman dengan 8 KB. Jadi, Anda harus memasukkan lebih dari 4096 baris halaman ke dalam tabel.

 => CREATE TABLE big( id integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY, s char(1000) ) WITH (fillfactor=10); => INSERT INTO big(s) SELECT 'FOO' FROM generate_series(1,4096+1); 

Mari kita menganalisis tabelnya.

 => ANALYZE big; => SELECT relpages FROM pg_class WHERE oid = 'big'::regclass; 
  relpages ---------- 4097 (1 row) 

Sekarang kita harus me-restart server untuk menghapus cache data tabel yang dibaca oleh analisis.

 student$ sudo pg_ctlcluster 11 main restart 

Setelah reboot, baca seluruh tabel:

 => EXPLAIN (ANALYZE, COSTS OFF) SELECT count(*) FROM big; 
  QUERY PLAN --------------------------------------------------------------------- Aggregate (actual time=14.472..14.473 rows=1 loops=1) -> Seq Scan on big (actual time=0.031..13.022 rows=4097 loops=1) Planning Time: 0.528 ms Execution Time: 14.590 ms (4 rows) 

Dan pastikan hanya 32 buffer ditempati oleh halaman tabular di cache buffer:

 => SELECT count(*) FROM pg_buffercache WHERE relfilenode = pg_relation_filenode('big'::regclass); 
  count ------- 32 (1 row) 

Jika pemindaian berurutan dilarang, tabel akan dibaca berdasarkan indeks:

 => SET enable_seqscan = off; => EXPLAIN (ANALYZE, COSTS OFF) SELECT count(*) FROM big; 
  QUERY PLAN ------------------------------------------------------------------------------------------- Aggregate (actual time=50.300..50.301 rows=1 loops=1) -> Index Only Scan using big_pkey on big (actual time=0.098..48.547 rows=4097 loops=1) Heap Fetches: 4097 Planning Time: 0.067 ms Execution Time: 50.340 ms (5 rows) 

Dalam hal ini, cincin buffer tidak digunakan dan seluruh tabel muncul di cache buffer (dan hampir seluruh indeks juga):

 => SELECT count(*) FROM pg_buffercache WHERE relfilenode = pg_relation_filenode('big'::regclass); 
  count ------- 4097 (1 row) 

Dengan cara yang sama, cincin buffer digunakan untuk proses pembersihan (juga 32 halaman) dan untuk operasi penulisan massal COPY IN dan BUAT TABEL SELECT (biasanya 2048 halaman, tetapi tidak lebih dari 1/8 dari total cache buffer).

Meja sementara


Pengecualian untuk aturan umum adalah tabel sementara. Karena data sementara hanya dapat dilihat oleh satu proses, mereka tidak ada hubungannya dalam cache buffer bersama. Selain itu, data sementara hanya ada dalam satu sesi, sehingga tidak perlu dilindungi dari kegagalan.

Untuk data sementara, cache digunakan dalam memori lokal dari proses yang memiliki tabel. Karena data tersebut hanya tersedia untuk satu proses, itu tidak perlu dilindungi dengan kunci. Cache lokal menggunakan algoritma preemptive yang biasa.

Tidak seperti cache buffer umum, memori untuk cache lokal dialokasikan sesuai kebutuhan, karena tabel sementara tidak digunakan di semua sesi. Jumlah maksimum memori untuk tabel sementara dalam satu sesi dibatasi oleh parameter temp_buffers .

Pemanasan cache


Setelah me-restart server, beberapa waktu akan berlalu sebelum cache β€œmenghangat” - mengakumulasi data yang sebenarnya digunakan secara aktif. Terkadang mungkin berguna untuk segera membaca data tabel tertentu ke dalam cache, dan ekstensi khusus dirancang untuk ini:

 => CREATE EXTENSION pg_prewarm; 

Sebelumnya, ekstensi hanya bisa membaca tabel tertentu di cache buffer (atau hanya di cache OS). Tetapi dalam PostgreSQL 11, ia dapat menyimpan status cache saat ini ke disk dan mengembalikannya setelah server reboot. Untuk memanfaatkan ini, Anda perlu menambahkan perpustakaan ke shared_preload_libraries dan restart server.

 => ALTER SYSTEM SET shared_preload_libraries = 'pg_prewarm'; 

 student$ sudo pg_ctlcluster 11 main restart 

Bidang restart, jika parameter pg_prewarm.autoprewarm tidak berubah, proses latar belakang master autoprewarm akan dimulai secara otomatis, yang sekali dalam pg_prewarm.autoprewarm_interval akan membuang daftar halaman dalam cache ke disk (jangan lupa untuk memperhitungkan proses baru saat mengatur max_parallel_processes ).

 => SELECT name, setting, unit FROM pg_settings WHERE name LIKE 'pg_prewarm%'; 
  name | setting | unit ---------------------------------+---------+------ pg_prewarm.autoprewarm | on | pg_prewarm.autoprewarm_interval | 300 | s (2 rows) 

 postgres$ ps -o pid,command --ppid `head -n 1 /var/lib/postgresql/11/main/postmaster.pid` | grep prewarm 
 10436 postgres: 11/main: autoprewarm master 

Sekarang tidak ada tabel besar dalam cache:

 => SELECT count(*) FROM pg_buffercache WHERE relfilenode = pg_relation_filenode('big'::regclass); 
  count ------- 0 (1 row) 

Jika kita menganggap bahwa semua isinya sangat penting, kita dapat membacanya ke dalam cache buffer dengan memanggil fungsi berikut:

 => SELECT pg_prewarm('big'); 
  pg_prewarm ------------ 4097 (1 row) 

 => SELECT count(*) FROM pg_buffercache WHERE relfilenode = pg_relation_filenode('big'::regclass); 
  count ------- 4097 (1 row) 

Daftar halaman dibuang ke file autoprewarm.blocks. Untuk melihatnya, Anda bisa menunggu sampai proses master autoprewarm berjalan untuk pertama kali, tetapi kami secara manual memulai ini:

 => SELECT autoprewarm_dump_now(); 
  autoprewarm_dump_now ---------------------- 4340 (1 row) 

Jumlah halaman yang dibuang lebih dari 4097 - ini termasuk halaman objek katalog sistem yang sudah dibaca oleh server. Dan inilah file tersebut:

 postgres$ ls -l /var/lib/postgresql/11/main/autoprewarm.blocks 
 -rw------- 1 postgres postgres 102078  29 15:51 /var/lib/postgresql/11/main/autoprewarm.blocks 

Sekarang restart server lagi.

 student$ sudo pg_ctlcluster 11 main restart 

Dan segera setelah peluncuran, tabel kami kembali muncul di cache.

 => SELECT count(*) FROM pg_buffercache WHERE relfilenode = pg_relation_filenode('big'::regclass); 
  count ------- 4097 (1 row) 

Ini memberikan proses master autoprewarm yang sama: ia membaca file, membagi halaman menjadi basis data, mengurutkannya (sehingga membaca dari disk sekonsisten mungkin) dan meneruskan pekerja autoprewarm ke alur kerja individual untuk diproses.

Untuk dilanjutkan .

Source: https://habr.com/ru/post/id458186/


All Articles