HÀlsa pÄ index i PostgreSQL ur en Java-utvecklares perspektiv

Hej.

Jag heter Vanya och jag Àr Java-utvecklare. Det rÄkade bli sÄ att jag arbetar mycket med PostgreSQL - jag sysslar med att konfigurera databaser, optimera strukturer, prestanda och leker lite DBA pÄ helgerna.

Under senaste tiden har jag ordnat upp flera databaser i vÄra mikrotjÀnster och skrivit ett Java-bibliotek pg-index-health, som underlÀttar detta arbete, sparar min tid och hjÀlper till att undvika vissa typiska misstag som utvecklare gör. Just om detta bibliotek kommer jag att prata idag.

HÀlsa pÄ index i PostgreSQL ur en Java-utvecklares perspektiv

Ansvarsfriskrivning

Den huvudsakliga versionen av PostgreSQL som jag arbetar med Àr 10. Alla SQL-frÄgor jag anvÀnder har ocksÄ testats pÄ version 11. Den minimi stödja versionen Àr 9.6.

Bakgrund

Det hela började för nÀstan ett Är sedan med en situation som kÀndes mÀrklig för mig: konkurrerande skapande av index pÄ en tom plats avslutades med ett fel. SjÀlva indexet, som det ofta Àr, förblev i ett ogiltigt tillstÄnd i databasen. Logganalysen visade brist pÄ temp_file_limit. Och sÄ började det... NÀr jag grÀvde djupare upptÀckte jag en hel uppsÀttning problem i databasens konfiguration och, med Àrmarna uppkavlade och glans i ögonen, satte jag igÄng att ÄtgÀrda dem.

Första problemet – standardkonfigurationen

Kanske Ă€r metaforen om Postgres som kan köras pĂ„ en kaffebryggare redan tröttsam för mĂ„nga, men... standardkonfigurationen vĂ€cker verkligen en hel del frĂ„gor. Åtminstone bör man uppmĂ€rksamma maintenance_work_mem, temp_file_limit, statement_timeout och lock_timeout.

I vÄrt fall maintenance_work_mem var som standard 64 megabyte, och temp_file_limit nÄgot runt 2 gigabyte - vi hade helt enkelt inte tillrÀckligt med minne för att skapa ett index pÄ en stor tabell.

DÀrför har jag i pg-index-health samlat ett antal nyckel-parametrar som jag tycker bör justeras för varje databas.

Andra problemet – dubblettindex

VÄra databaser lever pÄ SSD-diskar, och vi anvÀnder HA-konfiguration med flera datacenter, en huvudvÀrd och n-antal replikat. Utrymme pÄ disken Àr en mycket vÀrdefull resurs för oss; det Àr lika viktigt som prestanda och CPU-anvÀndning. SÄ, Ä ena sidan behöver vi index för snabb lÀsning, Ä andra sidan vill vi inte se onödiga index i databasen, eftersom de Àter utrymme och fördröjer uppdatering av data.

Och sÄ, efter att vi ÄterstÀllt alla ogiltiga index och sett pÄ Oleg Bartunovs föredrag, jag beslutade mig för att genomföra en "stor" rensning. Det visade sig att utvecklare inte gillar att lÀsa dokumentation om databaser. De gillar det verkligen inte. PÄ grund av detta uppstÄr tvÄ typiska fel - manuellt skapade index pÄ primÀrnyckeln och ett liknande "handgjort" index pÄ en unik kolumn. Saken Àr den att de inte behövs - Postgres sköter det sjÀlv. SÄdana index kan du tryggt ta bort, och för detta har vi en diagnostik. duplicated_indexes.

Tredje problemet - överlappande index

De flesta nybörjande utvecklare skapar index för en kolumn. Gradvis, efter att ha vant sig vid detta, börjar folk optimera sina frÄgor och lÀgga till mer komplexa index som inkluderar flera kolumner. SÄdana index uppstÄr för kolumner A, A+B, A+B+C och sÄ vidare. De första tvÄ av dessa index kan du tryggt kasta bort, eftersom de Àr prefix till det tredje. Detta sparar ocksÄ mycket plats pÄ disken, och för detta finns en diagnostik. intersected_indexes.

FjÀrde problemet - frÀmmande nycklar utan index

Postgres tillÄter skapande av begrÀnsningar för frÀmmande nycklar utan att ange stödjande index. I mÄnga situationer Àr detta inget problem, och det kan till och med inte pÄverka... Tills vidare...

SÄ var det Àven för oss: bara vid nÄgot tillfÀlle började jobbet, som kördes enligt schema och rensade databasen frÄn testbestÀllningar, att "lagra" oss en master host. CPU och IO sköt i höjden, förfrÄgningarna plockade och avbröts pÄ grund av timeout, tjÀnsten svarade med femhundra. En snabb analys pg_stat_activity visade att förfrÄgningar av typen:

ta bort från <table> där id i (…)

Samtidigt fanns det naturligtvis ett index pÄ id i mÄltabellen, och poster togs bort enligt villkoret, vilket var alldeles för lite. Det kÀndes som om allt borde fungera, men tyvÀrr fungerade det inte.

Till hjÀlp kom den underbara explain analyze och berÀttade att förutom att radera poster i mÄltabellen, sÄ gjordes det ocksÄ en kontroll av referensintegriteten, och pÄ en av de relaterade tabellerna föll denna kontroll ner i sequential scan pÄ grund av bristande passande index. SÄ föddes diagnostiken foreign_keys_without_index.

Femte problemet - null-vÀrden i index

Som standard inkluderar Postgres null-vĂ€rden i btree-index, men de Ă€r oftast inte nödvĂ€ndiga dĂ€r. DĂ€rför anstrĂ€nger jag mig för att ta bort dessa null-vĂ€rden (diagnostik indexes_with_null_values), genom att skapa partiella index pĂ„ nullable-kolumner av typen where is not null. Genom denna metod lyckades jag minska storleken pĂ„ ett av vĂ„ra index frĂ„n 1877 MB till 16 KB. I en av tjĂ€nsterna minskade storleken pĂ„ databasen totalt sett med 16 % (med 4,3 GB i absoluta siffror) genom att utesluta null-vĂ€rden frĂ„n indexen. En kolossal besparing av diskuppgifter med relativt enkla förĂ€ndringar. 🙂

Problem sex – avsaknad av primĂ€ra nycklar

PÄ grund av egenskaperna hos mekanismen MVCC i Postgres kan en sÄdan situation uppstÄ som bloat, nÀr storleken pÄ din tabell snabbt vÀxer pÄ grund av ett stort antal döda poster. Jag var naiv nog att tro att detta inte skulle drabba oss och att vÄr databas inte skulle drabbas, för vi Àr ju, wow!!!, helt normala utvecklare... Hur dum och naiv jag var...

En vacker dag uppdaterade en fantastisk migration alla poster i en stor och aktivt anvÀnd tabell. Vi fick +100 GB till storleken pÄ tabellen utan anledning. Det var jÀttefrustrerande, men vÄra motgÄngar slutade inte dÀr. Efter att autovakuum hade avslutats pÄ denna tabell efter 15 timmar stod det klart att det fysiska utrymmet inte skulle Äterkomma. Vi kunde inte stoppa tjÀnsten och göra VACUUM FULL, sÄ beslutet togs att anvÀnda pg_repack. HÀr visade det sig att pg_repack inte kan hantera tabeller utan primÀrnyckel eller nÄgot annat unikt begrÀnsningskrav, och i vÄr tabell fanns ingen primÀrnyckel. SÄ diagnostiken föddes tables_without_primary_key.

I versionen av biblioteket 0.1.5 lÀggs möjligheten till att samla in data om tabellernas och indexens bloat och reagera pÄ det i tid.

Problem sju och Ă„tta – brist pĂ„ index och oanvĂ€nda index

De tvĂ„ följande diagnostikerna – tables_with_missing_indexes och unused_indexes – i sin slutliga version dök upp relativt nyligen. Anledningen Ă€r att de inte bara kunde lĂ€ggas till.

Som jag redan har nÀmnt anvÀnder vi en konfiguration med flera repliker, och lÀsbelastningen pÄ olika vÀrdar Àr principiellt olika. I slutÀndan fÄr vi en situation dÀr vissa tabeller och index pÄ vissa vÀrdar praktiskt taget inte anvÀnds, och för analysen mÄste vi samla statistiken frÄn alla vÀrdar i klustret. Att ÄterstÀlla statistiken Àr ocksÄ nödvÀndigt pÄ varje vÀrd i klustret, det gÄr inte att göra detta endast pÄ master.

Denna metod har gjort det möjligt för oss att spara flera tiotals gigabyte genom att ta bort index som aldrig har anvÀnts, samt lÀgga till saknade index pÄ sÀllan anvÀnda tabeller.

Som en avslutning

SjÀlvklart kan de flesta diagnoser stÀllas in en lista över undantag. PÄ sÄ sÀtt kan kontroller snabbt implementeras i din applikation, vilket förhindrar uppkomsten av nya fel, och dÀrefter kan gamla fel gradvis fixas.

En del diagnoser kan utföras redan under funktionella tester direkt efter att databasmigreringar har genomförts. Och detta Àr kanske en av de kraftfullaste funktionerna i mitt bibliotek. Exempel pÄ anvÀndning kan ses i demoversioner.

Kontroller för oanvÀnda eller saknade index, samt för bloat, bör endast utföras pÄ en verklig databas. Samlade vÀrden kan skrivas till ClickHouse eller skickas till övervakningssystemet.

Jag hoppas verkligen att pg-index-health kommer att vara anvÀndbar och efterfrÄgad. Du kan ocksÄ bidra till utvecklingen av biblioteket genom att rapportera upptÀckta problem och föreslÄ nya diagnoser.

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster