Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Saya sarankan Anda membaca transkrip laporan awal tahun 2016 oleh Andrey Salnikov β€œKesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql”

Dalam laporan ini, saya akan menganalisis kesalahan utama dalam aplikasi yang muncul pada tahap perancangan dan penulisan kode aplikasi. Dan saya hanya akan mengambil kesalahan-kesalahan yang menyebabkan kembung di Postgresql. Biasanya, ini adalah awal dari akhir kinerja sistem Anda secara keseluruhan, meskipun pada awalnya tidak ada prasyarat yang terlihat untuk hal ini.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Senang menyambut semuanya! Laporan ini tidak se-teknis laporan sebelumnya dari rekan saya. Laporan ini terutama ditujukan untuk pengembang sistem backend karena kami memiliki jumlah klien yang cukup besar. Dan mereka semua melakukan kesalahan yang sama. Saya akan memberitahu Anda tentang mereka. Saya akan menjelaskan apa saja dampak fatal dan buruk dari kesalahan tersebut.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Mengapa kesalahan terjadi? Hal ini dilakukan karena dua alasan: secara acak, mungkin akan berhasil dan karena ketidaktahuan tentang beberapa mekanisme yang terjadi pada tingkat antara database dan aplikasi, serta di dalam database itu sendiri.

Saya akan memberi Anda tiga contoh dengan gambaran buruk tentang betapa buruknya keadaan. Saya akan bercerita secara singkat tentang mekanisme yang terjadi di sana. Dan bagaimana cara mengatasinya, kapan terjadinya, dan metode pencegahan apa yang digunakan untuk mencegah kesalahan. Saya akan memberi tahu Anda tentang alat bantu dan memberikan tautan yang bermanfaat.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Saya menggunakan database pengujian di mana saya memiliki dua tabel. Satu piring dengan rekening pelanggan, yang lain dengan transaksi pada rekening ini. Dan dengan frekuensi tertentu kami memperbarui saldo pada akun-akun ini.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Data awal pelat: cukup kecil, 2 MB. Waktu respon untuk database dan khususnya untuk tanda juga sangat baik. Dan beban yang cukup baik - 2 operasi per detik menurut pelat.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Dan melalui laporan ini saya akan menunjukkan kepada Anda grafik sehingga Anda dapat memahami dengan jelas apa yang sedang terjadi. Akan selalu ada 2 slide dengan grafik. Slide pertama adalah apa yang terjadi secara umum di server.

Dan dalam situasi ini, kita melihat bahwa kita sebenarnya mempunyai sebuah tanda kecil. Indeksnya kecil yaitu 2 MB. Ini adalah grafik pertama di sebelah kiri.

Rata-rata waktu respon di server juga stabil dan singkat. Ini adalah grafik kanan atas.

Grafik kiri bawah menunjukkan transaksi terpanjang. Kami melihat bahwa transaksi selesai dengan cepat. Dan autovacuum disini belum berfungsi, karena ini adalah tes permulaan. Ini akan terus bekerja dan bermanfaat bagi kami.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Slide kedua akan selalu didedikasikan untuk pelat yang diuji. Dalam situasi ini, kami terus memperbarui saldo akun klien. Dan kami melihat bahwa waktu respons rata-rata untuk operasi pembaruan cukup baik, kurang dari satu milidetik. Kami melihat bahwa sumber daya prosesor (grafik kanan atas) juga dikonsumsi secara merata dan cukup kecil.

Grafik kanan bawah menunjukkan berapa banyak operasi dan memori disk yang kita lalui untuk mencari baris yang kita inginkan sebelum memperbaruinya. Dan jumlah operasi menurut tandanya adalah 2 per detik, seperti yang saya katakan di awal.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Dan sekarang kita menghadapi sebuah tragedi. Entah kenapa ada transaksi yang sudah lama terlupakan. Alasannya biasanya dangkal:

  • Salah satu yang paling umum adalah kami mulai mengakses layanan eksternal dalam kode aplikasi. Dan layanan ini tidak menjawab kami. Artinya, kami membuka transaksi, membuat perubahan pada database dan beralih dari aplikasi untuk membaca email atau ke layanan lain dalam infrastruktur kami, dan karena alasan tertentu aplikasi tersebut tidak merespons kami. Dan sesi kami terjebak dalam keadaan yang tidak diketahui kapan akan terselesaikan.
  • Situasi kedua adalah ketika pengecualian terjadi pada kode kita karena alasan tertentu. Dan dalam pengecualian kami tidak memproses penutupan transaksi. Dan kami berakhir dengan sesi gantung dengan transaksi terbuka.
  • Dan yang terakhir juga merupakan kasus yang cukup umum. Ini adalah kode berkualitas rendah. Beberapa kerangka kerja membuka transaksi. Itu hang, dan Anda mungkin tidak tahu di aplikasi bahwa Anda menggantungnya.

Kemana arah hal-hal seperti itu?

Sampai-sampai tabel dan indeks kami mulai membengkak drastis. Ini adalah efek kembung yang sama persis. Untuk database, ini berarti waktu respon database akan meningkat sangat tajam dan beban pada server database akan meningkat. Dan akibatnya, aplikasi kita akan terganggu. Karena jika Anda menghabiskan 10 milidetik dalam kode Anda untuk permintaan ke database, 10 milidetik untuk logika Anda, maka fungsi Anda memerlukan waktu 20 milidetik untuk diselesaikan. Dan sekarang situasi Anda akan sangat menyedihkan.

Dan mari kita lihat apa yang terjadi. Grafik kiri bawah menunjukkan bahwa kita memiliki transaksi yang panjang. Dan jika kita melihat grafik kiri atas, kita melihat ukuran tabel kita tiba-tiba melonjak dari dua megabyte menjadi 300 megabyte. Pada saat yang sama, jumlah data dalam tabel tidak berubah, yaitu terdapat cukup banyak sampah di sana.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Situasi umum mengenai waktu respons server rata-rata juga telah berubah beberapa kali lipat. Artinya, semua permintaan di server mulai turun sepenuhnya. Dan pada saat yang sama, proses internal Postgres diluncurkan dalam bentuk autovacuum, yang mencoba melakukan sesuatu dan menghabiskan sumber daya.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Apa yang terjadi dengan tanda kita? Sama. Waktu respons rata-rata kami menurut tandanya telah melonjak beberapa kali lipat. Khususnya dalam hal sumber daya yang dikonsumsi, kami melihat bahwa beban pada prosesor telah meningkat pesat. Ini adalah grafik kanan atas. Dan itu meningkat karena prosesor harus memilah-milah banyak jalur yang tidak berguna untuk mencari yang dibutuhkan. Ini adalah grafik kanan bawah. Dan akibatnya, jumlah panggilan per detik kami mulai turun secara signifikan, karena database tidak punya waktu untuk memproses jumlah permintaan yang sama.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Kita perlu hidup kembali. Kami online dan menemukan bahwa transaksi panjang menimbulkan masalah. Kami menemukan dan menghentikan transaksi ini. Dan semuanya menjadi normal bagi kami. Semuanya berjalan sebagaimana mestinya.

Kami tenang, tetapi setelah beberapa saat kami mulai memperhatikan bahwa aplikasi tersebut tidak bekerja dengan cara yang sama seperti sebelum keadaan darurat. Permintaan masih diproses lebih lambat, dan jauh lebih lambat. Satu setengah hingga dua kali lebih lambat khususnya dalam contoh saya. Beban di server juga lebih tinggi dibandingkan sebelum kecelakaan.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Dan pertanyaannya: β€œApa yang terjadi dengan pangkalan saat ini?” Dan situasi berikut terjadi dengan pangkalan. Pada grafik transaksi terlihat sudah berhenti dan memang tidak ada transaksi jangka panjang. Namun ukuran tanda itu meningkat secara fatal selama kecelakaan itu. Dan sejak itu jumlahnya tidak berkurang. Waktu rata-rata di pangkalan telah stabil. Dan jawabannya nampaknya datang dengan cukup cepat dan dapat diterima oleh kita. Autovacuum menjadi lebih aktif dan mulai melakukan sesuatu dengan tanda tersebut, karena perlu menyaring lebih banyak data.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Secara khusus, menurut pelat uji dengan akun, tempat kami mengubah saldo: waktu respons untuk permintaan tampaknya telah kembali normal. Namun kenyataannya, angkanya satu setengah kali lebih tinggi.

Dan dari beban pada prosesor, kita melihat bahwa beban pada prosesor belum kembali ke nilai yang disyaratkan sebelum terjadinya crash. Dan alasannya justru terletak pada grafik kanan bawah. Dapat dilihat bahwa sejumlah memori sedang dicari di sana. Artinya, untuk menemukan baris yang diperlukan, kita menyia-nyiakan sumber daya server database sambil memilah-milah data yang tidak berguna. Jumlah transaksi per detik telah stabil.

Secara keseluruhan bagus, namun situasinya lebih buruk dari sebelumnya. Hapus degradasi database sebagai konsekuensi dari aplikasi kita yang bekerja dengan database ini.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Dan untuk memahami apa yang terjadi di sana, jika Anda belum melihat laporan sebelumnya, sekarang mari kita lihat sedikit teorinya. Teori tentang proses internal. Mengapa penyedot debu mobil dan apa fungsinya?

Secara harfiah singkat untuk pemahaman. Suatu saat kami memiliki meja. Kami memiliki baris di tabel. Garis-garis ini bisa aktif, hidup, dan kita butuhkan saat ini. Mereka ditandai dengan warna hijau di gambar. Dan ada tenggat waktu yang telah diselesaikan, telah diperbarui, dan entri baru telah muncul di dalamnya. Dan mereka ditandai bahwa mereka tidak lagi menarik untuk database. Namun mereka ada di tabel karena fitur Postgres.

Mengapa Anda membutuhkan penyedot debu mobil? Pada titik tertentu, autovacuum datang, mengakses database dan menanyakannya: β€œTolong beri saya id transaksi terlama yang saat ini terbuka di database.” Basis data mengembalikan id ini. Dan autovacuum, dengan mengandalkannya, memilah-milah garis-garis dalam tabel. Dan jika dia melihat bahwa beberapa baris diubah oleh transaksi yang jauh lebih lama, maka dia berhak menandainya sebagai baris yang dapat kita gunakan kembali di masa mendatang dengan menulis data baru di sana. Ini adalah proses latar belakang.

Saat ini, kami terus bekerja dengan database dan terus membuat beberapa perubahan pada tabel. Dan pada baris ini, yang dapat kita gunakan kembali, kita menulis data baru. Dan dengan demikian kita mendapatkan sebuah siklus, yaitu sepanjang waktu beberapa baris lama yang mati muncul di sana, alih-alih kita menulis baris baru yang kita butuhkan. Dan ini adalah keadaan normal agar PostgreSQL dapat berfungsi.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Apa yang terjadi saat kecelakaan itu? Bagaimana proses ini terjadi di sana?

Kami memiliki tanda dalam beberapa kondisi, beberapa hidup, beberapa batas waktu. Penyedot debu mobil telah tiba. Dia menanyakan database apa transaksi tertua kami dan apa id-nya. Saya menerima id ini, mungkin beberapa jam yang lalu, mungkin sepuluh menit yang lalu. Itu tergantung pada seberapa berat beban yang Anda miliki pada database Anda. Dan dia pergi mencari garis yang bisa dia tandai sebagai digunakan kembali. Dan saya tidak menemukan garis seperti itu di meja kami.

Namun saat ini kami terus mengerjakan tabel. Kami melakukan sesuatu di dalamnya, memperbaruinya, mengubah data. Apa yang harus dilakukan database saat ini? Dia tidak punya pilihan selain menambahkan baris baru ke akhir tabel yang ada. Dan dengan demikian ukuran meja kami mulai membengkak.

Pada kenyataannya, kita memerlukan jalur hijau agar dapat berfungsi. Namun selama masalah seperti itu, ternyata persentase garis hijau sangat rendah di seluruh tabel.

Dan saat kita menjalankan kueri, database harus menelusuri semua baris: merah dan hijau, untuk menemukan baris yang diinginkan. Dan efek membengkaknya tabel dengan data yang tidak berguna disebut β€œbloat”, yang juga memakan ruang disk kita. Ingat, tadinya 2 MB, menjadi 300 MB? Sekarang ubah megabyte menjadi gigabyte dan Anda akan segera kehilangan semua sumber daya disk Anda.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Apa dampaknya bagi kita?

  • Dalam contoh saya, tabel dan indeks tumbuh 150 kali lipat. Beberapa klien kami mengalami kasus yang lebih fatal ketika mereka mulai kehabisan ruang disk.
  • Ukuran tabelnya sendiri tidak akan pernah berkurang. Autovacuum dalam beberapa kasus dapat memotong bagian ekor tabel jika hanya ada garis batas waktu. Namun karena rotasinya konstan, satu garis hijau mungkin berhenti di bagian akhir dan tidak diperbarui, sementara garis lainnya akan ditulis di suatu tempat di awal pelat. Namun kecil kemungkinannya bahwa meja Anda akan menyusut ukurannya, jadi Anda tidak boleh berharap demikian.
  • Basis data perlu memilah-milah sejumlah baris yang tidak berguna. Dan kita menyia-nyiakan sumber daya disk, kita menyia-nyiakan sumber daya prosesor dan listrik.
  • Dan ini secara langsung mempengaruhi aplikasi kita, karena jika pada awalnya kita menghabiskan 10 milidetik untuk permintaan, 10 milidetik untuk kode kita, maka selama crash kita mulai menghabiskan satu detik untuk permintaan dan 10 milidetik untuk kode, yaitu urutan besarnya kinerja aplikasi menurun. Dan ketika kecelakaan itu teratasi, kami mulai menghabiskan 20 milidetik untuk sebuah permintaan, 10 milidetik untuk sebuah kode. Artinya, produktivitas kami masih turun satu setengah kali lipat. Dan ini semua karena satu transaksi yang terhenti, mungkin karena kesalahan kami.
  • Dan pertanyaannya: β€œBagaimana kami bisa mendapatkan semuanya kembali?” sehingga semuanya baik-baik saja dan permintaan datang secepat sebelum kecelakaan terjadi.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Untuk tujuan ini ada siklus kerja tertentu yang dilakukan.

Pertama kita perlu menemukan tabel bermasalah yang membengkak. Kami memahami bahwa di beberapa tabel pencatatannya lebih aktif, di tabel lain kurang aktif. Dan untuk ini kami menggunakan ekstensi pgstattuple. Dengan menginstal ekstensi ini, Anda dapat menulis kueri yang akan membantu Anda menemukan tabel yang cukup membengkak.

Setelah Anda menemukan tabel ini, Anda perlu mengompresnya. Sudah ada alat untuk melakukan hal ini. Di perusahaan kami, kami menggunakan tiga alat. Yang pertama adalah VACUUM FULL bawaan. Dia kejam, kasar dan tanpa ampun, tapi terkadang dia sangat berguna. Pg_repack ΠΈ pgcompacttable - Ini adalah utilitas pihak ketiga untuk mengompresi tabel. Dan mereka memperlakukan database dengan lebih hati-hati.

Mereka digunakan tergantung pada apa yang lebih nyaman bagi Anda. Tapi aku akan memberitahumu tentang ini di bagian akhir. Yang penting ada tiga alat. Ada banyak pilihan.

Setelah kita memperbaiki semuanya dan memastikan semuanya baik-baik saja, kita harus tahu bagaimana mencegah situasi ini di masa depan:

  • Hal ini dapat dicegah dengan cukup mudah. Anda perlu memantau durasi sesi di server Master. Sesi yang sangat berbahaya saat menganggur dalam keadaan transaksi. Ini adalah orang-orang yang baru saja membuka transaksi, melakukan sesuatu dan pergi, atau sekadar berhenti, tersesat dalam kode.
  • Dan bagi Anda, sebagai pengembang, penting untuk menguji kode Anda ketika situasi ini muncul. Ini tidak sulit untuk dilakukan. Ini akan menjadi pemeriksaan yang berguna. Anda akan terhindar dari banyak masalah β€œkekanak-kanakan” yang terkait dengan transaksi panjang.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Dalam grafik ini, saya ingin menunjukkan kepada Anda bagaimana tanda dan perilaku database berubah setelah saya melewati tanda dengan VACUUM FULL dalam kasus ini. Ini bukan produksi bagi saya.

Ukuran tabel segera kembali ke kondisi pengoperasian normal yaitu beberapa megabita. Hal ini tidak terlalu mempengaruhi waktu respons rata-rata server.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Namun khusus untuk rambu pengujian kami, saat kami memperbarui saldo akun, kami melihat bahwa waktu respons rata-rata untuk permintaan memperbarui data di rambu tersebut dikurangi ke tingkat sebelum keadaan darurat. Sumber daya yang digunakan oleh prosesor untuk menyelesaikan permintaan ini juga turun ke tingkat sebelum kerusakan. Dan grafik kanan bawah menunjukkan bahwa sekarang kita langsung menemukan garis yang kita butuhkan dengan tepat, tanpa melalui tumpukan garis mati yang ada sebelum tabel dikompresi. Dan waktu permintaan rata-rata tetap pada tingkat yang sama. Tapi di sini saya mengalami kesalahan pada perangkat keras saya.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Di sinilah cerita pertama berakhir. Ini adalah yang paling umum. Dan ini terjadi pada semua orang, terlepas dari pengalaman klien dan seberapa berkualitas pemrogramnya. Cepat atau lambat hal ini akan terjadi.

Cerita kedua, di mana kami mendistribusikan beban dan mengoptimalkan sumber daya server

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

  • Kami sudah dewasa dan menjadi pria yang serius. Dan kami memahami bahwa kami memiliki replikanya dan akan baik bagi kami untuk menyeimbangkan bebannya: menulis kepada Guru, dan membaca dari replika tersebut. Dan biasanya keadaan ini muncul ketika kita ingin menyiapkan beberapa laporan atau ETL. Dan bisnis sangat senang dengan hal ini. Dia sangat menginginkan laporan yang beragam dengan banyak analisis yang kompleks.
  • Laporan memakan waktu berjam-jam, karena analisis yang kompleks tidak dapat dihitung dalam hitungan milidetik. Kami, seperti orang pemberani, menulis kode. Dalam aplikasi penyisipan kami membuat rekaman pada Master, dan mengeksekusi laporan pada replikanya.
  • Mendistribusikan beban.
  • Semuanya bekerja dengan sempurna. Kami hebat.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Dan seperti apa situasi ini? Khusus pada grafik tersebut, saya juga menambahkan durasi transaksi dari replika untuk durasi transaksi. Semua grafik lainnya hanya merujuk ke server Master.

Saat ini, papan laporan saya telah berkembang. Ada lebih banyak dari mereka. Kami melihat rata-rata waktu respon server stabil. Kami melihat bahwa pada replika kami memiliki transaksi jangka panjang yang berjalan selama 2 jam. Kami melihat pengoperasian autovacuum yang tenang, yang memproses batas waktu. Dan semuanya baik-baik saja dengan kami.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Secara khusus, menurut pelat yang diuji, kami terus memperbarui saldo akun di sana. Dan kami juga memiliki waktu respons yang stabil terhadap permintaan, konsumsi sumber daya yang stabil. Semuanya baik-baik saja dengan kami.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Semuanya baik-baik saja hingga laporan ini mulai muncul kembali karena konflik dengan replikasi. Dan mereka membalas secara berkala.

Kami online dan mulai membaca mengapa hal ini terjadi. Dan kami menemukan solusinya.

Solusi pertama adalah meningkatkan latensi replikasi. Kami tahu bahwa laporan kami berjalan selama 3 jam. Kami mengatur penundaan replikasi menjadi 3 jam. Kami meluncurkan semuanya, namun kami masih terus mengalami masalah dengan laporan yang terkadang dibatalkan.

Kami ingin semuanya sempurna. Kami mendaki lebih jauh. Dan kami menemukan pengaturan keren di Internet - hot_standby_feedback. Ayo nyalakan. Hot_standby_feedback memungkinkan kita untuk menahan autovacuum pada Master. Dengan demikian, kami sepenuhnya menghilangkan konflik replikasi. Dan semuanya berjalan baik bagi kami dengan laporan.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Dan apa yang terjadi dengan server Master saat ini? Dan kami berada dalam masalah total dengan server Master. Sekarang kita melihat grafik ketika saya mengaktifkan kedua pengaturan ini. Dan kami melihat bahwa sesi pada replika kami mulai mempengaruhi situasi di server Master. Dia memang mempunyai efek karena dia menghentikan autovacuum, yang menghapus tenggat waktu. Ukuran meja kami kembali meroket. Waktu eksekusi kueri rata-rata di seluruh database juga meroket. Autovacuumnya sedikit diperketat.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Khususnya, dari piring kami, kami melihat bahwa pembaruan data di dalamnya juga melonjak tinggi. Konsumsi CPU juga meningkat pesat. Kita kembali melewati banyak jalur mati dan tidak berguna. Dan waktu respons untuk tanda ini serta jumlah transaksi telah menurun.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Bagaimana jadinya jika kita tidak tahu apa yang saya bicarakan sebelumnya?

  • Kami mulai mencari masalah. Jika kita menemui masalah di bagian pertama, kita tahu bahwa ini mungkin karena transaksi yang lama dan pergi ke Master. Kami punya masalah pada Master. Sosis dia. Memanas, Load Average-nya sekitar seratus.
  • Permintaan di sana lambat, tapi kami tidak melihat adanya transaksi yang berjalan lama di sana. Dan kami tidak mengerti apa yang terjadi. Kami tidak mengerti ke mana mencarinya.
  • Kami memeriksa peralatan server. Mungkin serangan kita gagal. Mungkin memory stick kita habis. Ya, apapun bisa terjadi. Tapi tidak, servernya baru, semuanya berfungsi dengan baik.
  • Semua orang menjalankannya: administrator, pengembang, dan direktur. Tidak ada yang membantu.
  • Dan pada titik tertentu semuanya tiba-tiba mulai membaik dengan sendirinya.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Saat ini, permintaan replika kami telah diproses dan ditinggalkan. Kami menerima laporannya. Bisnis masih bahagia. Seperti yang Anda lihat, tanda kami telah tumbuh lagi dan tidak akan menyusut. Pada grafik sesi, saya meninggalkan sebagian transaksi panjang ini dari replika sehingga Anda dapat memperkirakan berapa lama waktu yang dibutuhkan hingga situasi stabil.

Sesi selesai. Dan hanya setelah beberapa waktu server datang kurang lebih secara berurutan. Dan rata-rata waktu respon permintaan di server Master kembali normal. Sebab, pada akhirnya, autovacuum mempunyai kesempatan untuk membersihkan dan menandai batas waktu tersebut. Dan dia mulai melakukan pekerjaannya. Dan seberapa cepat dia melakukannya, begitu cepat kita akan membereskannya.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Menurut tablet yang diuji, saat kami memperbarui saldo akun, kami melihat gambar yang persis sama. Rata-rata waktu pembaruan akun juga berangsur normal. Sumber daya yang dikonsumsi oleh prosesor juga berkurang. Dan jumlah transaksi per detik kembali normal. Namun kembali lagi kita kembali normal, tidak sama seperti sebelum kecelakaan.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Bagaimanapun, kita mendapatkan penurunan kinerja, seperti dalam kasus pertama, sebanyak satu setengah hingga dua kali lipat, dan terkadang lebih.

Tampaknya kami telah melakukan segalanya dengan benar. Bagikan bebannya. Peralatan tidak menganggur. Kami membagi permintaan menurut pikiran kami, tetapi tetap saja semuanya berjalan buruk.

  • Jangan aktifkan hot_standby_feedback? Ya, tidak disarankan untuk menyalakannya tanpa alasan yang kuat. Karena twist ini berdampak langsung pada server Master dan menghentikan pengoperasian autovacuum di sana. Dengan mengaktifkannya pada beberapa replika dan melupakannya, Anda dapat mematikan Master dan mendapatkan masalah besar dengan aplikasi tersebut.
  • Tingkatkan max_standby_streaming_delay? Ya, untuk laporan ini benar. Jika Anda memiliki laporan berdurasi tiga jam dan tidak ingin laporan tersebut mogok karena konflik replikasi, cukup tingkatkan penundaannya. Laporan jangka panjang tidak memerlukan data yang sudah masuk ke database saat ini. Jika Anda memilikinya selama tiga jam, maka Anda menjalankannya untuk beberapa periode data lama. Dan bagi Anda, apakah ada penundaan tiga jam atau enam jam tidak akan ada bedanya, tetapi Anda akan menerima laporan secara konsisten dan tidak akan ada masalah jika laporan tersebut jatuh.
  • Tentu saja, Anda perlu mengontrol sesi panjang pada replika, terutama jika Anda memutuskan untuk mengaktifkan hot_standby_feedback pada replika. Karena apapun bisa terjadi. Kami memberikan replika ini kepada pengembang sehingga dia dapat menguji permintaan tersebut. Dia menulis permintaan gila. Dia meluncurkannya dan pergi minum teh, dan kami mendapatkan Guru yang mapan. Atau mungkin kita salah memasang aplikasi disana. Situasinya bervariasi. Sesi pada replika harus dipantau dengan hati-hati seperti pada Master.
  • Dan jika Anda memiliki pertanyaan yang cepat dan panjang tentang replika, maka dalam hal ini lebih baik membaginya untuk mendistribusikan beban. Ini adalah tautan ke streaming_delay. Untuk yang cepat, miliki satu replika dengan penundaan replikasi yang kecil. Untuk permintaan pelaporan jangka panjang, miliki replika yang dapat tertunda hingga 6 jam atau satu hari. Ini adalah situasi yang sepenuhnya normal.

Kami menghilangkan konsekuensinya dengan cara yang sama:

  • Kami menemukan tabel yang membengkak.
  • Dan kami mengompresnya dengan alat paling nyaman yang cocok untuk kami.

Cerita kedua berakhir di sini. Mari kita beralih ke cerita ketiga.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Juga cukup umum bagi kita di mana kita melakukan migrasi.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

  • Produk perangkat lunak apa pun sedang berkembang. Persyaratan untuk itu berubah. Bagaimanapun, kami ingin berkembang. Dan kebetulan kami perlu memperbarui data dalam tabel, yaitu untuk menjalankan pembaruan dalam hal migrasi untuk fungsi baru yang kami perkenalkan sebagai bagian dari pengembangan kami.
  • Format data lama tidak memuaskan. Katakanlah sekarang kita beralih ke tabel kedua, di mana saya memiliki transaksi pada akun ini. Dan katakanlah harganya dalam rubel, dan kami memutuskan untuk meningkatkan akurasi dan melakukannya dalam kopeck. Dan untuk ini kita perlu melakukan pembaruan: kalikan kolom dengan jumlah transaksi dengan seratus.
  • Di dunia sekarang ini, kami menggunakan alat kontrol versi database otomatis. Katakanlah Liquidbase. Kami mendaftarkan migrasi kami di sana. Kami mengujinya di basis pengujian kami. Semuanya baik-baik saja. Pembaruan sedang berlangsung. Ini memblokir pekerjaan untuk sementara waktu, tetapi kami mendapatkan data terbaru. Dan kami dapat meluncurkan fungsi baru dalam hal ini. Semuanya diuji dan diperiksa. Semuanya telah dikonfirmasi.
  • Kami melakukan pekerjaan yang direncanakan dan melakukan migrasi.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Inilah migrasi dengan pembaruan yang disajikan di depan Anda. Karena ini adalah transaksi akun saya, platnya 15 GB. Dan karena kami memperbarui setiap baris, kami menggandakan ukuran tabel dengan pembaruan, karena kami menulis ulang setiap baris.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Selama migrasi, kami tidak dapat melakukan apa pun dengan pelat ini, karena semua permintaan ke pelat tersebut diantri dan menunggu hingga pembaruan ini selesai. Namun disini saya ingin menarik perhatian anda pada angka-angka yang terletak pada sumbu vertikal. Artinya, kami memiliki waktu permintaan rata-rata sebelum migrasi sekitar 5 milidetik dan beban prosesor, jumlah operasi blok untuk membaca memori disk kurang dari 7,5.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Kami melakukan migrasi dan mendapat masalah lagi.

Migrasi berhasil, tetapi:

  • Fungsionalitas lama sekarang membutuhkan waktu lebih lama untuk diselesaikan.
  • Ukuran meja bertambah lagi.
  • Beban pada server kembali menjadi lebih besar dari sebelumnya.
  • Dan tentunya kami masih mengutak-atik fungsionalitas yang berfungsi dengan baik, kami telah memperbaikinya sedikit.

Dan ini lagi-lagi kembung, yang lagi-lagi menghancurkan hidup kita.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Di sini saya menunjukkan bahwa tabel, seperti dua kasus sebelumnya, tidak akan kembali ke ukuran sebelumnya. Beban server rata-rata tampaknya memadai.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Dan jika kita melihat tabel dengan akun, kita akan melihat bahwa waktu permintaan rata-rata meningkat dua kali lipat untuk tabel ini. Beban pada prosesor dan jumlah baris yang diurutkan dalam memori melonjak di atas 7,5, tetapi lebih rendah. Dan itu melonjak 2 kali lipat dalam hal prosesor, 1,5 kali lipat dalam hal operasi blok, yaitu kami mengalami penurunan kinerja server. Dan akibatnya - penurunan kinerja aplikasi kita. Pada saat yang sama, jumlah panggilan tetap pada tingkat yang sama.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Dan hal utama di sini adalah memahami bagaimana melakukan migrasi tersebut dengan benar. Dan itu perlu dilakukan. Kami melakukan migrasi ini dengan cukup konsisten.

  • Migrasi besar-besaran seperti itu tidak terjadi secara otomatis. Mereka harus selalu terkendali.
  • Diperlukan pengawasan oleh orang yang berpengetahuan. Jika Anda memiliki DBA di tim Anda, biarkan DBA yang melakukannya. Itu pekerjaannya. Jika tidak, biarkan orang yang paling berpengalaman melakukannya, yang tahu cara bekerja dengan database.
  • Skema database baru, meskipun kami memperbarui satu kolom, kami selalu mempersiapkannya secara bertahap, yaitu terlebih dahulu sebelum versi baru aplikasi diluncurkan:
  • Bidang baru ditambahkan di mana kami akan mencatat data yang diperbarui.
  • Kami mentransfer data dari bidang lama ke bidang baru dalam jumlah kecil. Mengapa kita melakukan ini? Pertama, kami selalu mengontrol jalannya proses ini. Kami tahu bahwa kami telah mentransfer begitu banyak batch dan masih banyak yang tersisa.
  • Dan efek positif kedua adalah di antara setiap kumpulan tersebut kami menutup transaksi, membuka yang baru, dan ini memungkinkan autovacuum bekerja sesuai dengan pelat, menandai batas waktu untuk digunakan kembali.
  • Untuk baris yang akan muncul saat aplikasi sedang berjalan (kami masih menjalankan aplikasi lama), kami menambahkan trigger yang menulis nilai baru ke kolom baru. Dalam kasus kami, ini adalah perkalian dengan seratus dari nilai lama.
  • Jika kami benar-benar keras kepala dan menginginkan bidang yang sama, maka setelah menyelesaikan semua migrasi dan sebelum meluncurkan versi baru aplikasi, kami cukup mengganti nama bidang tersebut. Bidang yang lama diberi nama yang dibuat-buat, dan bidang yang baru diganti namanya menjadi bidang yang lama.
  • Dan baru setelah itu kami meluncurkan aplikasi versi baru.

Dan pada saat yang sama kita tidak akan mengalami pembengkakan dan tidak akan menderita dalam hal kinerja.

Di sinilah cerita ketiga berakhir.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

https://github.com/dataegret/pg-utils/blob/master/sql/table_bloat.sql

https://github.com/dataegret/pg-utils/blob/master/sql/table_bloat_approx.sql

Dan sekarang sedikit lebih detail tentang alat-alat yang saya sebutkan di cerita pertama.

Sebelum mencari bloat, Anda harus menginstal ekstensinya pgstattuple.

Agar Anda tidak perlu mengajukan pertanyaan, kami telah menuliskan pertanyaan ini dalam pekerjaan kami. Anda bisa menggunakannya. Ada dua permintaan di sini.

  • Yang pertama membutuhkan waktu yang cukup lama untuk bekerja, tetapi ini akan menunjukkan kepada Anda nilai pengasapan yang tepat dari tabel.
  • Yang kedua bekerja lebih cepat dan sangat efektif ketika Anda perlu menilai dengan cepat apakah ada kembung atau tidak sesuai tabel. Dan Anda juga harus memahami bahwa mengasapi selalu ada di tabel Postgres. Ini adalah fitur model MVCC-nya.
  • Dan 20% kembung adalah normal untuk tabel dalam banyak kasus. Artinya, Anda tidak perlu khawatir dan mengompres tabel ini.

Kami menemukan cara mengidentifikasi tabel yang penuh dengan data yang tidak berguna.

Sekarang tentang cara mengatasi kembung:

  • Jika kita memiliki tablet kecil dan disk yang bagus, yaitu pada tablet hingga gigabyte, sangat mungkin untuk menggunakan VACUUM FULL. Dia akan mengambil kunci eksklusif dari Anda di atas meja selama beberapa detik dan oke, tapi dia akan melakukan semuanya dengan cepat dan kasar. Apa yang dilakukan VAKUM PENUH? Dibutuhkan kunci eksklusif pada tabel dan menulis ulang baris langsung dari tabel lama ke tabel baru. Dan pada akhirnya dia menggantikan mereka. Ini menghapus file lama dan mengganti file lama dengan yang baru. Namun selama pengerjaannya, dibutuhkan kunci eksklusif di atas meja. Ini berarti Anda tidak dapat melakukan apa pun dengan tabel ini: tidak menulis, membaca, atau memodifikasinya. Dan VACUUM FULL memerlukan ruang disk tambahan untuk menulis data.
  • Alat berikutnya pg_repack. Prinsipnya sangat mirip dengan VACUUM FULL, karena juga menulis ulang data dari file lama ke file baru dan menggantinya di tabel. Tetapi pada saat yang sama, ia tidak mengambil kunci eksklusif pada tabel di awal pekerjaannya, tetapi hanya mengambilnya pada saat ia sudah memiliki data siap pakai untuk mengganti file. Persyaratan sumber daya disknya mirip dengan VACUUM FULL. Anda memerlukan ruang disk tambahan, dan ini terkadang penting jika Anda memiliki tabel terabyte. Dan cukup haus prosesor karena aktif bekerja dengan I/O.
  • Utilitas ketiga adalah pgcompacttable. Ia lebih berhati-hati dengan sumber daya karena bekerja berdasarkan prinsip yang sedikit berbeda. Ide utama pgcompacttable adalah memindahkan semua baris aktif ke awal tabel menggunakan pembaruan dalam tabel. Dan kemudian terjadi kekosongan pada tabel ini, karena kita tahu bahwa kita memiliki baris aktif di awal dan baris mati di akhir. Dan ruang hampa itu sendiri memotong bagian ini, yaitu tidak memerlukan banyak ruang disk tambahan. Dan pada saat yang sama, masih dapat diperas dari segi sumber daya.

Semuanya dengan alat.

Kesalahan umum dalam aplikasi yang menyebabkan kembung di postgresql. Andrey Salnikov

Jika menurut Anda topik bloat menarik untuk dipelajari lebih jauh, berikut beberapa tautan yang berguna:

Saya mencoba lebih untuk menunjukkan kisah horor bagi pengembang, karena mereka adalah klien langsung kami dari database dan harus memahami apa dan tindakan apa yang mengarah pada hal tersebut. Saya harap saya berhasil. Terima kasih atas perhatian Anda!

pertanyaan

Terima kasih atas laporannya! Anda berbicara tentang bagaimana Anda dapat mengidentifikasi masalah. Bagaimana mereka bisa diperingatkan? Artinya, saya mengalami situasi ketika permintaan terhenti bukan hanya karena mereka mengakses beberapa layanan eksternal. Ini hanyalah beberapa gabungan liar. Ada beberapa permintaan kecil dan tidak berbahaya yang bertahan selama sehari, dan kemudian mulai melakukan hal-hal yang tidak masuk akal. Artinya, sangat mirip dengan apa yang Anda gambarkan. Bagaimana cara melacak ini? Duduk dan terus-menerus perhatikan permintaan mana yang macet? Bagaimana hal ini dapat dicegah?

Dalam hal ini, ini adalah tugas administrator perusahaan Anda, belum tentu untuk DBA.

Saya seorang administrator.

PostgreSQL memiliki tampilan bernama pg_stat_activity yang menampilkan kueri yang menggantung. Dan Anda dapat melihat berapa lama benda itu tergantung di sana.

Apakah saya harus masuk dan melihat setiap 5 menit?

Siapkan cron dan periksa. Jika Anda memiliki permintaan jangka panjang, tulislah surat dan selesai. Artinya, tidak perlu melihat dengan mata, bisa otomatis. Anda akan menerima surat, Anda bereaksi terhadapnya. Atau Anda dapat memotret secara otomatis.

Apakah ada alasan yang jelas mengapa hal ini terjadi?

Saya telah membuat daftar beberapa. Contoh lain yang lebih kompleks. Dan percakapan bisa berlangsung lama.

Terima kasih atas laporannya! Saya ingin menjelaskan tentang utilitas pg_repack. Jika dia tidak melakukan kunci eksklusif, maka...

Dia melakukan kunci eksklusif.

... maka saya berpotensi kehilangan data. Apakah aplikasi saya tidak boleh merekam apa pun selama waktu ini?

Tidak, ini berfungsi lancar dengan tabel, yaitu pg_repack terlebih dahulu mentransfer semua saluran langsung yang ada. Secara alami, semacam entri ke dalam tabel terjadi di sana. Dia baru saja membuang kuncir kuda ini.

Artinya, dia benar-benar melakukannya pada akhirnya?

Pada akhirnya, dia mengambil kunci eksklusif untuk menukar file-file ini.

Apakah akan lebih cepat dari VACUUM FULL?

VACUUM FULL, begitu mulai langsung ambil kunci eksklusif. Dan sampai dia melakukan segalanya, dia tidak akan membiarkannya pergi. Dan pg_repack mengambil kunci eksklusif hanya pada saat penggantian file. Saat ini Anda tidak akan menulis di sana, tetapi datanya tidak akan hilang, semuanya akan baik-baik saja.

Halo! Anda berbicara tentang pengoperasian penyedot debu mobil. Ada grafik dengan sel perekam berwarna merah, kuning dan hijau. Artinya, yang kuning - dia menandainya sebagai dihapus. Dan sebagai hasilnya, sesuatu yang baru dapat ditulis ke dalamnya?

Ya. Postgres tidak menghapus baris. Dia memiliki kekhususan seperti itu. Jika kami memperbarui sebuah baris, kami menandai baris lama sebagai dihapus. Id transaksi yang mengubah baris ini muncul di sana, dan kami menulis baris baru. Dan kami memiliki sesi yang berpotensi membacanya. Pada titik tertentu mereka menjadi sangat tua. Dan inti dari cara kerja autovacuum adalah ia melewati garis-garis ini dan menandainya sebagai tidak perlu. Dan Anda dapat menimpa data di sana.

Saya mengerti. Tapi pertanyaannya bukan itu. Saya belum menyelesaikannya. Anggap saja kita punya meja. Ini memiliki bidang dengan ukuran variabel. Dan jika saya mencoba memasukkan sesuatu yang baru, itu mungkin tidak muat di sel lama.

Tidak, bagaimanapun juga seluruh baris diperbarui di sana. Postgres memiliki dua model penyimpanan data. Ini memilih dari tipe data. Ada data yang langsung disimpan di tabel, ada juga yang datanya tos. Ini adalah data dalam jumlah besar: teks, json. Mereka disimpan di piring terpisah. Dan menurut tablet ini, cerita yang sama terjadi dengan kembung, yaitu semuanya sama. Mereka hanya dicantumkan secara terpisah.

Terima kasih atas laporannya! Apakah boleh menggunakan kueri batas waktu pernyataan untuk membatasi durasi?

Sangat bisa diterima. Kami menggunakan ini di mana saja. Dan karena kami tidak memiliki layanan sendiri, kami menyediakan dukungan jarak jauh, kami memiliki klien yang cukup beragam. Dan semua orang puas dengan ini. Artinya, kami memiliki pekerjaan cron yang memeriksa. Durasi sesi hanya disepakati dengan klien, yang sebelumnya tidak kami setujui. Bisa jadi satu menit, bisa juga 10 menit. Itu tergantung pada beban di pangkalan dan tujuannya. Tapi kita semua menggunakan pg_stat_activity.

Terima kasih atas laporannya! Saya mencoba menerapkan laporan Anda ke aplikasi saya. Dan sepertinya kita memulai transaksi di mana saja, dan menyelesaikannya dengan jelas di mana saja. Jika ada pengecualian, maka rollback masih terjadi. Dan kemudian saya mulai berpikir. Bagaimanapun, transaksi mungkin tidak dimulai secara eksplisit. Ini mungkin petunjuk untuk gadis itu. Jika saya baru saja memperbarui catatan, apakah transaksi akan dimulai di PostgreSQL dan hanya selesai ketika koneksi terputus?

Jika sekarang Anda berbicara tentang level aplikasi, maka itu tergantung pada driver yang Anda gunakan, pada ORM yang digunakan. Ada banyak pengaturan di sana. Jika Anda mengaktifkan komit otomatis, maka transaksi akan dimulai di sana dan segera ditutup.

Artinya, segera ditutup setelah pembaruan?

Itu tergantung pada pengaturannya. Saya menyebutkan satu pengaturan. Ini adalah komitmen otomatis. Ini cukup umum. Jika diaktifkan, maka transaksi telah dibuka dan ditutup. Kecuali Anda secara eksplisit mengatakan "mulai transaksi" dan "akhiri transaksi", tetapi cukup meluncurkan permintaan ke dalam sesi.

Halo! Terima kasih atas laporannya! Bayangkan kita mempunyai database yang membengkak dan kemudian ruang di server habis. Apakah ada alat untuk memperbaiki situasi ini?

Ruang di server perlu dipantau dengan baik.

Misalnya, DBA pergi minum teh, berada di resor, dll.

Ketika sistem file dibuat, setidaknya beberapa jenis ruang cadangan dibuat di mana data tidak ditulis.

Bagaimana jika suhunya benar-benar di bawah nol?

Di sana disebut ruang cadangan, yaitu dapat dikosongkan dan bergantung pada seberapa besar ruang tersebut dibuat, Anda mendapatkan ruang kosong. Secara default saya tidak tahu ada berapa banyak. Dan dalam kasus lain, kirimkan disk sehingga Anda memiliki ruang untuk melakukan operasi rekonstruktif. Anda dapat menghapus beberapa tabel yang dijamin tidak diperlukan.

Apakah ada alat lain?

Itu selalu buatan tangan. Dan secara lokal menjadi jelas apa yang terbaik untuk dilakukan di sana, karena sebagian data bersifat penting dan sebagian lagi tidak penting. Dan untuk setiap database dan aplikasi yang bekerja dengannya, itu tergantung pada bisnisnya. Itu selalu diputuskan secara lokal.

Terima kasih atas laporannya! Saya punya dua pertanyaan. Pertama, Anda memperlihatkan slide yang menunjukkan bahwa ketika transaksi macet, ukuran tablespace dan ukuran indeks bertambah. Dan selanjutnya dalam laporan tersebut ada banyak utilitas yang mengemas tablet tersebut. Bagaimana dengan indeksnya?

Mereka juga mengemasnya.

Tapi kevakuman tidak mempengaruhi indeks?

Beberapa bekerja dengan indeks. Misalnya, pg_rapack, pgcompacttable. Kekosongan membuat ulang indeks dan memengaruhinya. Dengan VACUUM FULL idenya adalah untuk menimpa semuanya, yaitu bekerja dengan semua orang.

Dan pertanyaan kedua. Saya tidak mengerti mengapa laporan replika sangat bergantung pada replikasi itu sendiri. Bagi saya, laporan dibaca, dan replikasi ditulis.

Apa yang menyebabkan konflik replikasi? Kami memiliki Guru tempat proses berlangsung. Kami sedang melakukan penyedot debu mobil. Apa sebenarnya fungsi autovacuum? Dia memotong beberapa baris lama. Jika saat ini kami memiliki permintaan pada replika yang membaca baris-baris lama ini, dan pada Master terjadi situasi di mana autovacuum menandai baris-baris ini sebagai kemungkinan untuk ditimpa, maka kami menimpanya. Dan kami menerima paket data, ketika kami perlu menulis ulang baris-baris yang diperlukan permintaan pada replika, proses replikasi akan menunggu batas waktu yang Anda konfigurasikan. Dan kemudian PostgreSQL akan memutuskan apa yang lebih penting. Dan replikasi lebih penting baginya daripada permintaan, dan dia akan menghapus permintaan tersebut untuk membuat perubahan ini pada replika.

Andre, saya punya pertanyaan. Grafik luar biasa yang Anda tunjukkan selama presentasi ini, apakah ini hasil karya Anda yang berguna? Bagaimana grafiknya dibuat?

Ini adalah layanan Okemeter.

Apakah ini produk komersial?

Ya. Ini adalah produk komersial.

Sumber: www.habr.com

Tambah komentar