Kesehatan indeks ing PostgreSQL liwat mata pangembang Java

Halo

Jenengku Vanya lan aku dadi pangembang Jawa. Iku kedadeyan yen aku kerja keras karo PostgreSQL - nyetel database, ngoptimalake struktur, kinerja, lan muter DBA cilik ing akhir minggu.

Bubar iki, aku wis ngrampungake sawetara database ing layanan mikro lan nulis perpustakaan java pg-index-kesehatan, sing nggawe karya iki luwih gampang, ngirit wektu lan mbantu aku ngindhari sawetara kesalahan umum sing ditindakake dening pangembang. Iki perpustakaan sing bakal kita bahas dina iki.

Kesehatan indeks ing PostgreSQL liwat mata pangembang Java

Nolak tanggung jawab

Versi utama PostgreSQL sing dakgarap yaiku 10. Kabeh pitakon SQL sing digunakake uga diuji ing versi 11. Versi sing didhukung minimal yaiku 9.6.

prasejarah

Iku kabeh diwiwiti meh setahun kepungkur karo kahanan sing aneh kanggo kula: nggawe competitive indeks metu saka biru rampung karo kesalahan. Indeks kasebut, kaya biasane, tetep ana ing basis data ing negara sing ora bener. Analisis log nuduhake kekurangan temp_file_limit. Lan kita lunga ... Digging luwih jero, aku nemokake akeh masalah ing konfigurasi database lan, nggulung lengen klambi, wiwit ndandani kanthi cemlorot ing mripatku.

Masalah siji - konfigurasi standar

Mbokmenawa saben wong wis kesel banget karo metafora babagan Postgres, sing bisa ditindakake ing pembuat kopi, nanging ... konfigurasi gawan pancen nuwuhake sawetara pitakonan. Ing minimal, iku worth mbayar manungsa waé kanggo pangopènan_karya_mem, temp_file_limit, statement_timeout и lock_timeout.

Ing kasus kita pangopènan_karya_mem ana standar 64 MB, lan temp_file_limit soko watara 2 GB - kita mung ora duwe cukup memori kanggo nggawe indeks ing meja gedhe.

Mulane, ing pg-index-kesehatan Aku ngumpulake seri kuncine, miturut pendapatku, paramèter sing kudu dikonfigurasi kanggo saben database.

Masalah loro - indeks duplikat

Database kita manggon ing drive SSD, lan digunakake HA-konfigurasi karo sawetara pusat data, master inang lan n-jumlah replika. Ruang disk minangka sumber daya sing penting banget kanggo kita; iku ora kurang penting saka kinerja lan konsumsi CPU. Mulane, ing tangan siji, kita butuh indeks kanggo maca cepet, lan ing tangan liyane, kita ora pengin ndeleng indeks sing ora perlu ing basis data, amarga padha mangan papan lan nganyari nganyari data.

Lan saiki, wis dibalèkaké kabeh indeks ora sah lan wis cukup ndeleng laporan dening Oleg Bartunov, Aku mutusaké kanggo ngatur "gedhe" purge. Ternyata pangembang ora seneng maca dokumentasi database. Dheweke ora seneng banget. Amarga iki, ana rong kesalahan khas - indeks digawe kanthi manual ing kunci utama lan indeks "manual" sing padha ing kolom unik. Kasunyatan iku ora dibutuhake - Postgres bakal nindakake kabeh dhewe. Indeks kasebut bisa dibusak kanthi aman, lan diagnostik wis muncul kanggo tujuan iki duplicated_indexes.

Masalah telu - indeks intersecting

Umume pangembang pemula nggawe indeks ing kolom siji. Mboko sithik, sawise ngalami bisnis iki, wong wiwit ngoptimalake pitakon lan nambah indeks sing luwih rumit sing kalebu sawetara kolom. Iki carane indeks ing kolom katon A, A + B, A + B + C lan liya-liyane. Loro indeks kasebut bisa dibuwang kanthi aman, amarga minangka prefiks nomer telu. Iki uga ngirit akeh ruang disk lan ana diagnostik kanggo iki intersected_indexes.

Masalah papat - kunci manca tanpa indeks

Postgres ngidini sampeyan nggawe watesan kunci asing tanpa nemtokake indeks backing. Ing pirang-pirang kahanan, iki ora dadi masalah, lan bisa uga ora katon dhewe ... Kanggo wektu iki ...

Iku padha karo kita: iku mung ing sawetara wektu proyek, mlaku miturut jadwal lan mbusak database pesenan test, wiwit "ditambahake" kanggo kita dening inang master. CPU lan IO dadi boros, panyuwunan saya kalem lan wis entek, layanan kasebut limang atus. Analisis cepet pg_stat_activity nuduhake pitakon kaya:

delete from <table> where id in (…)

