Praktik terbaik untuk mengelola penggunaan memori

Halaman ini menjelaskan cara mengonfigurasi penggunaan memori untuk instance Cloud SQL.

Pengantar

Saat membuat instance Cloud SQL, Anda memilih jumlah memori untuk instance. Seiring peningkatan workload database PostgreSQL, penggunaan memori instance akan meningkat. Instance yang memakai banyak memori dapat menimbulkan bottleneck performa yang terkadang dapat menyebabkan masalah kehabisan memori.

Jika instance Cloud SQL kehabisan memori karena peningkatan permintaan, hal tersebut dapat menyebabkan periode nonaktif database. Oleh karena itu, penting untuk mengonfigurasi memori instance dan flag database terkait memori dengan benar dan memantau penggunaan memori sehingga instance beroperasi dalam keadaan normal.

Komponen memori PostgreSQL dibagi secara luas menjadi dua bagian:

  • Memori global: memori ini dibagikan ke semua proses untuk menjalankan kueri; misalnya, shared_buffers dan max_connections.
  • Memori lokal: ini adalah memori khusus yang ditetapkan untuk setiap koneksi; misalnya, work_mem, maintenance_work_mem, dan temp_buffers.

Untuk pertimbangan konfigurasi lainnya, lihat Praktik terbaik umum dan Panduan operasional.

Penggunaan memori dan flag

Setiap kali ada penggunaan memori yang tinggi oleh instance Cloud SQL, pertanyaan berikut mungkin muncul:

  • Kueri atau proses mana yang menggunakan memori tinggi?
  • Apakah setelan memori sudah memadai untuk aktivitas database?
  • Bagaimana cara mengubah setelan memori?

Saat database PostgreSQL beroperasi, sebagian besar penggunaan memori terjadi di beberapa area:

  • Buffer bersama: ini adalah memori bersama yang dialokasikan PostgreSQL guna menyimpan data tabel untuk operasi read dan write. Untuk operasi read, data apa pun yang diminta dari disk akan diambil terlebih dahulu ke RAM, lalu diberikan ke klien. Demikian pula, di PostgreSQL, saat data diminta (misalnya, SELECT * from emp), data akan diambil terlebih dahulu dari disk ke shared_buffers untuk di-cache, lalu diberikan kepada klien. Hal yang sama terjadi dengan operasi write.

    Buffer bersama juga merupakan area memori bersama untuk semua proses dan koneksi untuk aktivitas database seperti caching data, caching koneksi, dan operasi Bahasa Manipulasi Data (DML). Batas maksimum yang dapat dialokasikan oleh area ini ditentukan oleh flag shared_buffers dan defaultnya adalah 33% dari memori instance. Jika nilai shared_buffers tinggi, ukuran data yang di-cache dalam memori akan tinggi.

  • Memori kerja kueri: saat kueri dijalankan, PostgreSQL mengalokasikan memori lokal untuk setiap operasi seperti pengurutan dan hashing. Batas maksimum yang dapat dialokasikan untuk setiap operasi kueri sebelum menulis ke file disk sementara dikonfigurasi oleh flag work_mem, dan nilai defaultnya adalah 4 MB. Jika nilai work_mem tinggi, jumlah data yang dapat diurutkan dalam memori akan tinggi.
  • Pemeliharaan memori kerja: beberapa operasi pemeliharaan seperti VACUUM, CREATE INDEX, ALTER TABLE, dan ADD FOREIGN KEY memerlukan memori lokal terpisah yang dialokasikan oleh PostgreSQL. Jumlah maksimum untuk proses backend yang digunakan dalam operasi ini dapat dikonfigurasi dengan flag maintenance_work_mem dan nilai defaultnya adalah 64 MB. Perlu diingat bahwa pekerja autovacuum juga menggunakan pemeliharaan memori kerja dan jumlah maksimumnya dapat diganti dengan flag autovacuum_work_mem. Jika nilai maintenance_work_mem tinggi, kecepatan performa operasi VACUUM juga tinggi.
  • Buffer sementara: ketika tabel sementara digunakan dalam sesi database, PostgreSQL mengalokasikan buffering sementara untuk menyimpan tabel sementara sesi-lokal. Jumlah maksimum dapat ditentukan melalui flag temp_buffers dan nilai defaultnya adalah 8 MB.
  • Koneksi database: saat klien terhubung ke database, PostgreSQL membuat proses backend untuk menayangkan sesi klien. Selain memori untuk menjalankan kueri, PostgreSQL mengalokasikan memori tambahan untuk mempertahankan informasi seperti cache katalog sistem dan rencana kueri yang sudah disiapkan. Jumlah maksimum koneksi konkurensi yang diizinkan ke server database dapat dikonfigurasi oleh flag max_connections. Setiap koneksi yang tidak ada aktivitas menggunakan memori bersama sekitar 2 MB hingga 3 MB. Jika nilai max_connections tinggi, instance dapat membuat lebih banyak koneksi, tetapi mengorbankan penggunaan memori.

Untuk mengetahui daftar lengkap komponen memori di PostgreSQL, lihat dokumentasi PostgreSQL. Untuk mengubah atau memodifikasi flag yang tercantum di bagian ini, lihat Mengonfigurasi flag database.

Memantau penggunaan memori

Pantau memori instance Anda di Cloud Monitoring secara rutin dan pertahankan agar nilainya di bawah batas penggunaan memori. Praktik yang baik adalah menyetel pemberitahuan di Cloud Monitoring untuk mengirimkan pemberitahuan ketika penggunaan melebihi 90% batas selama 6 jam. Pemberitahuan ini dapat memperingatkan Anda saat penggunaan memori mendekati batas secara konstan.

Selain itu, pantau insiden kehabisan memori. Untuk melakukannya, siapkan metrik berbasis log untuk pesan server process .* was terminated by signal 9: Killed di Cloud Monitoring guna menghitung peristiwa kehabisan memori, lalu beri tahu setiap kali peristiwa tersebut akan terjadi.

Jika instance Anda beroperasi secara konstan di atas 90% batas memori atau peristiwa kehabisan memori terjadi, Anda dapat meningkatkan memori instance. Atau, Anda dapat mengurangi penggunaan memori dengan membatasi jumlah koneksi database atau menurunkan flag database seperti shared_buffers, work_mem, atau max_connections. Menurunkan flag ini dapat membatasi performa instance.

Kehabisan memori

Jika memori tidak mencukupi untuk menangani workload database, sebagai upaya terakhir, sistem operasi Linux yang mendasarinya akan menggunakan out-of-memory (OOM) killer untuk mengakhiri proses pelepasan memori. Cloud SQL dikonfigurasi sehingga OOM killer hanya menargetkan proses pekerja PostgreSQL. Proses postmaster akan dipertahankan dalam situasi ini, sehingga hanya perlu mengakhiri semua koneksi database yang ada dan menjalankan pemulihan untuk melindungi integritas database. Jika hal ini terjadi, ada saat-saat gangguan layanan dan periode nonaktif pada database. Di log database PostgreSQL, pesan seperti berikut akan muncul:

2021-10-24 23:34:22.265 UTC [7]: [663-1] db=,user= LOG: server process (PID 1255039) was terminated by signal 9: Killed
2021-10-24 23:34:22.265 UTC [7]: [664-1] db=,user= DETAIL: Failed process was running: SELECT * FROM tab ORDER BY col
2021-10-24 23:34:22.277 UTC [7]: [665-1] db=,user= LOG: terminating any other active server processes
2021-10-24 23:34:22.278 UTC [1255458]: [1-1] db=postgres,user=postgres WARNING: terminating connection because of crash of another server process
2021-10-24 23:34:22.278 UTC [1255458]: [2-1] db=postgres,user=postgres DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
2021-10-24 23:34:22.278 UTC [1255458]: [3-1] db=postgres,user=postgres HINT: In a moment you should be able to reconnect to the database and repeat your command.
2021-10-24 23:34:22.278 UTC [1255458]: [4-1] db=postgres,user=postgres CONTEXT: while updating tuple (27,18) in relation "tab"
...
2021-10-24 23:34:22.558 UTC [1255477]: [1-1] db=postgres,user=postgres FATAL: the database system is in recovery mode
...
2021-10-24 23:34:25.579 UTC [7]: [666-1] db=,user= LOG: all server processes terminated; reinitializing
...
2021-10-24 23:34:25.691 UTC [1255482]: [1-1] db=,user= LOG: database system was interrupted; last known up at 2021-10-24 23:31:53 UTC
2021-10-24 23:34:25.776 UTC [1255482]: [2-1] db=,user= LOG: database system was not properly shut down; automatic recovery in progress
2021-10-24 23:34:25.789 UTC [1255482]: [3-1] db=,user= LOG: redo starts at 227/AB359400
2021-10-24 23:34:38.957 UTC [1255482]: [4-1] db=,user= LOG: redo done at 229/4621F508
2021-10-24 23:34:38.959 UTC [1255482]: [5-1] db=,user= LOG: last completed transaction was at log time 2021-10-24 23:34:18.5535+00
2021-10-24 23:34:39.290 UTC [7]: [667-1] db=,user= LOG: database system is ready to accept connections

Langkah selanjutnya