ProHoster > Blog > Amministrazione > Errori tipici di l'applicazione chì portanu à bloat in postgresql. Andrej Salnikov
Errori tipici di l'applicazione chì portanu à bloat in postgresql. Andrej Salnikov
Proponi di leghje a trascrizione di u rapportu di u principiu di 2016 da Andrey Salnikov "Errori tipici in l'applicazioni chì portanu à bloat in postgresql"
In questu rapportu, analizeraghju i principali errori in l'applicazioni chì si trovanu in u stadiu di cuncepimentu è scrittura di codice di l'applicazione. È pigliaraghju solu quelli errori chì portanu à bloat in Postgresql. In regula, questu hè u principiu di a fine di u funziunamentu di u vostru sistema in tuttu, ancu s'ellu inizialmente ùn hè statu vistu nisun prerequisite per questu.
Felice di accoglie tutti ! Stu rapportu ùn hè micca cusì tecnicu cum'è u precedente da u mo cullegu. Questa discussione hè diretta à i sviluppatori di sistemi back-end principalmente perchè avemu un numeru abbastanza grande di clienti. È tutti facenu i stessi sbagli. Vi dicu di elli. Spiegheraghju à ciò chì fatale è male sti errori portanu.
Perchè sò fatti i sbagli? Sò realizati per dui motivi: à l'aleatoriu, forse si travaglià fora di ignuranza di certi miccanismi chì si trovanu à u livellu trà a basa è l'applicazione, è ancu in a basa stessa.
Vi daraghju trè esempii cù ritratti terribili di cumu e cose sò andate male. Descriveraghju brevemente u mecanismu chì si trova quì. E cumu per trattà cun elli, quandu sò accaduti, è chì metudi preventivi à utilizà per prevene i sbagli. Vi diceraghju di l'arnesi ausiliari è dà ligami utili.
Aghju utilizatu una basa di dati di teste induve aghju avutu duie tavule. Un pianu cù i cunti di i clienti, l'altru cù l'operazioni nantu à questi cunti. È cù una certa periodicità, aghjurnemu i saldi nantu à questi cunti.
I dati iniziali di u pianu: hè abbastanza chjucu, 2 MB. U tempu di risposta per a basa di dati è specificamente per u platu hè ancu assai bonu. È una carica abbastanza bona - 2 000 operazioni per seconda nantu à a piastra.
È attraversu stu rapportu, vi mustraraghju grafici per chì sia chjaru ciò chì succede. Ci sarà sempre 2 slides cù grafici. U primu slide hè ciò chì succede in generale nantu à u servitore.
È in questa situazione, vedemu chì avemu veramente un picculu piattu. L'indice hè chjucu à 2 MB. Questu hè u primu graficu à a manca.
U tempu di risposta mediu in u servitore hè ancu stabile, chjucu. Questu hè u graficu in cima à diritta.
U graficu in basso à manca hè a transazzione più longa. Pudemu vede chì e transazzione sò cumplette rapidamente. È l'autovacuum ùn funziona micca ancu quì, perchè - era una prova iniziale. Allora hà da travaglià è serà utile per noi.
A seconda diapositiva serà sempre dedicata à a piastra di prova. In questa situazione, aghjurnemu constantemente i saldi di u contu di u cliente. È vedemu chì u tempu di risposta mediu per l'operazione di aghjurnamentu hè abbastanza bonu, menu di un millisecondu. Avemu vistu chì i risorsi di u processatore (questu hè u gràficu superiore dirittu) sò ancu cunsumati in modu uniforme è abbastanza chjucu.
U graficu in basso à destra mostra a quantità di memoria operativa è di discu chì andemu in cerca di a nostra linea desiderata prima di aghjurnà. È u numeru di operazioni nantu à u pianu hè 2 per seconda, cum'è aghju dettu à u principiu.
È avà avemu una tragedia. Per una certa ragione, una transazzione longa scurdata si trova. I mutivi sò generalmente tutti banali:
Unu di i più cumuni hè chì avemu cuminciatu à accede à un serviziu esternu in u codice di l'applicazione. È stu serviziu ùn ci risponde micca. Vale à dì, avemu apertu una transazzione, hà fattu un cambiamentu in a basa di dati è andò da l'applicazione per leghje mail o à un altru serviziu in a nostra infrastruttura, è per una certa ragione ùn ci risponde micca. È a nostra sessione s'impiccata in un statu - ùn hè micca cunnisciutu quandu serà risolta.
A seconda situazione hè quandu una eccezzioni hè accaduta in u nostru codice per una certa ragione. È ùn avemu micca processatu u chjusu di a transazzione in l'eccezzioni. È avemu avutu una sessione appesa cù una transazzione aperta.
È l'ultimu hè ancu abbastanza cumuni. Questu hè un codice di mala qualità. Certi frameworks apre una transazzione. Impicca, è pudete micca sapè in l'applicazione chì l'avete impiccatu.
Induve portanu tali cose ?
À u fattu chì i nostri tavulini è indici sò cuminciati à sbulicà dramaticamente. Questu hè esattamente u listessu effettu bloat. Per a basa di dati, questu serà spressu in u fattu chì averemu un aumentu assai forte in u tempu di risposta di a basa di dati, a carica nantu à u servitore di basa di dati cresce. È in u risultatu, a nostra applicazione soffrerà. Perchè se in u vostru codice avete passatu 10 millisecondi nantu à una dumanda à a basa di dati, 10 millisecondi nantu à a vostra logica, allora a vostra funzione hà travagliatu 20 milliseconds. È avà a vostra situazione serà assai triste.
È vedemu ciò chì succede. U graficu in basso à manca mostra chì avemu una transazzione longa longa. E se guardemu à u graficu superiore manca, vedemu chì a dimensione di a tavula salta da dui megabyte à 300 megabytes. À u listessu tempu, a quantità di dati in a tavula ùn hà micca cambiatu, vale à dì, ci hè una quantità abbastanza grande di basura.
A situazione generale in quantu à u tempu mediu di risposta di u servitore hà ancu cambiatu da parechji ordini di grandezza. Vale à dì, tutte e dumande nantu à u servitore cuminciaru à sag completamente. È à u listessu tempu, i prucessi internu di Postgres in a faccia di l'autovacuum sò stati lanciati, chì cercanu di fà qualcosa è cunsuma risorse.
Chì succede à a nostra piastra ? U listessu. U tempu di risposta mediu nantu à a tableta hà saltatu parechji ordini di grandezza. Sì specificamente in termini di risorse cunsumate, allora vedemu chì a carica nantu à u processatore hè assai aumentata. Questu hè u graficu in cima à diritta. È hè aumentatu perchè u processatore hà da passà per una mansa di linii inutili in cerca di quellu chì avete bisognu. Questu hè u graficu in basso à destra. È in u risultatu, u numeru di chjamati per seconda hà cuminciatu à calà assai, perchè a basa di dati ùn hà micca tempu per processà u listessu numeru di dumande.
Avemu bisognu di vultà à a vita. Scalemu in Internet è scopre chì e transazzioni longu portanu à un prublema. Truvemu è tumbemu sta transazzione. È tuttu va bè per noi. Tuttu travaglia cum'è deve.
Avemu calmatu, ma dopu un pocu tempu cuminciamu à nutà chì l'applicazione ùn funziona micca cum'è prima di l'emergenza. E dumande sò trattate tutte u listessu più lentamente, è assai più lentamente. Una è mezu à duie volte più lento specificamente in u mo esempiu. A carica nantu à u servitore hè ancu più altu ch'è prima di l'accidentu.
È a quistione: "Chì succede à a basa in questu mumentu?". È cù a basa ci hè una situazione seguente. Nantu à u graficu di transazzione, pudete vede chì hà firmatu è ùn ci hè veramente micca transazzione à longu andà. Ma e dimensioni di a piastra durante l'accidentu criscinu fatalmente. È ùn hè micca diminuitu da tandu. U tempu mediu nantu à a basa hè stabilizatu. È e risposte parenu andà in modu adattatu cù una velocità accettabile per noi. L'autovacuum hè diventatu più attivu è hà cuminciatu à fà qualcosa cù a tavuletta, perchè hà bisognu di sparà più dati.
In particulare, nantu à u scoreboard di a prova, induve cambiamu i saldi: u tempu di risposta per a dumanda pare avè tornatu à u normale. Ma in fattu hè una volta è mezu più altu.
È da a carica nantu à u processatore, vedemu chì a carica nantu à u processatore ùn hà micca tornatu à u valore desideratu prima di u crash. È i ragiuni si trovanu solu in u graficu in basso à destra. Si pò vede chì ci hè una ricerca di qualchi quantità di memoria. Vale à dì, per circà a linea desiderata, spendemu e risorse di u servitore di basa di dati quandu sguassate i dati inutili. U numaru di transazzione per seconda hè stabilizatu.
In generale, bona, ma a situazione hè peghju chè era. A degradazione esplicita di a basa di dati per via di a nostra applicazione chì travaglia cù sta basa di dati.
È per capisce ciò chì succede quì, sè ùn erate micca in u rapportu precedente, allora avà un pocu di teoria. Teoria di u prucessu internu. Perchè l'autovacuum è chì face?
Letteralmente in poche parole per capire. À un certu puntu in u tempu avemu un tavulinu. Avemu fila in a tavula. Queste linee ponu esse attive, vive, avemu bisognu avà. Sò marcati in verde in a stampa. E ci sò e linee di morte chì anu digià travagliatu, sò stati aghjurnati, novi entrate sò apparsu nantu à elli. È sò marcati chì ùn sò più interessanti à a basa di dati. Ma si trovanu in a tavula per via di e peculiarità di Postgres.
Perchè avete bisognu di un autovacuum? L'Autovacuum vene à un certu puntu, chjama a basa di dati è dumanda: "Per piacè, dammi l'id di a transazzione più antica chì hè attualmente aperta in a basa di dati". A basa di dati torna stu id. È l'autovacuum, cunfidendu nantu à questu, passa per e linee in a tavula. È s'ellu vede chì alcune linee sò state cambiate da transazzione assai più vechje, allora hà u dirittu di marcà cum'è linii chì pudemu reutilizà in u futuru scrivendu novi dati quì. Questu hè un prucessu di fondu.
À questu tempu, cuntinuemu à travaglià cù a basa di dati, cuntinuemu à fà qualchi cambiamenti in a tavula. È nantu à sti linii, chì pudemu reutilizà, scrivemu novi dati. È in questu modu avemu un ciculu, vale à dì, qualchi vechji fili morti appariscenu sempre quì, invece di elli scrivemu novi linee chì avemu bisognu. È questu hè u statu normale per PostgreSQL per travaglià.
Chì hè accadutu durante l'accidentu ? Cumu hè fattu stu prucessu?
Avemu avutu un piattu in qualchì cundizione, qualchì viventi, qualchì linea morta. L'autovacuum hè ghjuntu. Hà dumandatu à a basa di dati nantu à quale hè a nostra transazzione più antica, quale hè u so id. Aghju avutu questu id, chì pò esse parechje ore, forse deci minuti. Dipende da quantu pesa a carica chì avete nantu à a basa di dati. È si n'andò à circà e linee chì ponu marcà cum'è reutilizate. È ùn aghju micca trovu tali linii in a nostra tavula.
Ma à questu tempu cuntinuemu à travaglià cù a tavola. Facemu qualcosa in questu, aghjurnà, cambià i dati. Chì duverebbe fà a basa di dati à questu tempu? Ella ùn hà micca scelta ma aghjunghje novi linee à a fine di a tavula esistente. È cusì à noi a dimensione di a tavula cumencia à esse inflata.
Avemu veramente bisognu di linee verdi per travaglià. Ma duranti un tali prublema, risulta chì u percentualità di e linee verdi hè assai bassu in tuttu u voluminu di a tavula.
È quandu eseguimu una dumanda, a basa di dati hà da passà per tutte e linee, sia rosse sia verdi, per truvà a linea ghjusta. È l'effettu di inflating the table with data inùtule hè chjamatu "bloat", chì manghja ancu u nostru spaziu di discu. Ricurdativi, era 2 MB, avà hè 300 MB? Avà cambiate megabyte in gigabyte è perderete tutte e risorse di u discu abbastanza rapidamente.
Chì sò l'implicazioni per noi?
In u mo esempiu, a tavula è l'indici anu crisciutu 150 volte. Certi di i nostri clienti anu avutu più casi fatali quandu u spaziu di discu hà cuminciatu à scappà.
I tavulini ùn si stendenu mai per sè stessu. L'autovacuum in certi casi pò taglià a cuda di a tavula s'ellu ci sò solu ligne mortu. Ma siccomu ci hè una rotazione constante, una linea verde pò esse appiccicata à a fine è micca esse aghjurnata, è tuttu u restu in un locu à u principiu di a piastra serà arregistratu. Ma questu hè un avvenimentu cusì improbabile chì a vostra tavula stessu diminuirà in grandezza, perchè ùn deve micca sperà.
A basa di dati hà bisognu di sorte per tutta a pila di linii inutili. È perdimu risorse di discu, perdemu risorse di processore è elettricità.
È questu affetta direttamente a nostra applicazione, perchè se à u principiu avemu passatu 10 millisecondi nantu à una dumanda, 10 millisecondi nantu à u nostru codice, allora durante u crash avemu cuminciatu à passà una seconda nantu à una dumanda è 10 millisecondi nantu à u codice, vale à dì, un ordine di a prestazione di l'applicazione di magnitudine diminuite. È quandu l'accidentu hè stata risolta, avemu cuminciatu à passà 20 millisecondi per dumanda, 10 millisecondi per codice. Questu significa chì avemu sempre affundatu una volta è mezu in quantu à u rendiment. È questu hè tuttu per via di una transazzione chì pende, è, forsi, per culpa nostra.
È a quistione: "Cumu possu ritruvà tuttu?" Per quessa, tuttu hè bè cun noi è e dumande currenu cum'è prima di l'accidentu.
Per questu, ci hè un certu ciculu di travagliu chì hè realizatu.
Prima avemu bisognu di truvà e tavule problematiche chì anu gonfiate. Capemu chì certi tavulini registranu più attivamente, alcuni menu attivamente. È per questu avemu aduprà l'estensione pgstattuple. Installendu sta estensione, pudete scrive dumande per aiutà à truvà tavule chì sò abbastanza gonfiate.
Quandu avete trovu sti tavulini, anu da esse cumpressu. Ci sò digià arnesi per questu. In a nostra cumpagnia, avemu aduprà trè strumenti. U primu hè u VACUUM FULL integratu. Hè crudeli, duru è senza pietà, ma qualchì volta hè assai utile. pg_repack и pgcompacttable sò utilità di terzu per cumpressione di e tavule. È sò più attenti à a basa di dati.
Sò usati secondu ciò chì hè più convenientu per voi. Ma parleraghju di questu à a fine. A cosa principal hè chì ci sò trè strumenti. Ci sò assai da sceglie.
Dopu avè currettu tuttu, assicurendu chì tuttu hè bè, duvemu sapè cumu impedisce sta situazione in u futuru:
Hè abbastanza faciule per prevene. Avete bisognu di monitorà a durata di e sessione nantu à u servitore Master. Sessioni particularmente periculose in u statu inattivu di transazzione. Quessi sò quelli chì anu appena apertu una transazzione, anu fattu qualcosa è si sò lasciati, o simpricimenti impiccati, si sò persi in u codice.
È per voi, cum'è sviluppatori, hè impurtante di pruvà u codice à u mumentu chì queste situazioni si presentanu. Ùn hè micca difficiule di fà. Questu serà un cuntrollu utile. Eviterete assai prublemi "infantili" assuciati cù transazzioni longu.
Nantu à questi gràfiche, aghju vulsutu vede cumu a tavula è u cumpurtamentu di a basa di dati hà cambiatu dopu avè passatu VACUUM FULL nantu à a tavula in questu casu. Questa ùn hè micca a mo pruduzzione.
A dimensione di a tavula hà tornatu immediatamente à u so statu di travagliu normale di un paru di megabyte. Questu ùn hà micca affettatu assai u tempu di risposta mediu in u servitore.
Ma specificamente in a nostra tabella di teste, induve avemu aghjurnatu i saldi di u contu, vedemu chì u tempu di risposta mediu à una dumanda per aghjurnà e dati in a tavuletta hè stata ridutta à i livelli pre-crash. I risorsi cunsumati da u processatore per eseguisce sta dumanda sò ancu cascati à livelli pre-crash. È u graficu in basso à destra mostra chì avà truvamu esattamente a linea chì avemu bisognu subitu, senza passà per u munzeddu di linii morti chì eranu prima chì a tavola hè stata cumpressa. È u tempu mediu di dumanda ferma apprussimatamente à u listessu livellu. Ma quì aghju, piuttostu, l'errore di u mo hardware.
Hè quì chì a prima storia finisci. Ella hè a più cumuna. È succede à tutti, indipendentemente da l'esperienza di u cliente, quantu i programatori qualificati sò. Prima o poi succede.
A seconda storia, in quale distribuemu a carica è ottimisimu e risorse di u servitore
Avemu crisciutu è diventate omi seri. È avemu capitu chì avemu una rèplica è saria bè per noi per equilibrà a carica: scrivite à u Maestru, è leghje da a replica. È di solitu sta situazione si sviluppa quandu vulemu preparà un tipu di rapporti o ETL. E l'affari sò assai cuntenti. Vole veramente una varietà di rapporti cù una mansa di analitiche cumplesse.
I rapporti duranu parechje ore, perchè l'analitiche cumplesse ùn ponu esse calculate in millisecondi. Noi, cum'è i bravi, scrivemu codice. Facemu in l'applicazione di inserimentu chì avemu registratu nantu à u Maestru, facemu rapporti nantu à a replica.
Distribuemu a carica.
Tuttu funziona perfettamente. Semu grandi.
È ciò chì pare sta situazione? Specificamenti, nantu à questi charts, aghju ancu aghjustatu a durata di e transazzione da a replica per a durata di a transazzione. Tutti l'altri grafici riferite solu à u Servitore Maestru.
À questu tempu, u mo rapportu di rapportu era cresciutu. Ci sò più di elli. Pudemu vede chì u tempu mediu di risposta di u servitore hè stabile. Pudemu vede chì avemu una transazzione longa nantu à a replica chì dura per 2 ore. Videmu u travagliu tranquillu di l'autovacuum, chì processa i linii morti. È simu tutti bè.
In particulare, secondu a tableta di prova, cuntinuemu à aghjurnà i saldi nantu à i cunti quì. È avemu ancu un tempu di risposta stabile nantu à dumanda, cunsumu di risorse stabile. Tuttu hè bè cun noi.
Tuttu hè bè finu à u mumentu chì sti rapporti cumincianu à sparà à noi nantu à un cunflittu cù a replicazione. Et ils tirent en retour à intervalles réguliers.
Andemu in linea è cuminciamu à leghje perchè questu succede. È truvamu una suluzione.
A prima suluzione hè di aumentà a latenza di replicazione. Sapemu chì u nostru rapportu dura 3 ore. Pone u ritardu di replicazione à 3 ore. Cuminciamu tuttu, ma avemu sempre cuntinuà à avè prublemi cù u fattu chì i rapporti sò volte sparati.
Vulemu chì tuttu sia perfettu. Andemu più in là. È truvamu un paràmetru cool in Internet - hot_standby_feedback. L'accendemu. Hot_standby_feedback ci permette di mantene l'autovacuum in esecuzione nantu à u Master. Cusì, sguassemu cumplettamente i cunflitti di replicazione. È tutti travagliammu bè cù i rapporti.
È ciò chì succede cù u servitore Maestru in questu mumentu? È cù u servitore Master, avemu un disastru tutale. Avà vedemu i grafici cù questi dui paràmetri attivati. È vedemu chì a sessione nantu à a replica in qualchì modu hà cuminciatu à influenzà a situazione nantu à u servitore Maestru. Face un impattu perchè hà suspesu l'autovacuum chì pulisce e linee morte. A nostra dimensione di a tavula hè tornata à u celu. U tempu mediu di esecuzione di e dumande in tutta a basa di dati hè ancu sbulicatu. L'autovacuums si strinsenu un pocu.
In particulare, nantu à a nostra piastra, vedemu chì l'aghjurnamentu di dati nantu à ellu hà ancu saltatu in u celu. U cunsumu di risorse di u processatore hè ancu aumentatu assai. Iteremu di novu nantu à un gran numaru di linii inutili morti. È u tempu di risposta nantu à sta tableta, u numeru di transazzione hè cascatu.
Chì serebbe s'ellu ùn sapemu micca di ciò chì parlava prima ?
Cuminciamu à circà i prublemi. Sè avemu scontru prublemi in a prima parte, sapemu chì questu pò esse u mutivu di una transazzione longa è cullà nantu à u Maestru. U prublema hè cù u Maestru. I salsicce. Si scalda, hà una Load Average di menu di centu.
E dumande rallentanu quì, ma ùn vedemu micca transazzione à longu andà. È ùn capemu micca ciò chì passa. Ùn sapemu induve circà.
Verificazione di u hardware di u servitore. Forse a nostra incursione hè crollata. Forse avemu brusgiatu a barra di memoria. Iè, tuttu pò esse. Ma nò, i servitori sò novi, tuttu funziona bè.
Tutti corre: amministratori, sviluppatori è direttore. Nunda aiuta.
È à un certu puntu, tuttu di colpu principia à curregà.
Nantu à a replica, à quellu tempu, a dumanda hà travagliatu è partì. Avemu ricevutu un rapportu. L'affari hè sempre felice. Comu pudete vede, a nostra tavula hà crisciutu di novu è ùn hà micca da diminuisce. Nantu à u graficu cù sessioni, aghju lasciatu un pezzu di sta transazzione longa da a replica, per pudè evaluà quantu dura finu à chì a situazione stabilizza.
A sessione hè andata. È solu dopu à qualchì tempu u servitore vene più o menu in ordine. È u tempu mediu di risposta per e dumande nantu à u servitore Maestru torna à u normale. Perchè, infine, l'autovacuum hà avutu l'uppurtunità di pulizziari, marcate queste linee morte. È hà cuminciatu à fà u so travagliu. E quantu prestu faci, cusì prestu seremu in ordine.
Nantu à a tavola di prova, induve aghjurnà i saldi di u contu, vedemu esattamente a stessa stampa. U tempu mediu di l'aghjurnamentu di u contu hè ancu normalizatu gradualmente. I risorse cunsumati da u processatore sò ancu ridotti. È u numeru di transazzione per seconda hè tornatu à u normale. Ma dinò, torna à a nurmale, micca u listessu chì avemu avutu prima di l'accidentu.
In ogni casu, avemu un drawdown in u rendiment, cum'è in u primu casu, unu è mezu à duie volte, è qualchì volta ancu più.
Semu chì avemu fattu tuttu bè. Distribuite a carica. L'equipaggiu ùn hè micca inattivu. Sicondu a mente, anu rottu e dumande, ma ancu tuttu hà fattu male.
Ùn attivate micca hot_standby_feedback ? Iè, ùn hè micca cunsigliatu per accende senza motivi particularmente forti. Perchè sta torsione affetta direttamente u Master Server è suspende u travagliu di l'autovacuum quì. Accendendu nantu à qualchi replica è scurdate di questu, pudete tumbà u Maestru è avè grandi prublemi cù l'applicazione.
Aumentà max_standby_streaming_delay? Iè, per i rapporti hè. Sè vo avete un rapportu di trè ore è ùn vulete micca ch'ellu si chjappà per via di cunflitti di replicazione, allora simpricimenti aumentà u ritardu. Un rapportu longu ùn hà mai bisognu di dati chì sò intruti in a basa di dati avà. Sè vo avete lu per trè ore, allura vi sò corsa lu per qualchi piriudu dati vechji. È voi, chì trè ore di ritardu, chì sei ore di ritardu - ùn ghjucà micca un rolu, ma riceverete rapporti cunsistenti è ùn cunnosci micca i prublemi cù a so caduta.
Naturalmente, avete bisognu di cuntrullà e sessioni longu nantu à repliche, soprattuttu se decide di attivà hot_standby_feedback nantu à una replica. Perchè puderia esse qualcosa. Avemu datu sta rimarca à u sviluppatore per ch'ellu hà da pruvà e dumande. Hà scrittu una dumanda loca. Hà cuminciatu è andò à beie u tè, è avemu avutu u Maestru stabilitu. O avemu lanciatu l'applicazione sbagliata quì. E situazioni sò variate. Sessioni nantu à e rèpliche deve esse cuntrullate cù cura cum'è nantu à u Maestru.
E s'è vo avete dumande veloci è longu nantu à e rèpliche, allora in questu casu hè megliu di sparte per distribuisce a carica. Questu hè un ligame per streaming_delay. Per rapidità avè una replica cù un picculu ritardu di replicazione. Per e dumande di rappurtazioni di longa durata, avè una replica chì pò ritardà da 6 ore, da un ghjornu. Questa hè una situazione cumpletamente normale.
Eliminemu e cunsequenze in u listessu modu:
Truvemu tavule gonfiate.
E cumpressemu cù u strumentu più còmuda chì ci cunvene.
A seconda storia finisci quì. Passemu à a terza storia.
Ancu abbastanza cumuni per noi, in quale facemu a migrazione.
Ogni pruduttu software cresce. I bisogni cambianu. In ogni casu, vulemu sviluppà. È succede chì avemu bisognu di aghjurnà e dati in a tavula, vale à dì per eseguisce l'aghjurnamentu in quantu à a nostra migrazione à a nova funziunalità chì avemu implementatu cum'è parte di u nostru sviluppu.
U vechju furmatu di dati ùn cunvene micca. Dicemu chì avemu turnatu avà à a seconda tavola, induve aghju operazioni nantu à sti cunti. E, dicemu chì eranu in rubli, è avemu decisu di aumentà a precisione è fà in kopecks. È per questu avemu bisognu di fà un aghjurnamentu: multiplicate u campu cù a quantità di l'operazione per centu.
In u mondu d'oghje, usemu strumenti di versione di basa di dati automatizati. Dicemu Liquibase. Registramu a nostra migrazione quì. Testemu nantu à a nostra basa di teste. Tuttu hè bè. L'aghjurnamentu hè in esecuzione. I blocchi funzionanu per un certu tempu, ma avemu da ottene dati aghjurnati. È pudemu lancià una nova funziunalità in questu. Tutti pruvati è verificati. Tuttu cunfirmatu.
Realizatu u travagliu pianificatu, realizatu a migrazione.
Eccu a migrazione cù l'aghjurnamentu prisentatu davanti à voi. Siccomu aghju operazioni nantu à i cunti, a piastra era 15 GB. E postu chì aghjurnemu ogni linea, avemu radduppiatu a dimensione di a tavula perchè avemu soprascritta ogni linea.
Durante a migrazione, ùn pudemu micca fà nunda cù questa etichetta, perchè tutte e dumande per questu sò state in fila è aspittàvanu chì sta aghjurnazione finisci. Ma quì vogliu attirà a vostra attenzione à i numeri chì sò nantu à l'assi verticale. Questu hè, avemu un tempu mediu di dumanda prima di a migrazione in a regione di 5 millisecondi è una carica nantu à u processatore, u numeru di operazioni di bloccu per leghje a memoria di discu hè menu di 7,5.
Avemu migratu è avemu avutu prublemi di novu.
A migrazione hè stata successu, ma:
A vechja funziunalità cuminciò à curriri più longu.
A tavula hà crisciutu di novu in grandezza.
A carica nantu à u servitore hè diventata di novu più di ciò chì era.
E, sicuru, simu sempre fidling cù a funziunalità chì hà travagliatu bè, avemu migliuratu un pocu.
È questu hè di novu bloat, chì torna spoils a nostra vita.
Eccu dimustratu chì a tavula, cum'è i dui casi precedenti, ùn hà micca da vultà à e dimensioni previ. A carica media nantu à u servitore pare esse adatta.
È se vultemu à a tavula cù i cunti, allora vedemu chì u tempu mediu di dumanda hè duppiatu per questa tavola. A carica nantu à u processatore è u nùmeru di linii per esse urdinatu in memoria hà saltatu sopra à 7,5, ma era più bassu. È hà saltatu in u casu di processori per 2 volte, in u casu di l'operazioni di bloccu da 1,5 volte, vale à dì avemu una degradazione in u rendiment di u servitore. È in u risultatu - a degradazione di u rendiment di a nostra applicazione. À u listessu tempu, u numeru di chjama hè stata apprussimatamente à u listessu livellu.
È quì u principale hè di capisce cumu fà tali migrazioni currettamente. È anu da esse fattu. Facemu queste migrazioni abbastanza regularmente.
Tali migrazioni grandi ùn sò micca fatti automaticamente. Hanu da esse sempre cuntrullati.
Hè bisognu di a supervisione da una persona esperta. Sì avete un DBA in a squadra, lasciate chì u DBA fà. Hè u so travagliu. Se no, lasciate a persona più esperta, chì sà cumu travaglià cù basa di dati.
U novu schema di basa di dati, ancu s'ellu aghjurnà una colonna, avemu sempre preparatu in tappe, vale à dì in anticipu prima chì a nova versione di l'applicazione si sparghje:
I novi campi sò aghjuntu in quale scriveremu solu i dati aghjurnati.
Trasferemu dati da u vechju campu à u novu campu in picculi parti. Perchè facemu questu? Prima, avemu sempre cuntrullà u prucessu di stu prucessu. Sapemu chì avemu digià trasfirutu tanti batchs è avemu tanti parti.
È u sicondu effettu pusitivu hè chì trà ogni tali batch chjudemu una transazzione, apre una nova, è questu permette à l'autovacuum di travaglià secondu a piastra, per marcà e linee di morte per a reutilizazione.
Per e linee chì apparisceranu durante l'operazione di l'applicazione (avemu sempre a vechja applicazione), aghjunghjemu un trigger chì scrive novi valori à novi campi. In u nostru casu, questu hè una multiplicazione per centu di u vechju valore.
Sè simu cumplitamenti stubborn è vulemu u stessu campu, dopu à a fine di tutte e migrazioni è prima di lancià a nova versione di l'applicazione, simpricimenti rinominemu i campi. I vechji in qualchì nome inventatu, è rinominemu i novi campi à i vechji.
È solu dopu chì lanciamu una nova versione di l'applicazione.
È à u stessu tempu, ùn avemu micca gonfiate è ùn ci sag in performance.
È avà un pocu di più nantu à l'arnesi chì aghju citatu in a prima storia.
Prima di circà bloat, duvete installà l'estensione pgstattuple.
Per ùn inventà e dumande, avemu digià scrittu sti dumande in u nostru travagliu. Pudete aduprà. Ci sò duie dumande quì.
U primu pigghia un bellu pezzu, ma vi mostrarà i valori esatti di bloat secondu a tavula.
U sicondu travaglia più veloce è hè assai efficace quandu avete bisognu di valutà rapidamente s'ellu ci hè un bloat o micca in a tavula. È avete ancu capisce chì ci hè sempre un bloat in una tavola Postgres. Questa hè una caratteristica di u so mudellu MVCC.
È 20% bloat hè bè per i tavulini in a maiò parte di i casi. Questu hè, ùn deve micca preoccupatu è cumpressà sta tavola.
Avemu capitu cumu per identificà e tavule chì sò inch'elli cun noi, in più, quandu sò inch'elli cù dati inutili.
Avà nantu à cumu risolve u gonfiore:
Sè avemu un picculu piattu è boni dischi, vale à dì nantu à una piastra finu à un gigabyte, hè abbastanza pussibule di utilizà VACUUM FULL. Piglierà una serratura esclusiva da voi per uni pochi seconde, è va bè, ma farà tuttu rapidamente è duramente. Chì faci VACUUM FULL? Piglia una serratura esclusiva nantu à a tavula è riscrive e fila in diretta da i vechji tavulini à a nova tavola. È à a fine li rimpiazza. Elimina vechji fugliali, rimpiazza i novi per i vechji. Ma per a durata di u so travagliu, pigghia una serratura esclusiva nantu à a tavula. Questu significa chì ùn pudete micca fà nunda cù sta tavola: nè scrive, nè leghje, nè mudificà. È VACUUM FULL richiede spaziu di discu supplementu per scrive dati.
Next Tool pg_repack. Per u so principiu, hè assai simili à VACUUM FULL, perchè ancu overwrites dati da vechji schedari à novi è li rimpiazza in a tavula. Ma à u stessu tempu, ùn piglia micca una serratura esclusiva nantu à a tavula à u principiu di u so travagliu, ma piglia solu à u mumentu quandu hà dati pronti per rimpiazzà i schedari. Havi i stessi esigenze di risorse di discu cum'è VACUUM FULL. Avete bisognu di spaziu di discu extra, è questu hè qualchì volta criticu si avete tavule di terabyte. È hè abbastanza gluttonosu in quantu à u processatore, perchè travaglia attivamente cù I / O.
A terza utilità hè pgcompacttable. Tratta i risorse più cun cura, perchè travaglia nantu à principii ligeramente diffirenti. L'essenza principale di pgcompacttable hè chì move tutte e fila in diretta à u principiu di a tavula cù l'aghjurnamenti in a tavola. E poi principia u vacuum nantu à sta tavula, perchè sapemu chì avemu fila viva à u principiu è fila morta à a fine. È u vacuum stessu taglia sta cuda, vale à dì, ùn hà micca bisognu di assai spaziu di discu supplementu. È à u stessu tempu, pò ancu esse spressu da e risorse.
Tuttu cù arnesi.
Se trova u tema bloat interessante in quantu à scavà più in l'internu, allora eccu alcuni ligami utili per voi:
https://www.slideshare.net/alexius2Mb/where-is-the-space-postgres hè u rapportu di u mo cullega. Hè generale nantu à induve u postu di Postgres và in u cursu di u so travagliu è a vita. È ci hè un pezzu tecnicu assai grande è detallatu per i DBA nantu à bloat.
https://github.com/dataegret/pg-utils hè un ligame à u nostru repository, induve guardemu una mansa di script utili per verificà u statutu di a basa di dati. Quì pudete truvà script di ricerca di bloat.
U terzu и quartu ligami à arnesi chì vi aiuterà à cumpressà i piatti.
Quì aghju pruvatu à mustrà una storia d'orrore per i sviluppatori, perchè sò i nostri clienti diretti di basa di dati è devenu capisce ciò chì è ciò chì l'azzioni portanu. Spergu chì aghju successu. Grazie per a vostra attenzione!
I vostri dumanni
Grazie per u rapportu! Avete parlatu di cumu si ponu identificà i prublemi. Cumu ponu esse avvistati? Vale à dì, aghju avutu una situazione induve e dumande pende micca solu perchè anu vultatu à certi servizii esterni. Il s'agissait d'un certain nombre de jonctions sauvages. Ci era parechje dumande minuscule è inoffensive chì stavanu attornu per un ghjornu, è poi cuminciaru à fà una sorta di sciocchezza. Questu hè, hè assai simili à ciò chì descrivi. Cumu seguità? Siate è fighjate constantemente, quale dumanda hè bloccata? Cumu pò esse impeditu?
In questu casu, questu hè un compitu per l'amministratori di a vostra cumpagnia, micca necessariamente per u DBA.
Sò un amministratore.
PostgreSQL hà una vista chjamata pg_stat_activity chì mostra e dumande pendenti. È si pò vede quantu tempu ferma quì.
Aghju da vene in ogni 5 minuti è vede?
Configurate cron è verificate. Sì avete una dumanda longa, scrivite una lettera è basta. Questu hè, ùn avete micca bisognu di guardà cù i vostri ochji, questu pò esse automatizatu. Riceverete una lettera, vi rispondi. O pudete sparà automaticamente.
Ci sò ragiuni chjaru perchè questu succede?
Aghju listatu alcuni. Altri esempi più cumplessi. È pò esse una longa conversazione.
Grazie per u rapportu! Vuliu chjarificà l'utilità pg_repack. Se ùn ci vole micca un serratura esclusiva, allora...
Ella face una serratura esclusiva.
... tandu I putenziale putenziale perde dati. A mo app ùn deve micca esse registratu nunda in questu mumentu?
No, travaglia in silenziu cù a tavula, vale à dì pg_repack trasferisce prima tutte e linee in diretta chì ci sò. Naturalmente, ci hè un tipu di record in a tavula chì passa. Ellu tira solu sta coda di cavallu.
Vale à dì, a face sempre à a fine ?
À a fine, ci vole una serratura esclusiva per scambià questi schedari.
Serà più veloce di VACUUM FULL?
VACUUM FULL, cum'è cuminciò, hà pigliatu immediatamente un serratura esclusiva. È finu à ch'ellu hà fattu tuttu, ùn a lasciarà micca andà. È pg_repack piglia una serratura esclusiva solu à u mumentu di rimpiazzà i schedari. À questu puntu, ùn scrive micca quì, ma i dati ùn saranu micca persi, tuttu serà in ordine.
Bonghjornu! Avete parlatu di u travagliu di l'autovacuum. Ci era un graficu cù e cellule rosse, gialli è verdi di u record. Hè, i gialli - li hà marcatu cum'è sguassati. È in u risultatu, pudete scrive qualcosa di novu in elli?
Iè. Postgres ùn elimina micca e fila. Hà una tale specificità. Se avemu aghjurnatu a linea, avemu marcatu u vechju cum'è sguassatu. L'identificatore di transazzione chì hà cambiatu sta linea vene quì, è scrivimu una nova linea. È avemu sessioni chì puderanu leghje. À un certu puntu, diventanu abbastanza vechji. È l'essenza di l'autovacuum hè chì passa per queste linee è li marca cum'è innecessarii. È quì pudete overwrite i dati.
Capiscu. Ma a quistione ùn hè micca nantu à questu. Ùn aghju micca d'accordu. Dicemu chì avemu un tavulinu. Hà campi di dimensione variabile. E s'ellu pruvate d'inserisce qualcosa di novu, pò esse simpricimenti micca intruduce in a vechja cellula.
No, ci hè in ogni casu tutta a linea hè aghjurnata. Postgres hà dui mudelli di almacenamiento. Si sceglie da u tipu di dati. Ci hè dati chì hè cullucatu direttamente in a tavula, è ci hè ancu tos data. Quessi sò grandi quantità di dati: testu, json. Sò guardati in pasticchi separati. E sicondu sti pasticchi, a listessa storia cù bloat succede, vale à dì, tuttu hè listessu. Sò solu listati separatamente.
Grazie per u rapportu! Quantu hè accettabile aduprà richieste di timeout di dichjarazione per limità a durata?
Assai accettabile. Avemu aduprà in ogni locu. E postu chì ùn avemu micca i nostri servizii, furnisce un supportu remotu, ci sò una varietà di clienti. È tutti sò abbastanza soddisfatti di questu. Vale à dì, avemu impieghi in cron chì verificate. Hè solu chì a durazione di e sessioni hè negoziata cù u cliente, prima di quale ùn avemu micca chiovu. Puderia esse un minutu, puderia esse 10 minuti. Hè dipende di a carica nantu à a basa è u so scopu. Ma tutti usemu pg_stat_activity.
Grazie per u rapportu! Aghju pruvatu à pruvà u vostru rapportu per e mo applicazioni. E pare chì avemu principiatu una transazzione in ogni locu, è l'avemu esplicitamente cumpletu in ogni locu. Sì qualchì eccezzioni, allora tuttu u listessu rollback succede. È po pensu. Dopu tuttu, a transazzione pò principià micca esplicitamente. Questu hè un suggerimentu per a zitella, pensu. Se solu fà una aghjurnazione di registrazione, a transazzione cumminciarà in PostgreSQL è finisce solu quandu a cunnessione hè disconnected?
Sè vo site à parlà avà di u livellu di l'applicazione, allora dipende da u driver chì avete aduprà, da l'ORM chì hè stata utilizata. Ci sò assai paràmetri quì. Se avete attivatu l'auto commit, allora una transazzione principia quì è si chjude immediatamente.
Questu hè, si chjude immediatamente dopu l'aghjurnamentu?
Dipende da i paràmetri. Aghju chjamatu un paràmetru. Questu hè un impegnu automaticu. Hè abbastanza cumuna. Se hè attivatu, a transazzione hè stata aperta è chjusa. A menu chì ùn avete micca dettu esplicitamente "iniziu transazzione" è "fine transazzione", ma simpricimenti lanciatu una dumanda in a sessione.
Bonghjornu! Grazie per u rapportu! Immaginate chì avemu una basa di dati chì si stende è si stende è dopu u servitore esce da u spaziu. Ci sò strumenti per risolve sta situazione?
U locu nantu à u servitore in una bona manera deve esse monitoratu.
Per esempiu, DBA andò à beie tè, era in un resort, etc.
Quandu un sistema di schedari hè creatu, almenu qualchì spaziu di riserva hè creatu induve a dati ùn hè micca scrittu.
E s'ellu hè cumplettamente zero?
Ci hè chjamatu spaziu riservatu, vale à dì, pò esse liberatu, è secondu quantu grande hè stata creata, avete u spaziu liberu. Per difettu, ùn sò micca quantu ci sò. È in un altru casu, furnisce i dischi in modu chì avete un locu per fà una operazione di ricuperazione. Pudete sguassà qualchi tavula chì vi sò guarantiti micca bisognu.
Ùn ci hè micca altre arnesi ?
Hè sempre fattu a manu. È in u locu hè revelatu ciò chì hè megliu per fà quì, perchè ci sò dati chì sò critichi, ùn ci hè micca criticu. È per ogni basa di dati è applicazione chì travaglia cun ellu, dipende di l'affari. Hè sempre decisu in u locu.
Grazie per u rapportu! Aghju duie dumande. Prima, avete dimustratu diapositive induve hè statu dimustratu chì in u casu di e transazzione hang, sia a quantità di spaziu di tavula è a dimensione di l'indici crescenu. E più in u rapportu, ci era una mansa di utilità chì imballanu a tableta. Et quid de l'indice ?
Li imballanu ancu.
Ma u vacuum ùn affetta micca l'indici?
Certi travaglianu cù un indice. Per esempiu pg_rapack, pgcompacttable. Vacuum ricrea l'indici, li afecta. VACUUM FULL hà l'essenza di soprascrive tuttu, vale à dì chì travaglia cù tutti.
È a seconda quistione. Ùn aghju micca capitu perchè i rapporti nantu à e repliche dipendenu tantu da a replicazione stessa. Mi paria chì i rapporti sò leghje, è a replicazione hè scritta.
Chì provoca un cunflittu di replicazione? Avemu un Maestru nantu à quale i prucessi si facenu. Avemu un autovacuum. Autovacuum infatti, chì face? Taglia qualchi vechji linee. Se à questu tempu avemu una dumanda nantu à a replica chì leghje sti vechji linii, è nantu à u Maestru ci era una situazione chì l'autovacuum hà marcatu queste linee cum'è pussibule per a riscrittura, allora l'avemu soprascritta. È avemu ricivutu un pacchettu di dati, quandu avemu da riscrive e linee chì a dumanda necessita nantu à a replica, allora u prucessu di replicazione aspetta per u timeout chì avete cunfiguratu. E poi PostgreSQL deciderà ciò chì hè più impurtante per ellu. È a replicazione hè più impurtante per ellu ch'è una dumanda, è sparà a dumanda per fà questi cambiamenti nantu à a replica.
Andrew, aghju una dumanda. Questi maravigliosi grafici chì avete dimustratu durante a presentazione, hè questu u risultatu di qualchì travagliu di a vostra utilità? Cumu sò stati fatti i grafici?