Ing kasus iki, mesthi ana indeks kanthi id ing tabel target, lan sawetara cathetan sing dibusak miturut kondisi kasebut. Iku ketoke kaya kabeh kudu bisa, nanging, sayangé, ora.

Sing apik banget teka kanggo ngluwari nerangake analisis lan ujar manawa saliyane mbusak cathetan ing tabel target, ana uga mriksa integritas referensial, lan ing salah sawijining tabel sing gegandhengan, mriksa iki gagal. scan urutan amarga ora ana indeks sing cocog. Mangkono diagnostik lair foreign_keys_without_index.

Masalah lima - nilai null ing indeks

Kanthi gawan, Postgres kalebu nilai null ing indeks btree, nanging biasane ora dibutuhake ing kana. Mulane, aku sregep nyoba mbuwang nulls kasebut (diagnostics indexes_with_null_values), nggawe indeks parsial ing kolom nullable miturut jinis where <A> is not null. Kanthi cara iki aku bisa nyuda ukuran salah sawijining indeks saka 1877 MB dadi 16 KB. Lan ing salah sawijining layanan, ukuran database mudhun kanthi total 16% (dening 4.3 GB ing nomer absolut) amarga ora ana nilai null saka indeks. Simpenan gedhe banget ing papan disk kanthi modifikasi sing gampang banget. 🙂

Masalah enem - kurang kunci utama

Amarga sifat mekanisme kasebut MVCC ing Postgres kahanan kaya iki bisa kembungnalika ukuran meja sampeyan tuwuh kanthi cepet amarga akeh cathetan sing mati. Aku naif percaya yen iki ora bakal ngancam kita, lan iki ora bakal kelakon ing basis kita, amarga, wow!!!, kita pangembang normal ... Carane bodho lan naif aku iki ...

Sawijining dina, siji migrasi apik njupuk lan nganyari kabeh cathetan ing tabel gedhe lan aktif digunakake. We entuk +100 GB kanggo ukuran meja metu saka biru. Iku kawirangan peduli, nanging misadventures kita ora mungkasi ana. Sawise autovacuum ing meja iki rampung 15 jam mengko, dadi cetha yen lokasi fisik ora bakal bali. Kita ora bisa mungkasi layanan lan nggawe VACUUM FULL, supaya kita mutusaké kanggo nggunakake pg_repack. Banjur ternyata pg_repack ora ngerti carane ngolah tabel tanpa kunci utami utawa kendala keunikan liyane, lan tabel kita ora duwe kunci utama. Mangkono diagnostik lair tables_without_primary_key.

Ing versi perpustakaan 0.1.5 Kemampuan kanggo ngumpulake data saka bloat tabel lan indeks lan nanggapi kanthi pas wektune wis ditambahake.

Masalah pitu lan wolung - indeks ora cukup lan indeks sing ora digunakake

Loro diagnostik ing ngisor iki yaiku: tables_with_missing_indexes и unused_indexes – katon ing wangun final relatif bubar. Intine iku ora mung bisa dijupuk lan ditambahake.

Nalika aku wis wrote, kita nggunakake konfigurasi karo sawetara réplika, lan mbukak maca ing sarwa dumadi beda dhasar beda. Akibaté, kahanan dadi metu sing sawetara tabel lan indeks ing sawetara sarwa dumadi praktis ora digunakake, lan kanggo analisis sampeyan kudu ngumpulake statistik saka kabeh sarwa dumadi ing kluster. Reset statistik Iki uga perlu ing saben host ing kluster; sampeyan ora bisa nindakake iki mung ing master.

Pendekatan iki ngidini kita ngirit sawetara puluhan gigabyte kanthi ngilangi indeks sing durung nate digunakake, uga nambah indeks sing ilang menyang tabel sing jarang digunakake.

Minangka kesimpulan

Mesthi, kanggo meh kabeh diagnostik sampeyan bisa ngatur dhaptar pangecualian. Kanthi cara iki, sampeyan bisa kanthi cepet ngleksanakake mriksa ing aplikasi, nyegah kesalahan anyar saka katon, lan banjur mboko sithik ndandani sing lawas.

Sawetara diagnosa bisa dileksanakake ing tes fungsional sanalika sawise nggulung migrasi database. Lan iki mbok menawa salah siji fitur paling kuat saka perpustakaan sandi. Conto panggunaan bisa ditemokake ing demo.

Iku ndadekake pangertèn kanggo nindakake mriksa kanggo indeks sing ora digunakake utawa ilang, uga kanggo bloat, mung ing database nyata. Nilai sing diklumpukake bisa direkam ing clickhouse utawa dikirim menyang sistem ngawasi.

Aku pancene ngarep-arep pg-index-kesehatan bakal migunani lan dikarepake. Sampeyan uga bisa nyumbang kanggo pangembangan perpustakaan kanthi nglaporake masalah sing ditemokake lan menehi saran diagnostik anyar.

Source: www.habr.com

Add a comment