A PostgreSQL indexek egészsége Java fejlesztő szemszögéből

Helló.

A nevem Vanya, és Java fejlesztő vagyok. Úgy alakult, hogy sokat dolgozom PostgreSQL-lel – adatbázisok beállításával, struktúrák optimalizálásával, teljesítménnyel foglalkozom, és kicsit hétvégenként DBA-ként is játszom.

Az utóbbi időszakban rendbe raktam néhány adatbázist a mikroszolgáltatásainkban, és írtam egy Java könyvtárat pg-index-health, amely megkönnyíti ezt a munkát, időt takarít meg, és segít elkerülni a fejlesztők által elkövetett tipikus hibákat. Ma erről a könyvtárról fog szólni a beszélgetés.

A PostgreSQL indexek egészsége Java fejlesztő szemszögéből

Megjegyzés

A fő verzió, amellyel dolgozom, a PostgreSQL 10. Az összes SQL lekérdezésemet a 11-es verzióval is teszteltem. A minimálisan támogatott verzió a 9.6.

Háttér

Mindez majdnem egy éve kezdődött egy számomra furcsa helyzettel: az erőforrás-igényes index létrehozása egyenesen hibaüzenettel zárult. Magának az indexnek, ahogy az lenni szokott, érvénytelen állapotban kellett maradnia az adatbázisban. A naplók elemzése hiányzó temp_file_limit-et mutatott. És innentől kezdve... Miután jobban beleástam magam, egy rakás problémát találtam az adatbázis konfigurációjában, és ujjat felhúzva, csillogással a szememben, elkezdtem javítgatni őket.

Első probléma – az alapértelmezett konfiguráció

Valószínűleg a metafora, miszerint a Postgres egy kávéfőzőn is futtatható, már mindenkinek elegendő, de... az alapbeállítás valóban több kérdést is felvet. Legalábbis érdemes odafigyelni a maintenance_work_mem, temp_file_limit, statement_timeout és lock_timeout.

esetében, maintenance_work_mem amely alapértelmezetten 64 MB volt, míg temp_file_limit valami körülbelül 2 GB – nyilvánvalóan nem volt elég memóriánk ahhoz, hogy nagy táblán indexet hozzunk létre.

Ezért pg-index-health összegyűjtöttem néhány kulcsfontosságúparamétert, amelyet véleményem szerint érdemes beállítani minden adatbázis esetében.

Második probléma – a duplikált indexek

Az adatbázisaink SSD meghajtókon működnek, és HA-konfigurációt használunk több adatközponttal, mester-kiszolgálóval és n-db számú replikával. A lemezhely nagyon értékes erőforrás számunkra; ugyanolyan fontos, mint a teljesítmény és a CPU fogyasztás. Ezért egyrészt szükségünk van indexekre a gyors olvasáshoz, másrészt nem akarunk felesleges indexeket látni az adatbázisban, mivel ezek helyet foglalnak és lassítják az adatok frissítését.

Miután minden érvénytelen indexet helyreállítottam, és sokat néztem Oleg Bartunov előadásait, eldöntöttem, hogy egy „nagy” takarítást végezek. Kiderült, hogy a fejlesztők nem szeretik elolvasni az adatbázis dokumentációját. Nagyon nem szeretik. Ennek következményeként két tipikus hiba lép fel – manuálisan létrehozott index az elsődleges kulcson és hasonló „kézi” index egyedi oszlopokra. Az a helyzet, hogy ezekre nincs szükség – a Postgres mindent megold magától. Az ilyen indexeket nyugodtan törölhetjük, ezért készült el a diagnosztika. duplikált_indexek.

Harmadik probléma – átfedő indexek

A legtöbb kezdő fejlesztő egyetlen oszlopon hoz létre indexeket. Fokozatosan, ahogy ízlelgetni kezdik ezt a dolgot, az emberek elkezdik optimalizálni a lekérdezéseiket, és összetettebb indexeket adnak hozzá, amelyek több oszlopot tartalmaznak. Így jönnek létre az indexek az oszlopokra. A, A+B, A+B+C stb. Az első kettőt nyugodtan ki lehet dobni, mivel ezek a harmadik előtagjai. Ez is jelentősen megtakarítja a lemez helyet, és ezért van diagnosztika. átfedő_indexek.

Negyedik probléma – idegen kulcsok indexek nélkül

A Postgres megengedi idegen kulcs korlátozások létrehozását anélkül, hogy támogató indexet kellene megadni. Sok helyzetben ez nem jelent problémát, és még csak nem is nyilvánul meg... Egészen egy idő múlva...

Így volt nálunk is: egyszer csak abban a pillanatban a job, ami ütemezés szerint futott és tisztította a teszt megrendelésektől az adatbázist, elkezdett nekünk egy master hostot felhalmozni. A CPU és IO az egekbe szökött, a lekérdezések akadoztak és időtúllépés miatt megszakadtak, az szolgáltatás ötszázas hibát jelezett. Gyors elemzés. pg_stat_activity megmutatta, hogy a következő típusú lekérdezések akadtak el:

törölni <table> ahol az id szerepel (…)

Ezenkívül a cél táblában természetesen volt index az id-n, és a felvételek törlése a feltétel alapján nagyon kevés volt. Úgy tűnt, hogy mindennek működnie kellene, de sajnos nem működött.

A csodás explain analyze segített, és elmondta, hogy a cél táblában végzett törlés mellett a referenciális integritás ellenőrzése is folyik, és az egyik kapcsolódó táblában ez az ellenőrzés a sorozatos letapogatásba futott a megfelelő index hiánya miatt. Így született meg a diagnosztika. idegen_kulcsok_index_nélkül.

Ötödik probléma – null értékek az indexekben

Alapértelmezés szerint a Postgres beleszámítja a null értékeket a btree-indexekbe, de általában nincs szükség rájuk. Ezért szorgalmasan próbálom kidobni ezeket a null-okat (diagnosztika indexek_null_értékekkel), részleges indexeket létrehozva a nullable oszlopok esetében, mint például where is not nullEzzel a módszerrel sikerült csökkentenem az egyik indexünk méretét 1877 Mbyte-ról 16 Kbyte-ra. Egyik szolgáltatásunknál pedig az adatbázis mérete összesen 16%-kal (4,3 Gbyte-os abszolút számokban) csökkent a NULL értékek indexekből való eltávolítása révén. Óriási helymegtakarítás viszonylag egyszerű módosítások mellett. 🙂

Hatodik probléma – a primer kulcsok hiánya

A mechanizmus sajátosságai miatt MVCC a Postgres-ben lehetséges olyan helyzet, mint bloat, amikor az adatbázis egyik táblájának mérete gyorsan növekszik a sok elhalt rekord miatt. Naivan azt hittem, hogy minket ez nem fenyeget, és hogy a mi adatbázisunkkal ilyesmi nem történik meg, hiszen mi, ó jaj!!!, normális fejlesztők vagyunk… Milyen buta és naiv voltam…

Egy szép napon egy csodás migráció minden rekordot frissített egy nagy és aktívan használt táblában. 100 Gbyte-tal nőtt a tábla mérete a semmiből. Borzasztóan bosszantó volt, de kalandjaink nem értek véget itt. Miután 15 óra elteltével befejeződött az automatikus takarítás ezen a táblán, világossá vált, hogy a fizikai hely nem tér vissza. Megállítani a szolgáltatást és végrehajtani a VACUUM FULL-t nem tudtuk, ezért úgy döntöttünk, hogy használjuk pg_repack. És ekkor kiderült, hogy pg_repack nem tudja kezelni a primer kulcs nélküli táblákat vagy egyéb egyedi korlátozásokat, és a mi táblánkon nem volt primer kulcs. Így született meg a diagnosztika tables_without_primary_key.

A könyvtár verziójában 0.1.5 megjelent a lehetőség, hogy adatokat gyűjtsenek a táblák és indexek bloat-járól és időben reagáljanak rá.

Hetedik és nyolcadik probléma – a hiányzó indexek és a nem használt indexek

A következő két diagnosztika – tables_with_missing_indexes és unused_indexes – a végső formájukban viszonylag nemrégiben jelentek meg. Az a helyzet, hogy ezeket nem lehetett csak úgy hozzáadni.

Ahogy már említettem, több replikás konfigurációt használunk, és a különböző hosztokon eltérő a lekérdezési terhelés. Ennek eredményeként olyan helyzet alakul ki, hogy bizonyos táblák és indexek egyes hosztokon szinte nem használtak, és a statisztikák összegyűjtése minden hoszton a klaszterben szükséges. A statisztikákat szintén minden hoszton a klaszterben kell visszaállítani, ezt nem lehet csak a mester hoszton megtenni.

Ez a megközelítés lehetővé tette számunkra, hogy több tíz gigabájtot spóroljunk azzal, hogy eltávolítottuk a sosem használt indexeket, valamint hogy hozzáadtuk a szükséges indexeket a ritkán használt táblákhoz.

Összegzésül

Természetesen szinte minden diagnózist be lehet állítani kivételek listáját. Így gyorsan integrálhatjuk az ellenőrzéseket az alkalmazásában, megelőzve az új hibák megjelenését, és fokozatosan javítva a régiakat.

Néhány diagnózist már a funkcionális tesztek során végrehajthatunk közvetlenül a DB migrációk után. És ez talán a könyvtáram egyik legnagyobb lehetősége. Példa a használatra megtekinthető itt: demóból.

Azok az ellenőrzések, amelyek a nem használt vagy hiányzó indexekre, valamint a bloat-ra vonatkoznak, csak valós adatbázison érdemesek végrehajtani. Az összegyűjtött értékeket rögzíthetjük clickhousedb_fdw vagy elküldhetjük a monitoring rendszernek.

Nagyon remélem, hogy pg-index-health hasznos és keresett lesz. Ön is hozzájárulhat a könyvtár fejlesztéséhez, ha jelzi a felfedezett problémákat és új diagnosztikákat javasol.

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster